Merge "Adding an idle timeout to restart demo session" into nyc-mr1-dev

am: 67f82d16ea

* commit '67f82d16ea31f309b402b3a96bafcc9338528ece':
  Adding an idle timeout to restart demo session

Change-Id: I11db70fd323fb908aa137dedf1817fa28b577d79
This commit is contained in:
Suprabh Shukla
2016-06-03 00:23:14 +00:00
committed by android-build-merger
3 changed files with 129 additions and 45 deletions

View File

@@ -17,22 +17,29 @@
package com.android.server.am;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -43,8 +50,6 @@ import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerService;
import java.io.File;
public class RetailDemoModeService extends SystemService {
@@ -54,42 +59,89 @@ public class RetailDemoModeService extends SystemService {
private static final String DEMO_USER_NAME = "Demo";
private static final String ACTION_RESET_DEMO = "com.android.server.am.ACTION_RESET_DEMO";
private static final long SCREEN_WAKEUP_DELAY = 5000;
private static final int MSG_TURN_SCREEN_ON = 0;
private static final int MSG_INACTIVITY_TIME_OUT = 1;
private static final int MSG_START_NEW_SESSION = 2;
private static final long SCREEN_WAKEUP_DELAY = 2500;
private static final long USER_INACTIVITY_TIMEOUT = 30000;
boolean mDeviceInDemoMode = false;
private ActivityManagerService mAms;
private NotificationManager mNm;
private UserManager mUm;
private PowerManager mPm;
private PowerManager.WakeLock mWakeLock;
private Handler mHandler;
Handler mHandler;
private ServiceThread mHandlerThread;
private PendingIntent mResetDemoPendingIntent;
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!UserManager.isDeviceInDemoMode(getContext())) {
if (!mDeviceInDemoMode) {
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);
mHandler.removeMessages(MSG_TURN_SCREEN_ON);
mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY);
break;
case ACTION_RESET_DEMO:
createAndSwitchToDemoUser();
mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
break;
}
}
};
final class MainHandler extends Handler {
MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TURN_SCREEN_ON:
if (mWakeLock.isHeld()) {
mWakeLock.release();
}
mWakeLock.acquire();
break;
case MSG_INACTIVITY_TIME_OUT:
IPackageManager pm = AppGlobals.getPackageManager();
int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
String demoLauncherComponent = getContext().getResources()
.getString(R.string.config_demoModeLauncherComponent);
try {
enabledState = pm.getComponentEnabledSetting(
ComponentName.unflattenFromString(demoLauncherComponent),
getActivityManager().getCurrentUser().id);
} catch (RemoteException exc) {
// XXX: shouldn't happen
}
if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
Slog.i(TAG, "Restarting session due to user inactivity timeout");
sendEmptyMessage(MSG_START_NEW_SESSION);
}
break;
case MSG_START_NEW_SESSION:
if (DEBUG) {
Slog.d(TAG, "Switching to a new demo user");
}
removeMessages(MSG_START_NEW_SESSION);
UserInfo demoUser = getUserManager().createUser(DEMO_USER_NAME,
UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
if (demoUser != null) {
setupDemoUser(demoUser);
getActivityManager().switchUser(demoUser.id);
}
break;
}
}
}
public RetailDemoModeService(Context context) {
super(context);
}
@@ -103,6 +155,7 @@ public class RetailDemoModeService extends SystemService {
.setShowWhen(false)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setContentIntent(getResetDemoPendingIntent())
.setColor(getContext().getColor(R.color.system_notification_accent_color))
.build();
}
@@ -114,23 +167,6 @@ public class RetailDemoModeService extends SystemService {
return mResetDemoPendingIntent;
}
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) {
setupDemoUser(demoUser);
getActivityManager().switchUser(demoUser.id);
}
}
});
}
void setupDemoUser(UserInfo userInfo) {
UserManager um = getUserManager();
UserHandle user = UserHandle.of(userInfo.id);
@@ -166,14 +202,16 @@ public class RetailDemoModeService extends SystemService {
final ContentObserver deviceDemoModeSettingObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
boolean deviceInDemoMode = UserManager.isDeviceInDemoMode(getContext());
if (deviceDemoModeUri.equals(uri)) {
if (deviceInDemoMode) {
createAndSwitchToDemoUser();
mDeviceInDemoMode = UserManager.isDeviceInDemoMode(getContext());
if (mDeviceInDemoMode) {
mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
} else if (mWakeLock.isHeld()) {
mWakeLock.release();
}
}
// If device is provisioned and left demo mode - run the cleanup in demo folder
if (!deviceInDemoMode && isDeviceProvisioned()) {
if (!mDeviceInDemoMode && isDeviceProvisioned()) {
// Run on the bg thread to not block the fg thread
BackgroundThread.getHandler().post(new Runnable() {
@Override
@@ -218,7 +256,8 @@ public class RetailDemoModeService extends SystemService {
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,
false);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), null, true);
mHandler = new MainHandler(mHandlerThread.getLooper());
publishLocalService(RetailDemoModeServiceInternal.class, mLocalService);
}
@Override
@@ -232,7 +271,8 @@ public class RetailDemoModeService extends SystemService {
mNm = NotificationManager.from(getContext());
if (UserManager.isDeviceInDemoMode(getContext())) {
createAndSwitchToDemoUser();
mDeviceInDemoMode = true;
mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
}
registerSettingsChangeObserver();
registerBroadcastReceiver();
@@ -240,16 +280,15 @@ public class RetailDemoModeService extends SystemService {
@Override
public void onSwitchUser(int userId) {
if (!mDeviceInDemoMode) {
return;
}
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();
}
Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
return;
}
if (!mWakeLock.isHeld()) {
@@ -257,4 +296,23 @@ public class RetailDemoModeService extends SystemService {
}
mNm.notifyAsUser(TAG, 1, createResetNotification(), UserHandle.of(userId));
}
public RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000;
private long mLastUserActivityTime = 0;
@Override
public void onUserActivity() {
if (!mDeviceInDemoMode) {
return;
}
long timeOfActivity = SystemClock.uptimeMillis();
if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) {
return;
}
mLastUserActivityTime = timeOfActivity;
mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, USER_INACTIVITY_TIMEOUT);
}
};
}

View File

@@ -0,0 +1,21 @@
/*
* 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;
public interface RetailDemoModeServiceInternal {
public void onUserActivity();
}

View File

@@ -23,6 +23,7 @@ import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.am.RetailDemoModeServiceInternal;
import android.app.ActivityManagerNative;
import android.content.BroadcastReceiver;
@@ -91,6 +92,7 @@ final class Notifier {
private final ActivityManagerInternal mActivityManagerInternal;
private final InputManagerInternal mInputManagerInternal;
private final InputMethodManagerInternal mInputMethodManagerInternal;
private final RetailDemoModeServiceInternal mRetailDemoModeServiceInternal;
private final NotifierHandler mHandler;
private final Intent mScreenOnIntent;
@@ -136,6 +138,7 @@ final class Notifier {
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
mRetailDemoModeServiceInternal = LocalServices.getService(RetailDemoModeServiceInternal.class);
mHandler = new NotifierHandler(looper);
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
@@ -534,7 +537,9 @@ final class Notifier {
}
mUserActivityPending = false;
}
if (mRetailDemoModeServiceInternal != null) {
mRetailDemoModeServiceInternal.onUserActivity();
}
mPolicy.userActivity();
}