Merge "Use setCustomSelectActionModeCallback to disallow action bar." into jb-dev
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index c643137..bdcb2af 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -1208,6 +1208,9 @@
* affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
*/
private void addChild(ViewGroup parent, View child, boolean changesLayout) {
+ if (parent.getWindowVisibility() != View.VISIBLE) {
+ return;
+ }
if ((mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
// Want disappearing animations to finish up before proceeding
cancel(DISAPPEARING);
@@ -1243,6 +1246,9 @@
* @hide
*/
public void layoutChange(ViewGroup parent) {
+ if (parent.getWindowVisibility() != View.VISIBLE) {
+ return;
+ }
if ((mTransitionTypes & FLAG_CHANGING) == FLAG_CHANGING && !isRunning()) {
// This method is called for all calls to layout() in the container, including
// those caused by add/remove/hide/show events, which will already have set up
@@ -1301,6 +1307,9 @@
* affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
*/
private void removeChild(ViewGroup parent, View child, boolean changesLayout) {
+ if (parent.getWindowVisibility() != View.VISIBLE) {
+ return;
+ }
if ((mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
// Want appearing animations to finish up before proceeding
cancel(APPEARING);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a74a0ef..20eef11 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12725,6 +12725,7 @@
if (!initialized) {
a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
+ if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
onAnimationStart();
}
@@ -12738,6 +12739,7 @@
} else {
invalidationTransform = parent.mChildTransformation;
}
+
if (more) {
if (!a.willChangeBounds()) {
if ((flags & (parent.FLAG_OPTIMIZE_INVALIDATE | parent.FLAG_ANIMATION_DONE)) ==
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 421109f..a243c73 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3154,8 +3154,12 @@
}
/**
- * Adds a child view. If no layout parameters are already set on the child, the
- * default parameters for this ViewGroup are set on the child.
+ * <p>Adds a child view. If no layout parameters are already set on the child, the
+ * default parameters for this ViewGroup are set on the child.</p>
+ *
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*
* @param child the child view to add
*
@@ -3168,6 +3172,10 @@
/**
* Adds a child view. If no layout parameters are already set on the child, the
* default parameters for this ViewGroup are set on the child.
+ *
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*
* @param child the child view to add
* @param index the position at which to add the child
@@ -3189,6 +3197,10 @@
* Adds a child view with this ViewGroup's default layout parameters and the
* specified width and height.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param child the child view to add
*/
public void addView(View child, int width, int height) {
@@ -3201,6 +3213,10 @@
/**
* Adds a child view with the specified layout parameters.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param child the child view to add
* @param params the layout parameters to set on the child
*/
@@ -3211,6 +3227,10 @@
/**
* Adds a child view with the specified layout parameters.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param child the child view to add
* @param index the position at which to add the child
* @param params the layout parameters to set on the child
@@ -3528,6 +3548,10 @@
/**
* {@inheritDoc}
+ *
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*/
public void removeView(View view) {
removeViewInternal(view);
@@ -3539,6 +3563,10 @@
* Removes a view during layout. This is useful if in your onLayout() method,
* you need to remove more views.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param view the view to remove from the group
*/
public void removeViewInLayout(View view) {
@@ -3549,6 +3577,10 @@
* Removes a range of views during layout. This is useful if in your onLayout() method,
* you need to remove more views.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param start the index of the first view to remove from the group
* @param count the number of views to remove from the group
*/
@@ -3559,6 +3591,10 @@
/**
* Removes the view at the specified position in the group.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param index the position in the group of the view to remove
*/
public void removeViewAt(int index) {
@@ -3570,6 +3606,10 @@
/**
* Removes the specified range of views from the group.
*
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
+ *
* @param start the first position in the group of the range of views to remove
* @param count the number of views to remove
*/
@@ -3715,6 +3755,10 @@
/**
* Call this method to remove all child views from the
* ViewGroup.
+ *
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*/
public void removeAllViews() {
removeAllViewsInLayout();
@@ -3730,6 +3774,10 @@
* that can currently fit inside the object on screen. Do not call
* this method unless you are extending ViewGroup and understand the
* view measuring and layout pipeline.
+ *
+ * <p><strong>Note:</strong> do not invoke this method from
+ * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
+ * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*/
public void removeAllViewsInLayout() {
final int count = mChildrenCount;
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index d92ebcd..85d77cb 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.RectF;
+import android.os.Handler;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -207,6 +208,11 @@
private final CloseGuard guard = CloseGuard.get();
+ private Handler mListenerHandler;
+ private Runnable mOnStart;
+ private Runnable mOnRepeat;
+ private Runnable mOnEnd;
+
/**
* Creates a new animation with a duration of 0ms, the default interpolator, with
* fillBefore set to true and fillAfter set to false
@@ -275,6 +281,7 @@
mRepeated = 0;
mMore = true;
mOneMoreTime = true;
+ mListenerHandler = null;
}
/**
@@ -290,7 +297,7 @@
*/
public void cancel() {
if (mStarted && !mEnded) {
- if (mListener != null) mListener.onAnimationEnd(this);
+ fireAnimationEnd();
mEnded = true;
guard.close();
}
@@ -306,7 +313,7 @@
if (mStarted && !mEnded) {
mEnded = true;
guard.close();
- if (mListener != null) mListener.onAnimationEnd(this);
+ fireAnimationEnd();
}
}
@@ -341,6 +348,38 @@
}
/**
+ * Sets the handler used to invoke listeners.
+ *
+ * @hide
+ */
+ public void setListenerHandler(Handler handler) {
+ if (mListenerHandler == null) {
+ mOnStart = new Runnable() {
+ public void run() {
+ if (mListener != null) {
+ mListener.onAnimationStart(Animation.this);
+ }
+ }
+ };
+ mOnRepeat = new Runnable() {
+ public void run() {
+ if (mListener != null) {
+ mListener.onAnimationRepeat(Animation.this);
+ }
+ }
+ };
+ mOnEnd = new Runnable() {
+ public void run() {
+ if (mListener != null) {
+ mListener.onAnimationEnd(Animation.this);
+ }
+ }
+ };
+ }
+ mListenerHandler = handler;
+ }
+
+ /**
* Sets the acceleration curve for this animation. The interpolator is loaded as
* a resource from the specified context.
*
@@ -792,7 +831,6 @@
* @return True if the animation is still running
*/
public boolean getTransformation(long currentTime, Transformation outTransformation) {
-
if (mStartTime == -1) {
mStartTime = currentTime;
}
@@ -815,9 +853,7 @@
if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) {
if (!mStarted) {
- if (mListener != null) {
- mListener.onAnimationStart(this);
- }
+ fireAnimationStart();
mStarted = true;
if (USE_CLOSEGUARD) {
guard.open("cancel or detach or getTransformation");
@@ -839,9 +875,7 @@
if (!mEnded) {
mEnded = true;
guard.close();
- if (mListener != null) {
- mListener.onAnimationEnd(this);
- }
+ fireAnimationEnd();
}
} else {
if (mRepeatCount > 0) {
@@ -855,9 +889,7 @@
mStartTime = -1;
mMore = true;
- if (mListener != null) {
- mListener.onAnimationRepeat(this);
- }
+ fireAnimationRepeat();
}
}
@@ -868,7 +900,28 @@
return mMore;
}
-
+
+ private void fireAnimationStart() {
+ if (mListener != null) {
+ if (mListenerHandler == null) mListener.onAnimationStart(this);
+ else mListenerHandler.postAtFrontOfQueue(mOnStart);
+ }
+ }
+
+ private void fireAnimationRepeat() {
+ if (mListener != null) {
+ if (mListenerHandler == null) mListener.onAnimationRepeat(this);
+ else mListenerHandler.postAtFrontOfQueue(mOnRepeat);
+ }
+ }
+
+ private void fireAnimationEnd() {
+ if (mListener != null) {
+ if (mListenerHandler == null) mListener.onAnimationEnd(this);
+ else mListenerHandler.postAtFrontOfQueue(mOnEnd);
+ }
+ }
+
/**
* Gets the transformation to apply at a specified point in time. Implementations of this
* method should always replace the specified Transformation or document they are doing
diff --git a/core/java/android/view/textservice/SpellCheckerSubtype.java b/core/java/android/view/textservice/SpellCheckerSubtype.java
index f235295..c753188 100644
--- a/core/java/android/view/textservice/SpellCheckerSubtype.java
+++ b/core/java/android/view/textservice/SpellCheckerSubtype.java
@@ -146,7 +146,10 @@
return false;
}
- private static Locale constructLocaleFromString(String localeStr) {
+ /**
+ * @hide
+ */
+ public static Locale constructLocaleFromString(String localeStr) {
if (TextUtils.isEmpty(localeStr))
return null;
String[] localeParams = localeStr.split("_", 3);
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 58dd82e..f03fb86 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -7872,7 +7872,7 @@
nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);
if ((data.mSelectionReason == TextSelectionData.REASON_ACCESSIBILITY_INJECTOR)
- || (!mSelectingText
+ || (!mSelectingText && data.mStart != data.mEnd
&& data.mSelectionReason != TextSelectionData.REASON_SELECT_WORD)) {
selectionDone();
mShowTextSelectionExtra = true;
@@ -8494,6 +8494,11 @@
mWebView.postInvalidate();
}
+ // Note: must be called before first WebViewClassic is created.
+ public static void setShouldMonitorWebCoreThread() {
+ WebViewCore.setShouldMonitorWebCoreThread();
+ }
+
private native void nativeCreate(int ptr, String drawableDir, boolean isHighEndGfx);
private native void nativeDebugDump();
private native void nativeDestroy();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index af7914e..ba42ff5 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -144,6 +144,11 @@
private int mChromeCanFocusDirection;
private int mTextSelectionChangeReason = TextSelectionData.REASON_UNKNOWN;
+ // Used to determine if we should monitor the WebCore thread for responsiveness.
+ // If it "hangs", for example a web page enters a while(true) loop, we will
+ // prompt the user with a dialog allowing them to terminate the process.
+ private static boolean sShouldMonitorWebCoreThread;
+
// The thread name used to identify the WebCore thread and for use in
// debugging other classes that require operation within the WebCore thread.
/* package */ static final String THREAD_NAME = "WebViewCoreThread";
@@ -176,9 +181,13 @@
Log.e(LOGTAG, Log.getStackTraceString(e));
}
- // Start the singleton watchdog which will monitor the WebCore thread
- // to verify it's still processing messages.
- WebCoreThreadWatchdog.start(sWebCoreHandler);
+ if (sShouldMonitorWebCoreThread) {
+ // Start the singleton watchdog which will monitor the WebCore thread
+ // to verify it's still processing messages. Note that this is the only
+ // time we need to check the value as all the other public methods on
+ // the WebCoreThreadWatchdog are no-ops if start() is not called.
+ WebCoreThreadWatchdog.start(sWebCoreHandler);
+ }
}
// Make sure the Watchdog is aware of this new WebView.
WebCoreThreadWatchdog.registerWebView(w);
@@ -3061,6 +3070,10 @@
return mDeviceOrientationService;
}
+ static void setShouldMonitorWebCoreThread() {
+ sShouldMonitorWebCoreThread = true;
+ }
+
private native void nativeSetIsPaused(int nativeClass, boolean isPaused);
private native void nativePause(int nativeClass);
private native void nativeResume(int nativeClass);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6cee0f3..9abe72b 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -579,6 +579,7 @@
private InputConnectionWrapper mPublicInputConnection;
private Runnable mClearScrollingCache;
+ Runnable mPositionScrollAfterLayout;
private int mMinimumVelocity;
private int mMaximumVelocity;
private float mVelocityScale = 1.0f;
@@ -1910,6 +1911,7 @@
removeAllViewsInLayout();
mFirstPosition = 0;
mDataChanged = false;
+ mPositionScrollAfterLayout = null;
mNeedSync = false;
mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
@@ -4248,11 +4250,11 @@
if (mDataChanged) {
// Wait until we're back in a stable state to try this.
- post(new Runnable() {
+ mPositionScrollAfterLayout = new Runnable() {
@Override public void run() {
start(position);
}
- });
+ };
return;
}
@@ -4299,11 +4301,11 @@
if (mDataChanged) {
// Wait until we're back in a stable state to try this.
- post(new Runnable() {
+ mPositionScrollAfterLayout = new Runnable() {
@Override public void run() {
start(position, boundPosition);
}
- });
+ };
return;
}
@@ -4376,11 +4378,11 @@
if (mDataChanged) {
// Wait until we're back in a stable state to try this.
final int postOffset = offset;
- post(new Runnable() {
+ mPositionScrollAfterLayout = new Runnable() {
@Override public void run() {
startWithOffset(position, postOffset, duration);
}
- });
+ };
return;
}
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index be6b4e2..4eb169b 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -400,6 +400,9 @@
if (viewTreeObserver.isAlive()) {
viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
}
+ if (isShowingPopup()) {
+ dismissPopup();
+ }
mIsAttachedToWindow = false;
}
@@ -420,9 +423,7 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
mActivityChooserContent.layout(0, 0, right - left, bottom - top);
- if (getListPopupWindow().isShowing()) {
- showPopupUnchecked(mAdapter.getMaxActivityCount());
- } else {
+ if (!isShowingPopup()) {
dismissPopup();
}
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 0a40d5e..8975109 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1275,6 +1275,10 @@
mLayoutMode = LAYOUT_NORMAL;
mDataChanged = false;
+ if (mPositionScrollAfterLayout != null) {
+ post(mPositionScrollAfterLayout);
+ mPositionScrollAfterLayout = null;
+ }
mNeedSync = false;
setNextSelectedPositionInt(mSelectedPosition);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c62b62b..d2e55d9 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1691,6 +1691,10 @@
mLayoutMode = LAYOUT_NORMAL;
mDataChanged = false;
+ if (mPositionScrollAfterLayout != null) {
+ post(mPositionScrollAfterLayout);
+ mPositionScrollAfterLayout = null;
+ }
mNeedSync = false;
setNextSelectedPositionInt(mSelectedPosition);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 81a44fd..bd19f00 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7678,7 +7678,7 @@
mContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
final SpellCheckerSubtype subtype = textServicesManager.getCurrentSpellCheckerSubtype(true);
if (subtype != null) {
- locale = new Locale(subtype.getLocale());
+ locale = SpellCheckerSubtype.constructLocaleFromString(subtype.getLocale());
}
return locale;
}
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 35b8665..c235289 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -173,12 +173,11 @@
<RelativeLayout
android:id="@+id/faceLockAreaView"
android:visibility="invisible"
- android:layout_row="3"
+ android:layout_row="4"
android:layout_column="0"
- android:layout_rowSpan="2"
+ android:layout_rowSpan="1"
android:layout_columnSpan="1"
android:layout_gravity="fill"
- android:layout_marginTop="4dip"
android:layout_marginBottom="4dip"
android:layout_width="0dip"
android:layout_height="0dip"
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
index d8aa40f..8bb653b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
@@ -111,12 +111,12 @@
/** Frame width to be encoded, defaults to 320.
* Actual received frame size has to match this */
@GenerateFieldPort(name = "width", hasDefault = true)
- private int mWidth = 320;
+ private int mWidth = 0;
/** Frame height to to be encoded, defaults to 240.
* Actual received frame size has to match */
@GenerateFieldPort(name = "height", hasDefault = true)
- private int mHeight = 240;
+ private int mHeight = 0;
/** Stream framerate to encode the frames at.
* By default, frames are encoded at 30 FPS*/
@@ -245,6 +245,11 @@
if (mProfile != null) {
mMediaRecorder.setProfile(mProfile);
mFps = mProfile.videoFrameRate;
+ // If width and height are set larger than 0, then those
+ // overwrite the ones in the profile.
+ if (mWidth > 0 && mHeight > 0) {
+ mMediaRecorder.setVideoSize(mWidth, mHeight);
+ }
} else {
mMediaRecorder.setOutputFormat(mOutputFormat);
mMediaRecorder.setVideoEncoder(mVideoEncoder);
@@ -298,7 +303,10 @@
screenFormat.setBytesPerSample(4);
int width, height;
- if (mProfile != null) {
+ boolean widthHeightSpecified = mWidth > 0 && mHeight > 0;
+ // If width and height are specified, then use those instead
+ // of that in the profile.
+ if (mProfile != null && !widthHeightSpecified) {
width = mProfile.videoFrameWidth;
height = mProfile.videoFrameHeight;
} else {
@@ -410,7 +418,6 @@
// And swap buffers
glEnv.swapBuffers();
mNumFramesEncoded++;
- if (mLogVerbose) Log.v(TAG, "numFramesEncoded = " + mNumFramesEncoded);
}
private void stopRecording(FilterContext context) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 29de5c1..4ee0d25 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -33,6 +33,7 @@
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -1434,8 +1435,9 @@
&& attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
&& attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER;
}
-
+
/** {@inheritDoc} */
+ @Override
public View addStartingWindow(IBinder appToken, String packageName, int theme,
CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
int icon, int windowFlags) {
@@ -1445,7 +1447,7 @@
if (packageName == null) {
return null;
}
-
+
try {
Context context = mContext;
//Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
@@ -1458,16 +1460,19 @@
// Ignore
}
}
-
+
Window win = PolicyManager.makeNewWindow(context);
- if (win.getWindowStyle().getBoolean(
- com.android.internal.R.styleable.Window_windowDisablePreview, false)) {
+ final TypedArray ta = win.getWindowStyle();
+ if (ta.getBoolean(
+ com.android.internal.R.styleable.Window_windowDisablePreview, false)
+ || ta.getBoolean(
+ com.android.internal.R.styleable.Window_windowShowWallpaper,false)) {
return null;
}
-
+
Resources r = context.getResources();
win.setTitle(r.getText(labelRes, nonLocalizedLabel));
-
+
win.setType(
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
// Force the window flags: this is a fake window, so it is not really
@@ -1483,14 +1488,14 @@
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
-
+
if (!compatInfo.supportsScreen()) {
win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW);
}
win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
-
+
final WindowManager.LayoutParams params = win.getAttributes();
params.token = appToken;
params.packageName = packageName;
@@ -1512,7 +1517,7 @@
// earlier.)
return null;
}
-
+
if (localLOGV) Log.v(
TAG, "Adding starting window for " + packageName
+ " / " + appToken + ": "
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 499ff7a..c7b336f 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -254,10 +254,8 @@
return scs;
} else if (candidate == null) {
final String scsLocale = scs.getLocale();
- if (candidateLocale.length() >= 2
- && scsLocale.length() >= 2
- && candidateLocale.substring(0, 2).equals(
- scsLocale.substring(0, 2))) {
+ if (candidateLocale.length() >= 2 && scsLocale.length() >= 2
+ && candidateLocale.startsWith(scsLocale)) {
// Fall back to the applicable language
candidate = scs;
}
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 5e2f494..039efbd 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -191,8 +191,11 @@
@Override
public void onSomePackagesChanged() {
synchronized (mLock) {
- populateAccessibilityServiceListLocked();
- manageServicesLocked();
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ populateAccessibilityServiceListLocked();
+ manageServicesLocked();
+ }
}
}
@@ -242,11 +245,14 @@
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
synchronized (mLock) {
- populateAccessibilityServiceListLocked();
- handleAccessibilityEnabledSettingChangedLocked();
- handleTouchExplorationEnabledSettingChangedLocked();
- updateInputFilterLocked();
- sendStateToClientsLocked();
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ populateAccessibilityServiceListLocked();
+ handleAccessibilityEnabledSettingChangedLocked();
+ handleTouchExplorationEnabledSettingChangedLocked();
+ updateInputFilterLocked();
+ sendStateToClientsLocked();
+ }
}
return;
@@ -294,9 +300,12 @@
public void onChange(boolean selfChange) {
super.onChange(selfChange);
synchronized (mLock) {
- handleAccessibilityEnabledSettingChangedLocked();
- updateInputFilterLocked();
- sendStateToClientsLocked();
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ handleAccessibilityEnabledSettingChangedLocked();
+ updateInputFilterLocked();
+ sendStateToClientsLocked();
+ }
}
}
});
@@ -309,9 +318,12 @@
public void onChange(boolean selfChange) {
super.onChange(selfChange);
synchronized (mLock) {
- handleTouchExplorationEnabledSettingChangedLocked();
- updateInputFilterLocked();
- sendStateToClientsLocked();
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ handleTouchExplorationEnabledSettingChangedLocked();
+ updateInputFilterLocked();
+ sendStateToClientsLocked();
+ }
}
}
});
@@ -324,7 +336,10 @@
public void onChange(boolean selfChange) {
super.onChange(selfChange);
synchronized (mLock) {
- manageServicesLocked();
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ manageServicesLocked();
+ }
}
}
});
@@ -747,10 +762,6 @@
* Manages services by starting enabled ones and stopping disabled ones.
*/
private void manageServicesLocked() {
- // While the UI automation service is running it takes over.
- if (mUiAutomationService != null) {
- return;
- }
populateEnabledServicesLocked(mEnabledServices);
final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
mEnabledServices);
@@ -926,8 +937,13 @@
private void tryEnableTouchExploration(final Service service) {
if (!mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode) {
- mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG,
- service).sendToTarget();
+ if (!service.mIsAutomation) {
+ mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG,
+ service).sendToTarget();
+ } else {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+ }
}
}
@@ -1479,10 +1495,15 @@
// the state based on values in the settings database.
if (mIsAutomation) {
mUiAutomationService = null;
+
handleAccessibilityEnabledSettingChangedLocked();
+ sendStateToClientsLocked();
+
handleTouchExplorationEnabledSettingChangedLocked();
updateInputFilterLocked();
- sendStateToClientsLocked();
+
+ populateAccessibilityServiceListLocked();
+ manageServicesLocked();
}
}
}
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 97f65ad8..d6954a5 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -134,10 +134,11 @@
}
private void updateWindowsAppsAndRotationAnimationsLocked() {
+ final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
int i;
- final int NAT = mService.mAppTokens.size();
+ final int NAT = appTokens.size();
for (i=0; i<NAT; i++) {
- final AppWindowAnimator appAnimator = mService.mAppTokens.get(i).mAppAnimator;
+ final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
&& appAnimator.animation != AppWindowAnimator.sDummyAnimation;
if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
@@ -401,9 +402,10 @@
private void testTokenMayBeDrawnLocked() {
// See if any windows have been drawn, so they (and others
// associated with them) can now be shown.
- final int NT = mService.mAppTokens.size();
+ final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+ final int NT = appTokens.size();
for (int i=0; i<NT; i++) {
- AppWindowToken wtoken = mService.mAppTokens.get(i);
+ AppWindowToken wtoken = appTokens.get(i);
if (wtoken.mAppAnimator.freezingScreen) {
int numInteresting = wtoken.numInterestingWindows;
if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 895b5c1..d9e0ec6 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -351,13 +351,20 @@
final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
/**
- * Z-ordered (bottom-most first) list of all application tokens, for
- * controlling the ordering of windows in different applications. This
- * contains AppWindowToken objects.
+ * List controlling the ordering of windows in different applications which must
+ * be kept in sync with ActivityManager.
*/
final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
/**
+ * AppWindowTokens in the Z order they were in at the start of an animation. Between
+ * animations this list is maintained in the exact order of mAppTokens. If tokens
+ * are added to mAppTokens during an animation an attempt is made to insert them at the same
+ * logical location in this list. Note that this list is always in sync with mWindows.
+ */
+ ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
+
+ /**
* Application tokens that are in the process of exiting, but still
* on screen for animations.
*/
@@ -529,8 +536,6 @@
boolean mSkipAppTransitionAnimation = false;
final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
- final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
- final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Display mDisplay;
@@ -1010,10 +1015,10 @@
+ client.asBinder() + " (token=" + token + ")");
// Figure out where the window should go, based on the
// order of applications.
- final int NA = mAppTokens.size();
+ final int NA = mAnimatingAppTokens.size();
WindowState pos = null;
for (i=NA-1; i>=0; i--) {
- AppWindowToken t = mAppTokens.get(i);
+ AppWindowToken t = mAnimatingAppTokens.get(i);
if (t == token) {
i--;
break;
@@ -1046,7 +1051,7 @@
// Continue looking down until we find the first
// token that has windows.
while (i >= 0) {
- AppWindowToken t = mAppTokens.get(i);
+ AppWindowToken t = mAnimatingAppTokens.get(i);
final int NW = t.windows.size();
if (NW > 0) {
pos = t.windows.get(NW-1);
@@ -1167,6 +1172,7 @@
}
}
+ /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */
static boolean canBeImeTarget(WindowState w) {
final int fl = w.mAttrs.flags
& (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
@@ -1636,7 +1642,7 @@
continue;
}
}
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": readyfordisplay="
+ w.isReadyForDisplay() + " mDrawState=" + w.mWinAnimator.mDrawState);
if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
&& (mWallpaperTarget == w || w.isDrawnLw())) {
@@ -1729,12 +1735,15 @@
Slog.v(TAG, "Old wallpaper still the target.");
}
mWallpaperTarget = oldW;
- }
-
+ foundW = oldW;
+ foundI = oldI;
+ mLowerWallpaperTarget = null;
+ mUpperWallpaperTarget = null;
+ }
// Now set the upper and lower wallpaper targets
// correctly, and make sure that we are positioning
// the wallpaper below the lower.
- if (foundI > oldI) {
+ else if (foundI > oldI) {
// The new target is on top of the old one.
if (DEBUG_WALLPAPER) {
Slog.v(TAG, "Found target above old target.");
@@ -1872,7 +1881,7 @@
}
wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
- if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
+ if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "adjustWallpaper win "
+ wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
// First, if this window is at the current index, then all
@@ -1926,7 +1935,7 @@
curWallpaperIndex--;
WindowState wallpaper = token.windows.get(curWallpaperIndex);
wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
- if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
+ if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
+ wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
}
}
@@ -3484,6 +3493,25 @@
Binder.restoreCallingIdentity(origId);
}
+ /**
+ * Find the location to insert a new AppWindowToken into the window-ordered app token list.
+ * Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
+ * @param addPos The location the token was inserted into in mAppTokens.
+ * @param wtoken The token to insert.
+ */
+ private void addAppTokenToAnimating(final int addPos, final AppWindowToken wtoken) {
+ if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
+ // It was inserted into the beginning or end of mAppTokens. Honor that.
+ mAnimatingAppTokens.add(addPos, wtoken);
+ return;
+ }
+ // Find the item immediately above the mAppTokens insertion point and put the token
+ // immediately below that one in mAnimatingAppTokens.
+ final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
+ mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), wtoken);
+ }
+
+ @Override
public void addAppToken(int addPos, IApplicationToken token,
int groupId, int requestedOrientation, boolean fullscreen) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -3518,6 +3546,7 @@
wtoken.requestedOrientation = requestedOrientation;
if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
mAppTokens.add(addPos, wtoken);
+ addAppTokenToAnimating(addPos, wtoken);
mTokenMap.put(token.asBinder(), wtoken);
// Application tokens start out hidden.
@@ -3835,7 +3864,7 @@
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Prepare app transition: transit=" + transit
+ " mNextAppTransition=" + mNextAppTransition
- + "\nCallers=" + Debug.getCallers(3));
+ + " Callers=" + Debug.getCallers(3));
if (okToDisplay()) {
if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
|| mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
@@ -4467,6 +4496,7 @@
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"removeAppToken: " + wtoken);
mAppTokens.remove(wtoken);
+ mAnimatingAppTokens.remove(wtoken);
wtoken.removed = true;
if (wtoken.startingData != null) {
startingToken = wtoken;
@@ -4498,11 +4528,13 @@
private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
final int NW = token.windows.size();
+ if (NW > 0) {
+ mWindowsChanged = true;
+ }
for (int i=0; i<NW; i++) {
WindowState win = token.windows.get(i);
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
mWindows.remove(win);
- mWindowsChanged = true;
int j = win.mChildWindows.size();
while (j > 0) {
j--;
@@ -4521,6 +4553,12 @@
}
}
+ void dumpAnimatingAppTokensLocked() {
+ for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
+ Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token);
+ }
+ }
+
void dumpWindowsLocked() {
for (int i=mWindows.size()-1; i>=0; i--) {
Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
@@ -4530,7 +4568,7 @@
private int findWindowOffsetLocked(int tokenPos) {
final int NW = mWindows.size();
- if (tokenPos >= mAppTokens.size()) {
+ if (tokenPos >= mAnimatingAppTokens.size()) {
int i = NW;
while (i > 0) {
i--;
@@ -4544,7 +4582,7 @@
while (tokenPos > 0) {
// Find the first app token below the new position that has
// a window displayed.
- final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
+ final AppWindowToken wtoken = mAnimatingAppTokens.get(tokenPos-1);
if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
+ tokenPos + " -- " + wtoken.token);
if (wtoken.sendingToBottom) {
@@ -4632,9 +4670,16 @@
if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
if (DEBUG_REORDER) dumpAppTokensLocked();
final AppWindowToken wtoken = findAppWindowToken(token);
+ final int oldIndex = mAppTokens.indexOf(wtoken);
if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
"Start moving token " + wtoken + " initially at "
- + mAppTokens.indexOf(wtoken));
+ + oldIndex);
+ if (oldIndex > index && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
+ && !mAppTransitionRunning) {
+ // animation towards back has not started, copy old list for duration of animation.
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
+ }
if (wtoken == null || !mAppTokens.remove(wtoken)) {
Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
+ token + " (" + wtoken + ")");
@@ -4644,24 +4689,30 @@
if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
if (DEBUG_REORDER) dumpAppTokensLocked();
+ if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET && !mAppTransitionRunning) {
+ // Not animating, bring animating app list in line with mAppTokens.
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
- final long origId = Binder.clearCallingIdentity();
- if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
- if (DEBUG_REORDER) dumpWindowsLocked();
- if (tmpRemoveAppWindowsLocked(wtoken)) {
- if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
+ // Bring window ordering, window focus and input window in line with new app token
+ final long origId = Binder.clearCallingIdentity();
+ if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
if (DEBUG_REORDER) dumpWindowsLocked();
- reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
- if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
- if (DEBUG_REORDER) dumpWindowsLocked();
- updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
- false /*updateInputWindows*/);
- mLayoutNeeded = true;
- mInputMonitor.setUpdateInputWindowsNeededLw();
- performLayoutAndPlaceSurfacesLocked();
- mInputMonitor.updateInputWindowsLw(false /*force*/);
+ if (tmpRemoveAppWindowsLocked(wtoken)) {
+ if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
+ if (DEBUG_REORDER) dumpWindowsLocked();
+ reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
+ if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
+ if (DEBUG_REORDER) dumpWindowsLocked();
+ updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
+ false /*updateInputWindows*/);
+ mLayoutNeeded = true;
+ mInputMonitor.setUpdateInputWindowsNeededLw();
+ performLayoutAndPlaceSurfacesLocked();
+ mInputMonitor.updateInputWindowsLw(false /*force*/);
+ }
+ Binder.restoreCallingIdentity(origId);
}
- Binder.restoreCallingIdentity(origId);
}
}
@@ -4702,7 +4753,9 @@
assignLayersLocked();
}
mLayoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ if (!mInLayout) {
+ performLayoutAndPlaceSurfacesLocked();
+ }
mInputMonitor.updateInputWindowsLw(false /*force*/);
}
}
@@ -4758,22 +4811,22 @@
"Adding next to top: " + wt);
mAppTokens.add(wt);
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
- mToTopApps.remove(wt);
- mToBottomApps.remove(wt);
- mToTopApps.add(wt);
wt.sendingToBottom = false;
- wt.sendingToTop = true;
}
}
}
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
+ if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
+ && !mAppTransitionRunning) {
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
moveAppWindowsLocked(tokens, mAppTokens.size());
}
}
Binder.restoreCallingIdentity(origId);
}
+ @Override
public void moveAppTokensToBottom(List<IBinder> tokens) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"moveAppTokensToBottom()")) {
@@ -4782,8 +4835,14 @@
final long origId = Binder.clearCallingIdentity();
synchronized(mWindowMap) {
- removeAppTokensLocked(tokens);
final int N = tokens.size();
+ if (N > 0 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
+ && !mAppTransitionRunning) {
+ // animating towards back, hang onto old list for duration of animation.
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
+ }
+ removeAppTokensLocked(tokens);
int pos = 0;
for (int i=0; i<N; i++) {
AppWindowToken wt = findAppWindowToken(tokens.get(i));
@@ -4792,17 +4851,16 @@
"Adding next to bottom: " + wt + " at " + pos);
mAppTokens.add(pos, wt);
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
- mToTopApps.remove(wt);
- mToBottomApps.remove(wt);
- mToBottomApps.add(i, wt);
- wt.sendingToTop = false;
wt.sendingToBottom = true;
}
pos++;
}
}
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
+ if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
+ && !mAppTransitionRunning) {
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
moveAppWindowsLocked(tokens, 0);
}
}
@@ -7010,6 +7068,8 @@
"*** APP TRANSITION TIMEOUT");
mAppTransitionReady = true;
mAppTransitionTimeout = true;
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
performLayoutAndPlaceSurfacesLocked();
}
}
@@ -7533,9 +7593,9 @@
}
// And add in the still active app tokens in Z order.
- NT = mAppTokens.size();
+ NT = mAnimatingAppTokens.size();
for (int j=0; j<NT; j++) {
- i = reAddAppWindowsLocked(i, mAppTokens.get(j));
+ i = reAddAppWindowsLocked(i, mAnimatingAppTokens.get(j));
}
i -= lastWallpaper;
@@ -7555,7 +7615,7 @@
}
}
Slog.w(TAG, "Current app token list:");
- dumpAppTokensLocked();
+ dumpAnimatingAppTokensLocked();
Slog.w(TAG, "Final window list:");
dumpWindowsLocked();
}
@@ -7624,7 +7684,8 @@
if (DEBUG) {
throw new RuntimeException("Recursive call!");
}
- Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
+ Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+ + Debug.getCallers(3));
return;
}
@@ -7913,22 +7974,7 @@
mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
- // If there are applications waiting to come to the
- // top of the stack, now is the time to move their windows.
- // (Note that we don't do apps going to the bottom
- // here -- we want to keep their windows in the old
- // Z-order until the animation completes.)
- if (mToTopApps.size() > 0) {
- NN = mAppTokens.size();
- for (i=0; i<NN; i++) {
- AppWindowToken wtoken = mAppTokens.get(i);
- if (wtoken.sendingToTop) {
- wtoken.sendingToTop = false;
- moveAppWindowsLocked(wtoken, NN, false);
- }
- }
- mToTopApps.clear();
- }
+ rebuildAppWindowListLocked();
// if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
WindowState oldWallpaper =
@@ -8155,13 +8201,14 @@
int changes = 0;
mAppTransitionRunning = false;
- // Clear information about apps that were moving.
- mToBottomApps.clear();
-
+ // Restore window app tokens to the ActivityManager views
+ mAnimatingAppTokens.clear();
+ mAnimatingAppTokens.addAll(mAppTokens);
rebuildAppWindowListLocked();
+
changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
mInnerFields.mAdjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
- moveInputMethodWindowsIfNeededLocked(false);
+ moveInputMethodWindowsIfNeededLocked(true);
mInnerFields.mWallpaperMayChange = true;
// Since the window list has been rebuilt, focus might
// have to be recomputed since the actual order of windows
@@ -8242,7 +8289,7 @@
// to go through the process of getting informed
// by the application when it has finished drawing.
if (w.mOrientationChanging) {
- if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
+ if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
"Orientation start waiting for draw mDrawState=DRAW_PENDING in "
+ w + ", surface " + winAnimator.mSurface);
winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
@@ -8683,25 +8730,11 @@
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"performLayout: App token exiting now removed" + token);
mAppTokens.remove(token);
+ mAnimatingAppTokens.remove(token);
mExitingAppTokens.remove(i);
}
}
- if (!mAnimator.mAnimating && mAppTransitionRunning) {
- // We have finished the animation of an app transition. To do
- // this, we have delayed a lot of operations like showing and
- // hiding apps, moving apps in Z-order, etc. The app token list
- // reflects the correct Z-order, but the window list may now
- // be out of sync with it. So here we will just rebuild the
- // entire app window list. Fun!
- mAppTransitionRunning = false;
- mLayoutNeeded = true;
- rebuildAppWindowListLocked();
- assignLayersLocked();
- // Clear information about apps that were moving.
- mToBottomApps.clear();
- }
-
if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
try {
@@ -9030,7 +9063,7 @@
AppWindowToken thisApp = win.mAppToken;
// If this window's application has been removed, just skip it.
- if (thisApp != null && thisApp.removed) {
+ if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
continue;
}
@@ -9433,6 +9466,21 @@
}
}
}
+ if (mAppTransitionRunning && mAnimatingAppTokens.size() > 0) {
+ pw.println();
+ pw.println(" Application tokens during animation:");
+ for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
+ WindowToken token = mAnimatingAppTokens.get(i);
+ pw.print(" App moving to bottom #"); pw.print(i);
+ pw.print(' '); pw.print(token);
+ if (dumpAll) {
+ pw.println(':');
+ token.dump(pw, " ");
+ } else {
+ pw.println();
+ }
+ }
+ }
pw.println();
if (mOpeningApps.size() > 0) {
pw.print(" mOpeningApps="); pw.println(mOpeningApps);
@@ -9440,12 +9488,6 @@
if (mClosingApps.size() > 0) {
pw.print(" mClosingApps="); pw.println(mClosingApps);
}
- if (mToTopApps.size() > 0) {
- pw.print(" mToTopApps="); pw.println(mToTopApps);
- }
- if (mToBottomApps.size() > 0) {
- pw.print(" mToBottomApps="); pw.println(mToBottomApps);
- }
}
void dumpSessionsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index e2a904f..8f2ef76 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -841,7 +841,9 @@
}
}
- /** Returns true if this window desires key events. */
+ /** Returns true if this window desires key events.
+ * TODO(cmautner): Is this the same as {@link WindowManagerService#canBeImeTarget}
+ */
public final boolean canReceiveKeys() {
return isVisibleOrAdding()
&& (mViewVisibility == View.VISIBLE)
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 355db6e..affe5d4 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -403,8 +403,8 @@
boolean finishDrawingLocked() {
if (mDrawState == DRAW_PENDING) {
- if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
- TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
+ if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
+ Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
+ mSurface);
mDrawState = COMMIT_DRAW_PENDING;
return true;
@@ -417,7 +417,7 @@
if (mDrawState != COMMIT_DRAW_PENDING) {
return false;
}
- if (DEBUG_ANIM)
+ if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
mDrawState = READY_TO_SHOW;
final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
@@ -504,7 +504,9 @@
@Override
public void setWindowCrop(Rect crop) {
super.setWindowCrop(crop);
- mWindowCrop.set(crop);
+ if (crop != null) {
+ mWindowCrop.set(crop);
+ }
Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
+ Debug.getCallers(3));
}
@@ -1232,7 +1234,8 @@
// Force the show in the next prepareSurfaceLocked() call.
mLastAlpha = -1;
- if (DEBUG_ANIM) Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN");
+ if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
+ Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
mDrawState = HAS_DRAWN;
mService.scheduleAnimationLocked();
diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/java/com/android/server/wm/WindowToken.java
index 3cd256e..5ec151b 100644
--- a/services/java/com/android/server/wm/WindowToken.java
+++ b/services/java/com/android/server/wm/WindowToken.java
@@ -71,10 +71,6 @@
// windows will be put to the bottom of the list.
boolean sendingToBottom;
- // Set to true when this token is in a pending transaction where its
- // windows will be put to the top of the list.
- boolean sendingToTop;
-
WindowToken(WindowManagerService _service, IBinder _token, int type, boolean _explicit) {
service = _service;
token = _token;
@@ -88,11 +84,10 @@
pw.print(prefix); pw.print("windowType="); pw.print(windowType);
pw.print(" hidden="); pw.print(hidden);
pw.print(" hasVisible="); pw.println(hasVisible);
- if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
+ if (waitingToShow || waitingToHide || sendingToBottom) {
pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
pw.print(" waitingToHide="); pw.print(waitingToHide);
pw.print(" sendingToBottom="); pw.print(sendingToBottom);
- pw.print(" sendingToTop="); pw.println(sendingToTop);
}
}