diff options
| author | 2023-06-14 19:05:09 +0000 | |
|---|---|---|
| committer | 2023-06-14 19:05:09 +0000 | |
| commit | 781cf4ecbc68902c1ebb47ea166833c7950d3e0a (patch) | |
| tree | 354d4cacff6326036f0147e74788635a2493f5df | |
| parent | 5beb77da6dc677ffef7c3b1cf504c1ac796fc3ea (diff) | |
| parent | ea896c4cac63b441057c47ad86e087fcad2c8d7b (diff) | |
Merge "Remove KidsModeTaskOrganizer" into udc-dev
4 files changed, 0 insertions, 730 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index dda430a24c4d..acbdbf9d6769 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -61,7 +61,6 @@ import com.android.wm.shell.freeform.FreeformTaskListener; import com.android.wm.shell.freeform.FreeformTaskTransitionHandler; import com.android.wm.shell.freeform.FreeformTaskTransitionObserver; import com.android.wm.shell.keyguard.KeyguardTransitionHandler; -import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; @@ -711,42 +710,4 @@ public abstract class WMShellModule { static DesktopModeTaskRepository provideDesktopModeTaskRepository() { return new DesktopModeTaskRepository(); } - - // - // Kids mode - // - @WMSingleton - @Provides - static KidsModeTaskOrganizer provideKidsModeTaskOrganizer( - Context context, - ShellInit shellInit, - ShellCommandHandler shellCommandHandler, - SyncTransactionQueue syncTransactionQueue, - DisplayController displayController, - DisplayInsetsController displayInsetsController, - Optional<UnfoldAnimationController> unfoldAnimationController, - Optional<RecentTasksController> recentTasksOptional, - @ShellMainThread ShellExecutor mainExecutor, - @ShellMainThread Handler mainHandler - ) { - return new KidsModeTaskOrganizer(context, shellInit, shellCommandHandler, - syncTransactionQueue, displayController, displayInsetsController, - unfoldAnimationController, recentTasksOptional, mainExecutor, mainHandler); - } - - // - // Misc - // - - // TODO: Temporarily move dependencies to this instead of ShellInit since that is needed to add - // the callback. We will be moving to a different explicit startup mechanism in a follow- up CL. - @WMSingleton - @ShellCreateTriggerOverride - @Provides - static Object provideIndependentShellComponentsToCreate( - DefaultMixedHandler defaultMixedHandler, - KidsModeTaskOrganizer kidsModeTaskOrganizer, - Optional<DesktopModeController> desktopModeController) { - return new Object(); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java deleted file mode 100644 index 65cb7ac1e5f7..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.kidsmode; - -import android.annotation.NonNull; -import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.Context; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Handler; -import android.os.UserHandle; -import android.provider.Settings; - -import java.util.Collection; - -/** - * A ContentObserver for listening kids mode relative setting keys: - * - {@link Settings.Secure#NAVIGATION_MODE} - * - {@link Settings.Secure#NAV_BAR_KIDS_MODE} - * - * @hide - */ -public class KidsModeSettingsObserver extends ContentObserver { - private Context mContext; - private Runnable mOnChangeRunnable; - - public KidsModeSettingsObserver(Handler handler, Context context) { - super(handler); - mContext = context; - } - - public void setOnChangeRunnable(Runnable r) { - mOnChangeRunnable = r; - } - - /** - * Registers the observer. - */ - public void register() { - final ContentResolver r = mContext.getContentResolver(); - r.registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.NAVIGATION_MODE), - false, this, UserHandle.USER_ALL); - r.registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), - false, this, UserHandle.USER_ALL); - } - - /** - * Unregisters the observer. - */ - public void unregister() { - mContext.getContentResolver().unregisterContentObserver(this); - } - - @Override - public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags, int userId) { - if (userId != ActivityManager.getCurrentUser()) { - return; - } - - if (mOnChangeRunnable != null) { - mOnChangeRunnable.run(); - } - } - - /** - * Returns true only when it's in three button nav mode and the kid nav bar mode is enabled. - * Otherwise, return false. - */ - public boolean isEnabled() { - return Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.NAVIGATION_MODE, 0, UserHandle.USER_CURRENT) == 0 - && Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1; - } -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java deleted file mode 100644 index 6d46a9c3d0e7..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.kidsmode; - -import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; -import static android.view.Display.DEFAULT_DISPLAY; - -import android.app.ActivityManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.view.Display; -import android.view.InsetsSource; -import android.view.InsetsState; -import android.view.SurfaceControl; -import android.view.WindowInsets; -import android.window.ITaskOrganizerController; -import android.window.TaskAppearedInfo; -import android.window.WindowContainerToken; -import android.window.WindowContainerTransaction; - -import androidx.annotation.NonNull; - -import com.android.internal.R; -import com.android.internal.annotations.VisibleForTesting; -import com.android.wm.shell.ShellTaskOrganizer; -import com.android.wm.shell.common.DisplayController; -import com.android.wm.shell.common.DisplayInsetsController; -import com.android.wm.shell.common.DisplayLayout; -import com.android.wm.shell.common.ShellExecutor; -import com.android.wm.shell.common.SyncTransactionQueue; -import com.android.wm.shell.recents.RecentTasksController; -import com.android.wm.shell.sysui.ShellCommandHandler; -import com.android.wm.shell.sysui.ShellInit; -import com.android.wm.shell.unfold.UnfoldAnimationController; - -import java.io.PrintWriter; -import java.util.List; -import java.util.Optional; - -/** - * A dedicated task organizer when kids mode is enabled. - * - Creates a root task with bounds that exclude the navigation bar area - * - Launch all task into the root task except for Launcher - */ -public class KidsModeTaskOrganizer extends ShellTaskOrganizer { - private static final String TAG = "KidsModeTaskOrganizer"; - - private static final int[] CONTROLLED_ACTIVITY_TYPES = - {ACTIVITY_TYPE_UNDEFINED, ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_HOME}; - private static final int[] CONTROLLED_WINDOWING_MODES = - {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED}; - - private final Handler mMainHandler; - private final Context mContext; - private final ShellCommandHandler mShellCommandHandler; - private final SyncTransactionQueue mSyncQueue; - private final DisplayController mDisplayController; - private final DisplayInsetsController mDisplayInsetsController; - - /** - * The value of the {@link R.bool.config_reverseDefaultRotation} property which defines how - * {@link Display#getRotation} values are mapped to screen orientations - */ - private final boolean mReverseDefaultRotationEnabled; - - @VisibleForTesting - ActivityManager.RunningTaskInfo mLaunchRootTask; - @VisibleForTesting - SurfaceControl mLaunchRootLeash; - @VisibleForTesting - final IBinder mCookie = new Binder(); - - private final InsetsState mInsetsState = new InsetsState(); - private int mDisplayWidth; - private int mDisplayHeight; - - private KidsModeSettingsObserver mKidsModeSettingsObserver; - private boolean mEnabled; - - private ActivityManager.RunningTaskInfo mHomeTask; - - private final BroadcastReceiver mUserSwitchIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - updateKidsModeState(); - } - }; - - DisplayController.OnDisplaysChangedListener mOnDisplaysChangedListener = - new DisplayController.OnDisplaysChangedListener() { - @Override - public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { - if (displayId != DEFAULT_DISPLAY) { - return; - } - final DisplayLayout displayLayout = - mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); - if (displayLayout == null) { - return; - } - final int displayWidth = displayLayout.width(); - final int displayHeight = displayLayout.height(); - if (displayWidth == mDisplayWidth || displayHeight == mDisplayHeight) { - return; - } - mDisplayWidth = displayWidth; - mDisplayHeight = displayHeight; - updateBounds(); - } - }; - - DisplayInsetsController.OnInsetsChangedListener mOnInsetsChangedListener = - new DisplayInsetsController.OnInsetsChangedListener() { - @Override - public void insetsChanged(InsetsState insetsState) { - final boolean[] navigationBarChanged = {false}; - InsetsState.traverse(insetsState, mInsetsState, new InsetsState.OnTraverseCallbacks() { - @Override - public void onIdMatch(InsetsSource source1, InsetsSource source2) { - if (source1.getType() == WindowInsets.Type.navigationBars() - && !source1.equals(source2)) { - navigationBarChanged[0] = true; - } - } - - @Override - public void onIdNotFoundInState1(int index2, InsetsSource source2) { - if (source2.getType() == WindowInsets.Type.navigationBars()) { - navigationBarChanged[0] = true; - } - } - - @Override - public void onIdNotFoundInState2(int index1, InsetsSource source1) { - if (source1.getType() == WindowInsets.Type.navigationBars()) { - navigationBarChanged[0] = true; - } - } - }); - if (!navigationBarChanged[0]) { - return; - } - // Update bounds only when the insets of navigation bar or task bar is changed. - mInsetsState.set(insetsState); - updateBounds(); - } - }; - - @VisibleForTesting - KidsModeTaskOrganizer( - Context context, - ShellInit shellInit, - ShellCommandHandler shellCommandHandler, - ITaskOrganizerController taskOrganizerController, - SyncTransactionQueue syncTransactionQueue, - DisplayController displayController, - DisplayInsetsController displayInsetsController, - Optional<UnfoldAnimationController> unfoldAnimationController, - Optional<RecentTasksController> recentTasks, - KidsModeSettingsObserver kidsModeSettingsObserver, - ShellExecutor mainExecutor, - Handler mainHandler) { - // Note: we don't call super with the shell init because we will be initializing manually - super(/* shellInit= */ null, /* shellCommandHandler= */ null, taskOrganizerController, - /* compatUI= */ null, unfoldAnimationController, recentTasks, mainExecutor); - mContext = context; - mShellCommandHandler = shellCommandHandler; - mMainHandler = mainHandler; - mSyncQueue = syncTransactionQueue; - mDisplayController = displayController; - mDisplayInsetsController = displayInsetsController; - mKidsModeSettingsObserver = kidsModeSettingsObserver; - shellInit.addInitCallback(this::onInit, this); - mReverseDefaultRotationEnabled = context.getResources().getBoolean( - R.bool.config_reverseDefaultRotation); - } - - public KidsModeTaskOrganizer( - Context context, - ShellInit shellInit, - ShellCommandHandler shellCommandHandler, - SyncTransactionQueue syncTransactionQueue, - DisplayController displayController, - DisplayInsetsController displayInsetsController, - Optional<UnfoldAnimationController> unfoldAnimationController, - Optional<RecentTasksController> recentTasks, - ShellExecutor mainExecutor, - Handler mainHandler) { - // Note: we don't call super with the shell init because we will be initializing manually - super(/* shellInit= */ null, /* taskOrganizerController= */ null, /* compatUI= */ null, - unfoldAnimationController, recentTasks, mainExecutor); - mContext = context; - mShellCommandHandler = shellCommandHandler; - mMainHandler = mainHandler; - mSyncQueue = syncTransactionQueue; - mDisplayController = displayController; - mDisplayInsetsController = displayInsetsController; - shellInit.addInitCallback(this::onInit, this); - mReverseDefaultRotationEnabled = context.getResources().getBoolean( - R.bool.config_reverseDefaultRotation); - } - - /** - * Initializes kids mode status. - */ - public void onInit() { - if (mShellCommandHandler != null) { - mShellCommandHandler.addDumpCallback(this::dump, this); - } - if (mKidsModeSettingsObserver == null) { - mKidsModeSettingsObserver = new KidsModeSettingsObserver(mMainHandler, mContext); - } - mKidsModeSettingsObserver.setOnChangeRunnable(() -> updateKidsModeState()); - updateKidsModeState(); - mKidsModeSettingsObserver.register(); - - final IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_USER_SWITCHED); - mContext.registerReceiverForAllUsers(mUserSwitchIntentReceiver, filter, null, mMainHandler); - } - - @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { - if (mEnabled && mLaunchRootTask == null && taskInfo.launchCookies != null - && taskInfo.launchCookies.contains(mCookie)) { - mLaunchRootTask = taskInfo; - mLaunchRootLeash = leash; - updateTask(); - } - super.onTaskAppeared(taskInfo, leash); - - // Only allow home to draw under system bars. - if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME) { - final WindowContainerTransaction wct = getWindowContainerTransaction(); - wct.setBounds(taskInfo.token, new Rect(0, 0, mDisplayWidth, mDisplayHeight)); - mSyncQueue.queue(wct); - mHomeTask = taskInfo; - } - mSyncQueue.runInSync(t -> { - // Reset several properties back to fullscreen (PiP, for example, leaves all these - // properties in a bad state). - t.setCrop(leash, null); - t.setPosition(leash, 0, 0); - t.setAlpha(leash, 1f); - t.setMatrix(leash, 1, 0, 0, 1); - t.show(leash); - }); - } - - @Override - public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { - if (mLaunchRootTask != null && mLaunchRootTask.taskId == taskInfo.taskId - && !taskInfo.equals(mLaunchRootTask)) { - mLaunchRootTask = taskInfo; - } - - if (mHomeTask != null && mHomeTask.taskId == taskInfo.taskId - && !taskInfo.equals(mHomeTask)) { - mHomeTask = taskInfo; - } - - super.onTaskInfoChanged(taskInfo); - } - - @VisibleForTesting - void updateKidsModeState() { - final boolean enabled = mKidsModeSettingsObserver.isEnabled(); - if (mEnabled == enabled) { - return; - } - mEnabled = enabled; - if (mEnabled) { - enable(); - } else { - disable(); - } - } - - @VisibleForTesting - void enable() { - // Needed since many Kids apps aren't optimised to support both orientations and it will be - // hard for kids to understand the app compat mode. - // TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once possible. - if (mReverseDefaultRotationEnabled) { - setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled */ true, - /* fromOrientations */ - new int[]{SCREEN_ORIENTATION_LANDSCAPE, SCREEN_ORIENTATION_REVERSE_LANDSCAPE}, - /* toOrientations */ - new int[]{SCREEN_ORIENTATION_SENSOR_LANDSCAPE, - SCREEN_ORIENTATION_SENSOR_LANDSCAPE}); - } else { - setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled */ true, - /* fromOrientations */ null, /* toOrientations */ null); - } - final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); - if (displayLayout != null) { - mDisplayWidth = displayLayout.width(); - mDisplayHeight = displayLayout.height(); - } - mInsetsState.set(mDisplayController.getInsetsState(DEFAULT_DISPLAY)); - mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, - mOnInsetsChangedListener); - mDisplayController.addDisplayWindowListener(mOnDisplaysChangedListener); - List<TaskAppearedInfo> taskAppearedInfos = registerOrganizer(); - for (int i = 0; i < taskAppearedInfos.size(); i++) { - final TaskAppearedInfo info = taskAppearedInfos.get(i); - onTaskAppeared(info.getTaskInfo(), info.getLeash()); - } - createRootTask(DEFAULT_DISPLAY, WINDOWING_MODE_FULLSCREEN, mCookie); - updateTask(); - } - - @VisibleForTesting - void disable() { - setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled */ false, - /* fromOrientations */ null, /* toOrientations */ null); - mDisplayInsetsController.removeInsetsChangedListener(DEFAULT_DISPLAY, - mOnInsetsChangedListener); - mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener); - updateTask(); - final WindowContainerToken token = mLaunchRootTask.token; - if (token != null) { - deleteRootTask(token); - } - mLaunchRootTask = null; - mLaunchRootLeash = null; - if (mHomeTask != null && mHomeTask.token != null) { - final WindowContainerToken homeToken = mHomeTask.token; - final WindowContainerTransaction wct = getWindowContainerTransaction(); - wct.setBounds(homeToken, null); - mSyncQueue.queue(wct); - } - mHomeTask = null; - unregisterOrganizer(); - } - - private void updateTask() { - updateTask(getWindowContainerTransaction()); - } - - private void updateTask(WindowContainerTransaction wct) { - if (mLaunchRootTask == null || mLaunchRootLeash == null) { - return; - } - final Rect taskBounds = calculateBounds(); - final WindowContainerToken rootToken = mLaunchRootTask.token; - wct.setBounds(rootToken, mEnabled ? taskBounds : null); - wct.setLaunchRoot(rootToken, - mEnabled ? CONTROLLED_WINDOWING_MODES : null, - mEnabled ? CONTROLLED_ACTIVITY_TYPES : null); - wct.reparentTasks( - mEnabled ? null : rootToken /* currentParent */, - mEnabled ? rootToken : null /* newParent */, - CONTROLLED_WINDOWING_MODES, - CONTROLLED_ACTIVITY_TYPES, - true /* onTop */); - wct.reorder(rootToken, mEnabled /* onTop */); - mSyncQueue.queue(wct); - if (mEnabled) { - final SurfaceControl rootLeash = mLaunchRootLeash; - mSyncQueue.runInSync(t -> { - t.setPosition(rootLeash, taskBounds.left, taskBounds.top); - t.setWindowCrop(rootLeash, mDisplayWidth, mDisplayHeight); - }); - } - } - - private Rect calculateBounds() { - final Rect bounds = new Rect(0, 0, mDisplayWidth, mDisplayHeight); - bounds.inset(mInsetsState.calculateInsets( - bounds, WindowInsets.Type.navigationBars(), false /* ignoreVisibility */)); - return bounds; - } - - private void updateBounds() { - if (mLaunchRootTask == null) { - return; - } - final WindowContainerTransaction wct = getWindowContainerTransaction(); - final Rect taskBounds = calculateBounds(); - wct.setBounds(mLaunchRootTask.token, taskBounds); - wct.setBounds(mHomeTask.token, new Rect(0, 0, mDisplayWidth, mDisplayHeight)); - mSyncQueue.queue(wct); - final SurfaceControl finalLeash = mLaunchRootLeash; - mSyncQueue.runInSync(t -> { - t.setPosition(finalLeash, taskBounds.left, taskBounds.top); - t.setWindowCrop(finalLeash, mDisplayWidth, mDisplayHeight); - }); - } - - @VisibleForTesting - WindowContainerTransaction getWindowContainerTransaction() { - return new WindowContainerTransaction(); - } - - @Override - public void dump(@NonNull PrintWriter pw, String prefix) { - final String innerPrefix = prefix + " "; - pw.println(prefix + TAG); - pw.println(innerPrefix + " mEnabled=" + mEnabled); - pw.println(innerPrefix + " mLaunchRootTask=" + mLaunchRootTask); - pw.println(innerPrefix + " mLaunchRootLeash=" + mLaunchRootLeash); - pw.println(innerPrefix + " mDisplayWidth=" + mDisplayWidth); - pw.println(innerPrefix + " mDisplayHeight=" + mDisplayHeight); - pw.println(innerPrefix + " mInsetsState=" + mInsetsState); - super.dump(pw, innerPrefix); - } -} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java deleted file mode 100644 index 58e91cb50c7a..000000000000 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.kidsmode; - -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.view.Display.DEFAULT_DISPLAY; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.pm.ParceledListSlice; -import android.content.res.Resources; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.view.InsetsState; -import android.view.SurfaceControl; -import android.window.ITaskOrganizerController; -import android.window.TaskAppearedInfo; -import android.window.WindowContainerToken; -import android.window.WindowContainerTransaction; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.wm.shell.ShellTestCase; -import com.android.wm.shell.common.DisplayController; -import com.android.wm.shell.common.DisplayInsetsController; -import com.android.wm.shell.common.ShellExecutor; -import com.android.wm.shell.common.SyncTransactionQueue; -import com.android.wm.shell.sysui.ShellCommandHandler; -import com.android.wm.shell.sysui.ShellInit; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.ArrayList; -import java.util.Optional; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class KidsModeTaskOrganizerTest extends ShellTestCase { - @Mock private ITaskOrganizerController mTaskOrganizerController; - @Mock private Context mContext; - @Mock private Handler mHandler; - @Mock private SyncTransactionQueue mSyncTransactionQueue; - @Mock private ShellExecutor mTestExecutor; - @Mock private DisplayController mDisplayController; - @Mock private SurfaceControl mLeash; - @Mock private WindowContainerToken mToken; - @Mock private WindowContainerTransaction mTransaction; - @Mock private KidsModeSettingsObserver mObserver; - @Mock private ShellInit mShellInit; - @Mock private ShellCommandHandler mShellCommandHandler; - @Mock private DisplayInsetsController mDisplayInsetsController; - @Mock private Resources mResources; - - KidsModeTaskOrganizer mOrganizer; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - try { - doReturn(ParceledListSlice.<TaskAppearedInfo>emptyList()) - .when(mTaskOrganizerController).registerTaskOrganizer(any()); - } catch (RemoteException e) { - } - // NOTE: KidsModeTaskOrganizer should have a null CompatUIController. - doReturn(mResources).when(mContext).getResources(); - final KidsModeTaskOrganizer kidsModeTaskOrganizer = new KidsModeTaskOrganizer(mContext, - mShellInit, mShellCommandHandler, mTaskOrganizerController, mSyncTransactionQueue, - mDisplayController, mDisplayInsetsController, Optional.empty(), Optional.empty(), - mObserver, mTestExecutor, mHandler); - mOrganizer = spy(kidsModeTaskOrganizer); - doReturn(mTransaction).when(mOrganizer).getWindowContainerTransaction(); - doReturn(new InsetsState()).when(mDisplayController).getInsetsState(DEFAULT_DISPLAY); - } - - @Test - public void instantiateController_addInitCallback() { - verify(mShellInit, times(1)).addInitCallback(any(), any()); - } - - @Test - public void testKidsModeOn() { - doReturn(true).when(mObserver).isEnabled(); - - mOrganizer.updateKidsModeState(); - - verify(mOrganizer, times(1)).enable(); - verify(mOrganizer, times(1)).registerOrganizer(); - verify(mOrganizer, times(1)).createRootTask( - eq(DEFAULT_DISPLAY), eq(WINDOWING_MODE_FULLSCREEN), eq(mOrganizer.mCookie)); - verify(mOrganizer, times(1)) - .setOrientationRequestPolicy(eq(true), any(), any()); - - final ActivityManager.RunningTaskInfo rootTask = createTaskInfo(12, - WINDOWING_MODE_FULLSCREEN, mOrganizer.mCookie); - mOrganizer.onTaskAppeared(rootTask, mLeash); - - assertThat(mOrganizer.mLaunchRootLeash).isEqualTo(mLeash); - assertThat(mOrganizer.mLaunchRootTask).isEqualTo(rootTask); - } - - @Test - public void testKidsModeOff() { - doReturn(true).when(mObserver).isEnabled(); - mOrganizer.updateKidsModeState(); - final ActivityManager.RunningTaskInfo rootTask = createTaskInfo(12, - WINDOWING_MODE_FULLSCREEN, mOrganizer.mCookie); - mOrganizer.onTaskAppeared(rootTask, mLeash); - - doReturn(false).when(mObserver).isEnabled(); - mOrganizer.updateKidsModeState(); - - verify(mOrganizer, times(1)).disable(); - verify(mOrganizer, times(1)).unregisterOrganizer(); - verify(mOrganizer, times(1)).deleteRootTask(rootTask.token); - verify(mOrganizer, times(1)) - .setOrientationRequestPolicy(eq(false), any(), any()); - assertThat(mOrganizer.mLaunchRootLeash).isNull(); - assertThat(mOrganizer.mLaunchRootTask).isNull(); - } - - private ActivityManager.RunningTaskInfo createTaskInfo( - int taskId, int windowingMode, IBinder cookies) { - ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo(); - taskInfo.taskId = taskId; - taskInfo.token = mToken; - taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode); - final ArrayList<IBinder> launchCookies = new ArrayList<>(); - if (cookies != null) { - launchCookies.add(cookies); - } - taskInfo.launchCookies = launchCookies; - return taskInfo; - } -} |