allow locking UI mode and block launching car dock for automotive
- add config to lock UI mode change: When this is enabled,
request to change car mode will be ignored. Apps can check
the config using UiModeManager.isUiModeLocked()
- add config to lock day / night mode: When this is enabled,
apps cannot change day / night mode without having
MODIFY_DAY_NIGHT_MODE permission.
Apps can check the config using UiModeManager.isNightModeLocked()
- add config to disable car dock intent launch for home key
and mode change
- All new configs have default values which keeps the current behavior.
Car products should override the configs to get desirable behavior.
bug: 22700993
Change-Id: Ic0e58f3428151e0b1c19a2e9a7d6ded32ff962a6
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 0b67ad8..6f713cd 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -57,7 +57,6 @@
private static final boolean LOG = false;
// Enable launching of applications when entering the dock.
- private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
final Object mLock = new Object();
@@ -76,6 +75,13 @@
private boolean mComputedNightMode;
private int mCarModeEnableFlags;
+ // flag set by resource, whether to enable Car dock launch when starting car mode.
+ private boolean mEnableCarDockLaunch = true;
+ // flag set by resource, whether to lock UI mode to the default one or not.
+ private boolean mUiModeLocked = false;
+ // flag set by resource, whether to night mode change for normal all or not.
+ private boolean mNightModeLocked = false;
+
int mCurUiMode = 0;
private int mSetUiMode = 0;
private boolean mHoldingConfiguration = false;
@@ -176,6 +182,10 @@
com.android.internal.R.integer.config_carDockKeepsScreenOn) == 1);
mDeskModeKeepsScreenOn = (res.getInteger(
com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
+ mEnableCarDockLaunch = res.getBoolean(
+ com.android.internal.R.bool.config_enableCarDockHomeLaunch);
+ mUiModeLocked = res.getBoolean(com.android.internal.R.bool.config_lockUiMode);
+ mNightModeLocked = res.getBoolean(com.android.internal.R.bool.config_lockDayNightMode);
final PackageManager pm = context.getPackageManager();
mTelevision = pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
@@ -199,6 +209,10 @@
private final IBinder mService = new IUiModeManager.Stub() {
@Override
public void enableCarMode(int flags) {
+ if (isUiModeLocked()) {
+ Slog.e(TAG, "enableCarMode while UI mode is locked");
+ return;
+ }
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -214,6 +228,10 @@
@Override
public void disableCarMode(int flags) {
+ if (isUiModeLocked()) {
+ Slog.e(TAG, "disableCarMode while UI mode is locked");
+ return;
+ }
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -241,6 +259,13 @@
@Override
public void setNightMode(int mode) {
+ if (isNightModeLocked() && (getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
+ != PackageManager.PERMISSION_GRANTED)) {
+ Slog.e(TAG,
+ "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission");
+ return;
+ }
switch (mode) {
case UiModeManager.MODE_NIGHT_NO:
case UiModeManager.MODE_NIGHT_YES:
@@ -273,6 +298,20 @@
}
@Override
+ public boolean isUiModeLocked() {
+ synchronized (mLock) {
+ return mUiModeLocked;
+ }
+ }
+
+ @Override
+ public boolean isNightModeLocked() {
+ synchronized (mLock) {
+ return mNightModeLocked;
+ }
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -293,10 +332,13 @@
pw.print(" mDockState="); pw.print(mDockState);
pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
pw.print(" mNightMode="); pw.print(mNightMode);
+ pw.print(" mNightModeLocked="); pw.print(mNightModeLocked);
pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
pw.print(" mComputedNightMode="); pw.print(mComputedNightMode);
- pw.print(" mCarModeEnableFlags="); pw.println(mCarModeEnableFlags);
+ pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags);
+ pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch);
pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
+ pw.print(" mUiModeLocked="); pw.print(mUiModeLocked);
pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration);
pw.print(" mSystemReady="); pw.println(mSystemReady);
@@ -356,7 +398,9 @@
private void updateConfigurationLocked() {
int uiMode = mDefaultUiModeType;
- if (mTelevision) {
+ if (mUiModeLocked) {
+ // no-op, keeps default one
+ } else if (mTelevision) {
uiMode = Configuration.UI_MODE_TYPE_TELEVISION;
} else if (mWatch) {
uiMode = Configuration.UI_MODE_TYPE_WATCH;
@@ -460,7 +504,7 @@
} else {
String category = null;
if (mCarModeEnabled) {
- if (ENABLE_LAUNCH_CAR_DOCK_APP
+ if (mEnableCarDockLaunch
&& (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
category = Intent.CATEGORY_CAR_DOCK;
}
@@ -503,7 +547,7 @@
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) {
// Only launch car home when car mode is enabled and the caller
// has asked us to switch to it.
- if (ENABLE_LAUNCH_CAR_DOCK_APP
+ if (mEnableCarDockLaunch
&& (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
category = Intent.CATEGORY_CAR_DOCK;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9a7d153..2031061 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -158,8 +158,7 @@
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
// Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
- // No longer recommended for desk docks; still useful in car docks.
- static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
+ // No longer recommended for desk docks;
static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
static final int SHORT_PRESS_POWER_NOTHING = 0;
@@ -316,6 +315,10 @@
int[] mNavigationBarHeightForRotation = new int[4];
int[] mNavigationBarWidthForRotation = new int[4];
+ // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
+ // This is for car dock and this is updated from resource.
+ private boolean mEnableCarDockHomeCapture = true;
+
boolean mBootMessageNeedsHiding;
KeyguardServiceDelegate mKeyguardDelegate;
final Runnable mWindowManagerDrawCallback = new Runnable() {
@@ -1398,6 +1401,8 @@
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ mEnableCarDockHomeCapture = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableCarDockHomeLaunch);
mCarDockIntent = new Intent(Intent.ACTION_MAIN, null);
mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -6404,7 +6409,7 @@
* true:
* <ul>
* <li>The device is not in either car mode or desk mode
- * <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
+ * <li>The device is in car mode but mEnableCarDockHomeCapture is false
* <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
* <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
* <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
@@ -6418,7 +6423,7 @@
// is, when in car mode you should be taken to car home regardless
// of whether we are actually in a car dock.
if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
- if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
+ if (mEnableCarDockHomeCapture) {
intent = mCarDockIntent;
}
} else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
@@ -6938,6 +6943,7 @@
pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation);
pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
pw.print(" mDockMode="); pw.print(mDockMode);
+ pw.print(" mEnableCarDockHomeCapture="); pw.print(mEnableCarDockHomeCapture);
pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);