Replace inexact alarm setRepeasting with setExact alarm
Use exact alarm to fix entilement recheck delay problem while device asleep. Bug: 195370891 Test: atest TehteringTests Change-Id: I409e603bf2b990657551e1140b50f69640c328d8
This commit is contained in:
@@ -70,7 +70,8 @@ public class EntitlementManager {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
|
protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
|
||||||
private static final String ACTION_PROVISIONING_ALARM =
|
@VisibleForTesting
|
||||||
|
protected static final String ACTION_PROVISIONING_ALARM =
|
||||||
"com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM";
|
"com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM";
|
||||||
|
|
||||||
private final ComponentName mSilentProvisioningService;
|
private final ComponentName mSilentProvisioningService;
|
||||||
@@ -410,20 +411,23 @@ public class EntitlementManager {
|
|||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
PendingIntent createRecheckAlarmIntent() {
|
||||||
|
final Intent intent = new Intent(ACTION_PROVISIONING_ALARM);
|
||||||
|
return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);
|
||||||
|
}
|
||||||
|
|
||||||
// Not needed to check if this don't run on the handler thread because it's private.
|
// Not needed to check if this don't run on the handler thread because it's private.
|
||||||
private void scheduleProvisioningRechecks(final TetheringConfiguration config) {
|
private void scheduleProvisioningRecheck(final TetheringConfiguration config) {
|
||||||
if (mProvisioningRecheckAlarm == null) {
|
if (mProvisioningRecheckAlarm == null) {
|
||||||
final int period = config.provisioningCheckPeriod;
|
final int period = config.provisioningCheckPeriod;
|
||||||
if (period <= 0) return;
|
if (period <= 0) return;
|
||||||
|
|
||||||
Intent intent = new Intent(ACTION_PROVISIONING_ALARM);
|
mProvisioningRecheckAlarm = createRecheckAlarmIntent();
|
||||||
mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent,
|
|
||||||
PendingIntent.FLAG_IMMUTABLE);
|
|
||||||
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
|
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
|
||||||
Context.ALARM_SERVICE);
|
Context.ALARM_SERVICE);
|
||||||
long periodMs = period * MS_PER_HOUR;
|
long triggerAtMillis = SystemClock.elapsedRealtime() + (period * MS_PER_HOUR);
|
||||||
long firstAlarmTime = SystemClock.elapsedRealtime() + periodMs;
|
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtMillis,
|
||||||
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, firstAlarmTime, periodMs,
|
|
||||||
mProvisioningRecheckAlarm);
|
mProvisioningRecheckAlarm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -437,6 +441,11 @@ public class EntitlementManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void rescheduleProvisioningRecheck(final TetheringConfiguration config) {
|
||||||
|
cancelTetherProvisioningRechecks();
|
||||||
|
scheduleProvisioningRecheck(config);
|
||||||
|
}
|
||||||
|
|
||||||
private void evaluateCellularPermission(final TetheringConfiguration config) {
|
private void evaluateCellularPermission(final TetheringConfiguration config) {
|
||||||
final boolean permitted = isCellularUpstreamPermitted(config);
|
final boolean permitted = isCellularUpstreamPermitted(config);
|
||||||
|
|
||||||
@@ -452,7 +461,7 @@ public class EntitlementManager {
|
|||||||
// Only schedule periodic re-check when tether is provisioned
|
// Only schedule periodic re-check when tether is provisioned
|
||||||
// and the result is ok.
|
// and the result is ok.
|
||||||
if (permitted && mCurrentEntitlementResults.size() > 0) {
|
if (permitted && mCurrentEntitlementResults.size() > 0) {
|
||||||
scheduleProvisioningRechecks(config);
|
scheduleProvisioningRecheck(config);
|
||||||
} else {
|
} else {
|
||||||
cancelTetherProvisioningRechecks();
|
cancelTetherProvisioningRechecks();
|
||||||
}
|
}
|
||||||
@@ -493,6 +502,7 @@ public class EntitlementManager {
|
|||||||
if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) {
|
if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) {
|
||||||
mLog.log("Received provisioning alarm");
|
mLog.log("Received provisioning alarm");
|
||||||
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
|
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
|
||||||
|
rescheduleProvisioningRecheck(config);
|
||||||
reevaluateSimCardProvisioning(config);
|
reevaluateSimCardProvisioning(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,14 +43,18 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.anyBoolean;
|
import static org.mockito.Matchers.anyBoolean;
|
||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Matchers.anyLong;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.inOrder;
|
import static org.mockito.Mockito.inOrder;
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ModuleInfo;
|
import android.content.pm.ModuleInfo;
|
||||||
@@ -63,6 +67,7 @@ import android.os.Handler;
|
|||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -91,6 +96,7 @@ public final class EntitlementManagerTest {
|
|||||||
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
|
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
|
||||||
private static final String PROVISIONING_APP_RESPONSE = "app_response";
|
private static final String PROVISIONING_APP_RESPONSE = "app_response";
|
||||||
private static final String TEST_PACKAGE_NAME = "com.android.tethering.test";
|
private static final String TEST_PACKAGE_NAME = "com.android.tethering.test";
|
||||||
|
private static final int RECHECK_TIMER_HOURS = 24;
|
||||||
|
|
||||||
@Mock private CarrierConfigManager mCarrierConfigManager;
|
@Mock private CarrierConfigManager mCarrierConfigManager;
|
||||||
@Mock private Context mContext;
|
@Mock private Context mContext;
|
||||||
@@ -98,12 +104,14 @@ public final class EntitlementManagerTest {
|
|||||||
@Mock private SharedLog mLog;
|
@Mock private SharedLog mLog;
|
||||||
@Mock private PackageManager mPm;
|
@Mock private PackageManager mPm;
|
||||||
@Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener;
|
@Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener;
|
||||||
|
@Mock private AlarmManager mAlarmManager;
|
||||||
|
@Mock private PendingIntent mAlarmIntent;
|
||||||
|
|
||||||
// Like so many Android system APIs, these cannot be mocked because it is marked final.
|
// Like so many Android system APIs, these cannot be mocked because it is marked final.
|
||||||
// We have to use the real versions.
|
// We have to use the real versions.
|
||||||
private final PersistableBundle mCarrierConfig = new PersistableBundle();
|
private final PersistableBundle mCarrierConfig = new PersistableBundle();
|
||||||
private final TestLooper mLooper = new TestLooper();
|
private final TestLooper mLooper = new TestLooper();
|
||||||
private Context mMockContext;
|
private MockContext mMockContext;
|
||||||
private Runnable mPermissionChangeCallback;
|
private Runnable mPermissionChangeCallback;
|
||||||
|
|
||||||
private WrappedEntitlementManager mEnMgr;
|
private WrappedEntitlementManager mEnMgr;
|
||||||
@@ -119,6 +127,13 @@ public final class EntitlementManagerTest {
|
|||||||
public Resources getResources() {
|
public Resources getResources() {
|
||||||
return mResources;
|
return mResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getSystemService(String name) {
|
||||||
|
if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager;
|
||||||
|
|
||||||
|
return super.getSystemService(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WrappedEntitlementManager extends EntitlementManager {
|
public class WrappedEntitlementManager extends EntitlementManager {
|
||||||
@@ -184,6 +199,11 @@ public final class EntitlementManagerTest {
|
|||||||
assertEquals(config.activeDataSubId,
|
assertEquals(config.activeDataSubId,
|
||||||
intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
|
intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
PendingIntent createRecheckAlarmIntent() {
|
||||||
|
return mAlarmIntent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -245,6 +265,8 @@ public final class EntitlementManagerTest {
|
|||||||
.thenReturn(PROVISIONING_NO_UI_APP_NAME);
|
.thenReturn(PROVISIONING_NO_UI_APP_NAME);
|
||||||
when(mResources.getString(R.string.config_mobile_hotspot_provision_response)).thenReturn(
|
when(mResources.getString(R.string.config_mobile_hotspot_provision_response)).thenReturn(
|
||||||
PROVISIONING_APP_RESPONSE);
|
PROVISIONING_APP_RESPONSE);
|
||||||
|
when(mResources.getInteger(R.integer.config_mobile_hotspot_provision_check_period))
|
||||||
|
.thenReturn(RECHECK_TIMER_HOURS);
|
||||||
// Act like the CarrierConfigManager is present and ready unless told otherwise.
|
// Act like the CarrierConfigManager is present and ready unless told otherwise.
|
||||||
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
|
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
|
||||||
.thenReturn(mCarrierConfigManager);
|
.thenReturn(mCarrierConfigManager);
|
||||||
@@ -629,4 +651,31 @@ public final class EntitlementManagerTest {
|
|||||||
mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
|
mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
|
||||||
assertFalse(mEnMgr.isCellularUpstreamPermitted());
|
assertFalse(mEnMgr.isCellularUpstreamPermitted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendProvisioningRecheckAlarm() {
|
||||||
|
final Intent intent = new Intent(EntitlementManager.ACTION_PROVISIONING_ALARM);
|
||||||
|
mMockContext.sendBroadcastAsUser(intent, UserHandle.ALL);
|
||||||
|
mLooper.dispatchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScheduleProvisioningReCheck() throws Exception {
|
||||||
|
setupForRequiredProvisioning();
|
||||||
|
assertFalse(mEnMgr.isCellularUpstreamPermitted());
|
||||||
|
|
||||||
|
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
|
||||||
|
mEnMgr.notifyUpstream(true);
|
||||||
|
mLooper.dispatchAll();
|
||||||
|
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
|
||||||
|
mLooper.dispatchAll();
|
||||||
|
assertTrue(mEnMgr.isCellularUpstreamPermitted());
|
||||||
|
verify(mAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(),
|
||||||
|
eq(mAlarmIntent));
|
||||||
|
reset(mAlarmManager);
|
||||||
|
|
||||||
|
sendProvisioningRecheckAlarm();
|
||||||
|
verify(mAlarmManager).cancel(eq(mAlarmIntent));
|
||||||
|
verify(mAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(),
|
||||||
|
eq(mAlarmIntent));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user