diff --git a/core/res/res/layout/lock_to_app_checkbox.xml b/core/res/res/layout/lock_to_app_checkbox.xml
deleted file mode 100644
index 890507b850e74..0000000000000
--- a/core/res/res/layout/lock_to_app_checkbox.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1b1764929ab02..6467dd07188ac 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4867,16 +4867,6 @@
To unpin this screen, touch and hold Overview.
Screen is pinned. Unpinning isn\'t allowed by your organization.
-
- Use screen pinning?
-
- Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Back and Overview at the same time.
-
- Screen pinning locks the display in a single view.\n\nTo unpin, touch and hold Overview.
-
- NO, THANKS
-
- START
Screen pinned
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ddf520f4f9b73..fc4f77d1e7ed0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -668,13 +668,6 @@
-
-
-
-
-
-
-
diff --git a/packages/SystemUI/res/drawable/screen_pinning_bg_circ.xml b/packages/SystemUI/res/drawable/screen_pinning_bg_circ.xml
new file mode 100644
index 0000000000000..354b8bd7607b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/screen_pinning_bg_circ.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/screen_pinning_light_bg_circ.xml b/packages/SystemUI/res/drawable/screen_pinning_light_bg_circ.xml
new file mode 100644
index 0000000000000..9e83057041d0c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/screen_pinning_light_bg_circ.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/screen_pinning_request.xml b/packages/SystemUI/res/layout/screen_pinning_request.xml
new file mode 100644
index 0000000000000..fea45cc099cf2
--- /dev/null
+++ b/packages/SystemUI/res/layout/screen_pinning_request.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
new file mode 100644
index 0000000000000..224a0a0fd8591
--- /dev/null
+++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml
new file mode 100644
index 0000000000000..1e5193ff99259
--- /dev/null
+++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_land_phone.xml b/packages/SystemUI/res/layout/screen_pinning_request_land_phone.xml
new file mode 100644
index 0000000000000..e6c22d477886b
--- /dev/null
+++ b/packages/SystemUI/res/layout/screen_pinning_request_land_phone.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml b/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml
new file mode 100644
index 0000000000000..df957f42145db
--- /dev/null
+++ b/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/values-sw400dp/dimens.xml b/packages/SystemUI/res/values-sw400dp/dimens.xml
index 80e82c4fd5946..f19335bc6285a 100644
--- a/packages/SystemUI/res/values-sw400dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw400dp/dimens.xml
@@ -23,5 +23,13 @@
navigation_extra_key_width -->
50dp
+
+ 7dp
+
+ 44dp
+
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 2c22cef95eee3..3a62ad94f2c76 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -29,4 +29,15 @@
36dp
80dp
+
+
+ 490dp
+
+ 162dp
+
+ 39dp
+
+ 2dp
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index d3b5580d309bd..195fdb1642be8 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -87,4 +87,15 @@
2dp
+
+
+ 400dp
+
+ 128dp
+
+ 22dp
+
+ 8dp
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 82dccd2b215f4..ea9d3c33ca619 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -123,4 +123,10 @@
#03000000
+
+
+ #4080cbc4
+
+ #ff009688
+ #80000000
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 51ef0c367beeb..0edf60fbf6c38 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -520,4 +520,29 @@
3dp
+
+
+ @dimen/match_parent
+
+ 66dp
+
+ 84dp
+
+ 14dp
+
+ 18dp
+
+ 7dp
+
+ 34dp
+
+ 0dp
+
+ 56dp
+
+ 84dp
+
diff --git a/packages/SystemUI/res/values/internal.xml b/packages/SystemUI/res/values/internal.xml
index 3b593d2e21026..67685ee09c082 100644
--- a/packages/SystemUI/res/values/internal.xml
+++ b/packages/SystemUI/res/values/internal.xml
@@ -17,5 +17,6 @@
@*android:dimen/status_bar_height
@*android:dimen/navigation_bar_height
+ @*android:color/primary_text_default_material_light
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7a0d655514e47..d70f4e3127474 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -899,4 +899,16 @@
%1$s. %2$s
+
+
+ Screen is pinned
+
+ This keeps it in view until you unpin. Touch and hold Back and Overview at the same time to unpin.
+
+ This keeps it in view until you unpin. Touch and hold Overview to unpin.
+
+ Got it
+
+ No thanks
+
diff --git a/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java
new file mode 100644
index 0000000000000..9e5c2c8ce62c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recent/ScreenPinningRequest.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2014 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.systemui.recent;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+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.drawable.ColorDrawable;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.recents.model.RecentsTaskLoader;
+
+import java.util.ArrayList;
+
+public class ScreenPinningRequest implements View.OnClickListener {
+ private final Context mContext;
+
+ private final AccessibilityManager mAccessibilityService;
+ private final WindowManager mWindowManager;
+
+ private RequestWindowView mRequestWindow;
+
+ public ScreenPinningRequest(Context context) {
+ mContext = context;
+ mAccessibilityService = (AccessibilityManager)
+ mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+ mWindowManager = (WindowManager)
+ mContext.getSystemService(Context.WINDOW_SERVICE);
+ }
+
+ public void clearPrompt() {
+ if (mRequestWindow != null) {
+ mWindowManager.removeView(mRequestWindow);
+ mRequestWindow = null;
+ }
+ }
+
+ public void showPrompt(boolean allowCancel) {
+ clearPrompt();
+
+ mRequestWindow = new RequestWindowView(mContext, allowCancel);
+
+ mRequestWindow.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+
+ // show the confirmation
+ WindowManager.LayoutParams lp = getWindowLayoutParams();
+ mWindowManager.addView(mRequestWindow, lp);
+ }
+
+ public void onConfigurationChanged() {
+ if (mRequestWindow != null) {
+ mRequestWindow.onConfigurationChanged();
+ }
+ }
+
+ private WindowManager.LayoutParams getWindowLayoutParams() {
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ 0
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+ ,
+ PixelFormat.TRANSLUCENT);
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ lp.setTitle("ScreenPinningConfirmation");
+ lp.gravity = Gravity.FILL;
+ return lp;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.screen_pinning_ok_button || mRequestWindow == v) {
+ try {
+ ActivityManagerNative.getDefault().startLockTaskModeOnCurrent();
+ } catch (RemoteException e) {}
+ }
+ clearPrompt();
+ }
+
+ public FrameLayout.LayoutParams getRequestLayoutParams(boolean isLandscape) {
+ return new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ isLandscape ? (Gravity.CENTER_VERTICAL | Gravity.RIGHT)
+ : (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
+ }
+
+ private class RequestWindowView extends FrameLayout {
+ private static final int OFFSET_DP = 96;
+
+ private final ColorDrawable mColor = new ColorDrawable(0);
+ private ValueAnimator mColorAnim;
+ private ViewGroup mLayout;
+ private boolean mShowCancel;
+
+ public RequestWindowView(Context context, boolean showCancel) {
+ super(context);
+ setClickable(true);
+ setOnClickListener(ScreenPinningRequest.this);
+ setBackground(mColor);
+ mShowCancel = showCancel;
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ DisplayMetrics metrics = new DisplayMetrics();
+ mWindowManager.getDefaultDisplay().getMetrics(metrics);
+ float density = metrics.density;
+ boolean isLandscape = isLandscapePhone(mContext);
+
+ inflateView(isLandscape);
+ int bgColor = mContext.getResources().getColor(
+ R.color.screen_pinning_request_window_bg);
+ if (ActivityManager.isHighEndGfx()) {
+ mLayout.setAlpha(0f);
+ if (isLandscape) {
+ mLayout.setTranslationX(OFFSET_DP * density);
+ } else {
+ mLayout.setTranslationY(OFFSET_DP * density);
+ }
+ mLayout.animate()
+ .alpha(1f)
+ .translationX(0)
+ .translationY(0)
+ .setDuration(300)
+ .setInterpolator(new DecelerateInterpolator())
+ .start();
+
+ mColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(), 0, bgColor);
+ mColorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final int c = (Integer) animation.getAnimatedValue();
+ mColor.setColor(c);
+ }
+ });
+ mColorAnim.setDuration(1000);
+ mColorAnim.start();
+ } else {
+ mColor.setColor(bgColor);
+ }
+
+ IntentFilter filter = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ mContext.registerReceiver(mReceiver, filter);
+ }
+
+ private boolean isLandscapePhone(Context context) {
+ Configuration config = mContext.getResources().getConfiguration();
+ return config.orientation == Configuration.ORIENTATION_LANDSCAPE
+ && config.smallestScreenWidthDp < 600;
+ }
+
+ private void inflateView(boolean isLandscape) {
+ // We only want this landscape orientation on <600dp, so rather than handle
+ // resource overlay for -land and -sw600dp-land, just inflate this
+ // other view for this single case.
+ mLayout = (ViewGroup) View.inflate(getContext(), isLandscape
+ ? R.layout.screen_pinning_request_land_phone : R.layout.screen_pinning_request,
+ null);
+ // Catch touches so they don't trigger cancel/activate, like outside does.
+ mLayout.setClickable(true);
+ // Status bar is always on the right.
+ mLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
+ // Buttons and text do switch sides though.
+ View buttons = mLayout.findViewById(R.id.screen_pinning_buttons);
+ buttons.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
+ mLayout.findViewById(R.id.screen_pinning_text_area)
+ .setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
+ swapChildrenIfRtlAndVertical(buttons);
+
+ ((Button) mLayout.findViewById(R.id.screen_pinning_ok_button))
+ .setOnClickListener(ScreenPinningRequest.this);
+ if (mShowCancel) {
+ ((Button) mLayout.findViewById(R.id.screen_pinning_cancel_button))
+ .setOnClickListener(ScreenPinningRequest.this);
+ } else {
+ ((Button) mLayout.findViewById(R.id.screen_pinning_cancel_button))
+ .setVisibility(View.INVISIBLE);
+ }
+
+ final int description = mAccessibilityService.isEnabled()
+ ? R.string.screen_pinning_description_accessible
+ : R.string.screen_pinning_description;
+ ((TextView) mLayout.findViewById(R.id.screen_pinning_description))
+ .setText(description);
+ final int backBgVisibility =
+ mAccessibilityService.isEnabled() ? 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);
+
+ addView(mLayout, getRequestLayoutParams(isLandscape));
+ }
+
+ private void swapChildrenIfRtlAndVertical(View group) {
+ if (mContext.getResources().getConfiguration().getLayoutDirection()
+ != View.LAYOUT_DIRECTION_RTL) {
+ return;
+ }
+ LinearLayout linearLayout = (LinearLayout) group;
+ if (linearLayout.getOrientation() == LinearLayout.VERTICAL) {
+ int childCount = linearLayout.getChildCount();
+ ArrayList childList = new ArrayList<>(childCount);
+ for (int i = 0; i < childCount; i++) {
+ childList.add(linearLayout.getChildAt(i));
+ }
+ linearLayout.removeAllViews();
+ for (int i = childCount - 1; i >= 0; i--) {
+ linearLayout.addView(childList.get(i));
+ }
+ }
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ mContext.unregisterReceiver(mReceiver);
+ }
+
+ protected void onConfigurationChanged() {
+ removeAllViews();
+ inflateView(isLandscapePhone(mContext));
+ }
+
+ private final Runnable mUpdateLayoutRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (mLayout != null && mLayout.getParent() != null) {
+ mLayout.setLayoutParams(getRequestLayoutParams(isLandscapePhone(mContext)));
+ }
+ }
+ };
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
+ post(mUpdateLayoutRunnable);
+ } else if (intent.getAction().equals(Intent.ACTION_USER_SWITCHED)
+ || intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
+ clearPrompt();
+ }
+ }
+ };
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f8d981fc2d97d..de95ae81138a8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -37,6 +37,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewStub;
import android.widget.Toast;
+
import com.android.systemui.R;
import com.android.systemui.recents.misc.DebugTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
@@ -50,6 +51,8 @@ import com.android.systemui.recents.views.DebugOverlayView;
import com.android.systemui.recents.views.RecentsView;
import com.android.systemui.recents.views.SystemBarScrimViews;
import com.android.systemui.recents.views.ViewAnimation;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.SystemUIApplication;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
@@ -82,6 +85,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
// Runnables to finish the Recents activity
FinishRecentsRunnable mFinishLaunchHomeRunnable;
+ private PhoneStatusBar mStatusBar;
+
/**
* A common Runnable to finish Recents either by calling finish() (with a custom animation) or
* launching Home with some ActivityOptions. Generally we always launch home when we exit
@@ -430,6 +435,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
}
});
}
+
+ mStatusBar = ((SystemUIApplication) getApplication())
+ .getComponent(PhoneStatusBar.class);
}
/** Inflates the debug overlay if debug mode is enabled. */
@@ -631,6 +639,13 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
mFinishLaunchHomeRunnable.run();
}
+ @Override
+ public void onScreenPinningRequest() {
+ if (mStatusBar != null) {
+ mStatusBar.showScreenPinningRequest(false);
+ }
+ }
+
/**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 646d7018c3d36..51b3fb58275a3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -494,17 +494,6 @@ public class SystemServicesProxy {
return windowRect;
}
- /**
- * Locks the current task.
- */
- public void lockCurrentTask() {
- if (mIam == null) return;
-
- try {
- mIam.startLockTaskModeOnCurrent();
- } catch (RemoteException e) {}
- }
-
/**
* Takes a screenshot of the current surface.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 81ee839b67b27..6093584f6250c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -31,6 +31,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
+
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -54,6 +55,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
public void onTaskLaunchFailed();
public void onAllTaskViewsDismissed();
public void onExitToHomeAnimationTriggered();
+ public void onScreenPinningRequest();
}
RecentsConfiguration mConfig;
@@ -461,7 +463,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
postDelayed(new Runnable() {
@Override
public void run() {
- ssp.lockCurrentTask();
+ mCb.onScreenPinningRequest();
}
}, 350);
mTriggered = true;
@@ -485,7 +487,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
if (ssp.startActivityFromRecents(getContext(), task.key.id,
task.activityLabel, launchOpts)) {
if (launchOpts == null && lockToTask) {
- ssp.lockCurrentTask();
+ mCb.onScreenPinningRequest();
}
} else {
// Dismiss the task and return the user to home if we fail to
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 1485bdec65cc3..820aadfb8d442 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -123,6 +123,7 @@ import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.qs.QSPanel;
+import com.android.systemui.recent.ScreenPinningRequest;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -356,6 +357,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
? new GestureRecorder("/sdcard/statusbar_gestures.dat")
: null;
+ private ScreenPinningRequest mScreenPinningRequest;
+
private int mNavigationIconHints = 0;
// ensure quick settings is disabled until the current user makes it through the setup wizard
@@ -597,6 +600,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
setControllerUsers();
notifyUserAboutHiddenNotifications();
+
+ mScreenPinningRequest = new ScreenPinningRequest(mContext);
}
// ================================================================================
@@ -3144,6 +3149,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
updateShowSearchHoldoff();
updateRowStates();
+ mScreenPinningRequest.onConfigurationChanged();
}
@Override
@@ -4038,7 +4044,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override
public void showScreenPinningRequest() {
- // TODO: Show request.
+ if (mKeyguardMonitor.isShowing()) {
+ // Don't allow apps to trigger this from keyguard.
+ return;
+ }
+ // Show screen pinning request, since this comes from an app, show 'no thanks', button.
+ showScreenPinningRequest(true);
+ }
+
+ public void showScreenPinningRequest(boolean allowCancel) {
+ mScreenPinningRequest.showPrompt(allowCancel);
}
public boolean hasActiveNotifications() {
diff --git a/services/core/java/com/android/server/am/LockToAppRequestDialog.java b/services/core/java/com/android/server/am/LockToAppRequestDialog.java
deleted file mode 100644
index 739fd0a52661e..0000000000000
--- a/services/core/java/com/android/server/am/LockToAppRequestDialog.java
+++ /dev/null
@@ -1,141 +0,0 @@
-
-package com.android.server.am;
-
-import android.app.AlertDialog;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.res.Resources;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-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;
-import com.android.internal.widget.ILockSettings;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtilsCache;
-
-public class LockToAppRequestDialog implements OnClickListener {
- private static final String TAG = "ActivityManager";
-
- final private Context mContext;
- final private ActivityManagerService mService;
-
- private AlertDialog mDialog;
- private TaskRecord mRequestedTask;
-
- private CheckBox mCheckbox;
-
- private ILockSettings mLockSettingsService;
-
- private AccessibilityManager mAccessibilityService;
-
- public LockToAppRequestDialog(Context context, ActivityManagerService activityManagerService) {
- mContext = context;
- mAccessibilityService = (AccessibilityManager)
- mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
- mService = activityManagerService;
- }
-
- private ILockSettings getLockSettings() {
- if (mLockSettingsService == null) {
- mLockSettingsService = LockPatternUtilsCache.getInstance(
- ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings")));
- }
- return mLockSettingsService;
- }
-
- private int getLockString(int userId) {
- try {
- int quality = (int) getLockSettings().getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
- DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
- switch (quality) {
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
- return R.string.lock_to_app_unlock_pin;
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
- return R.string.lock_to_app_unlock_password;
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
- if (getLockSettings().getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false,
- userId)) {
- return R.string.lock_to_app_unlock_pattern;
- }
- }
- } catch (RemoteException e) {
- }
- return 0;
- }
-
- public void clearPrompt() {
- if (mDialog != null) {
- mDialog.dismiss();
- mDialog = null;
- }
- }
-
- public void showLockTaskPrompt(TaskRecord task) {
- clearPrompt();
- mRequestedTask = task;
- final int unlockStringId = getLockString(task.userId);
-
- final Resources r = Resources.getSystem();
- 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)
- .setPositiveButton(r.getString(R.string.lock_to_app_positive), this)
- .setNegativeButton(r.getString(R.string.lock_to_app_negative), this);
- if (unlockStringId != 0) {
- builder.setView(R.layout.lock_to_app_checkbox);
- }
- mDialog = builder.create();
-
- mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- mDialog.getWindow().getAttributes().privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- mDialog.show();
-
- if (unlockStringId != 0) {
- String unlockString = mContext.getString(unlockStringId);
- mCheckbox = (CheckBox) mDialog.findViewById(R.id.lock_to_app_checkbox);
- mCheckbox.setText(unlockString);
-
- // Remember state.
- try {
- boolean useLock = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
- mCheckbox.setChecked(useLock);
- } catch (SettingNotFoundException e) {
- }
- } else {
- mCheckbox = null;
- }
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (DialogInterface.BUTTON_POSITIVE == which) {
- Slog.d(TAG, "accept lock-to-app request");
- // Set whether to use the lock screen when exiting.
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
- mCheckbox != null && mCheckbox.isChecked() ? 1 : 0);
-
- // Start lock-to-app.
- mService.startLockTaskMode(mRequestedTask);
- } else {
- Slog.d(TAG, "ignore lock-to-app request");
- }
- }
-
-}