From cd26af70540d8a88a61efafa0fbe63091c1f941a Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Wed, 11 Jan 2017 14:32:58 -0500 Subject: [PATCH] Move all time ticks to bg handlers, and post This will hopefully avoid blaming sysui for ANRs when the system is hosed. Test: Manual, build, push, wait for time to change Change-Id: I1661ac1a997ad8917b449dd175229d8b77f583c9 --- core/java/android/widget/DateTimeView.java | 65 ++++++++++++++++------ .../systemui/plugins/PluginInstanceManager.java | 5 -- .../com/android/systemui/qs/tiles/BatteryTile.java | 5 +- .../statusbar/KeyguardIndicationController.java | 12 ++-- .../systemui/statusbar/phone/PhoneStatusBar.java | 29 ++++++++-- .../android/systemui/statusbar/policy/Clock.java | 27 +++++---- .../systemui/statusbar/policy/DateView.java | 10 ++-- 7 files changed, 105 insertions(+), 48 deletions(-) diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index e172044a87d6..4db3607f95f9 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -390,6 +390,18 @@ public class DateTimeView extends TextView { } } + /** + * @hide + */ + public static void setReceiverHandler(Handler handler) { + ReceiverInfo ri = sReceiverInfo.get(); + if (ri == null) { + ri = new ReceiverInfo(); + sReceiverInfo.set(ri); + } + ri.setHandler(handler); + } + private static class ReceiverInfo { private final ArrayList mAttachedViews = new ArrayList(); private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -416,35 +428,46 @@ public class DateTimeView extends TextView { } }; + private Handler mHandler = new Handler(); + public void addView(DateTimeView v) { - final boolean register = mAttachedViews.isEmpty(); - mAttachedViews.add(v); - if (register) { - register(getApplicationContextIfAvailable(v.getContext())); + synchronized (mAttachedViews) { + final boolean register = mAttachedViews.isEmpty(); + mAttachedViews.add(v); + if (register) { + register(getApplicationContextIfAvailable(v.getContext())); + } } } public void removeView(DateTimeView v) { - mAttachedViews.remove(v); - if (mAttachedViews.isEmpty()) { - unregister(getApplicationContextIfAvailable(v.getContext())); + synchronized (mAttachedViews) { + mAttachedViews.remove(v); + if (mAttachedViews.isEmpty()) { + unregister(getApplicationContextIfAvailable(v.getContext())); + } } } void updateAll() { - final int count = mAttachedViews.size(); - for (int i = 0; i < count; i++) { - mAttachedViews.get(i).clearFormatAndUpdate(); + synchronized (mAttachedViews) { + final int count = mAttachedViews.size(); + for (int i = 0; i < count; i++) { + DateTimeView view = mAttachedViews.get(i); + view.post(() -> view.clearFormatAndUpdate()); + } } } long getSoonestUpdateTime() { long result = Long.MAX_VALUE; - final int count = mAttachedViews.size(); - for (int i = 0; i < count; i++) { - final long time = mAttachedViews.get(i).mUpdateTimeMillis; - if (time < result) { - result = time; + synchronized (mAttachedViews) { + final int count = mAttachedViews.size(); + for (int i = 0; i < count; i++) { + final long time = mAttachedViews.get(i).mUpdateTimeMillis; + if (time < result) { + result = time; + } } } return result; @@ -461,11 +484,21 @@ public class DateTimeView extends TextView { filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - context.registerReceiver(mReceiver, filter); + context.registerReceiver(mReceiver, filter, null, mHandler); } void unregister(Context context) { context.unregisterReceiver(mReceiver); } + + public void setHandler(Handler handler) { + mHandler = handler; + synchronized (mAttachedViews) { + if (!mAttachedViews.isEmpty()) { + unregister(mAttachedViews.get(0).getContext()); + register(mAttachedViews.get(0).getContext()); + } + } + } } } diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java index 7b8eae241929..47b97bdc29e7 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java @@ -374,11 +374,6 @@ public class PluginInstanceManager { } return getBaseContext().getSystemService(name); } - - @Override - public Context getApplicationContext() { - return this; - } } static class PluginInfo { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java index 87b00a7febbd..833375e91395 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java @@ -22,6 +22,7 @@ import android.content.IntentFilter; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; +import android.os.Handler; import android.service.quicksettings.Tile; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -44,6 +45,7 @@ import com.android.systemui.R; import com.android.systemui.plugins.qs.QS.DetailAdapter; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.external.TileColorPicker; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.policy.BatteryController; import java.text.NumberFormat; @@ -290,7 +292,8 @@ public class BatteryTile extends QSTile implements BatteryControll if (!mDetailShown) { mDetailShown = true; v.getContext().registerReceiver(mReceiver, - new IntentFilter(Intent.ACTION_TIME_TICK)); + new IntentFilter(Intent.ACTION_TIME_TICK), null, + PhoneStatusBar.getTimeTickHandler(v.getContext())); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 218c1bbae48c..f451aef2dc5f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -45,6 +45,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; import com.android.systemui.statusbar.phone.LockIcon; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; /** @@ -107,7 +108,8 @@ public class KeyguardIndicationController { KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitor); context.registerReceiverAsUser(mTickReceiver, UserHandle.SYSTEM, - new IntentFilter(Intent.ACTION_TIME_TICK), null, null); + new IntentFilter(Intent.ACTION_TIME_TICK), null, + PhoneStatusBar.getTimeTickHandler(mContext)); updateDisclosure(); } @@ -374,9 +376,11 @@ public class KeyguardIndicationController { BroadcastReceiver mTickReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (mVisible) { - updateIndication(); - } + mHandler.post(() -> { + if (mVisible) { + updateIndication(); + } + }); } }; 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 5bdfd25e6f73..bd5296cd0e88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -80,6 +80,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.Process; @@ -116,6 +117,7 @@ import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.animation.AccelerateInterpolator; import android.view.animation.Interpolator; +import android.widget.DateTimeView; import android.widget.ImageView; import android.widget.TextView; @@ -136,6 +138,7 @@ import com.android.systemui.EventLogTags; import com.android.systemui.Interpolators; import com.android.systemui.Prefs; import com.android.systemui.R; +import com.android.systemui.SystemUIApplication; import com.android.systemui.SystemUIFactory; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.classifier.FalsingManager; @@ -426,6 +429,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private int mNavigationIconHints = 0; private HandlerThread mHandlerThread; + private HandlerThread mTimeTickThread; + private Handler mTimeTickHandler; // ensure quick settings is disabled until the current user makes it through the setup wizard private boolean mUserSetup = false; @@ -689,6 +694,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScrimSrcModeEnabled = mContext.getResources().getBoolean( R.bool.config_status_bar_scrim_behind_use_src); + // Background thread for any controllers that need it. + mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); + mHandlerThread.start(); + mTimeTickThread = new HandlerThread("TimeTick"); + mTimeTickThread.start(); + mTimeTickHandler = new Handler(mTimeTickThread.getLooper()); + DateTimeView.setReceiverHandler(mTimeTickHandler); + putComponent(PhoneStatusBar.class, this); + super.start(); // calls createAndAddWindows() mMediaSessionManager @@ -721,7 +735,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback); mDozeServiceHost = new DozeServiceHost(); putComponent(DozeHost.class, mDozeServiceHost); - putComponent(PhoneStatusBar.class, this); setControllerUsers(); @@ -741,7 +754,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // ================================================================================ protected PhoneStatusBarView makeStatusBarView() { final Context context = mContext; - updateDisplaySize(); // populates mDisplayMetrics updateResources(); @@ -887,10 +899,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStatusBarView.setScrimController(mScrimController); mDozeScrimController = new DozeScrimController(mScrimController, context, mStackScroller); - // Background thread for any controllers that need it. - mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); - mHandlerThread.start(); - // Other icons mLocationController = new LocationControllerImpl(mContext, mHandlerThread.getLooper()); // will post a notification @@ -1034,6 +1042,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mStatusBarView; } + public Handler getTimeTickHandler() { + return mTimeTickHandler; + } + + public static Handler getTimeTickHandler(Context context) { + return ((SystemUIApplication) context.getApplicationContext()) + .getComponent(PhoneStatusBar.class).getTimeTickHandler(); + } + private void initEmergencyCryptkeeperText() { View emergencyViewStub = mStatusBarWindow.findViewById(R.id.emergency_cryptkeeper_text); if (mNetworkController.hasEmergencyCryptKeeperText()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index dd16147f7152..1dbc6647d65e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -33,14 +33,13 @@ import android.text.SpannableStringBuilder; import android.text.format.DateFormat; import android.text.style.CharacterStyle; import android.text.style.RelativeSizeSpan; -import android.util.ArraySet; import android.util.AttributeSet; import android.view.Display; -import android.view.View; import android.widget.TextView; import com.android.systemui.DemoMode; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; @@ -108,7 +107,7 @@ public class Clock extends TextView implements DemoMode, Tunable { filter.addAction(Intent.ACTION_USER_SWITCHED); getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, - null, getHandler()); + null, PhoneStatusBar.getTimeTickHandler(getContext())); TunerService.get(getContext()).addTunable(this, CLOCK_SECONDS, StatusBarIconController.ICON_BLACKLIST); } @@ -140,18 +139,22 @@ public class Clock extends TextView implements DemoMode, Tunable { String action = intent.getAction(); if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) { String tz = intent.getStringExtra("time-zone"); - mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz)); - if (mClockFormat != null) { - mClockFormat.setTimeZone(mCalendar.getTimeZone()); - } + getHandler().post(() -> { + mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz)); + if (mClockFormat != null) { + mClockFormat.setTimeZone(mCalendar.getTimeZone()); + } + }); } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { final Locale newLocale = getResources().getConfiguration().locale; - if (! newLocale.equals(mLocale)) { - mLocale = newLocale; - mClockFormatString = ""; // force refresh - } + getHandler().post(() -> { + if (!newLocale.equals(mLocale)) { + mLocale = newLocale; + mClockFormatString = ""; // force refresh + } + }); } - updateClock(); + getHandler().post(() -> updateClock()); } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java index a92422a66a22..5544c707485d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java @@ -23,12 +23,13 @@ import android.content.IntentFilter; import android.content.res.TypedArray; import android.icu.text.DateFormat; import android.icu.text.DisplayContext; +import android.os.Handler; import android.util.AttributeSet; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.PhoneStatusBar; -import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -52,9 +53,9 @@ public class DateView extends TextView { if (Intent.ACTION_LOCALE_CHANGED.equals(action) || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { // need to get a fresh date format - mDateFormat = null; + getHandler().post(() -> mDateFormat = null); } - updateClock(); + getHandler().post(() -> updateClock()); } } }; @@ -85,7 +86,8 @@ public class DateView extends TextView { filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); filter.addAction(Intent.ACTION_LOCALE_CHANGED); - getContext().registerReceiver(mIntentReceiver, filter, null, null); + getContext().registerReceiver(mIntentReceiver, filter, null, + PhoneStatusBar.getTimeTickHandler(getContext())); updateClock(); } -- 2.11.0