RetailDemoModeService.java revision b632c5546968bc20e60e5b86ded4c41612a47c52
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.server.retaildemo; 18 19import android.Manifest; 20import android.app.ActivityManagerInternal; 21import android.app.ActivityManagerNative; 22import android.app.AppGlobals; 23import android.app.Notification; 24import android.app.NotificationManager; 25import android.app.PendingIntent; 26import android.app.RetailDemoModeServiceInternal; 27import android.content.BroadcastReceiver; 28import android.content.ComponentName; 29import android.content.ContentResolver; 30import android.content.Context; 31import android.content.DialogInterface; 32import android.content.Intent; 33import android.content.IntentFilter; 34import android.content.pm.IPackageManager; 35import android.content.pm.PackageManager; 36import android.content.pm.ResolveInfo; 37import android.content.pm.UserInfo; 38import android.content.res.Configuration; 39import android.database.ContentObserver; 40import android.hardware.camera2.CameraAccessException; 41import android.hardware.camera2.CameraCharacteristics; 42import android.hardware.camera2.CameraManager; 43import android.media.AudioManager; 44import android.media.AudioSystem; 45import android.net.Uri; 46import android.net.wifi.WifiManager; 47import android.os.Environment; 48import android.os.FileUtils; 49import android.os.Handler; 50import android.os.Looper; 51import android.os.Message; 52import android.os.PowerManager; 53import android.os.RemoteException; 54import android.os.SystemClock; 55import android.os.SystemProperties; 56import android.os.UserHandle; 57import android.os.UserManager; 58import android.provider.CallLog; 59import android.provider.MediaStore; 60import android.provider.Settings; 61import android.text.TextUtils; 62import android.util.KeyValueListParser; 63import android.util.Slog; 64import com.android.internal.os.BackgroundThread; 65import com.android.internal.R; 66import com.android.internal.annotations.GuardedBy; 67import com.android.internal.logging.MetricsLogger; 68import com.android.internal.widget.LockPatternUtils; 69import com.android.server.LocalServices; 70import com.android.server.ServiceThread; 71import com.android.server.SystemService; 72import com.android.server.am.ActivityManagerService; 73import com.android.server.retaildemo.UserInactivityCountdownDialog.OnCountDownExpiredListener; 74 75import java.io.File; 76import java.util.ArrayList; 77 78public class RetailDemoModeService extends SystemService { 79 private static final boolean DEBUG = false; 80 81 private static final String TAG = RetailDemoModeService.class.getSimpleName(); 82 private static final String DEMO_USER_NAME = "Demo"; 83 private static final String ACTION_RESET_DEMO = 84 "com.android.server.retaildemo.ACTION_RESET_DEMO"; 85 private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled"; 86 87 private static final int MSG_TURN_SCREEN_ON = 0; 88 private static final int MSG_INACTIVITY_TIME_OUT = 1; 89 private static final int MSG_START_NEW_SESSION = 2; 90 91 private static final long SCREEN_WAKEUP_DELAY = 2500; 92 private static final long USER_INACTIVITY_TIMEOUT_MIN = 10000; 93 private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 90000; 94 private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 0; 95 private static final long MILLIS_PER_SECOND = 1000; 96 97 private static final int[] VOLUME_STREAMS_TO_MUTE = { 98 AudioSystem.STREAM_RING, 99 AudioSystem.STREAM_MUSIC 100 }; 101 102 // Tron Vars 103 private static final String DEMO_SESSION_COUNT = "retail_demo_session_count"; 104 private static final String DEMO_SESSION_DURATION = "retail_demo_session_duration"; 105 106 boolean mDeviceInDemoMode; 107 boolean mIsCarrierDemoMode; 108 int mCurrentUserId = UserHandle.USER_SYSTEM; 109 long mUserInactivityTimeout; 110 long mWarningDialogTimeout; 111 private ActivityManagerService mAms; 112 private ActivityManagerInternal mAmi; 113 private AudioManager mAudioManager; 114 private NotificationManager mNm; 115 private UserManager mUm; 116 private PowerManager mPm; 117 private PowerManager.WakeLock mWakeLock; 118 Handler mHandler; 119 private ServiceThread mHandlerThread; 120 private PendingIntent mResetDemoPendingIntent; 121 private CameraManager mCameraManager; 122 private WifiManager mWifiManager; 123 private String[] mCameraIdsWithFlash; 124 private Configuration mSystemUserConfiguration; 125 private PreloadAppsInstaller mPreloadAppsInstaller; 126 127 final Object mActivityLock = new Object(); 128 // Whether the newly created demo user has interacted with the screen yet 129 @GuardedBy("mActivityLock") 130 boolean mUserUntouched; 131 @GuardedBy("mActivityLock") 132 long mFirstUserActivityTime; 133 @GuardedBy("mActivityLock") 134 long mLastUserActivityTime; 135 136 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 137 @Override 138 public void onReceive(Context context, Intent intent) { 139 if (!mDeviceInDemoMode) { 140 return; 141 } 142 final String action = intent.getAction(); 143 switch (action) { 144 case Intent.ACTION_SCREEN_OFF: 145 mHandler.removeMessages(MSG_TURN_SCREEN_ON); 146 mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY); 147 break; 148 case ACTION_RESET_DEMO: 149 mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); 150 break; 151 } 152 } 153 }; 154 155 final class MainHandler extends Handler { 156 157 MainHandler(Looper looper) { 158 super(looper, null, true); 159 } 160 161 @Override 162 public void handleMessage(Message msg) { 163 switch (msg.what) { 164 case MSG_TURN_SCREEN_ON: 165 if (mWakeLock.isHeld()) { 166 mWakeLock.release(); 167 } 168 mWakeLock.acquire(); 169 break; 170 case MSG_INACTIVITY_TIME_OUT: 171 if (!mIsCarrierDemoMode && isDemoLauncherDisabled()) { 172 Slog.i(TAG, "User inactivity timeout reached"); 173 showInactivityCountdownDialog(); 174 } 175 break; 176 case MSG_START_NEW_SESSION: 177 if (DEBUG) { 178 Slog.d(TAG, "Switching to a new demo user"); 179 } 180 removeMessages(MSG_START_NEW_SESSION); 181 removeMessages(MSG_INACTIVITY_TIME_OUT); 182 if (!mIsCarrierDemoMode && mCurrentUserId != UserHandle.USER_SYSTEM) { 183 logSessionDuration(); 184 } 185 186 UserInfo demoUser = null; 187 if (mIsCarrierDemoMode) { 188 // Re-use the existing demo user in carrier demo mode. 189 for (UserInfo user : getUserManager().getUsers()) { 190 if (user.isDemo()) { 191 demoUser = user; 192 break; 193 } 194 } 195 } 196 197 if (demoUser == null) { 198 // User in carrier demo mode should survive reboots. 199 final int flags = UserInfo.FLAG_DEMO 200 | (mIsCarrierDemoMode ? 0 : UserInfo.FLAG_EPHEMERAL); 201 demoUser = getUserManager().createUser(DEMO_USER_NAME, flags); 202 } 203 204 if (demoUser != null && mCurrentUserId != demoUser.id) { 205 setupDemoUser(demoUser); 206 getActivityManager().switchUser(demoUser.id); 207 } 208 break; 209 } 210 } 211 } 212 213 private class SettingsObserver extends ContentObserver { 214 215 private final static String KEY_USER_INACTIVITY_TIMEOUT = "user_inactivity_timeout_ms"; 216 private final static String KEY_WARNING_DIALOG_TIMEOUT = "warning_dialog_timeout_ms"; 217 218 private final Uri mDeviceProvisionedUri = Settings.Global 219 .getUriFor(Settings.Global.DEVICE_PROVISIONED); 220 private final Uri mRetailDemoConstantsUri = Settings.Global 221 .getUriFor(Settings.Global.RETAIL_DEMO_MODE_CONSTANTS); 222 223 private final KeyValueListParser mParser = new KeyValueListParser(','); 224 225 public SettingsObserver(Handler handler) { 226 super(handler); 227 } 228 229 public void register() { 230 ContentResolver cr = getContext().getContentResolver(); 231 cr.registerContentObserver(mDeviceProvisionedUri, false, this, UserHandle.USER_SYSTEM); 232 cr.registerContentObserver(mRetailDemoConstantsUri, false, this, 233 UserHandle.USER_SYSTEM); 234 } 235 236 @Override 237 public void onChange(boolean selfChange, Uri uri) { 238 if (mRetailDemoConstantsUri.equals(uri)) { 239 refreshTimeoutConstants(); 240 return; 241 } 242 // If device is provisioned and left demo mode - run the cleanup in demo folder 243 if (isDeviceProvisioned()) { 244 if (UserManager.isDeviceInDemoMode(getContext())) { 245 putDeviceInDemoMode(); 246 } else { 247 SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "0"); 248 249 // Run on the bg thread to not block the fg thread 250 BackgroundThread.getHandler().post(new Runnable() { 251 @Override 252 public void run() { 253 if (!deletePreloadsFolderContents()) { 254 Slog.w(TAG, "Failed to delete preloads folder contents"); 255 } 256 } 257 }); 258 259 if (mWakeLock.isHeld()) { 260 mWakeLock.release(); 261 } 262 } 263 } 264 } 265 266 private void refreshTimeoutConstants() { 267 try { 268 mParser.setString(Settings.Global.getString(getContext().getContentResolver(), 269 Settings.Global.RETAIL_DEMO_MODE_CONSTANTS)); 270 } catch (IllegalArgumentException exc) { 271 Slog.e(TAG, "Invalid string passed to KeyValueListParser"); 272 // Consuming the exception to fall back to default values. 273 } 274 mWarningDialogTimeout = mParser.getLong(KEY_WARNING_DIALOG_TIMEOUT, 275 WARNING_DIALOG_TIMEOUT_DEFAULT); 276 mUserInactivityTimeout = mParser.getLong(KEY_USER_INACTIVITY_TIMEOUT, 277 USER_INACTIVITY_TIMEOUT_DEFAULT); 278 mUserInactivityTimeout = Math.max(mUserInactivityTimeout, USER_INACTIVITY_TIMEOUT_MIN); 279 } 280 } 281 282 private void showInactivityCountdownDialog() { 283 UserInactivityCountdownDialog dialog = new UserInactivityCountdownDialog(getContext(), 284 mWarningDialogTimeout, MILLIS_PER_SECOND); 285 dialog.setNegativeButtonClickListener(null); 286 dialog.setPositiveButtonClickListener(new DialogInterface.OnClickListener() { 287 @Override 288 public void onClick(DialogInterface dialog, int which) { 289 mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); 290 } 291 }); 292 dialog.setOnCountDownExpiredListener(new OnCountDownExpiredListener() { 293 @Override 294 public void onCountDownExpired() { 295 mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); 296 } 297 }); 298 dialog.show(); 299 } 300 301 public RetailDemoModeService(Context context) { 302 super(context); 303 synchronized (mActivityLock) { 304 mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis(); 305 } 306 } 307 308 private Notification createResetNotification() { 309 return new Notification.Builder(getContext()) 310 .setContentTitle(getContext().getString(R.string.reset_retail_demo_mode_title)) 311 .setContentText(getContext().getString(R.string.reset_retail_demo_mode_text)) 312 .setOngoing(true) 313 .setSmallIcon(R.drawable.platlogo) 314 .setShowWhen(false) 315 .setVisibility(Notification.VISIBILITY_PUBLIC) 316 .setContentIntent(getResetDemoPendingIntent()) 317 .setColor(getContext().getColor(R.color.system_notification_accent_color)) 318 .build(); 319 } 320 321 private PendingIntent getResetDemoPendingIntent() { 322 if (mResetDemoPendingIntent == null) { 323 Intent intent = new Intent(ACTION_RESET_DEMO); 324 mResetDemoPendingIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0); 325 } 326 return mResetDemoPendingIntent; 327 } 328 329 boolean isDemoLauncherDisabled() { 330 int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 331 try { 332 final IPackageManager iPm = AppGlobals.getPackageManager(); 333 final String demoLauncherComponent = 334 getContext().getString(R.string.config_demoModeLauncherComponent); 335 enabledState = iPm.getComponentEnabledSetting( 336 ComponentName.unflattenFromString(demoLauncherComponent), mCurrentUserId); 337 } catch (RemoteException re) { 338 Slog.e(TAG, "Error retrieving demo launcher enabled setting", re); 339 } 340 return enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 341 } 342 343 private void setupDemoUser(UserInfo userInfo) { 344 final UserManager um = getUserManager(); 345 final UserHandle user = UserHandle.of(userInfo.id); 346 um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user); 347 um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user); 348 um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user); 349 um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user); 350 um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user); 351 um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user); 352 // Set this to false because the default is true on user creation 353 um.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user); 354 // Disallow rebooting in safe mode - controlled by user 0 355 um.setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM); 356 357 Settings.Secure.putIntForUser(getContext().getContentResolver(), 358 Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id); 359 Settings.Global.putInt(getContext().getContentResolver(), 360 Settings.Global.PACKAGE_VERIFIER_ENABLE, 0); 361 362 grantRuntimePermissionToCamera(user); 363 clearPrimaryCallLog(); 364 365 if (!mIsCarrierDemoMode) { 366 // Enable demo launcher. 367 final String demoLauncher = getContext().getString( 368 R.string.config_demoModeLauncherComponent); 369 if (!TextUtils.isEmpty(demoLauncher)) { 370 final ComponentName componentToEnable = 371 ComponentName.unflattenFromString(demoLauncher); 372 final String packageName = componentToEnable.getPackageName(); 373 try { 374 final IPackageManager iPm = AppGlobals.getPackageManager(); 375 iPm.setComponentEnabledSetting(componentToEnable, 376 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id); 377 iPm.setApplicationEnabledSetting(packageName, 378 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null); 379 } catch (RemoteException re) { 380 // Internal, shouldn't happen 381 } 382 } 383 } else { 384 // Set the carrier demo mode setting for the demo user. 385 final String carrierDemoModeSetting = getContext().getString( 386 R.string.config_carrierDemoModeSetting); 387 Settings.Secure.putIntForUser(getContext().getContentResolver(), 388 carrierDemoModeSetting, 1, userInfo.id); 389 390 // Enable packages for carrier demo mode. 391 final String packageList = getContext().getString( 392 R.string.config_carrierDemoModePackages); 393 final String[] packageNames = packageList == null ? new String[0] 394 : TextUtils.split(packageList, ","); 395 final IPackageManager iPm = AppGlobals.getPackageManager(); 396 for (String packageName : packageNames) { 397 try { 398 iPm.setApplicationEnabledSetting(packageName, 399 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null); 400 } catch (RemoteException re) { 401 Slog.e(TAG, "Error enabling application: " + packageName, re); 402 } 403 } 404 } 405 } 406 407 private void grantRuntimePermissionToCamera(UserHandle user) { 408 final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 409 final PackageManager pm = getContext().getPackageManager(); 410 final ResolveInfo handler = pm.resolveActivityAsUser(cameraIntent, 411 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 412 user.getIdentifier()); 413 if (handler == null || handler.activityInfo == null) { 414 return; 415 } 416 try { 417 pm.grantRuntimePermission(handler.activityInfo.packageName, 418 Manifest.permission.ACCESS_FINE_LOCATION, user); 419 } catch (Exception e) { 420 // Ignore 421 } 422 } 423 424 private void clearPrimaryCallLog() { 425 final ContentResolver resolver = getContext().getContentResolver(); 426 427 // Deleting primary user call log so that it doesn't get copied to the new demo user 428 final Uri uri = CallLog.Calls.CONTENT_URI; 429 try { 430 resolver.delete(uri, null, null); 431 } catch (Exception e) { 432 Slog.w(TAG, "Deleting call log failed: " + e); 433 } 434 } 435 436 void logSessionDuration() { 437 final int sessionDuration; 438 synchronized (mActivityLock) { 439 sessionDuration = (int) ((mLastUserActivityTime - mFirstUserActivityTime) / 1000); 440 } 441 MetricsLogger.histogram(getContext(), DEMO_SESSION_DURATION, sessionDuration); 442 } 443 444 private ActivityManagerService getActivityManager() { 445 if (mAms == null) { 446 mAms = (ActivityManagerService) ActivityManagerNative.getDefault(); 447 } 448 return mAms; 449 } 450 451 private UserManager getUserManager() { 452 if (mUm == null) { 453 mUm = getContext().getSystemService(UserManager.class); 454 } 455 return mUm; 456 } 457 458 private AudioManager getAudioManager() { 459 if (mAudioManager == null) { 460 mAudioManager = getContext().getSystemService(AudioManager.class); 461 } 462 return mAudioManager; 463 } 464 465 private boolean isDeviceProvisioned() { 466 return Settings.Global.getInt( 467 getContext().getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; 468 } 469 470 private boolean deletePreloadsFolderContents() { 471 final File dir = Environment.getDataPreloadsDirectory(); 472 Slog.i(TAG, "Deleting contents of " + dir); 473 return FileUtils.deleteContents(dir); 474 } 475 476 private void registerBroadcastReceiver() { 477 final IntentFilter filter = new IntentFilter(); 478 if (!mIsCarrierDemoMode) { 479 filter.addAction(Intent.ACTION_SCREEN_OFF); 480 } 481 filter.addAction(ACTION_RESET_DEMO); 482 getContext().registerReceiver(mBroadcastReceiver, filter); 483 } 484 485 private String[] getCameraIdsWithFlash() { 486 ArrayList<String> cameraIdsList = new ArrayList<String>(); 487 try { 488 for (String cameraId : mCameraManager.getCameraIdList()) { 489 CameraCharacteristics c = mCameraManager.getCameraCharacteristics(cameraId); 490 if (Boolean.TRUE.equals(c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE))) { 491 cameraIdsList.add(cameraId); 492 } 493 } 494 } catch (CameraAccessException e) { 495 Slog.e(TAG, "Unable to access camera while getting camera id list", e); 496 } 497 return cameraIdsList.toArray(new String[cameraIdsList.size()]); 498 } 499 500 private void turnOffAllFlashLights() { 501 for (String cameraId : mCameraIdsWithFlash) { 502 try { 503 mCameraManager.setTorchMode(cameraId, false); 504 } catch (CameraAccessException e) { 505 Slog.e(TAG, "Unable to access camera " + cameraId + " while turning off flash", e); 506 } 507 } 508 } 509 510 private void muteVolumeStreams() { 511 for (int stream : VOLUME_STREAMS_TO_MUTE) { 512 getAudioManager().setStreamVolume(stream, getAudioManager().getStreamMinVolume(stream), 513 0); 514 } 515 } 516 517 private Configuration getSystemUsersConfiguration() { 518 if (mSystemUserConfiguration == null) { 519 Settings.System.getConfiguration(getContext().getContentResolver(), 520 mSystemUserConfiguration = new Configuration()); 521 } 522 return mSystemUserConfiguration; 523 } 524 525 private void putDeviceInDemoMode() { 526 mDeviceInDemoMode = true; 527 528 final String carrierDemoModeSetting = 529 getContext().getString(R.string.config_carrierDemoModeSetting); 530 mIsCarrierDemoMode = !TextUtils.isEmpty(carrierDemoModeSetting) 531 && (Settings.Secure.getInt(getContext().getContentResolver(), 532 carrierDemoModeSetting, 0) == 1); 533 534 SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "1"); 535 mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); 536 } 537 538 @Override 539 public void onStart() { 540 if (DEBUG) { 541 Slog.d(TAG, "Service starting up"); 542 } 543 mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, 544 false); 545 mHandlerThread.start(); 546 mHandler = new MainHandler(mHandlerThread.getLooper()); 547 publishLocalService(RetailDemoModeServiceInternal.class, mLocalService); 548 } 549 550 @Override 551 public void onBootPhase(int bootPhase) { 552 switch (bootPhase) { 553 case PHASE_THIRD_PARTY_APPS_CAN_START: 554 mPreloadAppsInstaller = new PreloadAppsInstaller(getContext()); 555 mPm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); 556 mAmi = LocalServices.getService(ActivityManagerInternal.class); 557 mWakeLock = mPm.newWakeLock( 558 PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG); 559 mNm = NotificationManager.from(getContext()); 560 mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); 561 mCameraManager = (CameraManager) getContext() 562 .getSystemService(Context.CAMERA_SERVICE); 563 mCameraIdsWithFlash = getCameraIdsWithFlash(); 564 SettingsObserver settingsObserver = new SettingsObserver(mHandler); 565 settingsObserver.register(); 566 settingsObserver.refreshTimeoutConstants(); 567 break; 568 case PHASE_BOOT_COMPLETED: 569 if (UserManager.isDeviceInDemoMode(getContext())) { 570 putDeviceInDemoMode(); 571 registerBroadcastReceiver(); 572 } 573 break; 574 } 575 } 576 577 @Override 578 public void onSwitchUser(int userId) { 579 if (!mDeviceInDemoMode) { 580 return; 581 } 582 if (DEBUG) { 583 Slog.d(TAG, "onSwitchUser: " + userId); 584 } 585 final UserInfo ui = getUserManager().getUserInfo(userId); 586 if (!ui.isDemo()) { 587 Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode"); 588 return; 589 } 590 if (!mIsCarrierDemoMode && !mWakeLock.isHeld()) { 591 mWakeLock.acquire(); 592 } 593 mCurrentUserId = userId; 594 mAmi.updatePersistentConfigurationForUser(getSystemUsersConfiguration(), userId); 595 596 turnOffAllFlashLights(); 597 muteVolumeStreams(); 598 if (!mWifiManager.isWifiEnabled()) { 599 mWifiManager.setWifiEnabled(true); 600 } 601 602 // Disable lock screen for demo users. 603 LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext()); 604 lockPatternUtils.setLockScreenDisabled(true, userId); 605 606 if (!mIsCarrierDemoMode) { 607 // Show reset notification (except in carrier demo mode). 608 mNm.notifyAsUser(TAG, 1, createResetNotification(), UserHandle.of(userId)); 609 610 synchronized (mActivityLock) { 611 mUserUntouched = true; 612 } 613 MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, 1); 614 mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT); 615 mHandler.post(new Runnable() { 616 @Override 617 public void run() { 618 mPreloadAppsInstaller.installApps(userId); 619 } 620 }); 621 } 622 } 623 624 private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() { 625 private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000; 626 627 @Override 628 public void onUserActivity() { 629 if (!mDeviceInDemoMode || mIsCarrierDemoMode) { 630 return; 631 } 632 long timeOfActivity = SystemClock.uptimeMillis(); 633 synchronized (mActivityLock) { 634 if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) { 635 return; 636 } 637 mLastUserActivityTime = timeOfActivity; 638 if (mUserUntouched && isDemoLauncherDisabled()) { 639 Slog.d(TAG, "retail_demo first touch"); 640 mUserUntouched = false; 641 mFirstUserActivityTime = timeOfActivity; 642 } 643 } 644 mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT); 645 mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, mUserInactivityTimeout); 646 } 647 }; 648} 649