diff options
Diffstat (limited to 'packages/SystemUI')
20 files changed, 233 insertions, 113 deletions
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml index b5983bb..c2733fb 100644 --- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml +++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml @@ -59,7 +59,6 @@ android:src="@drawable/ic_sysbar_back" systemui:keyCode="4" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" @@ -69,7 +68,6 @@ systemui:keyCode="3" systemui:keyRepeat="true" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps" @@ -77,7 +75,6 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <Space @@ -98,7 +95,6 @@ systemui:keyCode="82" android:visibility="invisible" android:contentDescription="@string/accessibility_menu" - android:background="@drawable/ripple_drawable" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/ime_switcher" @@ -108,8 +104,7 @@ android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" - android:contentDescription="@string/accessibility_ime_switch_button" - android:background="@drawable/ripple_drawable" /> + android:contentDescription="@string/accessibility_ime_switch_button" /> </FrameLayout> </LinearLayout> @@ -205,7 +200,6 @@ android:src="@drawable/ic_sysbar_back" systemui:keyCode="4" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" @@ -215,7 +209,6 @@ systemui:keyCode="3" systemui:keyRepeat="true" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps" @@ -223,7 +216,6 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <Space @@ -243,9 +235,7 @@ android:src="@drawable/ic_sysbar_menu" systemui:keyCode="82" android:visibility="invisible" - android:contentDescription="@string/accessibility_menu" - android:background="@drawable/ripple_drawable" - /> + android:contentDescription="@string/accessibility_menu" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/ime_switcher" android:layout_width="@dimen/navigation_extra_key_width" @@ -254,8 +244,7 @@ android:src="@drawable/ic_ime_switcher_default" android:visibility="invisible" android:contentDescription="@string/accessibility_ime_switch_button" - android:scaleType="centerInside" - android:background="@drawable/ripple_drawable" /> + android:scaleType="centerInside" /> </FrameLayout> </LinearLayout> diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml index a165940..16027d9 100644 --- a/packages/SystemUI/res/layout/navigation_bar.xml +++ b/packages/SystemUI/res/layout/navigation_bar.xml @@ -55,7 +55,6 @@ systemui:keyCode="4" android:layout_weight="0" android:scaleType="center" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_back" /> <View @@ -71,7 +70,6 @@ systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_home" /> <View @@ -85,7 +83,6 @@ android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" - android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_recent" /> <FrameLayout @@ -99,7 +96,6 @@ android:contentDescription="@string/accessibility_menu" android:src="@drawable/ic_sysbar_menu" android:visibility="invisible" - android:background="@drawable/ripple_drawable" systemui:keyCode="82" /> <com.android.systemui.statusbar.policy.KeyButtonView @@ -109,8 +105,7 @@ android:contentDescription="@string/accessibility_ime_switch_button" android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" - android:visibility="invisible" - android:background="@drawable/ripple_drawable" /> + android:visibility="invisible" /> </FrameLayout> </LinearLayout> @@ -202,8 +197,7 @@ android:contentDescription="@string/accessibility_ime_switch_button" android:scaleType="centerInside" android:src="@drawable/ic_ime_switcher_default" - android:visibility="invisible" - android:background="@drawable/ripple_drawable" /> + android:visibility="invisible" /> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" @@ -212,7 +206,6 @@ android:contentDescription="@string/accessibility_menu" android:src="@drawable/ic_sysbar_menu_land" android:visibility="invisible" - android:background="@drawable/ripple_drawable" systemui:keyCode="82" /> </FrameLayout> @@ -222,7 +215,6 @@ android:src="@drawable/ic_sysbar_recent_land" android:layout_weight="0" android:contentDescription="@string/accessibility_recent" - android:background="@drawable/ripple_drawable" /> <View android:layout_height="match_parent" @@ -238,7 +230,6 @@ systemui:keyRepeat="false" android:layout_weight="0" android:contentDescription="@string/accessibility_home" - android:background="@drawable/ripple_drawable" /> <View android:layout_height="match_parent" @@ -254,7 +245,6 @@ systemui:keyCode="4" android:layout_weight="0" android:contentDescription="@string/accessibility_back" - android:background="@drawable/ripple_drawable" /> <View android:layout_height="40dp" diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 9b772bd..a9e7735 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -39,7 +39,7 @@ <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen> <!-- The side padding for the task stack as a percentage of the width. --> - <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.2229</item> + <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.26</item> <!-- Standard notification width + gravity --> <dimen name="notification_panel_width">@dimen/standard_notification_panel_width</dimen> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index cc77aaa..e22d78a 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -29,6 +29,12 @@ ImageView --> <bool name="config_recents_thumbnail_image_fits_to_xy">false</bool> + <!-- The number of app thumbnails we keep in memory --> + <integer name="config_recents_max_thumbnail_count">10</integer> + + <!-- The number of app icons we keep in memory --> + <integer name="config_recents_max_icon_count">20</integer> + <!-- Control whether status bar should distinguish HSPA data icon form UMTS data icon on devices --> <bool name="config_hspa_data_distinguishable">false</bool> diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index 4c7f8ec..f184ad2 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -31,6 +31,7 @@ import android.media.AudioAttributes; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; +import android.os.PowerManager; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; @@ -72,6 +73,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private final Context mContext; private final NotificationManager mNoMan; + private final PowerManager mPowerMan; private final Handler mHandler = new Handler(); private final Receiver mReceiver = new Receiver(); private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY); @@ -93,6 +95,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { public PowerNotificationWarnings(Context context, PhoneStatusBar phoneStatusBar) { mContext = context; mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mReceiver.init(); } @@ -356,9 +359,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { mSaverConfirmation = d; } - private void setSaverSetting(boolean mode) { - final int val = mode ? 1 : 0; - Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, val); + private void setSaverMode(boolean mode) { + mPowerMan.setPowerSaveMode(mode); } private final class Receiver extends BroadcastReceiver { @@ -384,7 +386,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { } else if (action.equals(ACTION_STOP_SAVER)) { dismissSaverNotification(); dismissLowBatteryNotification(); - setSaverSetting(false); + setSaverMode(false); } } } @@ -395,7 +397,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { AsyncTask.execute(new Runnable() { @Override public void run() { - setSaverSetting(true); + setSaverMode(true); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 6f4cf6b..52ec54b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -68,7 +68,7 @@ public class Constants { public static class RecentsTaskLoader { // XXX: This should be calculated on the first load - public static final int PreloadFirstTasksCount = 5; + public static final int PreloadFirstTasksCount = 6; } public static class TaskStackView { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index ed5c126..2a2caa0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -347,8 +347,8 @@ public class RecentsConfiguration { Rect searchBarBounds = new Rect(); getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds); if (isLandscape && hasTransposedSearchBar) { - // In landscape, the search bar appears on the left - taskStackBounds.set(searchBarBounds.right, topInset, windowWidth - rightInset, windowHeight); + // In landscape, the search bar appears on the left, but we overlay it on top + taskStackBounds.set(0, topInset, windowWidth - rightInset, windowHeight); } else { // In portrait, the search bar appears on the top (which already has the inset) taskStackBounds.set(0, searchBarBounds.bottom, windowWidth, windowHeight); 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 bbd0a0d..11b7b8b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -179,6 +179,12 @@ public class SystemServicesProxy { ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES | ActivityManager.RECENT_WITH_EXCLUDED, userId); + + // Break early if we can't get a valid set of tasks + if (tasks == null) { + return new ArrayList<ActivityManager.RecentTaskInfo>(); + } + boolean isFirstValidTask = true; Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator(); while (iter.hasNext()) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java index 757c07f..624a8ff 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java @@ -25,10 +25,4 @@ class BitmapLruCache extends KeyStoreLruCache<Bitmap> { public BitmapLruCache(int cacheSize) { super(cacheSize); } - - @Override - protected int computeSize(Bitmap b) { - // The cache size will be measured in kilobytes rather than number of items - return b.getAllocationByteCount(); - } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java index 5b50358..01a515b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java @@ -25,12 +25,4 @@ class DrawableLruCache extends KeyStoreLruCache<Drawable> { public DrawableLruCache(int cacheSize) { super(cacheSize); } - - @Override - protected int computeSize(Drawable d) { - // The cache size will be measured in kilobytes rather than number of items - // NOTE: this isn't actually correct, as the icon may be smaller - int maxBytes = (d.getIntrinsicWidth() * d.getIntrinsicHeight() * 4); - return maxBytes; - } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java index bb4dc76..7ccefc6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java @@ -34,10 +34,6 @@ public class KeyStoreLruCache<V> { public KeyStoreLruCache(int cacheSize) { mCache = new LruCache<Integer, V>(cacheSize) { - @Override - protected int sizeOf(Integer taskId, V v) { - return computeSize(v); - } @Override protected void entryRemoved(boolean evicted, Integer taskId, V oldV, V newV) { @@ -46,11 +42,6 @@ public class KeyStoreLruCache<V> { }; } - /** Computes the size of a value. */ - protected int computeSize(V value) { - return 0; - } - /** Gets a specific entry in the cache. */ final V get(Task.TaskKey key) { return mCache.get(key.id); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index f7ad35b..e5c06fd 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -29,6 +29,7 @@ import android.os.HandlerThread; import android.os.UserHandle; import android.util.Log; +import com.android.systemui.R; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.misc.SystemServicesProxy; @@ -123,8 +124,8 @@ class TaskResourceLoader implements Runnable { mDefaultThumbnail = defaultThumbnail; mDefaultApplicationIcon = defaultApplicationIcon; mMainThreadHandler = new Handler(); - mLoadThread = new HandlerThread("Recents-TaskResourceLoader"); - mLoadThread.setPriority(Thread.NORM_PRIORITY - 1); + mLoadThread = new HandlerThread("Recents-TaskResourceLoader", + android.os.Process.THREAD_PRIORITY_BACKGROUND); mLoadThread.start(); mLoadThreadHandler = new Handler(mLoadThread.getLooper()); mLoadThreadHandler.post(this); @@ -255,12 +256,10 @@ public class RecentsTaskLoader { /** Private Constructor */ private RecentsTaskLoader(Context context) { - // Calculate the cache sizes, we just use a reasonable number here similar to those - // suggested in the Android docs, 1/6th for the thumbnail cache and 1/30 of the max memory - // for icons. - int maxMemory = (int) Runtime.getRuntime().maxMemory(); - mMaxThumbnailCacheSize = maxMemory / 6; - mMaxIconCacheSize = mMaxThumbnailCacheSize / 5; + mMaxThumbnailCacheSize = context.getResources().getInteger( + R.integer.config_recents_max_thumbnail_count); + mMaxIconCacheSize = context.getResources().getInteger( + R.integer.config_recents_max_icon_count); int iconCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 : mMaxIconCacheSize; int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 : @@ -550,6 +549,12 @@ public class RecentsTaskLoader { case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: // Stop the loader immediately when the UI is no longer visible stopLoader(); + mThumbnailCache.trimToSize(Math.max( + Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount, + mMaxThumbnailCacheSize / 2)); + mApplicationIconCache.trimToSize(Math.max( + Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount, + mMaxIconCacheSize / 2)); break; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE: case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND: diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java index b06c454..6769716 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java @@ -23,10 +23,4 @@ class StringLruCache extends KeyStoreLruCache<String> { public StringLruCache(int cacheSize) { super(cacheSize); } - - @Override - protected int computeSize(String s) { - // The cache size is measured in number of strings - return 1; - } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 4563597..51adc28 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -41,6 +41,7 @@ import com.android.systemui.recents.model.Task; /* A task view */ public class TaskView extends FrameLayout implements Task.TaskCallbacks, TaskViewFooter.TaskFooterViewCallbacks, View.OnClickListener, View.OnLongClickListener { + /** The TaskView callbacks */ interface TaskViewCallbacks { public void onTaskViewAppIconClicked(TaskView tv); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 70b6952..5507944 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; +import android.view.Choreographer; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -43,7 +44,8 @@ public class KeyguardBouncer { private StatusBarWindowManager mWindowManager; private KeyguardViewBase mKeyguardView; private ViewGroup mRoot; - private boolean mFadingOut; + private boolean mShowingSoon; + private Choreographer mChoreographer = Choreographer.getInstance(); public KeyguardBouncer(Context context, ViewMediatorCallback callback, LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager, @@ -57,7 +59,7 @@ public class KeyguardBouncer { public void show() { ensureView(); - if (mRoot.getVisibility() == View.VISIBLE) { + if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) { // show() updates the current security method. This is needed in case we are already // showing and the current security method changed. @@ -68,10 +70,27 @@ public class KeyguardBouncer { // Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole // Keyguard. If we need to authenticate, show the bouncer. if (!mKeyguardView.dismiss()) { + mShowingSoon = true; + + // Split up the work over multiple frames. + mChoreographer.postCallbackDelayed(Choreographer.CALLBACK_ANIMATION, mShowRunnable, + null, 48); + } + } + + private final Runnable mShowRunnable = new Runnable() { + @Override + public void run() { mRoot.setVisibility(View.VISIBLE); mKeyguardView.onResume(); mKeyguardView.startAppearAnimation(); + mShowingSoon = false; } + }; + + private void cancelShowRunnable() { + mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mShowRunnable, null); + mShowingSoon = false; } public void showWithDismissAction(OnDismissAction r) { @@ -81,7 +100,8 @@ public class KeyguardBouncer { } public void hide(boolean destroyView) { - if (mKeyguardView != null) { + cancelShowRunnable(); + if (mKeyguardView != null) { mKeyguardView.setOnDismissAction(null); mKeyguardView.cleanUp(); } @@ -107,6 +127,7 @@ public class KeyguardBouncer { * Reset the state of the view. */ public void reset() { + cancelShowRunnable(); inflateView(); } @@ -127,7 +148,7 @@ public class KeyguardBouncer { } public boolean isShowing() { - return mRoot != null && mRoot.getVisibility() == View.VISIBLE && !mFadingOut; + return mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE); } public void prepare() { 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 3874b41..88e71e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -535,8 +535,6 @@ public class NavigationBarView extends LinearLayout { } } - - /* @Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) { 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 4272582..95f9866 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -2362,8 +2362,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller.setVisibility(View.VISIBLE); mNotificationPanel.setVisibility(View.GONE); - setAreThereNotifications(); // show the clear button - mNotificationPanel.closeQs(); mExpandedVisible = false; @@ -3578,6 +3576,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, disable(mDisabledUnmodified, true /* animate */); } + public boolean isKeyguardFadingAway() { + return mKeyguardFadingAway; + } + /** * Notifies that the Keyguard fading away animation is done. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index b4e2d57..55c861a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -43,6 +43,10 @@ public class StatusBarKeyguardViewManager { // When hiding the Keyguard with timing supplied from WindowManager, better be early than late. private static final long HIDE_TIMING_CORRECTION_MS = -3 * 16; + // Delay for showing the navigation bar when the bouncer appears. This should be kept in sync + // with the appear animations of the PIN/pattern/password views. + private static final long NAV_BAR_SHOW_DELAY_BOUNCER = 320; + private static String TAG = "StatusBarKeyguardViewManager"; private final Context mContext; @@ -323,12 +327,30 @@ public class StatusBarKeyguardViewManager { return mBouncer.isShowing(); } + private long getNavBarShowDelay() { + if (mPhoneStatusBar.isKeyguardFadingAway()) { + return mPhoneStatusBar.getKeyguardFadingAwayDelay(); + } else { + + // Keyguard is not going away, thus we are showing the navigation bar because the + // bouncer is appearing. + return NAV_BAR_SHOW_DELAY_BOUNCER; + } + } + + private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() { + @Override + public void run() { + mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE); + } + }; + private void updateStates() { int vis = mContainer.getSystemUiVisibility(); boolean showing = mShowing; boolean occluded = mOccluded; boolean bouncerShowing = mBouncer.isShowing(); - boolean bouncerDismissible = bouncerShowing && !mBouncer.needsFullscreenBouncer(); + boolean bouncerDismissible = !mBouncer.needsFullscreenBouncer(); if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing) || mFirstUpdate) { @@ -342,8 +364,10 @@ public class StatusBarKeyguardViewManager { != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) { if (mPhoneStatusBar.getNavigationBarView() != null) { if (!(showing && !occluded) || bouncerShowing) { - mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE); + mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable, + getNavBarShowDelay()); } else { + mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable); mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 42cfd39..7855452 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -55,12 +55,24 @@ public class StatusBarWindowView extends FrameLayout { @Override protected boolean fitSystemWindows(Rect insets) { if (getFitsSystemWindows()) { - setPadding(insets.left, insets.top, insets.right, 0); + boolean changed = insets.left != getPaddingLeft() + || insets.top != getPaddingTop() + || insets.right != getPaddingRight() + || insets.bottom != getPaddingBottom(); + if (changed) { + setPadding(insets.left, insets.top, insets.right, 0); + } insets.left = 0; insets.top = 0; insets.right = 0; } else { - setPadding(0, 0, 0, 0); + boolean changed = getPaddingLeft() != 0 + || getPaddingRight() != 0 + || getPaddingTop() != 0 + || getPaddingBottom() != 0; + if (changed) { + setPadding(0, 0, 0, 0); + } } return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 16c0e66..b814b61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -17,11 +17,15 @@ package com.android.systemui.statusbar.policy; import android.animation.Animator; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.animation.TimeInterpolator; import android.app.ActivityManager; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; import android.hardware.input.InputManager; import android.media.AudioManager; import android.os.Bundle; @@ -34,10 +38,12 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SoundEffectConstants; +import android.view.View; import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ImageView; +import java.lang.Math; import com.android.systemui.R; @@ -50,15 +56,21 @@ public class KeyButtonView extends ImageView { // TODO: Get rid of this public static final float DEFAULT_QUIESCENT_ALPHA = 1f; + public static final float MAX_ALPHA = 0.15f; + public static final float GLOW_MAX_SCALE_FACTOR = 1.5f; private long mDownTime; private int mCode; private int mTouchSlop; + private float mGlowAlpha = 0f; + private float mGlowScale = 1f; private float mDrawingAlpha = 1f; private float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA; private boolean mSupportsLongpress = true; + private AnimatorSet mPressedAnim; private Animator mAnimateToQuiescent = new ObjectAnimator(); - private Drawable mBackground; + private Paint mRipplePaint; + private final TimeInterpolator mInterpolator = (TimeInterpolator) new LogInterpolator(); private AudioManager mAudioManager; private final Runnable mCheckLongPress = new Runnable() { @@ -90,11 +102,6 @@ public class KeyButtonView extends ImageView { mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); - Drawable d = getBackground(); - if (d != null) { - mBackground = d.mutate(); - setBackground(mBackground); - } setDrawingAlpha(mQuiescentAlpha); @@ -134,13 +141,45 @@ public class KeyButtonView extends ImageView { return super.performAccessibilityAction(action, arguments); } + private Paint getRipplePaint() { + if (mRipplePaint == null) { + mRipplePaint = new Paint(); + mRipplePaint.setAntiAlias(true); + mRipplePaint.setColor(0xffffffff); + } + return mRipplePaint; + } + + @Override + protected void onDraw(Canvas canvas) { + final Paint p = getRipplePaint(); + p.setAlpha((int)(MAX_ALPHA * mDrawingAlpha * mGlowAlpha * 255)); + + final float w = getWidth(); + final float h = getHeight(); + final boolean horizontal = w > h; + final float diameter = (horizontal ? w : h) * mGlowScale; + final float radius = diameter * .5f; + final float cx = w * .5f; + final float cy = h * .5f; + final float rx = horizontal ? radius : cx; + final float ry = horizontal ? cy : radius; + final float corner = horizontal ? cy : cx; + + canvas.drawRoundRect(cx - rx, cy - ry, + cx + rx, cy + ry, + corner, corner, p); + + super.onDraw(canvas); + } + public void setQuiescentAlpha(float alpha, boolean animate) { mAnimateToQuiescent.cancel(); alpha = Math.min(Math.max(alpha, 0), 1); if (alpha == mQuiescentAlpha && alpha == mDrawingAlpha) return; mQuiescentAlpha = alpha; if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha); - if (mBackground != null && animate) { + if (animate) { mAnimateToQuiescent = animateToQuiescent(); mAnimateToQuiescent.start(); } else { @@ -162,32 +201,77 @@ public class KeyButtonView extends ImageView { public void setDrawingAlpha(float x) { setImageAlpha((int) (x * 255)); - if (mBackground != null) { - mBackground.setAlpha((int)(x * 255)); - } mDrawingAlpha = x; } - public void setPressed(boolean pressed) { - if (mBackground != null) { - if (pressed != isPressed()) { - if (pressed) { - setDrawingAlpha(1f); - } else { - mAnimateToQuiescent.cancel(); - mAnimateToQuiescent = animateToQuiescent(); - mAnimateToQuiescent.setDuration(500); - mAnimateToQuiescent.start(); - } - } + public float getGlowAlpha() { + return mGlowAlpha; + } + + public void setGlowAlpha(float x) { + mGlowAlpha = x; + invalidate(); + } + + public float getGlowScale() { + return mGlowScale; + } + + public void setGlowScale(float x) { + mGlowScale = x; + final float w = getWidth(); + final float h = getHeight(); + if (GLOW_MAX_SCALE_FACTOR <= 1.0f) { + // this only works if we know the glow will never leave our bounds + invalidate(); + } else { + final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; + final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f; + com.android.systemui.SwipeHelper.invalidateGlobalRegion( + this, + new RectF(getLeft() - rx, + getTop() - ry, + getRight() + rx, + getBottom() + ry)); + + // also invalidate our immediate parent to help avoid situations where nearby glows + // interfere + ((View)getParent()).invalidate(); } - super.setPressed(pressed); } - private void setHotspot(float x, float y) { - if (mBackground != null) { - mBackground.setHotspot(x, y); + public void setPressed(boolean pressed) { + if (pressed != isPressed()) { + if (mPressedAnim != null && mPressedAnim.isRunning()) { + mPressedAnim.cancel(); + } + final AnimatorSet as = mPressedAnim = new AnimatorSet(); + final ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this, + "glowScale", GLOW_MAX_SCALE_FACTOR); + scaleAnimator.setInterpolator(mInterpolator); + if (pressed) { + mGlowScale = 0f; + if (mGlowAlpha < mQuiescentAlpha) + mGlowAlpha = mQuiescentAlpha; + setDrawingAlpha(1f); + as.playTogether( + ObjectAnimator.ofFloat(this, "glowAlpha", 1f), + scaleAnimator + ); + as.setDuration(500); + } else { + mAnimateToQuiescent.cancel(); + mAnimateToQuiescent = animateToQuiescent(); + as.playTogether( + ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, mGlowAlpha * .2f, 0f), + scaleAnimator, + mAnimateToQuiescent + ); + as.setDuration(500); + } + as.start(); } + super.setPressed(pressed); } public boolean onTouchEvent(MotionEvent ev) { @@ -209,7 +293,6 @@ public class KeyButtonView extends ImageView { removeCallbacks(mCheckLongPress); postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); } - setHotspot(ev.getX(), ev.getY()); break; case MotionEvent.ACTION_MOVE: x = (int)ev.getX(); @@ -218,7 +301,6 @@ public class KeyButtonView extends ImageView { && x < getWidth() + mTouchSlop && y >= -mTouchSlop && y < getHeight() + mTouchSlop); - setHotspot(ev.getX(), ev.getY()); break; case MotionEvent.ACTION_CANCEL: setPressed(false); @@ -272,6 +354,17 @@ public class KeyButtonView extends ImageView { InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); } + + /** + * Interpolator with a smooth log deceleration + */ + private static final class LogInterpolator implements TimeInterpolator { + @Override + public float getInterpolation(float input) { + return 1 - (float) Math.pow(400, -input * 1.4); + } + } + } |