From 998bb765290066822ff8a3b378dadd71deb0ce73 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Mon, 21 May 2012 13:37:27 -0700 Subject: [PATCH] Fix6398209: reveal search when home button is long-pressed This change add a feature to reveal the swipe to search interface when the home key is pressed for longer than 50ms. It progressively reveals the interface. It still requires a bit of tuning, but all the basic parameters are in this CL. Change-Id: I1d3a5bb7b912265eb41da68bc9313eee1af2e415 --- .../widget/multiwaveview/MultiWaveView.java | 90 +++++++++++++------ .../com/android/systemui/SearchPanelView.java | 42 +++++---- .../statusbar/phone/PhoneStatusBar.java | 8 +- .../statusbar/tablet/TabletStatusBar.java | 12 +++ .../internal/policy/impl/LockScreen.java | 4 + 5 files changed, 103 insertions(+), 53 deletions(-) diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java index 6136206f46050..d6fb84747575b 100644 --- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java +++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java @@ -67,6 +67,7 @@ public class MultiWaveView extends View { public void onReleased(View v, int handle); public void onTrigger(View v, int target); public void onGrabbedStateChange(View v, int handle); + public void onFinishFinalAnimation(); } // Tuneable parameters for animation @@ -77,9 +78,13 @@ public class MultiWaveView extends View { private static final int HIDE_ANIMATION_DELAY = 200; private static final int HIDE_ANIMATION_DURATION = 200; private static final int SHOW_ANIMATION_DURATION = 200; - private static final int SHOW_ANIMATION_DELAY = 0; + private static final int SHOW_ANIMATION_DELAY = 50; private static final float TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.3f; - private static final float TARGET_INITIAL_POSITION_SCALE = 0.8f; + private static final float TARGET_SCALE_SELECTED = 0.8f; + private static final long INITIAL_SHOW_HANDLE_DURATION = 200; + private static final float TARGET_SCALE_UNSELECTED = 1.0f; + private static final float RING_SCALE_UNSELECTED = 0.5f; + private static final float RING_SCALE_SELECTED = 1.5f; private TimeInterpolator mChevronAnimationInterpolator = Ease.Quad.easeOut; @@ -126,6 +131,15 @@ public class MultiWaveView extends View { } } + public void cancel() { + final int count = size(); + for (int i = 0; i < count; i++) { + Tweener anim = get(i); + anim.animator.cancel(); + } + clear(); + } + public void stop() { final int count = size(); for (int i = 0; i < count; i++) { @@ -143,6 +157,7 @@ public class MultiWaveView extends View { private AnimatorListener mResetListener = new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animator) { switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY); + dispatchOnFinishFinalAnimation(); } }; @@ -150,6 +165,7 @@ public class MultiWaveView extends View { public void onAnimationEnd(Animator animator) { ping(); switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY); + dispatchOnFinishFinalAnimation(); } }; @@ -349,7 +365,7 @@ public class MultiWaveView extends View { stopHandleAnimation(); deactivateTargets(); showTargets(true); - mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE); + activateHandle(); setGrabbedState(OnTriggerListener.CENTER_HANDLE); if (AccessibilityManager.getInstance(mContext).isEnabled()) { announceTargets(); @@ -368,6 +384,19 @@ public class MultiWaveView extends View { } } + private void activateHandle() { + mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE); + if (mAlwaysTrackFinger) { + mHandleAnimations.stop(); + mHandleDrawable.setAlpha(0.0f); + mHandleAnimations.add(Tweener.to(mHandleDrawable, INITIAL_SHOW_HANDLE_DURATION, + "ease", Ease.Cubic.easeIn, + "alpha", 1.0f, + "onUpdate", mUpdateListener)); + mHandleAnimations.start(); + } + } + /** * Animation used to attract user's attention to the target button. * Assumes mChevronDrawables is an a list with an even number of chevrons filled with @@ -463,6 +492,12 @@ public class MultiWaveView extends View { } } + private void dispatchOnFinishFinalAnimation() { + if (mOnTriggerListener != null) { + mOnTriggerListener.onFinishFinalAnimation(); + } + } + private void doFinish() { final int activeTarget = mActiveTarget; boolean targetHit = activeTarget != -1; @@ -471,8 +506,9 @@ public class MultiWaveView extends View { hideTargets(true); // Highlight the selected one - mHandleDrawable.setAlpha(targetHit ? 0.0f : 1.0f); + mHandleAnimations.cancel(); if (targetHit) { + mHandleDrawable.setAlpha(0.0f); mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE); hideUnselected(activeTarget); @@ -483,12 +519,11 @@ public class MultiWaveView extends View { // Animate handle back to the center based on current state. int delay = targetHit ? RETURN_TO_HOME_DELAY : 0; - int duration = targetHit ? 0 : RETURN_TO_HOME_DURATION; - mHandleAnimations.stop(); + int duration = RETURN_TO_HOME_DURATION; mHandleAnimations.add(Tweener.to(mHandleDrawable, duration, "ease", Ease.Quart.easeOut, "delay", delay, - "alpha", 1.0f, + "alpha", mAlwaysTrackFinger ? 0.0f : 1.0f, "x", 0, "y", 0, "onUpdate", mUpdateListener, @@ -508,12 +543,15 @@ public class MultiWaveView extends View { } private void hideTargets(boolean animate) { - mTargetAnimations.stop(); + mTargetAnimations.cancel(); // Note: these animations should complete at the same time so that we can swap out // the target assets asynchronously from the setTargetResources() call. mAnimatingTargets = animate; final int duration = animate ? HIDE_ANIMATION_DURATION : 0; final int delay = animate ? HIDE_ANIMATION_DELAY : 0; + final boolean targetSelected = mActiveTarget != -1; + + final float targetScale = targetSelected ? TARGET_SCALE_SELECTED : TARGET_SCALE_UNSELECTED; final int length = mTargetDrawables.size(); for (int i = 0; i < length; i++) { TargetDrawable target = mTargetDrawables.get(i); @@ -521,13 +559,13 @@ public class MultiWaveView extends View { mTargetAnimations.add(Tweener.to(target, duration, "ease", Ease.Cubic.easeOut, "alpha", 0.0f, - "scaleX", TARGET_INITIAL_POSITION_SCALE, - "scaleY", TARGET_INITIAL_POSITION_SCALE, + "scaleX", targetScale, + "scaleY", targetScale, "delay", delay, "onUpdate", mUpdateListener)); } - float ringScaleTarget = mActiveTarget != -1 ? 1.5f : 0.5f; + final float ringScaleTarget = targetSelected ? RING_SCALE_SELECTED : RING_SCALE_UNSELECTED; mTargetAnimations.add(Tweener.to(mOuterRing, duration, "ease", Ease.Cubic.easeOut, "alpha", 0.0f, @@ -544,13 +582,14 @@ public class MultiWaveView extends View { mTargetAnimations.stop(); mAnimatingTargets = animate; final int delay = animate ? SHOW_ANIMATION_DELAY : 0; + final int duration = animate ? SHOW_ANIMATION_DURATION : 0; final int length = mTargetDrawables.size(); for (int i = 0; i < length; i++) { TargetDrawable target = mTargetDrawables.get(i); target.setState(TargetDrawable.STATE_INACTIVE); - target.setScaleX(TARGET_INITIAL_POSITION_SCALE); - target.setScaleY(TARGET_INITIAL_POSITION_SCALE); - mTargetAnimations.add(Tweener.to(target, animate ? SHOW_ANIMATION_DURATION : 0, + target.setScaleX(TARGET_SCALE_SELECTED); + target.setScaleY(TARGET_SCALE_SELECTED); + mTargetAnimations.add(Tweener.to(target, duration, "ease", Ease.Cubic.easeOut, "alpha", 1.0f, "scaleX", 1.0f, @@ -558,9 +597,7 @@ public class MultiWaveView extends View { "delay", delay, "onUpdate", mUpdateListener)); } - mOuterRing.setScaleX(0.5f); - mOuterRing.setScaleY(0.5f); - mTargetAnimations.add(Tweener.to(mOuterRing, animate ? SHOW_ANIMATION_DURATION : 0, + mTargetAnimations.add(Tweener.to(mOuterRing, duration, "ease", Ease.Cubic.easeOut, "alpha", 1.0f, "scaleX", 1.0f, @@ -572,10 +609,6 @@ public class MultiWaveView extends View { mTargetAnimations.start(); } - private void stopTargetAnimation() { - mTargetAnimations.stop(); - } - private void vibrate() { if (mVibrator != null) { mVibrator.vibrate(mVibrationDuration); @@ -708,7 +741,7 @@ public class MultiWaveView extends View { public void reset(boolean animate) { stopChevronAnimation(); stopHandleAnimation(); - stopTargetAnimation(); + mTargetAnimations.stop(); hideChevrons(); hideTargets(animate); mHandleDrawable.setX(0); @@ -760,7 +793,7 @@ public class MultiWaveView extends View { private void handleDown(MotionEvent event) { if (!trySwitchToFirstTouchState(event.getX(), event.getY())) { mDragging = false; - stopTargetAnimation(); + mTargetAnimations.cancel(); ping(); } } @@ -815,8 +848,8 @@ public class MultiWaveView extends View { // For more than one target, snap to the closest one less than hitRadius away. float best = Float.MAX_VALUE; final float hitRadius2 = mHitRadius * mHitRadius; + // Find first target in range for (int i = 0; i < ntargets; i++) { - // Snap to the first target in range TargetDrawable target = targets.get(i); float dx = limitX - target.getX(); float dy = limitY - target.getY(); @@ -842,10 +875,15 @@ public class MultiWaveView extends View { float newX = singleTarget ? x : target.getX(); float newY = singleTarget ? y : target.getY(); moveHandleTo(newX, newY, false); + mHandleAnimations.cancel(); + mHandleDrawable.setAlpha(0.0f); } else { switchToState(STATE_TRACKING, x, y); + if (mActiveTarget != -1) { + mHandleAnimations.cancel(); + mHandleDrawable.setAlpha(1.0f); + } moveHandleTo(x, y, false); - mHandleDrawable.setAlpha(1.0f); } // Draw handle outside parent's bounds @@ -857,7 +895,6 @@ public class MultiWaveView extends View { TargetDrawable target = targets.get(mActiveTarget); if (target.hasState(TargetDrawable.STATE_FOCUSED)) { target.setState(TargetDrawable.STATE_INACTIVE); - mHandleDrawable.setAlpha(1.0f); } } // Focus the new target @@ -865,7 +902,6 @@ public class MultiWaveView extends View { TargetDrawable target = targets.get(activeTarget); if (target.hasState(TargetDrawable.STATE_FOCUSED)) { target.setState(TargetDrawable.STATE_FOCUSED); - mHandleDrawable.setAlpha(0.0f); } dispatchGrabbedEvent(activeTarget); if (AccessibilityManager.getInstance(mContext).isEnabled()) { diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java index 6b0bb87109227..478d652e5947c 100644 --- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java @@ -18,6 +18,8 @@ package com.android.systemui; import android.animation.Animator; import android.animation.LayoutTransition; +import android.app.ActivityManagerNative; +import android.app.ActivityOptions; import android.app.SearchManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; @@ -36,6 +38,7 @@ import android.widget.FrameLayout; import com.android.internal.widget.multiwaveview.MultiWaveView; import com.android.internal.widget.multiwaveview.MultiWaveView.OnTriggerListener; +import com.android.server.am.ActivityManagerService; import com.android.systemui.R; import com.android.systemui.recent.StatusBarTouchProxy; import com.android.systemui.statusbar.BaseStatusBar; @@ -103,26 +106,20 @@ public class SearchPanelView extends FrameLayout implements } private void startAssistActivity() { - if (mSearchManager != null) { - ComponentName globalSearchActivity = mSearchManager.getGlobalSearchActivity(); - if (globalSearchActivity != null) { - Intent intent = new Intent(Intent.ACTION_ASSIST); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setPackage(globalSearchActivity.getPackageName()); - try { - mContext.startActivity(intent); - } catch (ActivityNotFoundException e) { - Slog.w(TAG, "Activity not found for " + intent.getAction()); - } - } else { - Slog.w(TAG, "No global search activity"); - } + Intent intent = getAssistIntent(); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + mContext.startActivity(intent); + } catch (ActivityNotFoundException e) { + Slog.w(TAG, "Activity not found for " + intent.getAction()); } } final MultiWaveView.OnTriggerListener mMultiWaveViewListener = new MultiWaveView.OnTriggerListener() { + private int mTarget = -1; + public void onGrabbed(View v, int handle) { } @@ -136,11 +133,18 @@ public class SearchPanelView extends FrameLayout implements } public void onTrigger(View v, int target) { - final int resId = mMultiWaveView.getResourceIdForTarget(target); - switch (resId) { - case com.android.internal.R.drawable.ic_lockscreen_search: - startAssistActivity(); - break; + mTarget = target; + } + + public void onFinishFinalAnimation() { + if (mTarget != -1) { + final int resId = mMultiWaveView.getResourceIdForTarget(mTarget); + mTarget = -1; // a safety to make sure we never launch w/o prior call to onTrigger + switch (resId) { + case com.android.internal.R.drawable.ic_lockscreen_search: + startAssistActivity(); + break; + } } mBar.hideSearchPanel(); } 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 69d2e73be50f9..d38611d58a3d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -515,14 +515,8 @@ public class PhoneStatusBar extends BaseStatusBar { public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: - Slog.d(TAG, "showing search panel"); showSearchPanel(); break; - - case MotionEvent.ACTION_UP: - Slog.d(TAG, "hiding search panel"); - hideSearchPanel(); - break; } return false; } @@ -533,8 +527,8 @@ public class PhoneStatusBar extends BaseStatusBar { mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener); mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel); + mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener); updateSearchPanel(); -// mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener); } // For small-screen devices (read: phones) that lack hardware navigation buttons diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index dba160667e7f6..10c5dd8afc57a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -188,6 +188,17 @@ public class TabletStatusBar extends BaseStatusBar implements public Context getContext() { return mContext; } + private View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() { + public boolean onTouch(View v, MotionEvent event) { + switch(event.getAction()) { + case MotionEvent.ACTION_DOWN: + showSearchPanel(); + break; + } + return false; + } + }; + @Override protected void createAndAddWindows() { addStatusBarWindow(); @@ -290,6 +301,7 @@ public class TabletStatusBar extends BaseStatusBar implements // Search Panel mStatusBarView.setBar(this); + mHomeButton.setOnTouchListener(mHomeSearchActionListener); updateSearchPanel(); // Input methods Panel diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 22f70a5838df9..30cb530935a12 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -401,6 +401,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen { public void cleanUp() { mMultiWaveView.setOnTriggerListener(null); } + + public void onFinishFinalAnimation() { + + } } private void requestUnlockScreen() {