diff options
author | Daniel Sandler <dsandler@android.com> | 2013-10-11 14:27:53 -0400 |
---|---|---|
committer | Daniel Sandler <dsandler@android.com> | 2013-10-13 15:28:19 -0400 |
commit | a953b6d968beba01baad095b9ed2e40dbb97f189 (patch) | |
tree | 5c21f49bac4c1137b2d2869aeb3dff84d8a33d1f /policy | |
parent | d38b1302b7506ae7eef6c6680228c0f07f6e1895 (diff) | |
download | frameworks_base-a953b6d968beba01baad095b9ed2e40dbb97f189.zip frameworks_base-a953b6d968beba01baad095b9ed2e40dbb97f189.tar.gz frameworks_base-a953b6d968beba01baad095b9ed2e40dbb97f189.tar.bz2 |
New window cling for immersive mode.
Bug: 11077915
Change-Id: I6858259b31301b76dee81d3e6fbc534c1cdea661
Diffstat (limited to 'policy')
-rw-r--r-- | policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java | 132 |
1 files changed, 120 insertions, 12 deletions
diff --git a/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java index 8613088..a6381a7 100644 --- a/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java +++ b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java @@ -16,18 +16,31 @@ package com.android.internal.policy.impl; +import android.animation.Animator; +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; +import android.app.ActivityManager; import android.content.Context; +import android.graphics.PixelFormat; +import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.os.Message; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.ArraySet; +import android.util.DisplayMetrics; import android.util.Slog; +import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; -import android.widget.Toast; +import android.view.animation.DecelerateInterpolator; +import android.widget.Button; +import android.widget.FrameLayout; import com.android.internal.R; @@ -40,6 +53,7 @@ import java.util.Arrays; public class TransientNavigationConfirmation { private static final String TAG = "TransientNavigationConfirmation"; private static final boolean DEBUG = false; + private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution private final Context mContext; private final H mHandler; @@ -47,11 +61,12 @@ public class TransientNavigationConfirmation { private final long mShowDelayMs; private final long mPanicThresholdMs; - private Toast mToast; + private ClingWindowView mClingWindow; private String mLastPackage; private String mPromptPackage; private long mPanicTime; private String mPanicPackage; + private WindowManager mWindowManager; public TransientNavigationConfirmation(Context context) { mContext = context; @@ -59,6 +74,8 @@ public class TransientNavigationConfirmation { mShowDelayMs = getNavBarExitDuration() * 3; mPanicThresholdMs = context.getResources() .getInteger(R.integer.config_transient_navigation_confirmation_panic); + mWindowManager = (WindowManager) + mContext.getSystemService(Context.WINDOW_SERVICE); } private long getNavBarExitDuration() { @@ -104,7 +121,7 @@ public class TransientNavigationConfirmation { mHandler.removeMessages(H.SHOW); if (isNavTransient) { mLastPackage = pkg; - if (!mConfirmedPackages.contains(pkg)) { + if (DEBUG_SHOW_EVERY_TIME || !mConfirmedPackages.contains(pkg)) { mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs); } } else { @@ -141,11 +158,90 @@ public class TransientNavigationConfirmation { } private void handleHide() { - if (mToast != null) { + if (mClingWindow != null) { if (DEBUG) Slog.d(TAG, "Hiding transient navigation confirmation for " + mPromptPackage); - mToast.cancel(); - mToast = null; + mWindowManager.removeView(mClingWindow); + mClingWindow = null; + } + } + + private class ClingWindowView extends FrameLayout { + private static final int BGCOLOR = 0x80000000; + private static final int OFFSET_DP = 48; + + private final ColorDrawable mColor = new ColorDrawable(0); + private ValueAnimator mColorAnim; + + public ClingWindowView(Context context) { + super(context); + setClickable(true); + setBackground(mColor); + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + + DisplayMetrics metrics = new DisplayMetrics(); + mWindowManager.getDefaultDisplay().getMetrics(metrics); + float density = metrics.density; + + // create the confirmation cling + final ViewGroup clingLayout = (ViewGroup) + View.inflate(getContext(), R.layout.transient_navigation_cling, null); + + final Button ok = (Button) clingLayout.findViewById(R.id.ok); + ok.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + handleHide(); + } + }); + addView(clingLayout, new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + )); + + if (ActivityManager.isHighEndGfx()) { + final View bubble = clingLayout.findViewById(R.id.text); + bubble.setAlpha(0f); + bubble.setTranslationY(-OFFSET_DP*density); + bubble.animate() + .alpha(1f) + .translationY(0) + .setDuration(300) + .setInterpolator(new DecelerateInterpolator()) + .start(); + + ok.setAlpha(0f); + ok.setTranslationY(-OFFSET_DP*density); + ok.animate().alpha(1f) + .translationY(0) + .setDuration(300) + .setStartDelay(200) + .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); + } + } + + @Override + public boolean onTouchEvent(MotionEvent motion) { + Slog.v(TAG, "ClingWindowView.onTouchEvent"); + return true; } } @@ -153,16 +249,28 @@ public class TransientNavigationConfirmation { mPromptPackage = pkg; if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + pkg); - // create the confirmation toast bar - final int msg = R.string.transient_navigation_confirmation; - mToast = Toast.makeBar(mContext, msg, Toast.LENGTH_INFINITE); - mToast.setAction(R.string.ok, confirmAction(pkg)); + mClingWindow = new ClingWindowView(mContext); // we will be hiding the nav bar, so layout as if it's already hidden - mToast.getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + mClingWindow.setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); // show the confirmation - mToast.show(); + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_TOAST, + 0 + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED + , + PixelFormat.TRANSLUCENT); + lp.setTitle("TransientNavigationConfirmation"); + lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; + lp.gravity = Gravity.FILL; + mWindowManager.addView(mClingWindow, lp); } private Runnable confirmAction(final String pkg) { |