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:
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,11 +374,6 @@ public class PluginInstanceManager<T extends Plugin> {
|
||||
}
|
||||
return getBaseContext().getSystemService(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getApplicationContext() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
static class PluginInfo<T> {
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user