Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +25 −2 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.common.annotations.ShellSplashscreenThread; import com.android.wm.shell.compatui.CompatUIController; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopModeTaskRepository; import com.android.wm.shell.displayareahelper.DisplayAreaHelper; import com.android.wm.shell.displayareahelper.DisplayAreaHelperController; Loading Loading @@ -716,15 +718,36 @@ public abstract class WMShellBaseModule { // Desktop mode (optional feature) // @WMSingleton @Provides static Optional<DesktopMode> provideDesktopMode( Optional<DesktopModeController> desktopModeController) { return desktopModeController.map(DesktopModeController::asDesktopMode); } @BindsOptionalOf @DynamicOverride abstract DesktopModeController optionalDesktopModeController(); @WMSingleton @Provides static Optional<DesktopModeController> providesDesktopModeController( @DynamicOverride Optional<DesktopModeController> desktopModeController) { if (DesktopModeStatus.IS_SUPPORTED) { return desktopModeController; } return Optional.empty(); } @BindsOptionalOf @DynamicOverride abstract DesktopModeTaskRepository optionalDesktopModeTaskRepository(); @WMSingleton @Provides static Optional<DesktopModeTaskRepository> providesDesktopModeTaskRepository( static Optional<DesktopModeTaskRepository> providesDesktopTaskRepository( @DynamicOverride Optional<DesktopModeTaskRepository> desktopModeTaskRepository) { if (DesktopMode.IS_SUPPORTED) { if (DesktopModeStatus.IS_SUPPORTED) { return desktopModeTaskRepository; } return Optional.empty(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +8 −10 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.annotations.ShellBackgroundThread; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeTaskRepository; import com.android.wm.shell.draganddrop.DragAndDropController; Loading Loading @@ -595,19 +594,18 @@ public abstract class WMShellModule { @WMSingleton @Provides static Optional<DesktopModeController> provideDesktopModeController( Context context, ShellInit shellInit, @DynamicOverride static DesktopModeController provideDesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Transitions transitions, @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository, @ShellMainThread Handler mainHandler, Transitions transitions @ShellMainThread ShellExecutor mainExecutor ) { if (DesktopMode.IS_SUPPORTED) { return Optional.of(new DesktopModeController(context, shellInit, shellTaskOrganizer, rootTaskDisplayAreaOrganizer, mainHandler, transitions)); } else { return Optional.empty(); } return new DesktopModeController(context, shellInit, shellTaskOrganizer, rootTaskDisplayAreaOrganizer, transitions, desktopModeTaskRepository, mainHandler, mainExecutor); } @WMSingleton Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +7 −34 Original line number Diff line number Diff line Loading @@ -16,43 +16,16 @@ package com.android.wm.shell.desktopmode; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.content.Context; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import com.android.internal.protolog.common.ProtoLog; /** * Constants for desktop mode feature */ public class DesktopMode { import com.android.wm.shell.common.annotations.ExternalThread; /** * Flag to indicate whether desktop mode is available on the device * Interface to interact with desktop mode feature in shell. */ public static final boolean IS_SUPPORTED = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode", false); @ExternalThread public interface DesktopMode { /** * Check if desktop mode is active * * @return {@code true} if active */ public static boolean isActive(Context context) { if (!IS_SUPPORTED) { return false; } try { int result = Settings.System.getIntForUser(context.getContentResolver(), Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "isDesktopModeEnabled=%s", result); return result != 0; } catch (Exception e) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "Failed to read DESKTOP_MODE setting %s", e); return false; } /** Returns a binder that can be passed to an external process to manipulate DesktopMode. */ default IDesktopMode createExternalInterface() { return null; } } libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +105 −6 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.TRANSIT_CHANGE; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.content.Context; import android.database.ContentObserver; Loading @@ -29,51 +31,83 @@ import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.window.DisplayAreaInfo; import android.window.WindowContainerTransaction; import androidx.annotation.BinderThread; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.Comparator; /** * Handles windowing changes when desktop mode system setting changes */ public class DesktopModeController { public class DesktopModeController implements RemoteCallable<DesktopModeController> { private final Context mContext; private final ShellTaskOrganizer mShellTaskOrganizer; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final SettingsObserver mSettingsObserver; private final Transitions mTransitions; private final DesktopModeTaskRepository mDesktopModeTaskRepository; private final ShellExecutor mMainExecutor; private final DesktopMode mDesktopModeImpl = new DesktopModeImpl(); private final SettingsObserver mSettingsObserver; public DesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Transitions transitions, DesktopModeTaskRepository desktopModeTaskRepository, @ShellMainThread Handler mainHandler, Transitions transitions) { @ShellMainThread ShellExecutor mainExecutor) { mContext = context; mShellTaskOrganizer = shellTaskOrganizer; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mSettingsObserver = new SettingsObserver(mContext, mainHandler); mTransitions = transitions; mDesktopModeTaskRepository = desktopModeTaskRepository; mMainExecutor = mainExecutor; mSettingsObserver = new SettingsObserver(mContext, mainHandler); shellInit.addInitCallback(this::onInit, this); } private void onInit() { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopModeController"); mSettingsObserver.observe(); if (DesktopMode.isActive(mContext)) { if (DesktopModeStatus.isActive(mContext)) { updateDesktopModeActive(true); } } @Override public Context getContext() { return mContext; } @Override public ShellExecutor getRemoteCallExecutor() { return mMainExecutor; } /** * Get connection interface between sysui and shell */ public DesktopMode asDesktopMode() { return mDesktopModeImpl; } @VisibleForTesting void updateDesktopModeActive(boolean active) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active); Loading Loading @@ -120,6 +154,28 @@ public class DesktopModeController { wct.setWindowingMode(displayAreaInfo.token, windowingMode); } /** * Show apps on desktop */ public void showDesktopApps() { ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); ArrayList<RunningTaskInfo> taskInfos = new ArrayList<>(); for (Integer taskId : activeTasks) { RunningTaskInfo taskInfo = mShellTaskOrganizer.getRunningTaskInfo(taskId); if (taskInfo != null) { taskInfos.add(taskInfo); } } // Order by lastActiveTime, descending taskInfos.sort(Comparator.comparingLong(task -> -task.lastActiveTime)); WindowContainerTransaction wct = new WindowContainerTransaction(); for (RunningTaskInfo task : taskInfos) { wct.reorder(task.token, true); } mShellTaskOrganizer.applyTransaction(wct); } /** * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE} */ Loading Loading @@ -150,8 +206,51 @@ public class DesktopModeController { } private void desktopModeSettingChanged() { boolean enabled = DesktopMode.isActive(mContext); boolean enabled = DesktopModeStatus.isActive(mContext); updateDesktopModeActive(enabled); } } /** * The interface for calls from outside the shell, within the host process. */ @ExternalThread private final class DesktopModeImpl implements DesktopMode { private IDesktopModeImpl mIDesktopMode; @Override public IDesktopMode createExternalInterface() { if (mIDesktopMode != null) { mIDesktopMode.invalidate(); } mIDesktopMode = new IDesktopModeImpl(DesktopModeController.this); return mIDesktopMode; } } /** * The interface for calls from outside the host process. */ @BinderThread private static class IDesktopModeImpl extends IDesktopMode.Stub { private DesktopModeController mController; IDesktopModeImpl(DesktopModeController controller) { mController = controller; } /** * Invalidates this instance, preventing future calls from updating the controller. */ void invalidate() { mController = null; } public void showDesktopApps() { executeRemoteCallWithTaskPermission(mController, "showDesktopApps", DesktopModeController::showDesktopApps); } } } libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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.desktopmode; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.content.Context; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import com.android.internal.protolog.common.ProtoLog; /** * Constants for desktop mode feature */ public class DesktopModeStatus { /** * Flag to indicate whether desktop mode is available on the device */ public static final boolean IS_SUPPORTED = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode", false); /** * Check if desktop mode is active * * @return {@code true} if active */ public static boolean isActive(Context context) { if (!IS_SUPPORTED) { return false; } try { int result = Settings.System.getIntForUser(context.getContentResolver(), Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "isDesktopModeEnabled=%s", result); return result != 0; } catch (Exception e) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "Failed to read DESKTOP_MODE setting %s", e); return false; } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +25 −2 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.common.annotations.ShellSplashscreenThread; import com.android.wm.shell.compatui.CompatUIController; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopModeTaskRepository; import com.android.wm.shell.displayareahelper.DisplayAreaHelper; import com.android.wm.shell.displayareahelper.DisplayAreaHelperController; Loading Loading @@ -716,15 +718,36 @@ public abstract class WMShellBaseModule { // Desktop mode (optional feature) // @WMSingleton @Provides static Optional<DesktopMode> provideDesktopMode( Optional<DesktopModeController> desktopModeController) { return desktopModeController.map(DesktopModeController::asDesktopMode); } @BindsOptionalOf @DynamicOverride abstract DesktopModeController optionalDesktopModeController(); @WMSingleton @Provides static Optional<DesktopModeController> providesDesktopModeController( @DynamicOverride Optional<DesktopModeController> desktopModeController) { if (DesktopModeStatus.IS_SUPPORTED) { return desktopModeController; } return Optional.empty(); } @BindsOptionalOf @DynamicOverride abstract DesktopModeTaskRepository optionalDesktopModeTaskRepository(); @WMSingleton @Provides static Optional<DesktopModeTaskRepository> providesDesktopModeTaskRepository( static Optional<DesktopModeTaskRepository> providesDesktopTaskRepository( @DynamicOverride Optional<DesktopModeTaskRepository> desktopModeTaskRepository) { if (DesktopMode.IS_SUPPORTED) { if (DesktopModeStatus.IS_SUPPORTED) { return desktopModeTaskRepository; } return Optional.empty(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +8 −10 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.annotations.ShellBackgroundThread; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.desktopmode.DesktopMode; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeTaskRepository; import com.android.wm.shell.draganddrop.DragAndDropController; Loading Loading @@ -595,19 +594,18 @@ public abstract class WMShellModule { @WMSingleton @Provides static Optional<DesktopModeController> provideDesktopModeController( Context context, ShellInit shellInit, @DynamicOverride static DesktopModeController provideDesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Transitions transitions, @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository, @ShellMainThread Handler mainHandler, Transitions transitions @ShellMainThread ShellExecutor mainExecutor ) { if (DesktopMode.IS_SUPPORTED) { return Optional.of(new DesktopModeController(context, shellInit, shellTaskOrganizer, rootTaskDisplayAreaOrganizer, mainHandler, transitions)); } else { return Optional.empty(); } return new DesktopModeController(context, shellInit, shellTaskOrganizer, rootTaskDisplayAreaOrganizer, transitions, desktopModeTaskRepository, mainHandler, mainExecutor); } @WMSingleton Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMode.java +7 −34 Original line number Diff line number Diff line Loading @@ -16,43 +16,16 @@ package com.android.wm.shell.desktopmode; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.content.Context; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import com.android.internal.protolog.common.ProtoLog; /** * Constants for desktop mode feature */ public class DesktopMode { import com.android.wm.shell.common.annotations.ExternalThread; /** * Flag to indicate whether desktop mode is available on the device * Interface to interact with desktop mode feature in shell. */ public static final boolean IS_SUPPORTED = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode", false); @ExternalThread public interface DesktopMode { /** * Check if desktop mode is active * * @return {@code true} if active */ public static boolean isActive(Context context) { if (!IS_SUPPORTED) { return false; } try { int result = Settings.System.getIntForUser(context.getContentResolver(), Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "isDesktopModeEnabled=%s", result); return result != 0; } catch (Exception e) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "Failed to read DESKTOP_MODE setting %s", e); return false; } /** Returns a binder that can be passed to an external process to manipulate DesktopMode. */ default IDesktopMode createExternalInterface() { return null; } }
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +105 −6 Original line number Diff line number Diff line Loading @@ -20,8 +20,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.TRANSIT_CHANGE; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.content.Context; import android.database.ContentObserver; Loading @@ -29,51 +31,83 @@ import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.window.DisplayAreaInfo; import android.window.WindowContainerTransaction; import androidx.annotation.BinderThread; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.Comparator; /** * Handles windowing changes when desktop mode system setting changes */ public class DesktopModeController { public class DesktopModeController implements RemoteCallable<DesktopModeController> { private final Context mContext; private final ShellTaskOrganizer mShellTaskOrganizer; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final SettingsObserver mSettingsObserver; private final Transitions mTransitions; private final DesktopModeTaskRepository mDesktopModeTaskRepository; private final ShellExecutor mMainExecutor; private final DesktopMode mDesktopModeImpl = new DesktopModeImpl(); private final SettingsObserver mSettingsObserver; public DesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, Transitions transitions, DesktopModeTaskRepository desktopModeTaskRepository, @ShellMainThread Handler mainHandler, Transitions transitions) { @ShellMainThread ShellExecutor mainExecutor) { mContext = context; mShellTaskOrganizer = shellTaskOrganizer; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mSettingsObserver = new SettingsObserver(mContext, mainHandler); mTransitions = transitions; mDesktopModeTaskRepository = desktopModeTaskRepository; mMainExecutor = mainExecutor; mSettingsObserver = new SettingsObserver(mContext, mainHandler); shellInit.addInitCallback(this::onInit, this); } private void onInit() { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopModeController"); mSettingsObserver.observe(); if (DesktopMode.isActive(mContext)) { if (DesktopModeStatus.isActive(mContext)) { updateDesktopModeActive(true); } } @Override public Context getContext() { return mContext; } @Override public ShellExecutor getRemoteCallExecutor() { return mMainExecutor; } /** * Get connection interface between sysui and shell */ public DesktopMode asDesktopMode() { return mDesktopModeImpl; } @VisibleForTesting void updateDesktopModeActive(boolean active) { ProtoLog.d(WM_SHELL_DESKTOP_MODE, "updateDesktopModeActive: active=%s", active); Loading Loading @@ -120,6 +154,28 @@ public class DesktopModeController { wct.setWindowingMode(displayAreaInfo.token, windowingMode); } /** * Show apps on desktop */ public void showDesktopApps() { ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); ArrayList<RunningTaskInfo> taskInfos = new ArrayList<>(); for (Integer taskId : activeTasks) { RunningTaskInfo taskInfo = mShellTaskOrganizer.getRunningTaskInfo(taskId); if (taskInfo != null) { taskInfos.add(taskInfo); } } // Order by lastActiveTime, descending taskInfos.sort(Comparator.comparingLong(task -> -task.lastActiveTime)); WindowContainerTransaction wct = new WindowContainerTransaction(); for (RunningTaskInfo task : taskInfos) { wct.reorder(task.token, true); } mShellTaskOrganizer.applyTransaction(wct); } /** * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE} */ Loading Loading @@ -150,8 +206,51 @@ public class DesktopModeController { } private void desktopModeSettingChanged() { boolean enabled = DesktopMode.isActive(mContext); boolean enabled = DesktopModeStatus.isActive(mContext); updateDesktopModeActive(enabled); } } /** * The interface for calls from outside the shell, within the host process. */ @ExternalThread private final class DesktopModeImpl implements DesktopMode { private IDesktopModeImpl mIDesktopMode; @Override public IDesktopMode createExternalInterface() { if (mIDesktopMode != null) { mIDesktopMode.invalidate(); } mIDesktopMode = new IDesktopModeImpl(DesktopModeController.this); return mIDesktopMode; } } /** * The interface for calls from outside the host process. */ @BinderThread private static class IDesktopModeImpl extends IDesktopMode.Stub { private DesktopModeController mController; IDesktopModeImpl(DesktopModeController controller) { mController = controller; } /** * Invalidates this instance, preventing future calls from updating the controller. */ void invalidate() { mController = null; } public void showDesktopApps() { executeRemoteCallWithTaskPermission(mController, "showDesktopApps", DesktopModeController::showDesktopApps); } } }
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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.desktopmode; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.content.Context; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import com.android.internal.protolog.common.ProtoLog; /** * Constants for desktop mode feature */ public class DesktopModeStatus { /** * Flag to indicate whether desktop mode is available on the device */ public static final boolean IS_SUPPORTED = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode", false); /** * Check if desktop mode is active * * @return {@code true} if active */ public static boolean isActive(Context context) { if (!IS_SUPPORTED) { return false; } try { int result = Settings.System.getIntForUser(context.getContentResolver(), Settings.System.DESKTOP_MODE, UserHandle.USER_CURRENT); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "isDesktopModeEnabled=%s", result); return result != 0; } catch (Exception e) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "Failed to read DESKTOP_MODE setting %s", e); return false; } } }