Merge "Fix issue #5283365: Rotating the device to portrait mode, hides the keyboard partly"
diff --git a/api/current.txt b/api/current.txt
index 5efa32f..0b6c245 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11369,13 +11369,13 @@
     method public static boolean isEffectSupported(java.lang.String);
     field public static final java.lang.String EFFECT_AUTOFIX = "android.media.effect.effects.AutoFixEffect";
     field public static final java.lang.String EFFECT_BACKDROPPER = "android.media.effect.effects.BackDropperEffect";
+    field public static final java.lang.String EFFECT_BITMAPOVERLAY = "android.media.effect.effects.BitmapOverlayEffect";
     field public static final java.lang.String EFFECT_BLACKWHITE = "android.media.effect.effects.BlackWhiteEffect";
     field public static final java.lang.String EFFECT_BRIGHTNESS = "android.media.effect.effects.BrightnessEffect";
     field public static final java.lang.String EFFECT_CONTRAST = "android.media.effect.effects.ContrastEffect";
     field public static final java.lang.String EFFECT_CROP = "android.media.effect.effects.CropEffect";
     field public static final java.lang.String EFFECT_CROSSPROCESS = "android.media.effect.effects.CrossProcessEffect";
     field public static final java.lang.String EFFECT_DOCUMENTARY = "android.media.effect.effects.DocumentaryEffect";
-    field public static final java.lang.String EFFECT_DOODLE = "android.media.effect.effects.DoodleEffect";
     field public static final java.lang.String EFFECT_DUOTONE = "android.media.effect.effects.DuotoneEffect";
     field public static final java.lang.String EFFECT_FILLLIGHT = "android.media.effect.effects.FillLightEffect";
     field public static final java.lang.String EFFECT_FISHEYE = "android.media.effect.effects.FisheyeEffect";
diff --git a/core/java/android/inputmethodservice/ExtractEditLayout.java b/core/java/android/inputmethodservice/ExtractEditLayout.java
index 25c0c99..220214b 100644
--- a/core/java/android/inputmethodservice/ExtractEditLayout.java
+++ b/core/java/android/inputmethodservice/ExtractEditLayout.java
@@ -16,6 +16,9 @@
 
 package android.inputmethodservice;
 
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuPopupHelper;
+
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.ActionMode;
@@ -23,12 +26,10 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.Button;
 import android.widget.LinearLayout;
 
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuPopupHelper;
-
 /**
  * ExtractEditLayout provides an ActionMode presentation for the
  * limited screen real estate in extract mode.
@@ -56,6 +57,7 @@
             mExtractActionButton.setVisibility(INVISIBLE);
             mEditButton.setVisibility(VISIBLE);
             mActionMode = mode;
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
             return mode;
         }
         return null;
@@ -158,6 +160,8 @@
             mExtractActionButton.setVisibility(VISIBLE);
             mEditButton.setVisibility(INVISIBLE);
 
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
             mActionMode = null;
         }
 
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index ccca22e..afb5bf1 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -48,6 +48,7 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.Window;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.SpinnerAdapter;
 
 import java.lang.ref.WeakReference;
@@ -397,6 +398,7 @@
                 // TODO animate this
                 mSplitView.setVisibility(View.VISIBLE);
             }
+            mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
             mActionMode = mode;
             return mode;
         }
@@ -681,6 +683,7 @@
 
             // Clear out the context mode views after the animation finishes
             mContextView.closeMode();
+            mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
 
             mActionMode = null;
 
diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java
index b54daba..ecda47e 100644
--- a/core/java/com/android/internal/view/StandaloneActionMode.java
+++ b/core/java/com/android/internal/view/StandaloneActionMode.java
@@ -26,6 +26,7 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
 
 import java.lang.ref.WeakReference;
 
@@ -86,6 +87,7 @@
         }
         mFinished = true;
 
+        mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
         mCallback.onDestroyActionMode(this);
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index a631380..7bc33c7 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -34,6 +34,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -455,4 +456,17 @@
     public boolean shouldDelayChildPressedState() {
         return false;
     }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+            // Action mode started
+            event.setSource(this);
+            event.setClassName(getClass().getName());
+            event.setPackageName(getContext().getPackageName());
+            event.setContentDescription(mTitle);
+        } else {
+            super.onInitializeAccessibilityEvent(event);
+        }
+    }
 }
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index eeff473..6e72fd7 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2485,7 +2485,10 @@
     <string name="textSelectionCABTitle">Text selection</string>
 
     <!-- Option to add the current misspelled word to the user dictionary. [CHAR LIMIT=25] -->
-    <string name="addToDictionary">+ add to dictionary</string>
+    <string name="addToDictionary">add to dictionary</string>
+
+    <!-- Option to delete the highlighted part of the text from the suggestion popup. [CHAR LIMIT=25] -->
+    <string name="deleteText">delete</string>
 
     <!-- EditText context menu -->
     <string name="inputMethod">Input method</string>
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 2932744..8baf5ec 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -303,7 +303,7 @@
     bool flushPortAsync(OMX_U32 portIndex);
 
     void disablePortAsync(OMX_U32 portIndex);
-    void enablePortAsync(OMX_U32 portIndex);
+    status_t enablePortAsync(OMX_U32 portIndex);
 
     static size_t countBuffersWeOwn(const Vector<BufferInfo> &buffers);
     static bool isIntermediateState(State state);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 9ab470b..6280f51 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2452,13 +2452,16 @@
                     mOutputPortSettingsHaveChanged = formatChanged;
                 }
 
-                enablePortAsync(portIndex);
-
-                status_t err = allocateBuffersOnPort(portIndex);
-
+                status_t err = enablePortAsync(portIndex);
                 if (err != OK) {
-                    CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
+                    CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err);
                     setState(ERROR);
+                } else {
+                    err = allocateBuffersOnPort(portIndex);
+                    if (err != OK) {
+                        CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
+                        setState(ERROR);
+                    }
                 }
             }
             break;
@@ -2773,16 +2776,14 @@
     freeBuffersOnPort(portIndex, true);
 }
 
-void OMXCodec::enablePortAsync(OMX_U32 portIndex) {
+status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
     CHECK(mState == EXECUTING || mState == RECONFIGURING);
 
     CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
     mPortStatus[portIndex] = ENABLING;
 
     CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex);
-    status_t err =
-        mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
-    CHECK_EQ(err, (status_t)OK);
+    return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
 }
 
 void OMXCodec::fillOutputBuffers() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index cd361ad..0448da7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -42,7 +42,7 @@
 
 public class NavigationBarView extends LinearLayout {
     final static boolean DEBUG = false;
-    final static String TAG = "NavigationBarView";
+    final static String TAG = "PhoneStatusBar/NavigationBarView";
 
     final static boolean DEBUG_DEADZONE = false;
 
@@ -60,6 +60,7 @@
     boolean mVertical;
 
     boolean mHidden, mLowProfile;
+    int mDisabledFlags = 0;
 
     public View getRecentsButton() {
         return mCurrentView.findViewById(R.id.recent_apps);
@@ -99,7 +100,7 @@
                 // even though setting the systemUI visibility below will turn these views
                 // on, we need them to come up faster so that they can catch this motion
                 // event
-                setLowProfile(false, false);
+                setLowProfile(false, false, false);
 
                 try {
                     mBarService.setSystemUiVisibility(0);
@@ -110,9 +111,18 @@
         }
     };
 
-    public void setNavigationVisibility(int disabledFlags) {
-        boolean disableNavigation = ((disabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) != 0);
-        boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
+    public void setDisabledFlags(int disabledFlags) {
+        Slog.d(TAG, "setDisabledFlags: " + disabledFlags);
+        setDisabledFlags(disabledFlags, false);
+    }
+
+    public void setDisabledFlags(int disabledFlags, boolean force) {
+        if (!force && mDisabledFlags == disabledFlags) return;
+
+        mDisabledFlags = disabledFlags;
+
+        final boolean disableNavigation = ((disabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) != 0);
+        final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
 
         getBackButton()   .setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
         getHomeButton()   .setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
@@ -121,11 +131,11 @@
     }
 
     public void setLowProfile(final boolean lightsOut) {
-        setLowProfile(lightsOut, true);
+        setLowProfile(lightsOut, true, false);
     }
 
-    public void setLowProfile(final boolean lightsOut, final boolean animate) {
-        if (lightsOut == mLowProfile) return;
+    public void setLowProfile(final boolean lightsOut, final boolean animate, final boolean force) {
+        if (!force && lightsOut == mLowProfile) return;
 
         mLowProfile = lightsOut;
 
@@ -245,6 +255,10 @@
         mCurrentView.setVisibility(View.VISIBLE);
         mVertical = (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270);
 
+        // force the low profile & disabled states into compliance
+        setLowProfile(mLowProfile, false, true /* force */);
+        setDisabledFlags(mDisabledFlags, true /* force */);
+
         if (DEBUG_DEADZONE) {
             mCurrentView.findViewById(R.id.deadzone).setBackgroundColor(0x808080FF);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 81233df..156d006 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -297,7 +297,7 @@
                 mNavigationBarView = 
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
-                setNavigationVisibility(mDisabled);
+                mNavigationBarView.setDisabledFlags(mDisabled);
 
                 sb.setOnSystemUiVisibilityChangeListener(
                     new View.OnSystemUiVisibilityChangeListener() {
@@ -1058,62 +1058,67 @@
                 old, state, diff));
         }
 
+        StringBuilder flagdbg = new StringBuilder();
+        flagdbg.append("disable: < ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "NAVIGATION" : "navigation");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
+        flagdbg.append(">");
+        Slog.d(TAG, flagdbg.toString());
+
         if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
             boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
             showClock(show);
         }
         if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
             if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
-                Slog.d(TAG, "DISABLE_EXPAND: yes");
                 animateCollapse();
             }
         }
 
         if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
-            setNavigationVisibility(state &
-                    (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK));
+            // the nav bar will take care of DISABLE_NAVIGATION and DISABLE_BACK
+            mNavigationBarView.setDisabledFlags(state);
+
+            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
+                // close recents if it's visible
+                mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
+                mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
+            }
         }
 
         if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
             if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
-                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
                 if (mTicking) {
                     mTicker.halt();
                 } else {
                     setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
                 }
             } else {
-                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
                 if (!mExpandedVisible) {
                     setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
                 }
             }
         } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
             if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-                Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes");
                 mTicker.halt();
             }
         }
     }
 
-    private void setNavigationVisibility(int visibility) {
-        boolean disableNavigation = ((visibility & StatusBarManager.DISABLE_NAVIGATION) != 0);
-        boolean disableBack = ((visibility & StatusBarManager.DISABLE_BACK) != 0);
-
-        Slog.i(TAG, "DISABLE_BACK: " + (disableBack ? "yes" : "no"));
-        Slog.i(TAG, "DISABLE_NAVIGATION: " + (disableNavigation ? "yes" : "no"));
-
-        if (mNavigationBarView != null) {
-            mNavigationBarView.setNavigationVisibility(visibility);
-        }
-
-        if (disableNavigation) {
-            // close recents if it's visible
-            mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
-            mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
-        }
-    }
-
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 20088b1..903b405 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2171,6 +2171,8 @@
                         if (mActionModePopup != null) {
                             post(mShowActionModePopup);
                         }
+                        mActionModeView.sendAccessibilityEvent(
+                                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
                     } else {
                         mActionMode = null;
                     }