summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-03-01 14:31:38 -0800
committerDianne Hackborn <hackbod@google.com>2011-03-01 14:45:28 -0800
commitce418e661ab52a08a2a2c3b2f10a4dd9adf33305 (patch)
tree2a79f6d41e0edab908f20e6c03edafcf7c457436 /core
parent6c2193a7e26c0794f45dfb60d2a0cf6ae776f390 (diff)
downloadframeworks_base-ce418e661ab52a08a2a2c3b2f10a4dd9adf33305.zip
frameworks_base-ce418e661ab52a08a2a2c3b2f10a4dd9adf33305.tar.gz
frameworks_base-ce418e661ab52a08a2a2c3b2f10a4dd9adf33305.tar.bz2
Fix issue #3495749: Crash on choosing to open the downloaded images
This is due to the window doing a relayout after its activity is stopped, at which point it may need to interact with the adapter to load data. The fix here is to tell ViewRoot about an activity being stopped and, if in this state, hold off on doing any new measurements and layouts of the hierarchy until it is no longer stopped. In this case the relayout was happening due to the cursor being deactivated, with causes the adapter to invalidate its data. Because this is now in a dialog window, this allows the window to actually be resized smaller (unlike when in a full screen activity), and boom. Change-Id: I26442b4679819b4a4e6bc56289afd3445526750b
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/Activity.java8
-rw-r--r--core/java/android/view/ViewRoot.java103
-rw-r--r--core/java/android/view/WindowManagerImpl.java14
3 files changed, 81 insertions, 44 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9e72c1b..210fd5d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -66,6 +66,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.WindowManagerImpl;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
@@ -4401,6 +4402,9 @@ public class Activity extends ContextThemeWrapper
if (mStopped) {
mStopped = false;
mCalled = false;
+ if (mToken != null && mParent == null) {
+ WindowManagerImpl.getDefault().setStoppedState(mToken, false);
+ }
mInstrumentation.callActivityOnRestart(this);
if (!mCalled) {
throw new SuperNotCalledException(
@@ -4477,6 +4481,10 @@ public class Activity extends ContextThemeWrapper
mWindow.closeAllPanels();
}
+ if (mToken != null && mParent == null) {
+ WindowManagerImpl.getDefault().setStoppedState(mToken, true);
+ }
+
mFragments.dispatchStop();
mCalled = false;
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index c7b1955..965c959 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -155,6 +155,10 @@ public final class ViewRoot extends Handler implements ViewParent,
int mViewVisibility;
boolean mAppVisible = true;
+ // Set to true if the owner of this window is in the stopped state,
+ // so the window should no longer be active.
+ boolean mStopped = false;
+
SurfaceHolder.Callback2 mSurfaceHolderCallback;
BaseSurfaceHolder mSurfaceHolder;
boolean mIsCreating;
@@ -618,6 +622,15 @@ public final class ViewRoot extends Handler implements ViewParent,
scheduleTraversals();
}
+ void setStopped(boolean stopped) {
+ if (mStopped != stopped) {
+ mStopped = stopped;
+ if (!stopped) {
+ scheduleTraversals();
+ }
+ }
+ }
+
public ViewParent getParent() {
return null;
}
@@ -760,7 +773,7 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean insetsChanged = false;
- if (mLayoutRequested) {
+ if (mLayoutRequested && !mStopped) {
// Execute enqueued actions on every layout in case a view that was detached
// enqueued an action after being detached
getRunQueue().executeActions(attachInfo.mHandler);
@@ -1143,54 +1156,56 @@ public final class ViewRoot extends Handler implements ViewParent,
mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
}
- boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
- (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
- if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
- || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
- childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
- childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
-
- if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth="
- + mWidth + " measuredWidth=" + host.getMeasuredWidth()
- + " mHeight=" + mHeight
- + " measuredHeight=" + host.getMeasuredHeight()
- + " coveredInsetsChanged=" + contentInsetsChanged);
-
- // Ask host how big it wants to be
- host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-
- // Implementation of weights from WindowManager.LayoutParams
- // We just grow the dimensions as needed and re-measure if
- // needs be
- int width = host.getMeasuredWidth();
- int height = host.getMeasuredHeight();
- boolean measureAgain = false;
-
- if (lp.horizontalWeight > 0.0f) {
- width += (int) ((mWidth - width) * lp.horizontalWeight);
- childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,
- MeasureSpec.EXACTLY);
- measureAgain = true;
- }
- if (lp.verticalWeight > 0.0f) {
- height += (int) ((mHeight - height) * lp.verticalWeight);
- childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
- MeasureSpec.EXACTLY);
- measureAgain = true;
- }
-
- if (measureAgain) {
- if (DEBUG_LAYOUT) Log.v(TAG,
- "And hey let's measure once more: width=" + width
- + " height=" + height);
+ if (!mStopped) {
+ boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
+ (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
+ if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
+ || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
+ childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
+ childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
+
+ if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed! mWidth="
+ + mWidth + " measuredWidth=" + host.getMeasuredWidth()
+ + " mHeight=" + mHeight
+ + " measuredHeight=" + host.getMeasuredHeight()
+ + " coveredInsetsChanged=" + contentInsetsChanged);
+
+ // Ask host how big it wants to be
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+ // Implementation of weights from WindowManager.LayoutParams
+ // We just grow the dimensions as needed and re-measure if
+ // needs be
+ int width = host.getMeasuredWidth();
+ int height = host.getMeasuredHeight();
+ boolean measureAgain = false;
+
+ if (lp.horizontalWeight > 0.0f) {
+ width += (int) ((mWidth - width) * lp.horizontalWeight);
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,
+ MeasureSpec.EXACTLY);
+ measureAgain = true;
+ }
+ if (lp.verticalWeight > 0.0f) {
+ height += (int) ((mHeight - height) * lp.verticalWeight);
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
+ MeasureSpec.EXACTLY);
+ measureAgain = true;
+ }
+
+ if (measureAgain) {
+ if (DEBUG_LAYOUT) Log.v(TAG,
+ "And hey let's measure once more: width=" + width
+ + " height=" + height);
+ host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ mLayoutRequested = true;
}
-
- mLayoutRequested = true;
}
}
- final boolean didLayout = mLayoutRequested;
+ final boolean didLayout = mLayoutRequested && !mStopped;
boolean triggerGlobalLayoutListener = didLayout
|| attachInfo.mRecomputeGlobalAttributes;
if (didLayout) {
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 07953d6..a4c4544 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -302,6 +302,20 @@ public class WindowManagerImpl implements WindowManager {
}
}
+ public void setStoppedState(IBinder token, boolean stopped) {
+ synchronized (this) {
+ if (mViews == null)
+ return;
+ int count = mViews.length;
+ for (int i=0; i<count; i++) {
+ if (token == null || mParams[i].token == token) {
+ ViewRoot root = mRoots[i];
+ root.setStopped(stopped);
+ }
+ }
+ }
+ }
+
public WindowManager.LayoutParams getRootViewLayoutParameter(View view) {
ViewParent vp = view.getParent();
while (vp != null && !(vp instanceof ViewRoot)) {