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
This commit is contained in:
Jason Monk
2017-01-11 14:32:58 -05:00
parent ed76b34c42
commit cd26af7054
7 changed files with 105 additions and 48 deletions

View File

@@ -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<DateTimeView> mAttachedViews = new ArrayList<DateTimeView>();
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());
}
}
}
}
}

View File

@@ -374,11 +374,6 @@ public class PluginInstanceManager<T extends Plugin> {
}
return getBaseContext().getSystemService(name);
}
@Override
public Context getApplicationContext() {
return this;
}
}
static class PluginInfo<T> {

View File

@@ -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<QSTile.State> 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()));
}
}

View File

@@ -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();
}
});
}
};

View File

@@ -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()) {

View File

@@ -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());
}
};

View File

@@ -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();
}