diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-02-02 01:48:23 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-02-02 01:48:23 +0000 |
| commit | df07d10609d96c68d2a97e5b0fa4c39cdc71085b (patch) | |
| tree | 7b0b3d43c08a2579730229ab844de72b3f0444ce | |
| parent | 0d2107bf88d786aa905614824c335ac39209dd14 (diff) | |
| parent | 9c3bce5c4444bcf98bc6342fa5c448345bb67a6c (diff) | |
Merge "Fixes crash null exception on land/seascape pinned orientations"
18 files changed, 305 insertions, 97 deletions
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index ebb5f9f9e446..f70d3c2a27fd 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -132,6 +132,12 @@ oneway interface IStatusBar void clickQsTile(in ComponentName tile); void handleSystemKey(in int key); + /** + * Methods to show toast messages for screen pinning + */ + void showPinningEnterExitToast(boolean entering); + void showPinningEscapeToast(); + void showShutdownUi(boolean isReboot, String reason); // Used to show the dialog when FingerprintService starts authentication diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index cb0b53c495dc..adf42878ebb3 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -81,6 +81,12 @@ interface IStatusBarService void clickTile(in ComponentName tile); void handleSystemKey(in int key); + /** + * Methods to show toast messages for screen pinning + */ + void showPinningEnterExitToast(boolean entering); + void showPinningEscapeToast(); + // Used to show the dialog when FingerprintService starts authentication void showFingerprintDialog(in Bundle bundle, IFingerprintDialogReceiver receiver); // Used to hide the dialog when a finger is authenticated diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index a24061621c3c..731b6f7b632b 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4423,15 +4423,6 @@ <!-- DO NOT TRANSLATE --> <string name="date_picker_day_typeface">sans-serif-medium</string> - <!-- Notify use that they are in Lock-to-app --> - <string name="lock_to_app_toast">To unpin this screen, touch & hold Back and Overview - buttons</string> - - <!-- Starting lock-to-app indication. --> - <string name="lock_to_app_start">Screen pinned</string> - <!-- Exting lock-to-app indication. --> - <string name="lock_to_app_exit">Screen unpinned</string> - <!-- Lock-to-app unlock pin string --> <string name="lock_to_app_unlock_pin">Ask for PIN before unpinning</string> <!-- Lock-to-app unlock pattern string --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index a338f89af201..fee5a80245b4 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -767,9 +767,6 @@ <java-symbol type="string" name="kilobyteShort" /> <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_start" /> - <java-symbol type="string" name="lock_to_app_exit" /> <java-symbol type="string" name="lock_to_app_unlock_pin" /> <java-symbol type="string" name="lock_to_app_unlock_pattern" /> <java-symbol type="string" name="lock_to_app_unlock_password" /> diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml index c2b1009c3137..a3118b0a5d91 100644 --- a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml @@ -84,7 +84,25 @@ android:layout_height="@dimen/screen_pinning_request_button_height" android:layout_weight="0" android:paddingStart="@dimen/screen_pinning_request_frame_padding" - android:paddingEnd="@dimen/screen_pinning_request_frame_padding" > + android:paddingEnd="@dimen/screen_pinning_request_frame_padding" + android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent"> + + <ImageView + android:id="@+id/screen_pinning_home_bg_light" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:id="@+id/screen_pinning_home_bg" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="@dimen/screen_pinning_request_inner_padding" + android:paddingStart="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_bg_circ" /> <ImageView android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml index b5ef1d72fd8f..61fe906d65fc 100644 --- a/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml @@ -78,7 +78,25 @@ android:id="@+id/screen_pinning_home_group" android:layout_height="@dimen/screen_pinning_request_button_width" android:layout_width="@dimen/screen_pinning_request_button_height" - android:layout_weight="0" > + android:layout_weight="0" + android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent"> + + <ImageView + android:id="@+id/screen_pinning_home_bg_light" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:id="@+id/screen_pinning_home_bg" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:paddingLeft="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:paddingBottom="@dimen/screen_pinning_request_inner_padding" + android:src="@drawable/screen_pinning_bg_circ" /> <ImageView android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons_sea.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons_sea.xml index f3a6d44f5ec7..d1ca2ce5935c 100644 --- a/packages/SystemUI/res/layout/screen_pinning_request_buttons_sea.xml +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons_sea.xml @@ -80,7 +80,27 @@ android:id="@+id/screen_pinning_home_group" android:layout_height="@dimen/screen_pinning_request_button_width" android:layout_width="@dimen/screen_pinning_request_button_height" - android:layout_weight="0" > + android:layout_weight="0" + android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent" > + + <ImageView + android:id="@+id/screen_pinning_home_bg_light" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:layout_marginLeft="@dimen/screen_pinning_request_seascape_padding_negative" + android:src="@drawable/screen_pinning_light_bg_circ" /> + + <ImageView + android:id="@+id/screen_pinning_home_bg" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="matrix" + android:layout_marginLeft="@dimen/screen_pinning_request_seascape_button_offset" + android:paddingRight="@dimen/screen_pinning_request_inner_padding" + android:paddingTop="@dimen/screen_pinning_request_inner_padding" + android:paddingBottom="@dimen/screen_pinning_request_inner_padding" + android:src="@drawable/screen_pinning_bg_circ" /> <ImageView android:layout_height="match_parent" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 5557f8eda005..fadcbcd4f4bc 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1281,12 +1281,23 @@ <string name="screen_pinning_title">Screen is pinned</string> <!-- Screen pinning dialog description. --> <string name="screen_pinning_description">This keeps it in view until you unpin. Touch & hold Back and Overview to unpin.</string> + <string name="screen_pinning_description_recents_invisible">This keeps it in view until you unpin. Touch & hold Back and Home to unpin.</string> <!-- Screen pinning dialog description. --> <string name="screen_pinning_description_accessible">This keeps it in view until you unpin. Touch & hold Overview to unpin.</string> + <string name="screen_pinning_description_recents_invisible_accessible">This keeps it in view until you unpin. Touch & hold Home to unpin.</string> + <!-- Notify use that they are in Lock-to-app --> + <string name="screen_pinning_toast">To unpin this screen, touch & hold Back and Overview + buttons</string> + <string name="screen_pinning_toast_recents_invisible">To unpin this screen, touch & hold Back + and Home buttons</string> <!-- Screen pinning positive response. --> <string name="screen_pinning_positive">Got it</string> <!-- Screen pinning negative response. --> <string name="screen_pinning_negative">No thanks</string> + <!-- Enter/Exiting screen pinning indication. --> + <string name="screen_pinning_start">Screen pinned</string> + <string name="screen_pinning_exit">Screen unpinned</string> + <!-- Hide quick settings tile confirmation title --> <string name="quick_settings_reset_confirmation_title">Hide <xliff:g id="tile_label" example="Hotspot">%1$s</xliff:g>?</string> diff --git a/packages/SystemUI/src/com/android/systemui/SysUIToast.java b/packages/SystemUI/src/com/android/systemui/SysUIToast.java index 89bc82f87930..43b918dbea73 100644 --- a/packages/SystemUI/src/com/android/systemui/SysUIToast.java +++ b/packages/SystemUI/src/com/android/systemui/SysUIToast.java @@ -15,13 +15,19 @@ */ package com.android.systemui; +import android.annotation.StringRes; import android.content.Context; import android.view.WindowManager; import android.widget.Toast; +import static android.widget.Toast.Duration; public class SysUIToast { - public static Toast makeText(Context context, CharSequence text, int duration) { + public static Toast makeText(Context context, @StringRes int resId, @Duration int duration) { + return makeText(context, context.getString(resId), duration); + } + + public static Toast makeText(Context context, CharSequence text, @Duration int duration) { Toast toast = Toast.makeText(context, text, duration); toast.getWindowParams().privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 316ad1661898..57f7818eae58 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -23,15 +23,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Configuration; import android.graphics.PixelFormat; -import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.os.Binder; import android.os.RemoteException; import android.util.DisplayMetrics; import android.view.Gravity; -import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -43,6 +40,9 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.statusbar.phone.NavigationBarView; +import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; @@ -233,11 +233,30 @@ public class ScreenPinningRequest implements View.OnClickListener { .setVisibility(View.INVISIBLE); } + StatusBar statusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); + NavigationBarView navigationBarView = statusBar.getNavigationBarView(); + final boolean recentsVisible = navigationBarView != null + && navigationBarView.isRecentsButtonVisible(); boolean touchExplorationEnabled = mAccessibilityService.isTouchExplorationEnabled(); + int descriptionStringResId; + if (recentsVisible) { + mLayout.findViewById(R.id.screen_pinning_recents_group).setVisibility(VISIBLE); + mLayout.findViewById(R.id.screen_pinning_home_bg_light).setVisibility(INVISIBLE); + mLayout.findViewById(R.id.screen_pinning_home_bg).setVisibility(INVISIBLE); + descriptionStringResId = touchExplorationEnabled + ? R.string.screen_pinning_description_accessible + : R.string.screen_pinning_description; + } else { + mLayout.findViewById(R.id.screen_pinning_recents_group).setVisibility(INVISIBLE); + mLayout.findViewById(R.id.screen_pinning_home_bg_light).setVisibility(VISIBLE); + mLayout.findViewById(R.id.screen_pinning_home_bg).setVisibility(VISIBLE); + descriptionStringResId = touchExplorationEnabled + ? R.string.screen_pinning_description_recents_invisible_accessible + : R.string.screen_pinning_description_recents_invisible; + } + ((TextView) mLayout.findViewById(R.id.screen_pinning_description)) - .setText(touchExplorationEnabled - ? R.string.screen_pinning_description_accessible - : R.string.screen_pinning_description); + .setText(descriptionStringResId); final int backBgVisibility = touchExplorationEnabled ? View.INVISIBLE : View.VISIBLE; mLayout.findViewById(R.id.screen_pinning_back_bg).setVisibility(backBgVisibility); mLayout.findViewById(R.id.screen_pinning_back_bg_light).setVisibility(backBgVisibility); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 79e9f7b45d8d..11bdf6b3c72e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -24,6 +24,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.RemoteException; import android.support.annotation.VisibleForTesting; import android.util.Pair; @@ -90,6 +91,8 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_FINGERPRINT_ERROR = 42 << MSG_SHIFT; private static final int MSG_FINGERPRINT_HIDE = 43 << MSG_SHIFT; private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT; + private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT; + private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT; public static final int FLAG_EXCLUDE_NONE = 0; public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; @@ -148,6 +151,8 @@ public class CommandQueue extends IStatusBar.Stub { default void clickTile(ComponentName tile) { } default void handleSystemKey(int arg1) { } + default void showPinningEnterExitToast(boolean entering) { } + default void showPinningEscapeToast() { } default void handleShowGlobalActionsMenu() { } default void handleShowShutdownUi(boolean isReboot, String reason) { } @@ -453,6 +458,21 @@ public class CommandQueue extends IStatusBar.Stub { } @Override + public void showPinningEnterExitToast(boolean entering) { + synchronized (mLock) { + mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget(); + } + } + + @Override + public void showPinningEscapeToast() { + synchronized (mLock) { + mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget(); + } + } + + + @Override public void showGlobalActionsMenu() { synchronized (mLock) { mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS); @@ -767,6 +787,16 @@ public class CommandQueue extends IStatusBar.Stub { mCallbacks.get(i).showChargingAnimation(msg.arg1); } break; + case MSG_SHOW_PINNING_TOAST_ENTER_EXIT: + for (int i = 0; i < mCallbacks.size(); i++) { + mCallbacks.get(i).showPinningEnterExitToast((Boolean) msg.obj); + } + break; + case MSG_SHOW_PINNING_TOAST_ESCAPE: + for (int i = 0; i < mCallbacks.size(); i++) { + mCallbacks.get(i).showPinningEscapeToast(); + } + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 65c45a3120c1..1239a9ea0240 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -22,11 +22,13 @@ import static android.app.StatusBarManager.windowStateToString; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE; import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions; +import static com.android.systemui.OverviewProxyService.OverviewProxyListener; import android.accessibilityservice.AccessibilityServiceInfo; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; +import android.annotation.IdRes; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerNative; @@ -69,6 +71,7 @@ import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; +import android.widget.Button; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -153,6 +156,18 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private Animator mRotateShowAnimator; private Animator mRotateHideAnimator; + private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { + @Override + public void onConnectionChanged(boolean isConnected) { + mNavigationBarView.onOverviewProxyConnectionChanged(isConnected); + updateScreenPinningGestures(); + } + + @Override + public void onRecentsAnimationStarted() { + mNavigationBarView.setRecentsAnimationStarted(true); + } + }; // ----- Fragment Lifecycle Callbacks ----- @@ -239,12 +254,14 @@ public class NavigationBarFragment extends Fragment implements Callbacks { filter.addAction(Intent.ACTION_SCREEN_ON); getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); notifyNavigationBarScreenOn(); + mOverviewProxyService.addCallback(mOverviewProxyListener); } @Override public void onDestroyView() { super.onDestroyView(); mNavigationBarView.getLightTransitionsController().destroy(getContext()); + mOverviewProxyService.removeCallback(mOverviewProxyListener); getContext().unregisterReceiver(mBroadcastReceiver); } @@ -514,6 +531,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { if (masked != mDisabledFlags1) { mDisabledFlags1 = masked; if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1); + updateScreenPinningGestures(); } } @@ -528,7 +546,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private boolean shouldDisableNavbarGestures() { return !mStatusBar.isDeviceProvisioned() || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0 - || mOverviewProxyService.getProxy() != null; + || mNavigationBarView.getRecentsButton().getVisibility() != View.VISIBLE; } private void repositionNavigationBar() { @@ -540,6 +558,24 @@ public class NavigationBarFragment extends Fragment implements Callbacks { ((View) mNavigationBarView.getParent()).getLayoutParams()); } + private void updateScreenPinningGestures() { + if (mNavigationBarView == null) { + return; + } + + // Change the cancel pin gesture to home and back if recents button is invisible + boolean recentsVisible = mNavigationBarView.isRecentsButtonVisible(); + ButtonDispatcher homeButton = mNavigationBarView.getHomeButton(); + ButtonDispatcher backButton = mNavigationBarView.getBackButton(); + if (recentsVisible) { + homeButton.setOnLongClickListener(this::onHomeLongClick); + backButton.setOnLongClickListener(this::onLongPressBackRecents); + } else { + homeButton.setOnLongClickListener(this::onLongPressBackHome); + backButton.setOnLongClickListener(this::onLongPressBackHome); + } + } + private void notifyNavigationBarScreenOn() { mNavigationBarView.notifyScreenOn(); } @@ -555,11 +591,9 @@ public class NavigationBarFragment extends Fragment implements Callbacks { ButtonDispatcher backButton = mNavigationBarView.getBackButton(); backButton.setLongClickable(true); - backButton.setOnLongClickListener(this::onLongPressBackRecents); ButtonDispatcher homeButton = mNavigationBarView.getHomeButton(); homeButton.setOnTouchListener(this::onHomeTouch); - homeButton.setOnLongClickListener(this::onHomeLongClick); ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton(); accessibilityButton.setOnClickListener(this::onAccessibilityClick); @@ -569,6 +603,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { ButtonDispatcher rotateSuggestionButton = mNavigationBarView.getRotateSuggestionButton(); rotateSuggestionButton.setOnClickListener(this::onRotateSuggestionClick); rotateSuggestionButton.setOnHoverListener(this::onRotateSuggestionHover); + updateScreenPinningGestures(); } private boolean onHomeTouch(View v, MotionEvent event) { @@ -649,20 +684,29 @@ public class NavigationBarFragment extends Fragment implements Callbacks { mCommandQueue.toggleRecentApps(); } + private boolean onLongPressBackHome(View v) { + return onLongPressNavigationButtons(v, R.id.back, R.id.home); + } + + private boolean onLongPressBackRecents(View v) { + return onLongPressNavigationButtons(v, R.id.back, R.id.recent_apps); + } + /** - * This handles long-press of both back and recents. They are - * handled together to capture them both being long-pressed + * This handles long-press of both back and recents/home. Back is the common button with + * combination of recents if it is visible or home if recents is invisible. + * 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 + * When accessibility mode is on, only a long-press from recents/home * 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. + * 2) Back is long-pressed without recents/home. */ - private boolean onLongPressBackRecents(View v) { + private boolean onLongPressNavigationButtons(View v, @IdRes int btnId1, @IdRes int btnId2) { try { boolean sendBackLongPress = false; IActivityManager activityManager = ActivityManagerNative.getDefault(); @@ -670,6 +714,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { boolean inLockTaskMode = activityManager.isInLockTaskMode(); if (inLockTaskMode && !touchExplorationEnabled) { 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) { @@ -677,26 +722,32 @@ public class NavigationBarFragment extends Fragment implements Callbacks { // When exiting refresh disabled flags. mNavigationBarView.setDisabledFlags(mDisabledFlags1, true); return true; - } else if ((v.getId() == R.id.back) - && !mNavigationBarView.getRecentsButton().getCurrentView().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; + } else if (v.getId() == btnId1) { + ButtonDispatcher button = btnId2 == R.id.recent_apps + ? mNavigationBarView.getRecentsButton() + : mNavigationBarView.getHomeButton(); + if (!button.getCurrentView().isPressed()) { + // If we aren't pressing recents/home 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) { + if (v.getId() == btnId1) { sendBackLongPress = true; } else if (touchExplorationEnabled && inLockTaskMode) { - // When in accessibility mode a long press that is recents (not back) + // When in accessibility mode a long press that is recents/home (not back) // should stop lock task. activityManager.stopSystemLockTaskMode(); // When exiting refresh disabled flags. mNavigationBarView.setDisabledFlags(mDisabledFlags1, true); return true; - } else if (v.getId() == R.id.recent_apps) { - return onLongPressRecents(); + } else if (v.getId() == btnId2) { + return btnId2 == R.id.recent_apps + ? onLongPressRecents() + : onHomeLongClick(mNavigationBarView.getHomeButton().getCurrentView()); } } if (sendBackLongPress) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index e04ba8341949..c37dd55cc6ff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -207,23 +207,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } } - private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { - @Override - public void onConnectionChanged(boolean isConnected) { - updateSlippery(); - setDisabledFlags(mDisabledFlags, true); - setUpSwipeUpOnboarding(isConnected); - } - - @Override - public void onRecentsAnimationStarted() { - mRecentsAnimationStarted = true; - if (mSwipeUpOnboarding != null) { - mSwipeUpOnboarding.onRecentsAnimationStarted(); - } - } - }; - public NavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -280,6 +263,19 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav notifyVerticalChangedListener(mVertical); } + public void setRecentsAnimationStarted(boolean started) { + mRecentsAnimationStarted = started; + if (mSwipeUpOnboarding != null) { + mSwipeUpOnboarding.onRecentsAnimationStarted(); + } + } + + public void onConnectionChanged(boolean isConnected) { + updateSlippery(); + setDisabledFlags(mDisabledFlags, true); + setUpSwipeUpOnboarding(isConnected); + } + @Override public boolean onTouchEvent(MotionEvent event) { if (mGestureHelper.onTouchEvent(event)) { @@ -353,6 +349,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mButtonDispatchers; } + public boolean isRecentsButtonVisible() { + return getRecentsButton().getVisibility() == View.VISIBLE; + } + private void updateCarModeIcons(Context ctx) { mBackCarModeIcon = getDrawable(ctx, R.drawable.ic_sysbar_back_carmode, R.drawable.ic_sysbar_back_carmode); @@ -613,6 +613,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav final ViewGroup navbarView = ((ViewGroup) getParent()); final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView .getLayoutParams(); + if (lp == null) { + return; + } if (slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) == 0) { lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY; changed = true; @@ -676,6 +679,12 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } } + public void onOverviewProxyConnectionChanged(boolean isConnected) { + setSlippery(!isConnected); + setDisabledFlags(mDisabledFlags, true); + setUpSwipeUpOnboarding(isConnected); + } + @Override protected void onDraw(Canvas canvas) { mGestureHelper.onDraw(canvas); @@ -873,7 +882,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav onPluginDisconnected(null); // Create default gesture helper Dependency.get(PluginManager.class).addPluginListener(this, NavGesture.class, false /* Only one */); - mOverviewProxyService.addCallback(mOverviewProxyListener); setUpSwipeUpOnboarding(mOverviewProxyService.getProxy() != null); } @@ -884,7 +892,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav if (mGestureHelper != null) { mGestureHelper.destroy(); } - mOverviewProxyService.removeCallback(mOverviewProxyListener); setUpSwipeUpOnboarding(false); } diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java index 1dcb0addc18b..0d07ad9cdf2e 100644 --- a/services/core/java/com/android/server/am/LockTaskNotify.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2018 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.am; +package com.android.systemui.statusbar.phone; import android.content.Context; import android.os.SystemClock; @@ -22,36 +22,37 @@ import android.util.Slog; import android.view.WindowManager; import android.widget.Toast; -import com.android.internal.R; +import com.android.systemui.R; +import com.android.systemui.SysUIToast; /** * Helper to manage showing/hiding a image to notify them that they are entering or exiting screen * pinning mode. All exposed methods should be called from a handler thread. */ -public class LockTaskNotify { - private static final String TAG = "LockTaskNotify"; +public class ScreenPinningNotify { + private static final String TAG = "ScreenPinningNotify"; private static final long SHOW_TOAST_MINIMUM_INTERVAL = 1000; private final Context mContext; private Toast mLastToast; private long mLastShowToastTime; - public LockTaskNotify(Context context) { + public ScreenPinningNotify(Context context) { mContext = context; } /** Show "Screen pinned" toast. */ void showPinningStartToast() { - makeAllUserToastAndShow(R.string.lock_to_app_start); + makeAllUserToastAndShow(R.string.screen_pinning_start); } /** Show "Screen unpinned" toast. */ void showPinningExitToast() { - makeAllUserToastAndShow(R.string.lock_to_app_exit); + makeAllUserToastAndShow(R.string.screen_pinning_exit); } /** Show a toast that describes the gesture the user should use to escape pinned mode. */ - void showEscapeToast() { + void showEscapeToast(boolean isRecentsButtonVisible) { long showToastTime = SystemClock.elapsedRealtime(); if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) { Slog.i(TAG, "Ignore toast since it is requested in very short interval."); @@ -60,14 +61,14 @@ public class LockTaskNotify { if (mLastToast != null) { mLastToast.cancel(); } - mLastToast = makeAllUserToastAndShow(R.string.lock_to_app_toast); + mLastToast = makeAllUserToastAndShow(isRecentsButtonVisible + ? R.string.screen_pinning_toast + : R.string.screen_pinning_toast_recents_invisible); mLastShowToastTime = showToastTime; } private Toast makeAllUserToastAndShow(int resId) { - Toast toast = Toast.makeText(mContext, resId, Toast.LENGTH_LONG); - toast.getWindowParams().privateFlags |= - WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; + Toast toast = SysUIToast.makeText(mContext, resId, Toast.LENGTH_LONG); toast.show(); return toast; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 426268ba490c..1bf719ae68af 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -404,6 +404,13 @@ public class StatusBar extends SystemUI implements DemoMode, protected NotificationEntryManager mEntryManager; protected NotificationViewHierarchyManager mViewHierarchyManager; + /** + * Helper that is responsible for showing the right toast when a disallowed activity operation + * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in + * fully locked mode we only show that unlocking is blocked. + */ + private ScreenPinningNotify mScreenPinningNotify; + // for disabling the status bar private int mDisabled1 = 0; private int mDisabled2 = 0; @@ -830,7 +837,7 @@ public class StatusBar extends SystemUI implements DemoMode, } catch (RemoteException ex) { // no window manager? good luck with that } - + mScreenPinningNotify = new ScreenPinningNotify(mContext); mStackScroller.setLongPressListener(mEntryManager.getNotificationLongClicker()); mStackScroller.setStatusBar(this); mStackScroller.setGroupManager(mGroupManager); @@ -2141,6 +2148,21 @@ public class StatusBar extends SystemUI implements DemoMode, } + @Override + public void showPinningEnterExitToast(boolean entering) { + if (entering) { + mScreenPinningNotify.showPinningStartToast(); + } else { + mScreenPinningNotify.showPinningExitToast(); + } + } + + @Override + public void showPinningEscapeToast() { + mScreenPinningNotify.showEscapeToast(getNavigationBarView() == null + || getNavigationBarView().isRecentsButtonVisible()); + } + boolean panelsEnabled() { return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0 diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java index 21f9135bd03d..e5762d294922 100644 --- a/services/core/java/com/android/server/am/LockTaskController.java +++ b/services/core/java/com/android/server/am/LockTaskController.java @@ -38,6 +38,7 @@ import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; @@ -142,14 +143,6 @@ public class LockTaskController { TelecomManager mTelecomManager; /** - * Helper that is responsible for showing the right toast when a disallowed activity operation - * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in - * fully locked mode we only show that unlocking is blocked. - */ - @VisibleForTesting - LockTaskNotify mLockTaskNotify; - - /** * The chain of tasks in LockTask mode, in the order of when they first entered LockTask mode. * * The first task in the list, which started the current LockTask session, is called the root @@ -475,7 +468,7 @@ public class LockTaskController { getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId); } if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { - getLockTaskNotify().showPinningExitToast(); + getStatusBarService().showPinningEnterExitToast(false /* entering */); } } catch (RemoteException ex) { throw new RuntimeException(ex); @@ -490,7 +483,11 @@ public class LockTaskController { */ void showLockTaskToast() { if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { - mHandler.post(() -> getLockTaskNotify().showEscapeToast()); + try { + getStatusBarService().showPinningEscapeToast(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to send pinning escape toast", e); + } } } @@ -582,7 +579,7 @@ public class LockTaskController { // When lock task starts, we disable the status bars. try { if (lockTaskModeState == LOCK_TASK_MODE_PINNED) { - getLockTaskNotify().showPinningStartToast(); + getStatusBarService().showPinningEnterExitToast(true /* entering */); } mLockTaskModeState = lockTaskModeState; setStatusBarState(lockTaskModeState, userId); @@ -835,15 +832,6 @@ public class LockTaskController { return mTelecomManager; } - // Should only be called on the handler thread - @NonNull - private LockTaskNotify getLockTaskNotify() { - if (mLockTaskNotify == null) { - mLockTaskNotify = new LockTaskNotify(mContext); - } - return mLockTaskNotify; - } - public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "LockTaskController"); prefix = prefix + " "; diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index adb368b074c0..7c170aee92fa 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -56,7 +56,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; - /** * A note on locking: We rely on the fact that calls onto mBar are oneway or * if they are local, that they just enqueue messages to not deadlock. @@ -525,6 +524,26 @@ public class StatusBarManagerService extends IStatusBarService.Stub { } @Override + public void showPinningEnterExitToast(boolean entering) throws RemoteException { + if (mBar != null) { + try { + mBar.showPinningEnterExitToast(entering); + } catch (RemoteException ex) { + } + } + } + + @Override + public void showPinningEscapeToast() throws RemoteException { + if (mBar != null) { + try { + mBar.showPinningEscapeToast(); + } catch (RemoteException ex) { + } + } + } + + @Override public void showFingerprintDialog(Bundle bundle, IFingerprintDialogReceiver receiver) { if (mBar != null) { try { diff --git a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java index d2ae22b43445..1cbb3991e461 100644 --- a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java @@ -90,7 +90,6 @@ public class LockTaskControllerTest { @Mock private IStatusBarService mStatusBarService; @Mock private WindowManagerService mWindowManager; @Mock private LockPatternUtils mLockPatternUtils; - @Mock private LockTaskNotify mLockTaskNotify; @Mock private StatusBarManagerInternal mStatusBarManagerInternal; @Mock private TelecomManager mTelecomManager; @Mock private RecentTasks mRecentTasks; @@ -123,7 +122,6 @@ public class LockTaskControllerTest { mLockTaskController.mDevicePolicyManager = mDevicePolicyManager; mLockTaskController.mTelecomManager = mTelecomManager; mLockTaskController.mLockPatternUtils = mLockPatternUtils; - mLockTaskController.mLockTaskNotify = mLockTaskNotify; LocalServices.removeServiceForTest(StatusBarManagerInternal.class); LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal); @@ -208,7 +206,7 @@ public class LockTaskControllerTest { // THEN lock task mode should be started verifyLockTaskStarted(STATUS_BAR_MASK_PINNED, DISABLE2_NONE); // THEN screen pinning toast should be shown - verify(mLockTaskNotify).showPinningStartToast(); + verify(mStatusBarService).showPinningEnterExitToast(true /* entering */); } @Test @@ -377,7 +375,7 @@ public class LockTaskControllerTest { // THEN the keyguard should be shown verify(mLockPatternUtils).requireCredentialEntry(UserHandle.USER_ALL); // THEN screen pinning toast should be shown - verify(mLockTaskNotify).showPinningExitToast(); + verify(mStatusBarService).showPinningEnterExitToast(false /* entering */); } @Test |
