Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5030ecb authored by Craig Mautner's avatar Craig Mautner Committed by Android Git Automerger
Browse files

am 4a9f1298: Close ActivityView and ActivityContainer cleanly.

* commit '4a9f1298':
  Close ActivityView and ActivityContainer cleanly.
parents 28084383 4a9f1298
Loading
Loading
Loading
Loading
+12 −5
Original line number Original line Diff line number Diff line
@@ -354,9 +354,11 @@ public class ActivityView extends ViewGroup {
    private static class ActivityContainerWrapper {
    private static class ActivityContainerWrapper {
        private final IActivityContainer mIActivityContainer;
        private final IActivityContainer mIActivityContainer;
        private final CloseGuard mGuard = CloseGuard.get();
        private final CloseGuard mGuard = CloseGuard.get();
        boolean mOpened; // Protected by mGuard.


        ActivityContainerWrapper(IActivityContainer container) {
        ActivityContainerWrapper(IActivityContainer container) {
            mIActivityContainer = container;
            mIActivityContainer = container;
            mOpened = true;
            mGuard.open("release");
            mGuard.open("release");
        }
        }


@@ -424,12 +426,17 @@ public class ActivityView extends ViewGroup {
        }
        }


        void release() {
        void release() {
            synchronized (mGuard) {
                if (mOpened) {
                    if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called");
                    if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called");
                    try {
                    try {
                        mIActivityContainer.release();
                        mIActivityContainer.release();
                        mGuard.close();
                        mGuard.close();
                    } catch (RemoteException e) {
                    } catch (RemoteException e) {
                    }
                    }
                    mOpened = false;
                }
            }
        }
        }


        @Override
        @Override
+9 −6
Original line number Original line Diff line number Diff line
@@ -32,12 +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_ADD_REMOVE;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP;
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_SAVED_STATE;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
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.HOME_STACK_ID;


import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.CONTAINER_STATE_HAS_SURFACE;

import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.Watchdog;
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.am.ActivityManagerService.ItemMatcher;
@@ -1276,7 +1275,7 @@ final class ActivityStack {


        ActivityRecord parent = mActivityContainer.mParentActivity;
        ActivityRecord parent = mActivityContainer.mParentActivity;
        if ((parent != null && parent.state != ActivityState.RESUMED) ||
        if ((parent != null && parent.state != ActivityState.RESUMED) ||
                !mActivityContainer.isAttached()) {
                !mActivityContainer.isAttachedLocked()) {
            // Do not resume this stack if its parent is not resumed.
            // 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.
            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
            return false;
            return false;
@@ -2540,11 +2539,14 @@ final class ActivityStack {
                || prevState == ActivityState.INITIALIZING) {
                || prevState == ActivityState.INITIALIZING) {
            // If this activity is already stopped, we can just finish
            // If this activity is already stopped, we can just finish
            // it right now.
            // it right now.
            boolean activityRemoved = destroyActivityLocked(r, true,
            r.makeFinishing();
                    oomAdj, "finish-imm");
            boolean activityRemoved = destroyActivityLocked(r, true, oomAdj, "finish-imm");
            if (activityRemoved) {
            if (activityRemoved) {
                mStackSupervisor.resumeTopActivitiesLocked();
                mStackSupervisor.resumeTopActivitiesLocked();
            }
            }
            if (DEBUG_CONTAINERS) Slog.d(TAG, 
                    "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
                    " destroy returned removed=" + activityRemoved);
            return activityRemoved ? null : r;
            return activityRemoved ? null : r;
        }
        }


@@ -2916,6 +2918,7 @@ final class ActivityStack {
            if (r != null) {
            if (r != null) {
                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
            }
            }
            if (DEBUG_CONTAINERS) Slog.d(TAG, "activityDestroyedLocked: r=" + r);


            if (isInStackLocked(token) != null) {
            if (isInStackLocked(token) != null) {
                if (r.state == ActivityState.DESTROYING) {
                if (r.state == ActivityState.DESTROYING) {
@@ -3673,7 +3676,7 @@ final class ActivityStack {
                mStacks.remove(this);
                mStacks.remove(this);
                mStacks.add(0, this);
                mStacks.add(0, this);
            }
            }
            mActivityContainer.onTaskListEmpty();
            mActivityContainer.onTaskListEmptyLocked();
        }
        }
    }
    }


+57 −30
Original line number Original line Diff line number Diff line
@@ -105,6 +105,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
    static final boolean DEBUG_STATES = DEBUG || false;
    static final boolean DEBUG_STATES = DEBUG || false;
    static final boolean DEBUG_IDLE = DEBUG || false;
    static final boolean DEBUG_IDLE = DEBUG || false;
    static final boolean DEBUG_CONTAINERS = DEBUG || false;


    public static final int HOME_STACK_ID = 0;
    public static final int HOME_STACK_ID = 0;


@@ -127,6 +128,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
    static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
    static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 9;
    static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 9;
    static final int CONTAINER_TASK_LIST_EMPTY_TIMEOUT = FIRST_SUPERVISOR_STACK_MSG + 10;


    private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
    private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";


@@ -224,7 +226,7 @@ public final class ActivityStackSupervisor implements DisplayListener {


    // TODO: Add listener for removal of references.
    // TODO: Add listener for removal of references.
    /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
    /** 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 */
    /** Mapping from displayId to display current state */
    private final SparseArray<ActivityDisplay> mActivityDisplays =
    private final SparseArray<ActivityDisplay> mActivityDisplays =
@@ -2161,8 +2163,10 @@ public final class ActivityStackSupervisor implements DisplayListener {


    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
    ActivityContainer createActivityContainer(ActivityRecord parentActivity,
            IActivityContainerCallback callback) {
            IActivityContainerCallback callback) {
        ActivityContainer activityContainer = new VirtualActivityContainer(parentActivity, callback);
        ActivityContainer activityContainer =
                new VirtualActivityContainer(parentActivity, callback);
        mActivityContainers.put(activityContainer.mStackId, activityContainer);
        mActivityContainers.put(activityContainer.mStackId, activityContainer);
        if (DEBUG_CONTAINERS) Slog.d(TAG, "createActivityContainer: " + activityContainer);
        parentActivity.mChildContainers.add(activityContainer);
        parentActivity.mChildContainers.add(activityContainer);
        return activityContainer;
        return activityContainer;
    }
    }
@@ -2171,6 +2175,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
        final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
        for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
            ActivityContainer container = childStacks.remove(containerNdx);
            ActivityContainer container = childStacks.remove(containerNdx);
            if (DEBUG_CONTAINERS) Slog.d(TAG, "removeChildActivityContainers: removing " +
                    container);
            container.release();
            container.release();
        }
        }
    }
    }
@@ -2178,11 +2184,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
    void deleteActivityContainer(IActivityContainer container) {
    void deleteActivityContainer(IActivityContainer container) {
        ActivityContainer activityContainer = (ActivityContainer)container;
        ActivityContainer activityContainer = (ActivityContainer)container;
        if (activityContainer != null) {
        if (activityContainer != null) {
            activityContainer.mStack.finishAllActivitiesLocked();
            if (DEBUG_CONTAINERS) Slog.d(TAG, "deleteActivityContainer: ",
            final ActivityRecord parent = activityContainer.mParentActivity;
                    new RuntimeException("here").fillInStackTrace());
            if (parent != null) {
                parent.mChildContainers.remove(activityContainer);
            }
            final int stackId = activityContainer.mStackId;
            final int stackId = activityContainer.mStackId;
            mActivityContainers.remove(stackId);
            mActivityContainers.remove(stackId);
            mWindowManager.removeStack(stackId);
            mWindowManager.removeStack(stackId);
@@ -2950,6 +2953,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
                        }
                        }
                    }
                    }
                } break;
                } 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;
            }
            }
        }
        }
    }
    }
@@ -3006,9 +3016,11 @@ public final class ActivityStackSupervisor implements DisplayListener {


        @Override
        @Override
        public int getDisplayId() {
        public int getDisplayId() {
            synchronized (mService) {
                if (mActivityDisplay != null) {
                if (mActivityDisplay != null) {
                    return mActivityDisplay.mDisplayId;
                    return mActivityDisplay.mDisplayId;
                }
                }
            }
            return -1;
            return -1;
        }
        }


@@ -3016,11 +3028,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
        public boolean injectEvent(InputEvent event) {
        public boolean injectEvent(InputEvent event) {
            final long origId = Binder.clearCallingIdentity();
            final long origId = Binder.clearCallingIdentity();
            try {
            try {
                synchronized (mService) {
                    if (mActivityDisplay != null) {
                    if (mActivityDisplay != null) {
                        return mInputManagerInternal.injectInputEvent(event,
                        return mInputManagerInternal.injectInputEvent(event,
                                mActivityDisplay.mDisplayId,
                                mActivityDisplay.mDisplayId,
                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
                    }
                    }
                }
                return false;
                return false;
            } finally {
            } finally {
                Binder.restoreCallingIdentity(origId);
                Binder.restoreCallingIdentity(origId);
@@ -3029,10 +3043,16 @@ public final class ActivityStackSupervisor implements DisplayListener {


        @Override
        @Override
        public void release() {
        public void release() {
            synchronized (mService) {
                if (mContainerState == CONTAINER_STATE_FINISHING) {
                    return;
                }
                mContainerState = CONTAINER_STATE_FINISHING;
                mContainerState = CONTAINER_STATE_FINISHING;
                final Message msg =
                        mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
                mHandler.sendMessageDelayed(msg, 1000);
                mStack.finishAllActivitiesLocked();
                mStack.finishAllActivitiesLocked();
            detachLocked();
            }
            mWindowManager.removeStack(mStackId);
        }
        }


        private void detachLocked() {
        private void detachLocked() {
@@ -3123,17 +3143,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
            return ActivityStackSupervisor.this;
            return ActivityStackSupervisor.this;
        }
        }


        boolean isAttached() {
        boolean isAttachedLocked() {
            return mActivityDisplay != null;
            return mActivityDisplay != null;
        }
        }


        void getBounds(Point outBounds) {
        void getBounds(Point outBounds) {
            synchronized (mService) {
                    if (mActivityDisplay != null) {
                    if (mActivityDisplay != null) {
                    mActivityDisplay.getBounds(outBounds);
                    mActivityDisplay.getBounds(outBounds);
                } else {
                } else {
                    outBounds.set(0, 0);
                    outBounds.set(0, 0);
                }
                }
            }
            }
        }


        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
        // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
        void setVisible(boolean visible) {
        void setVisible(boolean visible) {
@@ -3154,7 +3176,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
            return true;
            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();
            mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
        }
        }


@@ -3173,7 +3200,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
            mParentActivity = parent;
            mParentActivity = parent;
            mCallback = callback;
            mCallback = callback;
            mContainerState = CONTAINER_STATE_NO_SURFACE;
            mContainerState = CONTAINER_STATE_NO_SURFACE;
            mIdString = "VirtualActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}";
            mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
        }
        }


        @Override
        @Override
@@ -3219,22 +3246,22 @@ public final class ActivityStackSupervisor implements DisplayListener {
                }
                }
            }
            }


            setSurfaceIfReady();
            setSurfaceIfReadyLocked();


            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
            if (DEBUG_STACK) Slog.d(TAG, "setSurface: " + this + " to display="
                    + virtualActivityDisplay);
                    + virtualActivityDisplay);
        }
        }


        @Override
        @Override
        boolean isAttached() {
        boolean isAttachedLocked() {
            return mSurface != null && super.isAttached();
            return mSurface != null && super.isAttachedLocked();
        }
        }


        @Override
        @Override
        void setDrawn() {
        void setDrawn() {
            synchronized (mService) {
            synchronized (mService) {
                mDrawn = true;
                mDrawn = true;
                setSurfaceIfReady();
                setSurfaceIfReadyLocked();
            }
            }
        }
        }


@@ -3244,8 +3271,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
            return false;
            return false;
        }
        }


        private void setSurfaceIfReady() {
        private void setSurfaceIfReadyLocked() {
            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReady: mDrawn=" + mDrawn +
            if (DEBUG_STACK) Slog.v(TAG, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
                    " mContainerState=" + mContainerState + " mSurface=" + mSurface);
            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
            if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
                ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);