Add ability to listen to LockTask state changes

Bug: 176211023
Test: Presubmit
Change-Id: I1e9e7151d45751ec6398588788c512f23b2f9fb5
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index a9e28bb..b1c39d3 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -209,4 +209,10 @@
      * @param taskInfo info about the task which moved
      */
     void onTaskMovedToBack(in ActivityManager.RunningTaskInfo taskInfo);
+
+    /**
+     * Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and
+     * LockTaskController.
+     */
+    void onLockTaskModeChanged(int mode);
 }
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 517ae24..1e38230 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -193,4 +193,8 @@
     @Override
     public void onTaskMovedToBack(RunningTaskInfo taskInfo) {
     }
+
+    @Override
+    public void onLockTaskModeChanged(int mode) {
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 6c77af7..c5d5439 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -100,4 +100,10 @@
 
     /** @see ITaskStackListener#onActivityRotation(int)*/
     public void onActivityRotation(int displayId) { }
+
+    /**
+     * Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and
+     * LockTaskController.
+     */
+    public void onLockTaskModeChanged(int mode) { }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index 8f08f5a..d2698ee 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -93,6 +93,7 @@
         private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 20;
         private static final int ON_TASK_DESCRIPTION_CHANGED = 21;
         private static final int ON_ACTIVITY_ROTATION = 22;
+        private static final int ON_LOCK_TASK_MODE_CHANGED = 23;
 
         /**
          * List of {@link TaskStackChangeListener} registered from {@link #addListener}.
@@ -273,6 +274,11 @@
         }
 
         @Override
+        public void onLockTaskModeChanged(int mode) {
+            mHandler.obtainMessage(ON_LOCK_TASK_MODE_CHANGED, mode, 0 /* unused */).sendToTarget();
+        }
+
+        @Override
         public boolean handleMessage(Message msg) {
             synchronized (mTaskStackListeners) {
                 switch (msg.what) {
@@ -421,6 +427,12 @@
                         }
                         break;
                     }
+                    case ON_LOCK_TASK_MODE_CHANGED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onLockTaskModeChanged(msg.arg1);
+                        }
+                        break;
+                    }
                 }
             }
             if (msg.obj instanceof SomeArgs) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2e98c2c..0f6671b1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -863,7 +863,8 @@
 
         mTaskChangeNotificationController =
                 new TaskChangeNotificationController(mGlobalLock, mTaskSupervisor, mH);
-        mLockTaskController = new LockTaskController(mContext, mTaskSupervisor, mH);
+        mLockTaskController = new LockTaskController(mContext, mTaskSupervisor, mH,
+                mTaskChangeNotificationController);
         mActivityStartController = new ActivityStartController(this);
         setRecentTasks(new RecentTasks(this, mTaskSupervisor));
         mVrController = new VrController(mGlobalLock);
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 4b3a434..e18516d 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -141,6 +141,7 @@
     private final IBinder mToken = new LockTaskToken();
     private final ActivityTaskSupervisor mSupervisor;
     private final Context mContext;
+    private final TaskChangeNotificationController mTaskChangeNotificationController;
 
     // The following system services cannot be final, because they do not exist when this class
     // is instantiated during device boot
@@ -204,10 +205,11 @@
     private int mPendingDisableFromDismiss = UserHandle.USER_NULL;
 
     LockTaskController(Context context, ActivityTaskSupervisor supervisor,
-            Handler handler) {
+            Handler handler, TaskChangeNotificationController taskChangeNotificationController) {
         mContext = context;
         mSupervisor = supervisor;
         mHandler = handler;
+        mTaskChangeNotificationController = taskChangeNotificationController;
     }
 
     /**
@@ -532,6 +534,7 @@
         // thread, which makes it guarded by ATMS#mGlobalLock as ATMS#getLockTaskModeState.
         final int oldLockTaskModeState = mLockTaskModeState;
         mLockTaskModeState = LOCK_TASK_MODE_NONE;
+        mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState);
         // When lock task ends, we enable the status bars.
         try {
             setStatusBarState(mLockTaskModeState, userId);
@@ -661,6 +664,7 @@
             }
             mWindowManager.onLockTaskStateChanged(lockTaskModeState);
             mLockTaskModeState = lockTaskModeState;
+            mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState);
             setStatusBarState(lockTaskModeState, userId);
             setKeyguardState(lockTaskModeState, userId);
             if (getDevicePolicyManager() != null) {
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 622fe05..9b72570 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -59,6 +59,7 @@
     private static final int NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG = 25;
     private static final int NOTIFY_ACTIVITY_ROTATED_MSG = 26;
     private static final int NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG = 27;
+    private static final int NOTIFY_LOCK_TASK_MODE_CHANGED_MSG = 28;
 
     // Delay in notifying task stack change listeners (in millis)
     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -177,6 +178,10 @@
         l.onTaskMovedToBack((RunningTaskInfo) m.obj);
     };
 
+    private final TaskStackConsumer mNotifyLockTaskModeChanged = (l, m) -> {
+        l.onLockTaskModeChanged(m.arg1);
+    };
+
     @FunctionalInterface
     public interface TaskStackConsumer {
         void accept(ITaskStackListener t, Message m) throws RemoteException;
@@ -268,6 +273,9 @@
                 case NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG:
                     forAllRemoteListeners(mNotifyTaskMovedToBack, msg);
                     break;
+                case NOTIFY_LOCK_TASK_MODE_CHANGED_MSG:
+                    forAllRemoteListeners(mNotifyLockTaskModeChanged, msg);
+                    break;
             }
             if (msg.obj instanceof SomeArgs) {
                 ((SomeArgs) msg.obj).recycle();
@@ -550,4 +558,11 @@
         forAllLocalListeners(mNotifyTaskMovedToBack, msg);
         msg.sendToTarget();
     }
+
+    void notifyLockTaskModeChanged(int lockTaskModeState) {
+        final Message msg = mHandler.obtainMessage(NOTIFY_LOCK_TASK_MODE_CHANGED_MSG,
+                lockTaskModeState, 0 /* unused */);
+        forAllLocalListeners(mNotifyLockTaskModeChanged, msg);
+        msg.sendToTarget();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index f935bfc..d663b64 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -122,6 +122,7 @@
     @Mock private StatusBarManagerInternal mStatusBarManagerInternal;
     @Mock private TelecomManager mTelecomManager;
     @Mock private RecentTasks mRecentTasks;
+    @Mock private TaskChangeNotificationController mTaskChangeNotificationController;
 
     private LockTaskController mLockTaskController;
     private Context mContext;
@@ -145,7 +146,7 @@
         mSupervisor.mRootWindowContainer = mRootWindowContainer;
 
         mLockTaskController = new LockTaskController(mContext, mSupervisor,
-                new ImmediatelyExecuteHandler());
+                new ImmediatelyExecuteHandler(), mTaskChangeNotificationController);
         mLockTaskController.setWindowManager(mWindowManager);
         mLockTaskController.mStatusBarService = mStatusBarService;
         mLockTaskController.mDevicePolicyManager = mDevicePolicyManager;