ImmersiveModeConfirmation.java revision a953b6d968beba01baad095b9ed2e40dbb97f189
134e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock/* 234e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * Copyright (C) 2013 The Android Open Source Project 334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * 434e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 534e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * you may not use this file except in compliance with the License. 634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * You may obtain a copy of the License at 734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * 834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * http://www.apache.org/licenses/LICENSE-2.0 934e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * 1034e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * Unless required by applicable law or agreed to in writing, software 1134e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 1234e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * See the License for the specific language governing permissions and 1434e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * limitations under the License. 1534e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock */ 1634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 1734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockpackage com.android.internal.policy.impl; 1834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 19a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.animation.Animator; 20a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.animation.ArgbEvaluator; 21a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.animation.ValueAnimator; 22a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.app.ActivityManager; 2334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockimport android.content.Context; 24a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.graphics.PixelFormat; 25a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.graphics.drawable.ColorDrawable; 2634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockimport android.os.Handler; 274cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlockimport android.os.Message; 28d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlockimport android.os.UserHandle; 29d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlockimport android.provider.Settings; 30d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlockimport android.text.TextUtils; 3134e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockimport android.util.ArraySet; 32a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.util.DisplayMetrics; 3334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockimport android.util.Slog; 34a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.view.Gravity; 35a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.view.MotionEvent; 3634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockimport android.view.View; 37a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.view.ViewGroup; 38a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.view.WindowManager; 394cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlockimport android.view.animation.Animation; 404cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlockimport android.view.animation.AnimationUtils; 41a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.view.animation.DecelerateInterpolator; 42a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.widget.Button; 43a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandlerimport android.widget.FrameLayout; 4434e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 4534e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockimport com.android.internal.R; 4634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 47d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlockimport java.util.Arrays; 48d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock 4934e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock/** 5034e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * Helper to manage showing/hiding a confirmation prompt when the transient navigation bar 5134e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock * is hidden. 5234e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock */ 5334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlockpublic class TransientNavigationConfirmation { 544cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private static final String TAG = "TransientNavigationConfirmation"; 554cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private static final boolean DEBUG = false; 56a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution 5734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 5834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock private final Context mContext; 594cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private final H mHandler; 60d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private final ArraySet<String> mConfirmedPackages = new ArraySet<String>(); 614cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private final long mShowDelayMs; 62d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private final long mPanicThresholdMs; 6334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 64a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private ClingWindowView mClingWindow; 65d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private String mLastPackage; 66d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private String mPromptPackage; 67d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private long mPanicTime; 68d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private String mPanicPackage; 69a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private WindowManager mWindowManager; 7034e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 714cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock public TransientNavigationConfirmation(Context context) { 7234e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock mContext = context; 734cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock mHandler = new H(); 744cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock mShowDelayMs = getNavBarExitDuration() * 3; 75d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mPanicThresholdMs = context.getResources() 76d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock .getInteger(R.integer.config_transient_navigation_confirmation_panic); 77a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mWindowManager = (WindowManager) 78a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mContext.getSystemService(Context.WINDOW_SERVICE); 794cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock } 804cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock 814cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private long getNavBarExitDuration() { 824cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock Animation exit = AnimationUtils.loadAnimation(mContext, R.anim.dock_bottom_exit); 834cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock return exit != null ? exit.getDuration() : 0; 8434e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 8534e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 86d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock public void loadSetting() { 87d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "loadSetting()"); 88d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mConfirmedPackages.clear(); 89d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock String packages = null; 90d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock try { 91d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock packages = Settings.Secure.getStringForUser(mContext.getContentResolver(), 92d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS, 93d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock UserHandle.USER_CURRENT); 94d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (packages != null) { 95d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mConfirmedPackages.addAll(Arrays.asList(packages.split(","))); 96d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "Loaded mConfirmedPackages=" + mConfirmedPackages); 97d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 98d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } catch (Throwable t) { 99d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock Slog.w(TAG, "Error loading confirmations, packages=" + packages, t); 100d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 101d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 102d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock 103d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private void saveSetting() { 104d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "saveSetting()"); 105d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock try { 106d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock final String packages = TextUtils.join(",", mConfirmedPackages); 107d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock Settings.Secure.putStringForUser(mContext.getContentResolver(), 108d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock Settings.Secure.TRANSIENT_NAV_CONFIRMATIONS, 109d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock packages, 110d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock UserHandle.USER_CURRENT); 111d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "Saved packages=" + packages); 112d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } catch (Throwable t) { 113d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock Slog.w(TAG, "Error saving confirmations, mConfirmedPackages=" + mConfirmedPackages, t); 114d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 115d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 116d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock 117d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock public void transientNavigationChanged(String pkg, boolean isNavTransient) { 11834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock if (pkg == null) { 11934e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock return; 12034e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 1214cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock mHandler.removeMessages(H.SHOW); 12234e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock if (isNavTransient) { 123d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mLastPackage = pkg; 124a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler if (DEBUG_SHOW_EVERY_TIME || !mConfirmedPackages.contains(pkg)) { 125d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs); 12634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 12734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } else { 128d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mLastPackage = null; 1294cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock mHandler.sendEmptyMessage(H.HIDE); 13034e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 13134e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 13234e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 133d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock public void onPowerKeyDown(boolean isScreenOn, long time, boolean transientNavigationAllowed) { 134d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) { 135d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock // turning the screen back on within the panic threshold 136d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock unconfirmPackage(mPanicPackage); 137d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 138d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (isScreenOn && transientNavigationAllowed) { 139d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock // turning the screen off, remember if we were hiding the transient nav 140d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mPanicTime = time; 141d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mPanicPackage = mLastPackage; 142d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } else { 143d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mPanicTime = 0; 144d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mPanicPackage = null; 145d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 146d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 147d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock 148d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock public void confirmCurrentPrompt() { 149d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mHandler.post(confirmAction(mPromptPackage)); 150d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 151d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock 152d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private void unconfirmPackage(String pkg) { 153d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (pkg != null) { 154d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + pkg); 155d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mConfirmedPackages.remove(pkg); 156d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock saveSetting(); 15734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 15834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 15934e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 1604cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private void handleHide() { 161a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler if (mClingWindow != null) { 162d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, 163d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock "Hiding transient navigation confirmation for " + mPromptPackage); 164a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mWindowManager.removeView(mClingWindow); 165a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mClingWindow = null; 166a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 167a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 168a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 169a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private class ClingWindowView extends FrameLayout { 170a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private static final int BGCOLOR = 0x80000000; 171a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private static final int OFFSET_DP = 48; 172a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 173a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private final ColorDrawable mColor = new ColorDrawable(0); 174a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler private ValueAnimator mColorAnim; 175a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 176a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler public ClingWindowView(Context context) { 177a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler super(context); 178a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler setClickable(true); 179a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler setBackground(mColor); 180a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 181a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 182a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler @Override 183a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler public void onAttachedToWindow() { 184a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler super.onAttachedToWindow(); 185a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 186a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler DisplayMetrics metrics = new DisplayMetrics(); 187a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mWindowManager.getDefaultDisplay().getMetrics(metrics); 188a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler float density = metrics.density; 189a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 190a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler // create the confirmation cling 191a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler final ViewGroup clingLayout = (ViewGroup) 192a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler View.inflate(getContext(), R.layout.transient_navigation_cling, null); 193a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 194a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler final Button ok = (Button) clingLayout.findViewById(R.id.ok); 195a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler ok.setOnClickListener(new OnClickListener() { 196a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler @Override 197a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler public void onClick(View v) { 198a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler handleHide(); 199a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 200a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler }); 201a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler addView(clingLayout, new FrameLayout.LayoutParams( 202a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler FrameLayout.LayoutParams.MATCH_PARENT, 203a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler FrameLayout.LayoutParams.WRAP_CONTENT 204a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler )); 205a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 206a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler if (ActivityManager.isHighEndGfx()) { 207a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler final View bubble = clingLayout.findViewById(R.id.text); 208a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler bubble.setAlpha(0f); 209a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler bubble.setTranslationY(-OFFSET_DP*density); 210a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler bubble.animate() 211a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .alpha(1f) 212a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .translationY(0) 213a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .setDuration(300) 214a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .setInterpolator(new DecelerateInterpolator()) 215a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .start(); 216a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 217a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler ok.setAlpha(0f); 218a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler ok.setTranslationY(-OFFSET_DP*density); 219a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler ok.animate().alpha(1f) 220a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .translationY(0) 221a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .setDuration(300) 222a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .setStartDelay(200) 223a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .setInterpolator(new DecelerateInterpolator()) 224a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler .start(); 225a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 226a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(), 0, BGCOLOR); 227a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mColorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 228a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler @Override 229a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler public void onAnimationUpdate(ValueAnimator animation) { 230a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler final int c = (Integer) animation.getAnimatedValue(); 231a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mColor.setColor(c); 232a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 233a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler }); 234a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mColorAnim.setDuration(1000); 235a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mColorAnim.start(); 236a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } else { 237a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mColor.setColor(BGCOLOR); 238a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 239a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler } 240a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 241a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler @Override 242a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler public boolean onTouchEvent(MotionEvent motion) { 243a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler Slog.v(TAG, "ClingWindowView.onTouchEvent"); 244a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler return true; 2454cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock } 2464cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock } 24734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 248d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private void handleShow(String pkg) { 249d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mPromptPackage = pkg; 250d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + pkg); 251d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock 252a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mClingWindow = new ClingWindowView(mContext); 25334e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 2544cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock // we will be hiding the nav bar, so layout as if it's already hidden 255a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mClingWindow.setSystemUiVisibility( 256a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 257a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 2584cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock 2594cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock // show the confirmation 260a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 261a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler ViewGroup.LayoutParams.MATCH_PARENT, 262a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler ViewGroup.LayoutParams.MATCH_PARENT, 263a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler WindowManager.LayoutParams.TYPE_TOAST, 264a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler 0 265a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 266a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 267a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED 268a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler , 269a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler PixelFormat.TRANSLUCENT); 270a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler lp.setTitle("TransientNavigationConfirmation"); 271a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; 272a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler lp.gravity = Gravity.FILL; 273a953b6d968beba01baad095b9ed2e40dbb97f189Daniel Sandler mWindowManager.addView(mClingWindow, lp); 27434e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 27534e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock 276d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock private Runnable confirmAction(final String pkg) { 27734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock return new Runnable() { 27834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock @Override 27934e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock public void run() { 280d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (pkg != null && !mConfirmedPackages.contains(pkg)) { 281d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock if (DEBUG) Slog.d(TAG, "Confirming transient navigation for " + pkg); 282d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock mConfirmedPackages.add(pkg); 283d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock saveSetting(); 284d67ec25a9c4bf728e4805248d0b287cc3c3ab8aeJohn Spurlock } 2854cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock handleHide(); 28634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 28734e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock }; 28834e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock } 2894cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock 2904cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private final class H extends Handler { 2914cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private static final int SHOW = 0; 2924cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock private static final int HIDE = 1; 2934cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock 2944cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock @Override 2954cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock public void handleMessage(Message msg) { 2964cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock switch(msg.what) { 2974cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock case SHOW: 2984cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock handleShow((String)msg.obj); 2994cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock break; 3004cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock case HIDE: 3014cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock handleHide(); 3024cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock break; 3034cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock } 3044cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock } 3054cf6a948f9998204d2bfdceebae89954b2b4ae7eJohn Spurlock } 30634e13d90eda9bfda7a70998d190a95c88aa3d3d1John Spurlock} 307