diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 097c64e723aed..c29d75e516efa 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -53,6 +53,7 @@ public class ActivityView extends ViewGroup { private int mHeight; private Surface mSurface; private int mLastVisibility; + private ActivityViewCallback mActivityViewCallback; // Only one IIntentSender or Intent may be queued at a time. Most recent one wins. IIntentSender mQueuedPendingIntent; @@ -254,6 +255,25 @@ public class ActivityView extends ViewGroup { } } + /** + * Set the callback to use to report certain state changes. + * @param callback The callback to report events to. + * + * @see ActivityViewCallback + */ + public void setCallback(ActivityViewCallback callback) { + mActivityViewCallback = callback; + } + + public static abstract class ActivityViewCallback { + /** + * Called when all activities in the ActivityView have completed and been removed. Register + * using {@link ActivityView#setCallback(ActivityViewCallback)}. Each ActivityView may + * have at most one callback registered. + */ + public abstract void onAllActivitiesComplete(ActivityView view); + } + private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, @@ -313,6 +333,22 @@ public class ActivityView extends ViewGroup { if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible + " ActivityView=" + mActivityViewWeakReference.get()); } + + @Override + public void onAllActivitiesComplete(IBinder container) { + final ActivityView activityView = mActivityViewWeakReference.get(); + if (activityView != null) { + final ActivityViewCallback callback = activityView.mActivityViewCallback; + if (callback != null) { + activityView.post(new Runnable() { + @Override + public void run() { + callback.onAllActivitiesComplete(activityView); + } + }); + } + } + } } private static class ActivityContainerWrapper { diff --git a/core/java/android/app/IActivityContainerCallback.aidl b/core/java/android/app/IActivityContainerCallback.aidl index 7f6d2c3570ae5..99d0a6f8189e5 100644 --- a/core/java/android/app/IActivityContainerCallback.aidl +++ b/core/java/android/app/IActivityContainerCallback.aidl @@ -21,4 +21,5 @@ import android.os.IBinder; /** @hide */ interface IActivityContainerCallback { oneway void setVisible(IBinder container, boolean visible); + oneway void onAllActivitiesComplete(IBinder container); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index e4b196ee1bb02..685da13b8ada0 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3669,6 +3669,7 @@ final class ActivityStack { mStacks.remove(this); mStacks.add(0, this); } + mActivityContainer.onTaskListEmpty(); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index be37ee2bc6cd2..5a79e662f29c9 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -126,6 +126,7 @@ public final class ActivityStackSupervisor implements DisplayListener { static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 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_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 9; private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; @@ -523,7 +524,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) { - // TODO: Put all stacks in supervisor and iterate through them instead. + // TODO: Put all stacks in supervisor and iterate through them instead. for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { @@ -2931,12 +2932,24 @@ public final class ActivityStackSupervisor implements DisplayListener { } break; case CONTAINER_CALLBACK_VISIBILITY: { final ActivityContainer container = (ActivityContainer) msg.obj; - try { - // We only send this message if mCallback is non-null. - container.mCallback.setVisible(container.asBinder(), msg.arg1 == 1); - } catch (RemoteException e) { + final IActivityContainerCallback callback = container.mCallback; + if (callback != null) { + try { + callback.setVisible(container.asBinder(), msg.arg1 == 1); + } catch (RemoteException e) { + } } - } + } break; + case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { + final ActivityContainer container = (ActivityContainer) msg.obj; + final IActivityContainerCallback callback = container.mCallback; + if (callback != null) { + try { + callback.onAllActivitiesComplete(container.asBinder()); + } catch (RemoteException e) { + } + } + } break; } } } @@ -3141,6 +3154,10 @@ public final class ActivityStackSupervisor implements DisplayListener { return true; } + void onTaskListEmpty() { + mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); + } + @Override public String toString() { return mIdString + (mActivityDisplay == null ? "N" : "A");