Loading src/com/android/settings/TetherService.java +63 −8 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.AlarmManager; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.PendingIntent; import android.app.Service; import android.app.Service; import android.app.usage.UsageStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile; Loading @@ -29,6 +30,8 @@ import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.ConnectivityManager; import android.net.ConnectivityManager; import android.os.IBinder; import android.os.IBinder; import android.os.ResultReceiver; import android.os.ResultReceiver; Loading Loading @@ -63,6 +66,7 @@ public class TetherService extends Service { private int mCurrentTypeIndex; private int mCurrentTypeIndex; private boolean mInProvisionCheck; private boolean mInProvisionCheck; private UsageStatsManagerWrapper mUsageManagerWrapper; private ArrayList<Integer> mCurrentTethers; private ArrayList<Integer> mCurrentTethers; private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks; private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks; Loading @@ -87,6 +91,9 @@ public class TetherService extends Service { mPendingCallbacks.put(ConnectivityManager.TETHERING_USB, new ArrayList<ResultReceiver>()); mPendingCallbacks.put(ConnectivityManager.TETHERING_USB, new ArrayList<ResultReceiver>()); mPendingCallbacks.put( mPendingCallbacks.put( ConnectivityManager.TETHERING_BLUETOOTH, new ArrayList<ResultReceiver>()); ConnectivityManager.TETHERING_BLUETOOTH, new ArrayList<ResultReceiver>()); if (mUsageManagerWrapper == null) { mUsageManagerWrapper = new UsageStatsManagerWrapper(this); } } } @Override @Override Loading Loading @@ -228,17 +235,43 @@ public class TetherService extends Service { private void startProvisioning(int index) { private void startProvisioning(int index) { if (index < mCurrentTethers.size()) { if (index < mCurrentTethers.size()) { Intent intent = getProvisionBroadcastIntent(index); setEntitlementAppActive(index); if (DEBUG) Log.d(TAG, "Sending provisioning broadcast: " + intent.getAction() + " type: " + mCurrentTethers.get(index)); sendBroadcast(intent); mInProvisionCheck = true; } } private Intent getProvisionBroadcastIntent(int index) { String provisionAction = getResources().getString( String provisionAction = getResources().getString( com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui); com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui); if (DEBUG) Log.d(TAG, "Sending provisioning broadcast: " + provisionAction + " type: " + mCurrentTethers.get(index)); Intent intent = new Intent(provisionAction); Intent intent = new Intent(provisionAction); int type = mCurrentTethers.get(index); int type = mCurrentTethers.get(index); intent.putExtra(TETHER_CHOICE, type); intent.putExtra(TETHER_CHOICE, type); intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); sendBroadcast(intent); return intent; mInProvisionCheck = true; } private void setEntitlementAppActive(int index) { final PackageManager packageManager = getPackageManager(); Intent intent = getProvisionBroadcastIntent(index); List<ResolveInfo> resolvers = packageManager.queryBroadcastReceivers(intent, PackageManager.MATCH_ALL); if (resolvers.isEmpty()) { Log.e(TAG, "No found BroadcastReceivers for provision intent."); return; } for (ResolveInfo resolver : resolvers) { if (resolver.activityInfo.applicationInfo.isSystemApp()) { String packageName = resolver.activityInfo.packageName; mUsageManagerWrapper.setAppInactive(packageName, false); } } } } } Loading Loading @@ -335,4 +368,26 @@ public class TetherService extends Service { } } }; }; @VisibleForTesting void setUsageStatsManagerWrapper(UsageStatsManagerWrapper wrapper) { mUsageManagerWrapper = wrapper; } /** * A static helper class used for tests. UsageStatsManager cannot be mocked out becasue * it's marked final. This class can be mocked out instead. */ @VisibleForTesting public static class UsageStatsManagerWrapper { private final UsageStatsManager mUsageStatsManager; UsageStatsManagerWrapper(Context context) { mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); } void setAppInactive(String packageName, boolean isInactive) { mUsageStatsManager.setAppInactive(packageName, isInactive); } } } } tests/unit/src/com/android/settings/TetherServiceTest.java +88 −0 Original line number Original line Diff line number Diff line Loading @@ -35,11 +35,16 @@ import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; import android.app.Activity; import android.app.Activity; import android.app.AlarmManager; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.PendingIntent; import android.app.usage.UsageStatsManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.ContextWrapper; import android.content.ContextWrapper; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.content.pm.PackageManager; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor; import android.content.res.Resources; import android.content.res.Resources; Loading @@ -61,10 +66,16 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations; import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class TetherServiceTest extends ServiceTestCase<TetherService> { public class TetherServiceTest extends ServiceTestCase<TetherService> { private static final String TAG = "TetherServiceTest"; private static final String TAG = "TetherServiceTest"; private static final String FAKE_PACKAGE_NAME = "com.some.package.name"; private static final String ENTITLEMENT_PACKAGE_NAME = "com.some.entitlement.name"; private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction"; private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction"; private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction"; private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction"; private static final int BOGUS_RECEIVER_RESULT = -5; private static final int BOGUS_RECEIVER_RESULT = -5; Loading @@ -75,6 +86,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { private TetherService mService; private TetherService mService; private MockResources mResources; private MockResources mResources; private FakeUsageStatsManagerWrapper mUsageStatsManagerWrapper; int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT; int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT; private int mLastTetherRequestType = TETHERING_INVALID; private int mLastTetherRequestType = TETHERING_INVALID; private int mProvisionResponse = BOGUS_RECEIVER_RESULT; private int mProvisionResponse = BOGUS_RECEIVER_RESULT; Loading @@ -83,6 +95,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { @Mock private AlarmManager mAlarmManager; @Mock private AlarmManager mAlarmManager; @Mock private ConnectivityManager mConnectivityManager; @Mock private ConnectivityManager mConnectivityManager; @Mock private PackageManager mPackageManager; @Mock private WifiManager mWifiManager; @Mock private WifiManager mWifiManager; @Mock private SharedPreferences mPrefs; @Mock private SharedPreferences mPrefs; @Mock private Editor mPrefEditor; @Mock private Editor mPrefEditor; Loading Loading @@ -115,6 +128,27 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { when(mPrefs.edit()).thenReturn(mPrefEditor); when(mPrefs.edit()).thenReturn(mPrefEditor); when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn( when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn( mPrefEditor); mPrefEditor); mUsageStatsManagerWrapper = new FakeUsageStatsManagerWrapper(mContext); ResolveInfo systemAppResolveInfo = new ResolveInfo(); ActivityInfo systemActivityInfo = new ActivityInfo(); systemActivityInfo.packageName = ENTITLEMENT_PACKAGE_NAME; ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; systemActivityInfo.applicationInfo = systemAppInfo; systemAppResolveInfo.activityInfo = systemActivityInfo; ResolveInfo nonSystemResolveInfo = new ResolveInfo(); ActivityInfo nonSystemActivityInfo = new ActivityInfo(); nonSystemActivityInfo.packageName = FAKE_PACKAGE_NAME; nonSystemActivityInfo.applicationInfo = new ApplicationInfo(); nonSystemResolveInfo.activityInfo = nonSystemActivityInfo; List<ResolveInfo> resolvers = new ArrayList(); resolvers.add(nonSystemResolveInfo); resolvers.add(systemAppResolveInfo); when(mPackageManager.queryBroadcastReceivers( any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers); } } @Override @Override Loading @@ -139,6 +173,19 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); } } public void testStartKeepsProvisionAppActive() { setupService(); getService().setUsageStatsManagerWrapper(mUsageStatsManagerWrapper); runProvisioningForType(TETHERING_WIFI); assertTrue(waitForProvisionRequest(TETHERING_WIFI)); assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); assertFalse(mUsageStatsManagerWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME)); // Non-system handler of the intent action should stay idle. assertTrue(mUsageStatsManagerWrapper.isAppInactive(FAKE_PACKAGE_NAME)); } public void testScheduleRechecks() { public void testScheduleRechecks() { Intent intent = new Intent(); Intent intent = new Intent(); intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI); intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI); Loading Loading @@ -229,6 +276,19 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { startService(intent); startService(intent); } } private boolean waitForAppInactive(UsageStatsManager usageStatsManager, String packageName) { long startTime = SystemClock.uptimeMillis(); while (true) { if (usageStatsManager.isAppInactive(packageName)) { return true; } if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) { return false; } SystemClock.sleep(SHORT_TIMEOUT); } } private boolean waitForProvisionRequest(int expectedType) { private boolean waitForProvisionRequest(int expectedType) { long startTime = SystemClock.uptimeMillis(); long startTime = SystemClock.uptimeMillis(); while (true) { while (true) { Loading Loading @@ -307,6 +367,11 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { return super.getSharedPreferences(name, mode); return super.getSharedPreferences(name, mode); } } @Override public PackageManager getPackageManager() { return mPackageManager; } @Override @Override public Object getSystemService(String name) { public Object getSystemService(String name) { if (ALARM_SERVICE.equals(name)) { if (ALARM_SERVICE.equals(name)) { Loading Loading @@ -355,4 +420,27 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { responseIntent, android.Manifest.permission.CONNECTIVITY_INTERNAL); responseIntent, android.Manifest.permission.CONNECTIVITY_INTERNAL); } } } } private static class FakeUsageStatsManagerWrapper extends TetherService.UsageStatsManagerWrapper { private final Set<String> mActivePackages; FakeUsageStatsManagerWrapper(Context context) { super(context); mActivePackages = new HashSet<>(); } @Override void setAppInactive(String packageName, boolean isInactive) { if (!isInactive) { mActivePackages.add(packageName); } else { mActivePackages.remove(packageName); } } boolean isAppInactive(String packageName) { return !mActivePackages.contains(packageName); } } } } Loading
src/com/android/settings/TetherService.java +63 −8 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.AlarmManager; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.PendingIntent; import android.app.Service; import android.app.Service; import android.app.usage.UsageStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile; Loading @@ -29,6 +30,8 @@ import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.ConnectivityManager; import android.net.ConnectivityManager; import android.os.IBinder; import android.os.IBinder; import android.os.ResultReceiver; import android.os.ResultReceiver; Loading Loading @@ -63,6 +66,7 @@ public class TetherService extends Service { private int mCurrentTypeIndex; private int mCurrentTypeIndex; private boolean mInProvisionCheck; private boolean mInProvisionCheck; private UsageStatsManagerWrapper mUsageManagerWrapper; private ArrayList<Integer> mCurrentTethers; private ArrayList<Integer> mCurrentTethers; private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks; private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks; Loading @@ -87,6 +91,9 @@ public class TetherService extends Service { mPendingCallbacks.put(ConnectivityManager.TETHERING_USB, new ArrayList<ResultReceiver>()); mPendingCallbacks.put(ConnectivityManager.TETHERING_USB, new ArrayList<ResultReceiver>()); mPendingCallbacks.put( mPendingCallbacks.put( ConnectivityManager.TETHERING_BLUETOOTH, new ArrayList<ResultReceiver>()); ConnectivityManager.TETHERING_BLUETOOTH, new ArrayList<ResultReceiver>()); if (mUsageManagerWrapper == null) { mUsageManagerWrapper = new UsageStatsManagerWrapper(this); } } } @Override @Override Loading Loading @@ -228,17 +235,43 @@ public class TetherService extends Service { private void startProvisioning(int index) { private void startProvisioning(int index) { if (index < mCurrentTethers.size()) { if (index < mCurrentTethers.size()) { Intent intent = getProvisionBroadcastIntent(index); setEntitlementAppActive(index); if (DEBUG) Log.d(TAG, "Sending provisioning broadcast: " + intent.getAction() + " type: " + mCurrentTethers.get(index)); sendBroadcast(intent); mInProvisionCheck = true; } } private Intent getProvisionBroadcastIntent(int index) { String provisionAction = getResources().getString( String provisionAction = getResources().getString( com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui); com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui); if (DEBUG) Log.d(TAG, "Sending provisioning broadcast: " + provisionAction + " type: " + mCurrentTethers.get(index)); Intent intent = new Intent(provisionAction); Intent intent = new Intent(provisionAction); int type = mCurrentTethers.get(index); int type = mCurrentTethers.get(index); intent.putExtra(TETHER_CHOICE, type); intent.putExtra(TETHER_CHOICE, type); intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); sendBroadcast(intent); return intent; mInProvisionCheck = true; } private void setEntitlementAppActive(int index) { final PackageManager packageManager = getPackageManager(); Intent intent = getProvisionBroadcastIntent(index); List<ResolveInfo> resolvers = packageManager.queryBroadcastReceivers(intent, PackageManager.MATCH_ALL); if (resolvers.isEmpty()) { Log.e(TAG, "No found BroadcastReceivers for provision intent."); return; } for (ResolveInfo resolver : resolvers) { if (resolver.activityInfo.applicationInfo.isSystemApp()) { String packageName = resolver.activityInfo.packageName; mUsageManagerWrapper.setAppInactive(packageName, false); } } } } } Loading Loading @@ -335,4 +368,26 @@ public class TetherService extends Service { } } }; }; @VisibleForTesting void setUsageStatsManagerWrapper(UsageStatsManagerWrapper wrapper) { mUsageManagerWrapper = wrapper; } /** * A static helper class used for tests. UsageStatsManager cannot be mocked out becasue * it's marked final. This class can be mocked out instead. */ @VisibleForTesting public static class UsageStatsManagerWrapper { private final UsageStatsManager mUsageStatsManager; UsageStatsManagerWrapper(Context context) { mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); } void setAppInactive(String packageName, boolean isInactive) { mUsageStatsManager.setAppInactive(packageName, isInactive); } } } }
tests/unit/src/com/android/settings/TetherServiceTest.java +88 −0 Original line number Original line Diff line number Diff line Loading @@ -35,11 +35,16 @@ import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; import android.app.Activity; import android.app.Activity; import android.app.AlarmManager; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.PendingIntent; import android.app.usage.UsageStatsManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.ContextWrapper; import android.content.ContextWrapper; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.content.pm.PackageManager; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor; import android.content.res.Resources; import android.content.res.Resources; Loading @@ -61,10 +66,16 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations; import java.lang.ref.WeakReference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class TetherServiceTest extends ServiceTestCase<TetherService> { public class TetherServiceTest extends ServiceTestCase<TetherService> { private static final String TAG = "TetherServiceTest"; private static final String TAG = "TetherServiceTest"; private static final String FAKE_PACKAGE_NAME = "com.some.package.name"; private static final String ENTITLEMENT_PACKAGE_NAME = "com.some.entitlement.name"; private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction"; private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction"; private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction"; private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction"; private static final int BOGUS_RECEIVER_RESULT = -5; private static final int BOGUS_RECEIVER_RESULT = -5; Loading @@ -75,6 +86,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { private TetherService mService; private TetherService mService; private MockResources mResources; private MockResources mResources; private FakeUsageStatsManagerWrapper mUsageStatsManagerWrapper; int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT; int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT; private int mLastTetherRequestType = TETHERING_INVALID; private int mLastTetherRequestType = TETHERING_INVALID; private int mProvisionResponse = BOGUS_RECEIVER_RESULT; private int mProvisionResponse = BOGUS_RECEIVER_RESULT; Loading @@ -83,6 +95,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { @Mock private AlarmManager mAlarmManager; @Mock private AlarmManager mAlarmManager; @Mock private ConnectivityManager mConnectivityManager; @Mock private ConnectivityManager mConnectivityManager; @Mock private PackageManager mPackageManager; @Mock private WifiManager mWifiManager; @Mock private WifiManager mWifiManager; @Mock private SharedPreferences mPrefs; @Mock private SharedPreferences mPrefs; @Mock private Editor mPrefEditor; @Mock private Editor mPrefEditor; Loading Loading @@ -115,6 +128,27 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { when(mPrefs.edit()).thenReturn(mPrefEditor); when(mPrefs.edit()).thenReturn(mPrefEditor); when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn( when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn( mPrefEditor); mPrefEditor); mUsageStatsManagerWrapper = new FakeUsageStatsManagerWrapper(mContext); ResolveInfo systemAppResolveInfo = new ResolveInfo(); ActivityInfo systemActivityInfo = new ActivityInfo(); systemActivityInfo.packageName = ENTITLEMENT_PACKAGE_NAME; ApplicationInfo systemAppInfo = new ApplicationInfo(); systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; systemActivityInfo.applicationInfo = systemAppInfo; systemAppResolveInfo.activityInfo = systemActivityInfo; ResolveInfo nonSystemResolveInfo = new ResolveInfo(); ActivityInfo nonSystemActivityInfo = new ActivityInfo(); nonSystemActivityInfo.packageName = FAKE_PACKAGE_NAME; nonSystemActivityInfo.applicationInfo = new ApplicationInfo(); nonSystemResolveInfo.activityInfo = nonSystemActivityInfo; List<ResolveInfo> resolvers = new ArrayList(); resolvers.add(nonSystemResolveInfo); resolvers.add(systemAppResolveInfo); when(mPackageManager.queryBroadcastReceivers( any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers); } } @Override @Override Loading @@ -139,6 +173,19 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); } } public void testStartKeepsProvisionAppActive() { setupService(); getService().setUsageStatsManagerWrapper(mUsageStatsManagerWrapper); runProvisioningForType(TETHERING_WIFI); assertTrue(waitForProvisionRequest(TETHERING_WIFI)); assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); assertFalse(mUsageStatsManagerWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME)); // Non-system handler of the intent action should stay idle. assertTrue(mUsageStatsManagerWrapper.isAppInactive(FAKE_PACKAGE_NAME)); } public void testScheduleRechecks() { public void testScheduleRechecks() { Intent intent = new Intent(); Intent intent = new Intent(); intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI); intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI); Loading Loading @@ -229,6 +276,19 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { startService(intent); startService(intent); } } private boolean waitForAppInactive(UsageStatsManager usageStatsManager, String packageName) { long startTime = SystemClock.uptimeMillis(); while (true) { if (usageStatsManager.isAppInactive(packageName)) { return true; } if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) { return false; } SystemClock.sleep(SHORT_TIMEOUT); } } private boolean waitForProvisionRequest(int expectedType) { private boolean waitForProvisionRequest(int expectedType) { long startTime = SystemClock.uptimeMillis(); long startTime = SystemClock.uptimeMillis(); while (true) { while (true) { Loading Loading @@ -307,6 +367,11 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { return super.getSharedPreferences(name, mode); return super.getSharedPreferences(name, mode); } } @Override public PackageManager getPackageManager() { return mPackageManager; } @Override @Override public Object getSystemService(String name) { public Object getSystemService(String name) { if (ALARM_SERVICE.equals(name)) { if (ALARM_SERVICE.equals(name)) { Loading Loading @@ -355,4 +420,27 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> { responseIntent, android.Manifest.permission.CONNECTIVITY_INTERNAL); responseIntent, android.Manifest.permission.CONNECTIVITY_INTERNAL); } } } } private static class FakeUsageStatsManagerWrapper extends TetherService.UsageStatsManagerWrapper { private final Set<String> mActivePackages; FakeUsageStatsManagerWrapper(Context context) { super(context); mActivePackages = new HashSet<>(); } @Override void setAppInactive(String packageName, boolean isInactive) { if (!isInactive) { mActivePackages.add(packageName); } else { mActivePackages.remove(packageName); } } boolean isAppInactive(String packageName) { return !mActivePackages.contains(packageName); } } } }