diff options
author | John Spurlock <jspurlock@google.com> | 2013-10-30 19:40:48 -0400 |
---|---|---|
committer | John Spurlock <jspurlock@google.com> | 2013-10-31 10:49:50 -0400 |
commit | 385a63d56a1f5afdf064539d033da999b748289a (patch) | |
tree | 80f343a34012745968f97d21ea3a055241e35a29 /packages/Keyguard | |
parent | a223d1933ba69fbf454cf17e93ab62bd13fa9293 (diff) | |
download | frameworks_base-385a63d56a1f5afdf064539d033da999b748289a.zip frameworks_base-385a63d56a1f5afdf064539d033da999b748289a.tar.gz frameworks_base-385a63d56a1f5afdf064539d033da999b748289a.tar.bz2 |
Move coalescing to callback, optimize KeyguardStatusView.
Move the recent keyguard hidden coalescing down to the callback
level. The lifetime of each callback can be short, make sure
they see visibility changes at least once for each change local
to their lifetime.
KeyguardStatusView.refresh() is called multiple times, and instances
are recreated often. This results in expensive computations
filling the sysui/keyguard ui queue, adding to overall sluggishness.
Traceview points to DateFormat.getBestDateTimePattern as the
main culprit.
As of this change, refresh() will only call the expensive date pattern
computations when absolutely necessary, resulting in better
performance turning the screen off/on.
Bug:11221659
Bug:11447043
Change-Id: I3d4105af7db608803b82d8ef0ff141e42c154257
Diffstat (limited to 'packages/Keyguard')
4 files changed, 54 insertions, 26 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java index 8ccd6fe..36b2446 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java @@ -68,8 +68,6 @@ public class KeyguardService extends Service { } private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() { - private boolean mSetHiddenCalled; - private boolean mIsHidden; public boolean isShowing() { return mKeyguardViewMediator.isShowing(); } @@ -91,10 +89,7 @@ public class KeyguardService extends Service { } public void setHidden(boolean isHidden) { checkPermission(); - if (mSetHiddenCalled && mIsHidden == isHidden) return; mKeyguardViewMediator.setHidden(isHidden); - mSetHiddenCalled = true; - mIsHidden = isHidden; } public void dismiss() { mKeyguardViewMediator.dismiss(); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java index d933275..0bfee38 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java @@ -98,26 +98,13 @@ public class KeyguardStatusView extends GridLayout { } protected void refresh() { - Resources res = mContext.getResources(); - Locale locale = Locale.getDefault(); - final String dateFormat = DateFormat.getBestDateTimePattern(locale, - res.getString(R.string.abbrev_wday_month_day_no_year)); - - mDateView.setFormat24Hour(dateFormat); - mDateView.setFormat12Hour(dateFormat); - - // 12-hour clock. - // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton - // format. The following code removes the AM/PM indicator if we didn't want it. - final String clock12skel = res.getString(R.string.clock_12hr_format); - String clock12hr = DateFormat.getBestDateTimePattern(locale, clock12skel); - clock12hr = clock12skel.contains("a") ? clock12hr : clock12hr.replaceAll("a", "").trim(); - mClockView.setFormat12Hour(clock12hr); - - // 24-hour clock - final String clock24skel = res.getString(R.string.clock_24hr_format); - final String clock24hr = DateFormat.getBestDateTimePattern(locale, clock24skel); - mClockView.setFormat24Hour(clock24hr); + Patterns.update(mContext); + + mDateView.setFormat24Hour(Patterns.dateView); + mDateView.setFormat12Hour(Patterns.dateView); + + mClockView.setFormat12Hour(Patterns.clockView12); + mClockView.setFormat24Hour(Patterns.clockView24); refreshAlarmStatus(); } @@ -149,4 +136,35 @@ public class KeyguardStatusView extends GridLayout { return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET; } + // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often. + // This is an optimization to ensure we only recompute the patterns when the inputs change. + private static final class Patterns { + static String dateView; + static String clockView12; + static String clockView24; + static String cacheKey; + + static void update(Context context) { + final Locale locale = Locale.getDefault(); + final Resources res = context.getResources(); + final String dateViewSkel = res.getString(R.string.abbrev_wday_month_day_no_year); + final String clockView12Skel = res.getString(R.string.clock_12hr_format); + final String clockView24Skel = res.getString(R.string.clock_24hr_format); + final String key = locale.toString() + dateViewSkel + clockView12Skel + clockView24Skel; + if (key.equals(cacheKey)) return; + + dateView = DateFormat.getBestDateTimePattern(locale, dateViewSkel); + + clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel); + // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton + // format. The following code removes the AM/PM indicator if we didn't want it. + if (!clockView12Skel.contains("a")) { + clockView12 = clockView12.replaceAll("a", "").trim(); + } + + clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel); + + cacheKey = key; + } + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 520cea3..a849316 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -815,7 +815,7 @@ public class KeyguardUpdateMonitor { for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onKeyguardVisibilityChanged(isShowing); + cb.onKeyguardVisibilityChangedRaw(isShowing); } } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 76f9637..c08880d 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -19,6 +19,7 @@ import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.graphics.Bitmap; import android.media.AudioManager; +import android.os.SystemClock; import android.view.WindowManagerPolicy; import com.android.internal.telephony.IccCardConstants; @@ -27,6 +28,11 @@ import com.android.internal.telephony.IccCardConstants; * Callback for general information relevant to lock screen. */ class KeyguardUpdateMonitorCallback { + + private static final long VISIBILITY_CHANGED_COLLAPSE_MS = 1000; + private long mVisibilityChangedCalled; + private boolean mShowing; + /** * Called when the battery status changes, e.g. when plugged in or unplugged, charge * level, etc. changes. @@ -70,6 +76,15 @@ class KeyguardUpdateMonitorCallback { */ void onKeyguardVisibilityChanged(boolean showing) { } + void onKeyguardVisibilityChangedRaw(boolean showing) { + final long now = SystemClock.elapsedRealtime(); + if (showing == mShowing + && (now - mVisibilityChangedCalled) < VISIBILITY_CHANGED_COLLAPSE_MS) return; + onKeyguardVisibilityChanged(showing); + mVisibilityChangedCalled = now; + mShowing = showing; + } + /** * Called when visibility of lockscreen clock changes, such as when * obscured by a widget. |