OSDN Git Service

Revert "Revert "Close ActivityView and ActivityContainer cleanly.""
authorCraig Mautner <cmautner@google.com>
Sat, 14 Jun 2014 00:18:47 +0000 (17:18 -0700)
committerCraig Mautner <cmautner@google.com>
Sat, 14 Jun 2014 00:39:35 +0000 (17:39 -0700)
This reverts commit dd5c94717077c9366dee364c88a86a78e5ee2688.

Change-Id: I7bac1aa1d96fa7922cc835949730a26204f15f2f

core/java/android/app/ActivityView.java
services/core/java/com/android/server/am/ActivityStack.java
services/core/java/com/android/server/am/ActivityStackSupervisor.java

index c29d75e..94ea2c5 100644 (file)
@@ -354,9 +354,11 @@ public class ActivityView extends ViewGroup {
     private static class ActivityContainerWrapper {
         private final IActivityContainer mIActivityContainer;
         private final CloseGuard mGuard = CloseGuard.get();
+        boolean mOpened; // Protected by mGuard.
 
         ActivityContainerWrapper(IActivityContainer container) {
             mIActivityContainer = container;
+            mOpened = true;
             mGuard.open("release");
         }
 
@@ -424,11 +426,16 @@ public class ActivityView extends ViewGroup {
         }
 
         void release() {
-            if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called");
-            try {
-                mIActivityContainer.release();
-                mGuard.close();
-            } catch (RemoteException e) {
+            synchronized (mGuard) {
+                if (mOpened) {
+                    if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called");
+                    try {
+                        mIActivityContainer.release();
+                        mGuard.close();
+                    } catch (RemoteException e) {
+                    }
+                    mOpened = false;
+                }
             }
         }
 
index d7cf7b1..03ce530 100755 (executable)
@@ -32,11 +32,11 @@ import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS;
 
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP;
+import static com.android.server.am.ActivityStackSupervisor.DEBUG_CONTAINERS;
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE;
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_SCREENSHOTS;
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
-import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.CONTAINER_STATE_HAS_SURFACE;
 
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.BatteryStatsImpl;
@@ -1406,7 +1406,7 @@ final class ActivityStack {
 
         ActivityRecord parent = mActivityContainer.mParentActivity;
         if ((parent != null && parent.state != ActivityState.RESUMED) ||
-                !mActivityContainer.isAttached()) {
+                !mActivityContainer.isAttachedLocked()) {
             // Do not resume this stack if its parent is not resumed.
             // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
             return false;
@@ -2678,11 +2678,14 @@ final class ActivityStack {
                 || prevState == ActivityState.INITIALIZING) {
             // If this activity is already stopped, we can just finish
             // it right now.
-            boolean activityRemoved = destroyActivityLocked(r, true,
-                    oomAdj, "finish-imm");
+            r.makeFinishing();
+            boolean activityRemoved = destroyActivityLocked(r, true, oomAdj, "finish-imm");
             if (activityRemoved) {
                 mStackSupervisor.resumeTopActivitiesLocked();
             }
+            if (DEBUG_CONTAINERS) Slog.d(TAG, 
+                    "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
+                    " destroy returned removed=" + activityRemoved);
             return activityRemoved ? null : r;
         }
 
@@ -3045,6 +3048,7 @@ final class ActivityStack {
             if (r != null) {
                 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
             }
+            if (DEBUG_CONTAINERS) Slog.d(TAG, "activityDestroyedLocked: r=" + r);
 
             if (isInStackLocked(token) != null) {
                 if (r.state == ActivityState.DESTROYING) {
@@ -3804,7 +3808,7 @@ final class ActivityStack {
                 mStacks.remove(this);
                 mStacks.add(0, this);
             }
-            mActivityContainer.onTaskListEmpty();
+            mActivityContainer.onTaskListEmptyLocked();
         }
     }
 
index c4cdbd7..66e9eb3 100644 (file)
@@ -107,11 +107,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
     static final boolean DEBUG = ActivityManagerService.DEBUG || false;
     static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
     static final boolean DEBUG_APP = DEBUG || false;
-    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
-    static final boolean DEBUG_STATES = DEBUG || false;
+    static final boolean DEBUG_CONTAINERS = DEBUG || false;
     static final boolean DEBUG_IDLE = DEBUG || false;
+    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
     static final boolean DEBUG_SCREENSHOTS = DEBUG || false;
-    static final boolean DEBUG_CONTAINERS = DEBUG || false;
+    static final boolean DEBUG_STATES = DEBUG || false;
 
     public static final int HOME_STACK_ID = 0;
 
@@ -241,7 +241,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
     // TODO: Add listener for removal of references.
     /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
-    SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
+    private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<ActivityContainer>();
 
     /** Mapping from displayId to display current state */
     private final SparseArray<ActivityDisplay> mActivityDisplays =
@@ -2257,8 +2257,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
     ActivityContainer createActivityContainer(ActivityRecord parentActivity,
             IActivityContainerCallback callback) {
-        ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback);
+        ActivityContainer activityContainer =
+                new VirtualActivityContainer(parentActivity, callback);
         mActivityContainers.put(activityContainer.mStackId, activityContainer);
+        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
         parentActivity.mChildContainers.add(activityContainer);
         return activityContainer;
     }
@@ -2267,6 +2269,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
         final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
         for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
             ActivityContainer container = childStacks.remove(containerNdx);
+            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
+                    container);
             container.release();
         }
     }
@@ -2274,11 +2278,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
     void deleteActivityContainer(IActivityContainer container) {
         ActivityContainer activityContainer = (ActivityContainer)container;
         if (activityContainer != null) {
-            activityContainer.mStack.finishAllActivitiesLocked();
-            final ActivityRecord parent = activityContainer.mParentActivity;
-            if (parent != null) {
-                parent.mChildContainers.remove(activityContainer);
-            }
+            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
+                    new RuntimeException("here").fillInStackTrace());
             final int stackId = activityContainer.mStackId;
             mActivityContainers.remove(stackId);
             mWindowManager.removeStack(stackId);
@@ -2887,16 +2888,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
     @Override
     public void onDisplayAdded(int displayId) {
+        Slog.v(TAG, "Display added displayId=" + displayId);
         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
     }
 
     @Override
     public void onDisplayRemoved(int displayId) {
+        Slog.v(TAG, "Display removed displayId=" + displayId);
         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
     }
 
     @Override
     public void onDisplayChanged(int displayId) {
+        Slog.v(TAG, "Display changed displayId=" + displayId);
         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
     }
 
@@ -3130,6 +3134,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
                         }
                     }
                 } break;
+                case CONTAINER_TASK_LIST_EMPTY_TIMEOUT: {
+                    synchronized (mService) {
+                        Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
+                                msg.obj);
+                        ((ActivityContainer) msg.obj).onTaskListEmptyLocked();
+                    }
+                } break;
             }
         }
     }
@@ -3186,8 +3197,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
         @Override
         public int getDisplayId() {
-            if (mActivityDisplay != null) {
-                return mActivityDisplay.mDisplayId;
+            synchronized (mService) {
+                if (mActivityDisplay != null) {
+                    return mActivityDisplay.mDisplayId;
+                }
             }
             return -1;
         }
@@ -3196,10 +3209,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
         public boolean injectEvent(InputEvent event) {
             final long origId = Binder.clearCallingIdentity();
             try {
-                if (mActivityDisplay != null) {
-                    return mInputManagerInternal.injectInputEvent(event,
-                            mActivityDisplay.mDisplayId,
-                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+                synchronized (mService) {
+                    if (mActivityDisplay != null) {
+                        return mInputManagerInternal.injectInputEvent(event,
+                                mActivityDisplay.mDisplayId,
+                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+                    }
                 }
                 return false;
             } finally {
@@ -3209,10 +3224,23 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
         @Override
         public void release() {
-            mContainerState = CONTAINER_STATE_FINISHING;
-            mStack.finishAllActivitiesLocked();
-            detachLocked();
-            mWindowManager.removeStack(mStackId);
+            synchronized (mService) {
+                if (mContainerState == CONTAINER_STATE_FINISHING) {
+                    return;
+                }
+                mContainerState = CONTAINER_STATE_FINISHING;
+
+                final Message msg =
+                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
+                mHandler.sendMessageDelayed(msg, 1000);
+
+                long origId = Binder.clearCallingIdentity();
+                try {
+                    mStack.finishAllActivitiesLocked();
+                } finally {
+                    Binder.restoreCallingIdentity(origId);
+                }
+            }
         }
 
         private void detachLocked() {
@@ -3303,15 +3331,17 @@ public final class ActivityStackSupervisor implements DisplayListener {
             return ActivityStackSupervisor.this;
         }
 
-        boolean isAttached() {
+        boolean isAttachedLocked() {
             return mActivityDisplay != null;
         }
 
         void getBounds(Point outBounds) {
-            if (mActivityDisplay != null) {
-                mActivityDisplay.getBounds(outBounds);
-            } else {
-                outBounds.set(0, 0);
+            synchronized (mService) {
+                    if (mActivityDisplay != null) {
+                    mActivityDisplay.getBounds(outBounds);
+                } else {
+                    outBounds.set(0, 0);
+                }
             }
         }
 
@@ -3334,7 +3364,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
             return true;
         }
 
-        void onTaskListEmpty() {
+        void onTaskListEmptyLocked() {
+            mHandler.removeMessages(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
+            if (!mStack.isHomeStack()) {
+                detachLocked();
+                deleteActivityContainer(this);
+            }
             mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
         }
 
@@ -3353,7 +3388,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
             mParentActivity = parent;
             mCallback = callback;
             mContainerState = CONTAINER_STATE_NO_SURFACE;
-            mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
+            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
         }
 
         @Override
@@ -3399,22 +3434,22 @@ public final class ActivityStackSupervisor implements DisplayListener {
                 }
             }
 
-            setSurfaceIfReady();
+            setSurfaceIfReadyLocked();
 
             if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
                     + virtualActivityDisplay);
         }
 
         @Override
-        boolean isAttached() {
-            return mSurface != null && super.isAttached();
+        boolean isAttachedLocked() {
+            return mSurface != null && super.isAttachedLocked();
         }
 
         @Override
         void setDrawn() {
             synchronized (mService) {
                 mDrawn = true;
-                setSurfaceIfReady();
+                setSurfaceIfReadyLocked();
             }
         }
 
@@ -3424,8 +3459,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
             return false;
         }
 
-        private void setSurfaceIfReady() {
-            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn +
+        private void setSurfaceIfReadyLocked() {
+            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
                     " mContainerState=" + mContainerState + " mSurface=" + mSurface);
             if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
                 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);