Merge "Adding RetailModeService to handle retail mode" into nyc-mr1-dev

am: a09c9e0fc4

* commit 'a09c9e0fc48816096349aac8960a3b49101d90a3':
  Adding RetailModeService to handle retail mode

Change-Id: I8ac04712c319eeb4ff8087ea828331bdb0450867
This commit is contained in:
Suprabh Shukla
2016-05-24 02:31:46 +00:00
committed by android-build-merger
5 changed files with 195 additions and 28 deletions

View File

@@ -20939,6 +20939,11 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "No user info for user #" + targetUserId);
return false;
}
if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
+ " when device is in demo mode");
return false;
}
if (!targetUserInfo.supportsSwitchTo()) {
Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
return false;

View File

@@ -0,0 +1,179 @@
/*
* Copyright (C) 2016 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.server.am;
import android.app.ActivityManagerNative;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.PowerManager;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Slog;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerService;
public class RetailDemoModeService extends SystemService {
private static final boolean DEBUG = false;
private static final String TAG = RetailDemoModeService.class.getSimpleName();
private static final String DEMO_USER_NAME = "Demo";
private static final long SCREEN_WAKEUP_DELAY = 5000;
private ActivityManagerService mAms;
private UserManagerService mUms;
private PowerManager mPm;
private PowerManager.WakeLock mWakeLock;
private Handler mHandler;
private ServiceThread mHandlerThread;
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!UserManager.isDeviceInDemoMode(getContext())) {
return;
}
switch (intent.getAction()) {
case Intent.ACTION_SCREEN_OFF:
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (mWakeLock.isHeld()) {
mWakeLock.release();
}
mWakeLock.acquire();
}
}, SCREEN_WAKEUP_DELAY);
break;
}
}
};
public RetailDemoModeService(Context context) {
super(context);
}
private void createAndSwitchToDemoUser() {
if (DEBUG) {
Slog.d(TAG, "Switching to a new demo user");
}
mHandler.post(new Runnable() {
@Override
public void run() {
UserInfo demoUser = getUserManager().createUser(DEMO_USER_NAME,
UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
if (demoUser != null) {
getActivityManager().switchUser(demoUser.id);
}
}
});
}
private ActivityManagerService getActivityManager() {
if (mAms == null) {
mAms = (ActivityManagerService) ActivityManagerNative.getDefault();
}
return mAms;
}
private UserManagerService getUserManager() {
if (mUms == null) {
mUms = (UserManagerService) UserManagerService.Stub
.asInterface(ServiceManager.getService(Context.USER_SERVICE));
}
return mUms;
}
private void registerSettingsChangeObserver() {
final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
final ContentResolver cr = getContext().getContentResolver();
final ContentObserver deviceDemoModeSettingObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
if (deviceDemoModeUri.equals(uri)) {
if (UserManager.isDeviceInDemoMode(getContext())) {
createAndSwitchToDemoUser();
}
}
}
};
cr.registerContentObserver(deviceDemoModeUri, false, deviceDemoModeSettingObserver,
UserHandle.USER_SYSTEM);
}
private void registerBroadcastReceiver() {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
}
@Override
public void onStart() {
if (DEBUG) {
Slog.d(TAG, "Service starting up");
}
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,
false);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), null, true);
}
@Override
public void onBootPhase(int bootPhase) {
if (bootPhase != PHASE_THIRD_PARTY_APPS_CAN_START) {
return;
}
mPm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = mPm
.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
if (UserManager.isDeviceInDemoMode(getContext())) {
createAndSwitchToDemoUser();
}
registerSettingsChangeObserver();
registerBroadcastReceiver();
}
@Override
public void onSwitchUser(int userId) {
if (DEBUG) {
Slog.d(TAG, "onSwitchUser: " + userId);
}
UserInfo ui = getUserManager().getUserInfo(userId);
if (!ui.isDemo()) {
if (UserManager.isDeviceInDemoMode(getContext())) {
Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
} else if (mWakeLock.isHeld()) {
mWakeLock.release();
}
return;
}
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
}
}
}

View File

@@ -223,8 +223,7 @@ final class UserController {
private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
final int userId = uss.mHandle.getIdentifier();
boolean deviceInDemoMode = UserManager.isDeviceInDemoMode(mService.mContext);
boolean switchToDemoUser = false;
Slog.d(TAG, "Finishing user boot " + userId);
synchronized (mService) {
// Bail if we ended up with a stale user
@@ -261,32 +260,7 @@ final class UserController {
} else {
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);
}
}
});
}
/**

View File

@@ -2074,7 +2074,8 @@ public class UserManagerService extends IUserManager.Stub {
return null;
}
}
if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0) {
if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0
&& (flags & UserInfo.FLAG_DEMO) == 0) {
Log.e(LOG_TAG,
"Ephemeral users are supported on split-system-user systems only.");
return null;

View File

@@ -42,7 +42,9 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IMountService;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
@@ -55,6 +57,7 @@ import com.android.internal.os.ZygoteInit;
import com.android.internal.widget.ILockSettings;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.RetailDemoModeService;
import com.android.server.audio.AudioService;
import com.android.server.camera.CameraService;
import com.android.server.clipboard.ClipboardService;
@@ -1180,6 +1183,11 @@ public final class SystemServer {
// MMS service broker
mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
if (Settings.Global.getInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0 ||
UserManager.isDeviceInDemoMode(mSystemContext)) {
mSystemServiceManager.startService(RetailDemoModeService.class);
}
// It is now time to start up the app processes...
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeVibratorServiceReady");