diff options
6 files changed, 95 insertions, 21 deletions
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index d74aaeb..52c3db5 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4839,24 +4839,28 @@ <string name="day_of_week_label_typeface">sans-serif</string> <!-- Notify use that they are in Lock-to-app --> - <string name="lock_to_app_toast">You are in lock-to-app mode. To exit, touch and hold the Recents button</string> + <string name="lock_to_app_toast">To unpin this screen, touch and hold Back and Recents at the same time.</string> + <!-- Notify use that they are in Lock-to-app in accessibility mode --> + <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Recents.</string> <!-- Notify user that they are locked in lock-to-app mode --> - <string name="lock_to_app_toast_locked">You are in Lock-to-App mode.</string> + <string name="lock_to_app_toast_locked">Screen is pinned. Unpinning isn\'t allowed by your organization.</string> <!-- Lock-to-app dialog title. --> - <string name="lock_to_app_title">Use lock-to-app?</string> + <string name="lock_to_app_title">Use screen pinning?</string> <!-- Lock-to-app dialog description. --> - <string name="lock_to_app_description">Lock-to-app locks the display in a single app.\n\nTo exit, touch and hold the Recents button.</string> + <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Back and Recents at the same time.</string> + <!-- Lock-to-app dialog description when in accessibility mode. --> + <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Recents.</string> <!-- Lock-to-app negative response. --> <string name="lock_to_app_negative">NO, THANKS</string> <!-- Lock-to-app positive response. --> <string name="lock_to_app_positive">START</string> <!-- Starting lock-to-app indication. --> - <string name="lock_to_app_start">Locked to app</string> + <string name="lock_to_app_start">Screen pinned</string> <!-- Exting lock-to-app indication. --> - <string name="lock_to_app_exit">No longer locked to app</string> + <string name="lock_to_app_exit">Screen unpinned</string> <!-- Lock-to-app checkbox for lock on exit --> - <string name="lock_to_app_use_screen_lock">Ask for %1$s before exiting</string> + <string name="lock_to_app_use_screen_lock">Ask for %1$s before unpinning</string> <!-- Lock-to-app unlock pin string --> <string name="lock_to_app_unlock_pin">PIN</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 220f5ab..45ba51e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -610,9 +610,11 @@ <java-symbol type="string" name="last_month" /> <java-symbol type="string" name="launchBrowserDefault" /> <java-symbol type="string" name="lock_to_app_toast" /> + <java-symbol type="string" name="lock_to_app_toast_accessible" /> <java-symbol type="string" name="lock_to_app_toast_locked" /> <java-symbol type="string" name="lock_to_app_title" /> <java-symbol type="string" name="lock_to_app_description" /> + <java-symbol type="string" name="lock_to_app_description_accessible" /> <java-symbol type="string" name="lock_to_app_negative" /> <java-symbol type="string" name="lock_to_app_positive" /> <java-symbol type="layout" name="lock_to_app_checkbox" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index a29eaed..7a9cbef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -91,6 +91,8 @@ import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.view.ViewTreeObserver; import android.view.WindowManager; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; @@ -137,6 +139,7 @@ import com.android.systemui.statusbar.policy.CastControllerImpl; import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.policy.HeadsUpNotificationView; import com.android.systemui.statusbar.policy.HotspotControllerImpl; +import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.LocationControllerImpl; @@ -210,6 +213,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public static final int FADE_KEYGUARD_START_DELAY = 100; public static final int FADE_KEYGUARD_DURATION = 300; + /** Allow some time inbetween the long press for back and recents. */ + private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; + PhoneStatusBarPolicy mIconPolicy; // These are no longer handled by the policy, because we need custom strategies for them @@ -1054,10 +1060,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }; - private View.OnLongClickListener mLockToAppClickListener = new View.OnLongClickListener() { + private long mLastLockToAppLongPress; + private AccessibilityManager mAccessibilityManager; + private View.OnLongClickListener mLongPressBackRecentsListener = + new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - toggleLockedApp(); + handleLongPressBackRecents(v); return true; } }; @@ -1106,7 +1115,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener); mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener); mNavigationBarView.getRecentsButton().setLongClickable(true); - mNavigationBarView.getRecentsButton().setOnLongClickListener(mLockToAppClickListener); + mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener); + mNavigationBarView.getBackButton().setLongClickable(true); + mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener); mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener); updateSearchPanel(); } @@ -3773,15 +3784,58 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller.setAnimationsEnabled(true); } - public void toggleLockedApp() { - Log.d(TAG, "Trying to toggle lock-to-app"); + /** + * This handles long-press of both back and recents. They are + * handled together to capture them both being long-pressed + * at the same time to exit screen pinning (lock task). + * + * When accessibility mode is on, only a long-press from recents + * is required to exit. + * + * In all other circumstances we try to pass through long-press events + * for Back, so that apps can still use it. Which can be from two things. + * 1) Not currently in screen pinning (lock task). + * 2) Back is long-pressed without recents. + */ + private void handleLongPressBackRecents(View v) { try { + boolean sendBackLongPress = false; IActivityManager activityManager = ActivityManagerNative.getDefault(); - if (activityManager.isInLockTaskMode()) { - activityManager.stopLockTaskModeOnCurrent(); + if (mAccessibilityManager == null) { + mAccessibilityManager = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); + } + boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled(); + if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) { + long time = System.currentTimeMillis(); + // If we recently long-pressed the other button then they were + // long-pressed 'together' + if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) { + activityManager.stopLockTaskModeOnCurrent(); + } else if ((v.getId() == R.id.back) + && !mNavigationBarView.getRecentsButton().isPressed()) { + // If we aren't pressing recents right now then they presses + // won't be together, so send the standard long-press action. + sendBackLongPress = true; + } + mLastLockToAppLongPress = time; + } else { + // If this is back still need to handle sending the long-press event. + if (v.getId() == R.id.back) { + sendBackLongPress = true; + } else if (isAccessiblityEnabled && activityManager.isInLockTaskMode()) { + // When in accessibility mode a long press that is recents (not back) + // should stop lock task. + activityManager.stopLockTaskModeOnCurrent(); + } + } + if (sendBackLongPress) { + KeyButtonView keyButtonView = (KeyButtonView) v; + keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); + keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); } } catch (RemoteException e) { - Log.d(TAG, "Unable to toggle Lock-to-app", e); + Log.d(TAG, "Unable to reach activity manager", e); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 330b599..e9581fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -56,12 +56,12 @@ public class KeyButtonView extends ImageView { public void run() { if (isPressed()) { // Log.d("KeyButtonView", "longpressed: " + this); - if (mCode != 0) { - sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); - } else { + if (isLongClickable()) { // Just an old-fashioned ImageView performLongClick(); + } else { + sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); } } } @@ -216,7 +216,7 @@ public class KeyButtonView extends ImageView { return true; } - void sendEvent(int action, int flags) { + public void sendEvent(int action, int flags) { sendEvent(action, flags, SystemClock.uptimeMillis()); } diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java index 6f9b23d..cf65243 100644 --- a/services/core/java/com/android/server/am/LockTaskNotify.java +++ b/services/core/java/com/android/server/am/LockTaskNotify.java @@ -19,6 +19,7 @@ package com.android.server.am; import android.content.Context; import android.os.Handler; import android.os.Message; +import android.view.accessibility.AccessibilityManager; import android.widget.Toast; import com.android.internal.R; @@ -32,9 +33,12 @@ public class LockTaskNotify { private final Context mContext; private final H mHandler; + private AccessibilityManager mAccessibilityManager; public LockTaskNotify(Context context) { mContext = context; + mAccessibilityManager = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mHandler = new H(); } @@ -45,6 +49,9 @@ public class LockTaskNotify { public void handleShowToast(boolean isLocked) { String text = mContext.getString(isLocked ? R.string.lock_to_app_toast_locked : R.string.lock_to_app_toast); + if (!isLocked && mAccessibilityManager.isEnabled()) { + text = mContext.getString(R.string.lock_to_app_toast_accessible); + } Toast.makeText(mContext, text, Toast.LENGTH_LONG).show(); } diff --git a/services/core/java/com/android/server/am/LockToAppRequestDialog.java b/services/core/java/com/android/server/am/LockToAppRequestDialog.java index 0847b52..12dcf7e 100644 --- a/services/core/java/com/android/server/am/LockToAppRequestDialog.java +++ b/services/core/java/com/android/server/am/LockToAppRequestDialog.java @@ -13,6 +13,7 @@ import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.Slog; import android.view.WindowManager; +import android.view.accessibility.AccessibilityManager; import android.widget.CheckBox; import com.android.internal.R; @@ -33,8 +34,12 @@ public class LockToAppRequestDialog implements OnClickListener { private ILockSettings mLockSettingsService; + private AccessibilityManager mAccessibilityService; + public LockToAppRequestDialog(Context context, ActivityManagerService activityManagerService) { mContext = context; + mAccessibilityService = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mService = activityManagerService; } @@ -78,7 +83,9 @@ public class LockToAppRequestDialog implements OnClickListener { final int unlockStringId = getLockString(task.userId); final Resources r = Resources.getSystem(); - final String description= r.getString(R.string.lock_to_app_description); + final String description= r.getString(mAccessibilityService.isEnabled() + ? R.string.lock_to_app_description_accessible + : R.string.lock_to_app_description); AlertDialog.Builder builder = new AlertDialog.Builder(mContext) .setTitle(r.getString(R.string.lock_to_app_title)) .setMessage(description) |