Merge "Retail mode flag and some clients for it" into nyc-mr1-dev
am: dbf0dbd8c2
* commit 'dbf0dbd8c216e801b3d95f83d13ae05c1ba0ea39':
Retail mode flag and some clients for it
Change-Id: I5f9e7c49759154925c6f20ab3fd647d84259b1bb
This commit is contained in:
@@ -28,8 +28,8 @@ import android.os.UserManager;
|
|||||||
*/
|
*/
|
||||||
public class UserInfo implements Parcelable {
|
public class UserInfo implements Parcelable {
|
||||||
|
|
||||||
/** 8 bits for user type */
|
/** 16 bits for user type */
|
||||||
public static final int FLAG_MASK_USER_TYPE = 0x000000FF;
|
public static final int FLAG_MASK_USER_TYPE = 0x0000FFFF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* *************************** NOTE ***************************
|
* *************************** NOTE ***************************
|
||||||
@@ -87,6 +87,11 @@ public class UserInfo implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final int FLAG_EPHEMERAL = 0x00000100;
|
public static final int FLAG_EPHEMERAL = 0x00000100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User is for demo purposes only and can be removed at any time.
|
||||||
|
*/
|
||||||
|
public static final int FLAG_DEMO = 0x00000200;
|
||||||
|
|
||||||
public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;
|
public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;
|
||||||
|
|
||||||
public int id;
|
public int id;
|
||||||
@@ -153,6 +158,10 @@ public class UserInfo implements Parcelable {
|
|||||||
return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;
|
return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDemo() {
|
||||||
|
return (flags & FLAG_DEMO) == FLAG_DEMO;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the user is a split system user.
|
* Returns true if the user is a split system user.
|
||||||
* <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
|
* <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
|
||||||
|
|||||||
@@ -1972,6 +1972,10 @@ public class UserManager {
|
|||||||
if (!supportsMultipleUsers()) {
|
if (!supportsMultipleUsers()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// If Demo Mode is on, don't show user switcher
|
||||||
|
if (isDeviceInDemoMode(mContext)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
List<UserInfo> users = getUsers(true);
|
List<UserInfo> users = getUsers(true);
|
||||||
if (users == null) {
|
if (users == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1987,6 +1991,14 @@ public class UserManager {
|
|||||||
return switchableUserCount > 1 || guestEnabled;
|
return switchableUserCount > 1 || guestEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static boolean isDeviceInDemoMode(Context context) {
|
||||||
|
return Settings.Global.getInt(context.getContentResolver(),
|
||||||
|
Settings.Global.DEVICE_DEMO_MODE, 0) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a serial number on this device for a given userHandle. User handles can be recycled
|
* Returns a serial number on this device for a given userHandle. User handles can be recycled
|
||||||
* when deleting and creating users, but serial numbers are not reused until the device is wiped.
|
* when deleting and creating users, but serial numbers are not reused until the device is wiped.
|
||||||
|
|||||||
@@ -8537,6 +8537,15 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public static final String SAFE_BOOT_DISALLOWED = "safe_boot_disallowed";
|
public static final String SAFE_BOOT_DISALLOWED = "safe_boot_disallowed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this device is currently in retail demo mode. If true, device
|
||||||
|
* usage is severely limited.
|
||||||
|
* <p>
|
||||||
|
* Type: int (0 for false, 1 for true)
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final String DEVICE_DEMO_MODE = "device_demo_mode";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings to backup. This is here so that it's in the same place as the settings
|
* Settings to backup. This is here so that it's in the same place as the settings
|
||||||
* keys and easy to update.
|
* keys and easy to update.
|
||||||
|
|||||||
@@ -2484,4 +2484,7 @@
|
|||||||
<string-array translatable="false" name="config_defaultPinnerServiceFiles">
|
<string-array translatable="false" name="config_defaultPinnerServiceFiles">
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<!-- Component that is the default launcher when demo mode is enabled. -->
|
||||||
|
<string name="config_demoModeLauncherComponent"></string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1104,6 +1104,7 @@
|
|||||||
<java-symbol type="string" name="lockscreen_transport_pause_description" />
|
<java-symbol type="string" name="lockscreen_transport_pause_description" />
|
||||||
<java-symbol type="string" name="config_ethernet_tcp_buffers" />
|
<java-symbol type="string" name="config_ethernet_tcp_buffers" />
|
||||||
<java-symbol type="string" name="config_wifi_tcp_buffers" />
|
<java-symbol type="string" name="config_wifi_tcp_buffers" />
|
||||||
|
<java-symbol type="string" name="config_demoModeLauncherComponent" />
|
||||||
|
|
||||||
<java-symbol type="plurals" name="bugreport_countdown" />
|
<java-symbol type="plurals" name="bugreport_countdown" />
|
||||||
<java-symbol type="plurals" name="duration_hours" />
|
<java-symbol type="plurals" name="duration_hours" />
|
||||||
|
|||||||
@@ -399,8 +399,7 @@ public class KeyguardViewMediator extends SystemUI {
|
|||||||
sendUserPresentBroadcast();
|
sendUserPresentBroadcast();
|
||||||
synchronized (KeyguardViewMediator.this) {
|
synchronized (KeyguardViewMediator.this) {
|
||||||
// If system user is provisioned, we might want to lock now to avoid showing launcher
|
// If system user is provisioned, we might want to lock now to avoid showing launcher
|
||||||
if (UserManager.isSplitSystemUser()
|
if (mustNotUnlockCurrentUser()) {
|
||||||
&& KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM) {
|
|
||||||
doKeyguardLocked(null);
|
doKeyguardLocked(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,7 +598,6 @@ public class KeyguardViewMediator extends SystemUI {
|
|||||||
return KeyguardSecurityView.PROMPT_REASON_WRONG_CREDENTIAL;
|
return KeyguardSecurityView.PROMPT_REASON_WRONG_CREDENTIAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return KeyguardSecurityView.PROMPT_REASON_NONE;
|
return KeyguardSecurityView.PROMPT_REASON_NONE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -608,6 +606,11 @@ public class KeyguardViewMediator extends SystemUI {
|
|||||||
mPM.userActivity(SystemClock.uptimeMillis(), false);
|
mPM.userActivity(SystemClock.uptimeMillis(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean mustNotUnlockCurrentUser() {
|
||||||
|
return (UserManager.isSplitSystemUser() || UserManager.isDeviceInDemoMode(mContext))
|
||||||
|
&& KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
private void setupLocked() {
|
private void setupLocked() {
|
||||||
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||||
mWM = WindowManagerGlobal.getWindowManagerService();
|
mWM = WindowManagerGlobal.getWindowManagerService();
|
||||||
@@ -1176,8 +1179,7 @@ public class KeyguardViewMediator extends SystemUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// In split system user mode, we never unlock system user.
|
// In split system user mode, we never unlock system user.
|
||||||
if (!UserManager.isSplitSystemUser()
|
if (!mustNotUnlockCurrentUser()
|
||||||
|| KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM
|
|
||||||
|| !mUpdateMonitor.isDeviceProvisioned()) {
|
|| !mUpdateMonitor.isDeviceProvisioned()) {
|
||||||
|
|
||||||
// if the setup wizard hasn't run yet, don't show
|
// if the setup wizard hasn't run yet, don't show
|
||||||
@@ -1615,8 +1617,7 @@ public class KeyguardViewMediator extends SystemUI {
|
|||||||
synchronized (KeyguardViewMediator.this) {
|
synchronized (KeyguardViewMediator.this) {
|
||||||
if (DEBUG) Log.d(TAG, "handleHide");
|
if (DEBUG) Log.d(TAG, "handleHide");
|
||||||
|
|
||||||
if (UserManager.isSplitSystemUser()
|
if (mustNotUnlockCurrentUser()) {
|
||||||
&& KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM) {
|
|
||||||
// In split system user mode, we never unlock system user. The end user has to
|
// In split system user mode, we never unlock system user. The end user has to
|
||||||
// switch to another user.
|
// switch to another user.
|
||||||
// TODO: We should stop it early by disabling the swipe up flow. Right now swipe up
|
// TODO: We should stop it early by disabling the swipe up flow. Right now swipe up
|
||||||
|
|||||||
@@ -223,6 +223,8 @@ final class UserController {
|
|||||||
|
|
||||||
private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
|
private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
|
||||||
final int userId = uss.mHandle.getIdentifier();
|
final int userId = uss.mHandle.getIdentifier();
|
||||||
|
boolean deviceInDemoMode = UserManager.isDeviceInDemoMode(mService.mContext);
|
||||||
|
boolean switchToDemoUser = false;
|
||||||
Slog.d(TAG, "Finishing user boot " + userId);
|
Slog.d(TAG, "Finishing user boot " + userId);
|
||||||
synchronized (mService) {
|
synchronized (mService) {
|
||||||
// Bail if we ended up with a stale user
|
// Bail if we ended up with a stale user
|
||||||
@@ -259,7 +261,32 @@ final class UserController {
|
|||||||
} else {
|
} else {
|
||||||
maybeUnlockUser(userId);
|
maybeUnlockUser(userId);
|
||||||
}
|
}
|
||||||
|
if (deviceInDemoMode && mCurrentUserId == UserHandle.USER_SYSTEM) {
|
||||||
|
switchToDemoUser = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (switchToDemoUser) {
|
||||||
|
doSwitchToDemoUser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doSwitchToDemoUser() {
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Remove any demo users first
|
||||||
|
for (UserInfo user: mUserManager.getUsers(true)) {
|
||||||
|
if (user.isDemo()) {
|
||||||
|
mUserManager.removeUser(user.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UserInfo demoUser = mUserManager.createUser("Demo", UserInfo.FLAG_DEMO);
|
||||||
|
if (demoUser != null) {
|
||||||
|
mService.switchUser(demoUser.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.app.Activity;
|
|||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityManagerInternal;
|
import android.app.ActivityManagerInternal;
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
|
import android.app.AppGlobals;
|
||||||
import android.app.IActivityManager;
|
import android.app.IActivityManager;
|
||||||
import android.app.IStopUserCallback;
|
import android.app.IStopUserCallback;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
@@ -70,6 +71,7 @@ import android.os.storage.StorageManager;
|
|||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
import android.system.OsConstants;
|
import android.system.OsConstants;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.IntArray;
|
import android.util.IntArray;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -414,7 +416,9 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
// user restriction was not a default guest restriction.
|
// user restriction was not a default guest restriction.
|
||||||
setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id);
|
setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
maybeInitializeDemoMode(UserHandle.USER_SYSTEM);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUserAccount(int userId) {
|
public String getUserAccount(int userId) {
|
||||||
@@ -2710,6 +2714,8 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
mPm.onBeforeUserStartUninitialized(userId);
|
mPm.onBeforeUserStartUninitialized(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybeInitializeDemoMode(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2724,6 +2730,7 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a note of the last started time of a user and do some cleanup.
|
* Make a note of the last started time of a user and do some cleanup.
|
||||||
|
* This is called with ActivityManagerService lock held.
|
||||||
* @param userId the user that was just foregrounded
|
* @param userId the user that was just foregrounded
|
||||||
*/
|
*/
|
||||||
public void onUserLoggedIn(@UserIdInt int userId) {
|
public void onUserLoggedIn(@UserIdInt int userId) {
|
||||||
@@ -2741,6 +2748,24 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
scheduleWriteUser(userData);
|
scheduleWriteUser(userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeInitializeDemoMode(int userId) {
|
||||||
|
if (UserManager.isDeviceInDemoMode(mContext)) {
|
||||||
|
String demoLauncher =
|
||||||
|
mContext.getResources().getString(
|
||||||
|
com.android.internal.R.string.config_demoModeLauncherComponent);
|
||||||
|
if (!TextUtils.isEmpty(demoLauncher)) {
|
||||||
|
ComponentName componentToEnable = ComponentName.unflattenFromString(demoLauncher);
|
||||||
|
try {
|
||||||
|
AppGlobals.getPackageManager().setComponentEnabledSetting(componentToEnable,
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, /* flags= */ 0,
|
||||||
|
/* userId= */ userId);
|
||||||
|
} catch (RemoteException re) {
|
||||||
|
// Internal, shouldn't happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next available user id, filling in any holes in the ids.
|
* Returns the next available user id, filling in any holes in the ids.
|
||||||
* TODO: May not be a good idea to recycle ids, in case it results in confusion
|
* TODO: May not be a good idea to recycle ids, in case it results in confusion
|
||||||
|
|||||||
Reference in New Issue
Block a user