diff options
author | 2016-06-23 23:11:47 +0000 | |
---|---|---|
committer | 2016-06-23 23:11:48 +0000 | |
commit | 33657640ec420968dd97e68bbe84556fbdb86d87 (patch) | |
tree | 846e4379a468c7eb6748157ddcc0e84ff5be1e5d | |
parent | 631a8dcb5d5241dbceba1ade5bb3c6659a9a266b (diff) | |
parent | f38b1d7abee34722e9293f7ed78875290369b850 (diff) |
Merge "Adding a warning dialog before restarting demo session" into nyc-mr1-dev
-rw-r--r-- | core/res/res/values/strings.xml | 18 | ||||
-rw-r--r-- | core/res/res/values/symbols.xml | 4 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/RetailDemoModeService.java | 42 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/UserInactivityCountdownDialog.java | 109 |
4 files changed, 158 insertions, 15 deletions
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index c036c369d3b4..ae2a9e4e1b4e 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4372,15 +4372,21 @@ <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string> <!-- Title of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] --> - <string name="reset_retail_demo_mode_title">Restart Session</string> + <string name="reset_retail_demo_mode_title">Reset device?</string> <!-- Text of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] --> - <string name="reset_retail_demo_mode_text">Tap to start a new demo session</string> + <string name="reset_retail_demo_mode_text">Tap to reset device</string> <!-- Text of dialog shown when starting a demo user for the first time [CHAR LIMIT=40] --> - <string name="demo_starting_message">Starting demo</string> + <string name="demo_starting_message">Starting demo\u2026</string> <!-- Text of dialog shown when starting a new demo user in retail demo mode [CHAR LIMIT=40] --> - <string name="demo_restarting_message">Restarting session</string> - - + <string name="demo_restarting_message">Resetting device\u2026</string> + <!-- Title of the dialog shown when user inactivity times out in retail demo mode [CHAR LIMIT=40] --> + <string name="demo_user_inactivity_timeout_title">Reset device?</string> + <!-- Warning message shown when user inactivity times out in retail demo mode [CHAR LIMIT=none] --> + <string name="demo_user_inactivity_timeout_countdown">You\'ll lose any changes and the demo will start again in <xliff:g id="timeout" example="9">%1$s</xliff:g> seconds\u2026</string> + <!-- Text of button to allow user to abort countdown and continue current session in retail demo mode [CHAR LIMIT=40] --> + <string name="demo_user_inactivity_timeout_left_button">Cancel</string> + <!-- Text of button to allow user to abort countdown and immediately start another session in retail demo mode [CHAR LIMIT=40] --> + <string name="demo_user_inactivity_timeout_right_button">Reset now</string> <!-- Title of notification shown when device has been forced to safe mode after a security compromise. --> <string name="audit_safemode_notification">Factory reset to use this device without restrictions</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 385c61a652ab..6b7d32d25053 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1892,6 +1892,10 @@ <java-symbol type="string" name="audit_safemode_notification_details" /> <java-symbol type="string" name="reset_retail_demo_mode_title" /> <java-symbol type="string" name="reset_retail_demo_mode_text" /> + <java-symbol type="string" name="demo_user_inactivity_timeout_title" /> + <java-symbol type="string" name="demo_user_inactivity_timeout_countdown" /> + <java-symbol type="string" name="demo_user_inactivity_timeout_left_button" /> + <java-symbol type="string" name="demo_user_inactivity_timeout_right_button" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> diff --git a/services/core/java/com/android/server/am/RetailDemoModeService.java b/services/core/java/com/android/server/am/RetailDemoModeService.java index 6a5ec9697a41..bcf1bd4cc1d2 100644 --- a/services/core/java/com/android/server/am/RetailDemoModeService.java +++ b/services/core/java/com/android/server/am/RetailDemoModeService.java @@ -25,6 +25,7 @@ import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.IPackageManager; @@ -44,12 +45,13 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.util.Slog; - import com.android.internal.os.BackgroundThread; 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.am.UserInactivityCountdownDialog.OnCountDownExpiredListener; + import java.io.File; public class RetailDemoModeService extends SystemService { @@ -65,6 +67,8 @@ public class RetailDemoModeService extends SystemService { private static final long SCREEN_WAKEUP_DELAY = 2500; private static final long USER_INACTIVITY_TIMEOUT = 30000; + private static final long WARNING_DIALOG_TIMEOUT = 6000; + private static final long MILLIS_PER_SECOND = 1000; boolean mDeviceInDemoMode = false; private ActivityManagerService mAms; @@ -110,7 +114,7 @@ public class RetailDemoModeService extends SystemService { mWakeLock.acquire(); break; case MSG_INACTIVITY_TIME_OUT: - IPackageManager pm = AppGlobals.getPackageManager(); + final IPackageManager pm = AppGlobals.getPackageManager(); int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; String demoLauncherComponent = getContext().getResources() .getString(R.string.config_demoModeLauncherComponent); @@ -122,8 +126,8 @@ public class RetailDemoModeService extends SystemService { // 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); + Slog.i(TAG, "User inactivity timeout reached"); + showInactivityCountdownDialog(); } break; case MSG_START_NEW_SESSION: @@ -131,7 +135,8 @@ public class RetailDemoModeService extends SystemService { Slog.d(TAG, "Switching to a new demo user"); } removeMessages(MSG_START_NEW_SESSION); - UserInfo demoUser = getUserManager().createUser(DEMO_USER_NAME, + removeMessages(MSG_INACTIVITY_TIME_OUT); + final UserInfo demoUser = getUserManager().createUser(DEMO_USER_NAME, UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL); if (demoUser != null) { setupDemoUser(demoUser); @@ -142,6 +147,25 @@ public class RetailDemoModeService extends SystemService { } } + private void showInactivityCountdownDialog() { + UserInactivityCountdownDialog dialog = new UserInactivityCountdownDialog(getContext(), + WARNING_DIALOG_TIMEOUT, MILLIS_PER_SECOND); + dialog.setPositiveButtonClickListener(null); + dialog.setNegativeButtonClickListener(new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); + } + }); + dialog.setOnCountDownExpiredListener(new OnCountDownExpiredListener() { + @Override + public void onCountDownExpired() { + mHandler.sendEmptyMessage(MSG_START_NEW_SESSION); + } + }); + dialog.show(); + } + public RetailDemoModeService(Context context) { super(context); } @@ -167,7 +191,7 @@ public class RetailDemoModeService extends SystemService { return mResetDemoPendingIntent; } - void setupDemoUser(UserInfo userInfo) { + private void setupDemoUser(UserInfo userInfo) { UserManager um = getUserManager(); UserHandle user = UserHandle.of(userInfo.id); LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext()); @@ -230,13 +254,13 @@ public class RetailDemoModeService extends SystemService { UserHandle.USER_SYSTEM); } - boolean isDeviceProvisioned() { + private boolean isDeviceProvisioned() { return Settings.Global.getInt( getContext().getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; } private boolean deleteDemoFolderContents() { - File dir = Environment.getDataPreloadsDemoDirectory(); + final File dir = Environment.getDataPreloadsDemoDirectory(); Slog.i(TAG, "Deleting contents of " + dir); return FileUtils.deleteContents(dir); } @@ -286,7 +310,7 @@ public class RetailDemoModeService extends SystemService { if (DEBUG) { Slog.d(TAG, "onSwitchUser: " + userId); } - UserInfo ui = getUserManager().getUserInfo(userId); + final UserInfo ui = getUserManager().getUserInfo(userId); if (!ui.isDemo()) { Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode"); return; diff --git a/services/core/java/com/android/server/am/UserInactivityCountdownDialog.java b/services/core/java/com/android/server/am/UserInactivityCountdownDialog.java new file mode 100644 index 000000000000..1a1e85c847a9 --- /dev/null +++ b/services/core/java/com/android/server/am/UserInactivityCountdownDialog.java @@ -0,0 +1,109 @@ +/* + * 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.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.os.CountDownTimer; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.TextView; + +import com.android.internal.R; + +public class UserInactivityCountdownDialog extends AlertDialog { + + private OnCountDownExpiredListener mOnCountDownExpiredListener; + private View mDialogView; + private CountDownTimer mCountDownTimer; + private long mCountDownDuration; + private long mRefreshInterval; + + protected UserInactivityCountdownDialog(Context context, long duration, long refreshInterval) { + super(context); + + mCountDownDuration = duration; + mRefreshInterval = refreshInterval; + mDialogView = LayoutInflater.from(context).inflate(R.layout.alert_dialog, null); + String msg = context.getString(R.string.demo_user_inactivity_timeout_countdown, duration); + getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; + getWindow().setAttributes(attrs); + setTitle(R.string.demo_user_inactivity_timeout_title); + setView(mDialogView); + setMessage(msg); + } + + public void setOnCountDownExpiredListener( + OnCountDownExpiredListener onCountDownExpiredListener) { + mOnCountDownExpiredListener = onCountDownExpiredListener; + } + + public void setPositiveButtonClickListener(OnClickListener onClickListener) { + setButton(Dialog.BUTTON_POSITIVE, + getContext().getString(R.string.demo_user_inactivity_timeout_left_button), + onClickListener); + } + + public void setNegativeButtonClickListener(OnClickListener onClickListener) { + setButton(Dialog.BUTTON_NEGATIVE, + getContext().getString(R.string.demo_user_inactivity_timeout_right_button), + onClickListener); + } + + @Override + public void show() { + super.show(); + mDialogView.post(new Runnable() { + @Override + public void run() { + mCountDownTimer = new CountDownTimer(mCountDownDuration, mRefreshInterval) { + + @Override + public void onTick(long millisUntilFinished) { + String msg = getContext().getResources().getString( + R.string.demo_user_inactivity_timeout_countdown, + millisUntilFinished / 1000); + ((TextView) mDialogView.findViewById(R.id.message)).setText(msg); + } + + @Override + public void onFinish() { + dismiss(); + if (mOnCountDownExpiredListener != null) + mOnCountDownExpiredListener.onCountDownExpired(); + } + }.start(); + } + }); + } + + @Override + public void dismiss() { + super.dismiss(); + if (mCountDownTimer != null) { + mCountDownTimer.cancel(); + } + } + + interface OnCountDownExpiredListener { + void onCountDownExpired(); + } +} |