Reduce number of TIME_TICK broadcasts

SysUI was registering too many TIME_TICK events and
this led to some of them being dropped. Most common
symptom is clock being stuck.

Bug: 116488358
Test: atest KeyguardSliceProviderTest
Test: set calendar events, plug device into a charger
Change-Id: I234b983039fd9917249c7419e71825096f017e3f
This commit is contained in:
Lucas Dupin
2018-12-20 11:29:35 -08:00
parent 3ca78699fd
commit 7e171e28fa
3 changed files with 45 additions and 33 deletions

View File

@@ -41,6 +41,8 @@ import androidx.slice.builders.ListBuilder.RowBuilder;
import androidx.slice.builders.SliceAction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
@@ -49,6 +51,7 @@ import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
/**
@@ -100,21 +103,28 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_TIME_TICK.equals(action)
|| Intent.ACTION_DATE_CHANGED.equals(action)
|| Intent.ACTION_TIME_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)
|| Intent.ACTION_LOCALE_CHANGED.equals(action)) {
if (Intent.ACTION_LOCALE_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
// need to get a fresh date format
mHandler.post(KeyguardSliceProvider.this::cleanDateFormat);
}
if (Intent.ACTION_DATE_CHANGED.equals(action)) {
mHandler.post(KeyguardSliceProvider.this::updateClock);
} else if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
mHandler.post(KeyguardSliceProvider.this::cleanDateFormat);
}
}
};
@VisibleForTesting
final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
public void onTimeChanged() {
mHandler.post(KeyguardSliceProvider.this::updateClock);
}
@Override
public void onTimeZoneChanged(TimeZone timeZone) {
mHandler.post(KeyguardSliceProvider.this::cleanDateFormat);
}
};
public KeyguardSliceProvider() {
this(new Handler());
}
@@ -250,11 +260,10 @@ public class KeyguardSliceProvider extends SliceProvider implements
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
getContext().registerReceiver(mIntentReceiver, filter, null /* permission*/,
null /* scheduler */);
getKeyguardUpdateMonitor().registerCallback(mKeyguardUpdateMonitorCallback);
mRegistered = true;
}
@@ -300,4 +309,9 @@ public class KeyguardSliceProvider extends SliceProvider implements
}
updateNextAlarm();
}
@VisibleForTesting
protected KeyguardUpdateMonitor getKeyguardUpdateMonitor() {
return KeyguardUpdateMonitor.getInstance(getContext());
}
}

View File

@@ -19,10 +19,7 @@ package com.android.systemui.statusbar;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Color;
@@ -35,7 +32,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.text.format.Formatter;
@@ -152,10 +148,7 @@ public class KeyguardIndicationController implements StateListener {
private void registerCallbacks(KeyguardUpdateMonitor monitor) {
monitor.registerCallback(getKeyguardCallback());
mContext.registerReceiverAsUser(mTickReceiver, UserHandle.SYSTEM,
new IntentFilter(Intent.ACTION_TIME_TICK), null,
Dependency.get(Dependency.TIME_TICK_HANDLER));
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mTickReceiver);
Dependency.get(StatusBarStateController.class).addCallback(this);
}
@@ -166,7 +159,7 @@ public class KeyguardIndicationController implements StateListener {
* //TODO: This can probably be converted to a fragment and not have to be manually recreated
*/
public void destroy() {
mContext.unregisterReceiver(mTickReceiver);
KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mTickReceiver);
Dependency.get(StatusBarStateController.class).removeCallback(this);
}
@@ -477,16 +470,15 @@ public class KeyguardIndicationController implements StateListener {
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
}
private final BroadcastReceiver mTickReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mHandler.post(() -> {
if (mVisible) {
updateIndication(false);
private final KeyguardUpdateMonitorCallback mTickReceiver =
new KeyguardUpdateMonitorCallback() {
@Override
public void onTimeChanged() {
if (mVisible) {
updateIndication(false /* animate */);
}
}
});
}
};
};
private final Handler mHandler = new Handler() {
@Override

View File

@@ -19,13 +19,13 @@ package com.android.systemui.keyguard;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.support.test.filters.SmallTest;
@@ -40,6 +40,7 @@ import androidx.slice.SliceSpecs;
import androidx.slice.builders.ListBuilder;
import androidx.slice.core.SliceQuery;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import org.junit.Assert;
@@ -91,7 +92,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
@Test
public void cleansDateFormat() {
mProvider.mIntentReceiver.onReceive(getContext(), new Intent(Intent.ACTION_TIMEZONE_CHANGED));
mProvider.mKeyguardUpdateMonitorCallback.onTimeZoneChanged(null);
TestableLooper.get(this).processAllMessages();
Assert.assertEquals("Date format should have been cleaned.", 1 /* expected */,
mProvider.mCleanDateFormatInvokations);
@@ -99,7 +100,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
@Test
public void updatesClock() {
mProvider.mIntentReceiver.onReceive(getContext(), new Intent(Intent.ACTION_TIME_TICK));
mProvider.mKeyguardUpdateMonitorCallback.onTimeChanged();
TestableLooper.get(this).processAllMessages();
verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
}
@@ -170,6 +171,11 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
mCleanDateFormatInvokations++;
}
@Override
public KeyguardUpdateMonitor getKeyguardUpdateMonitor() {
return mock(KeyguardUpdateMonitor.class);
}
@Override
protected String getFormattedDate() {
return super.getFormattedDate() + mCounter++;