Merge "Support entitlement check in DSDS"

This commit is contained in:
Mark Chien
2019-02-12 08:05:11 +00:00
committed by Android (Google) Code Review
5 changed files with 69 additions and 28 deletions

View File

@@ -443,7 +443,7 @@
android:exported="true" android:exported="true"
android:permission="android.permission.TETHER_PRIVILEGED" /> android:permission="android.permission.TETHER_PRIVILEGED" />
<activity android:name="TetherProvisioningActivity" <activity android:name="network.TetherProvisioningActivity"
android:exported="true" android:exported="true"
android:permission="android.permission.TETHER_PRIVILEGED" android:permission="android.permission.TETHER_PRIVILEGED"
android:excludeFromRecents="true" android:excludeFromRecents="true"

View File

@@ -71,6 +71,7 @@ import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile; import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.RawContacts;
import android.provider.Settings; import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
@@ -980,4 +981,13 @@ public final class Utils extends com.android.settingslib.Utils {
} }
return false; return false;
} }
/** Get {@link Resources} by subscription id if subscription id is valid. */
public static Resources getResourcesForSubId(Context context, int subId) {
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return SubscriptionManager.getResourcesForSubId(context, subId);
} else {
return context.getResources();
}
}
} }

View File

@@ -14,17 +14,21 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.settings; package com.android.settings.network;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.UserHandle; import android.os.UserHandle;
import android.telephony.SubscriptionManager;
import android.util.Log; import android.util.Log;
import com.android.settings.Utils;
/** /**
* Activity which acts as a proxy to the tether provisioning app for sanity checks and permission * Activity which acts as a proxy to the tether provisioning app for sanity checks and permission
* restrictions. Specifically, the provisioning apps require * restrictions. Specifically, the provisioning apps require
@@ -47,7 +51,9 @@ public class TetherProvisioningActivity extends Activity {
int tetherType = getIntent().getIntExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, int tetherType = getIntent().getIntExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE,
ConnectivityManager.TETHERING_INVALID); ConnectivityManager.TETHERING_INVALID);
String[] provisionApp = getResources().getStringArray( final int subId = SubscriptionManager.getDefaultDataSubscriptionId();
final Resources res = Utils.getResourcesForSubId(this, subId);
final String[] provisionApp = res.getStringArray(
com.android.internal.R.array.config_mobile_hotspot_provision_app); com.android.internal.R.array.config_mobile_hotspot_provision_app);
Intent intent = new Intent(Intent.ACTION_MAIN); Intent intent = new Intent(Intent.ACTION_MAIN);

View File

@@ -32,16 +32,20 @@ import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.IBinder; import android.os.IBinder;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.SystemClock; import android.os.SystemClock;
import android.telephony.SubscriptionManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.settings.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -65,7 +69,7 @@ public class TetherService extends Service {
private int mCurrentTypeIndex; private int mCurrentTypeIndex;
private boolean mInProvisionCheck; private boolean mInProvisionCheck;
private UsageStatsManagerWrapper mUsageManagerWrapper; private TetherServiceWrapper mWrapper;
private ArrayList<Integer> mCurrentTethers; private ArrayList<Integer> mCurrentTethers;
private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks; private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks;
private HotspotOffReceiver mHotspotReceiver; private HotspotOffReceiver mHotspotReceiver;
@@ -79,7 +83,7 @@ public class TetherService extends Service {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
if (DEBUG) Log.d(TAG, "Creating TetherService"); if (DEBUG) Log.d(TAG, "Creating TetherService");
String provisionResponse = getResources().getString( String provisionResponse = getResourceForDefaultDataSubId().getString(
com.android.internal.R.string.config_mobile_hotspot_provision_response); com.android.internal.R.string.config_mobile_hotspot_provision_response);
registerReceiver(mReceiver, new IntentFilter(provisionResponse), registerReceiver(mReceiver, new IntentFilter(provisionResponse),
android.Manifest.permission.CONNECTIVITY_INTERNAL, null); android.Manifest.permission.CONNECTIVITY_INTERNAL, null);
@@ -91,9 +95,6 @@ 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);
}
mHotspotReceiver = new HotspotOffReceiver(this); mHotspotReceiver = new HotspotOffReceiver(this);
} }
@@ -258,7 +259,7 @@ public class TetherService extends Service {
} }
private Intent getProvisionBroadcastIntent(int index) { private Intent getProvisionBroadcastIntent(int index) {
String provisionAction = getResources().getString( String provisionAction = getResourceForDefaultDataSubId().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);
Intent intent = new Intent(provisionAction); Intent intent = new Intent(provisionAction);
int type = mCurrentTethers.get(index); int type = mCurrentTethers.get(index);
@@ -282,7 +283,7 @@ public class TetherService extends Service {
for (ResolveInfo resolver : resolvers) { for (ResolveInfo resolver : resolvers) {
if (resolver.activityInfo.applicationInfo.isSystemApp()) { if (resolver.activityInfo.applicationInfo.isSystemApp()) {
String packageName = resolver.activityInfo.packageName; String packageName = resolver.activityInfo.packageName;
mUsageManagerWrapper.setAppInactive(packageName, false); getTetherServiceWrapper().setAppInactive(packageName, false);
} }
} }
} }
@@ -294,7 +295,7 @@ public class TetherService extends Service {
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0); PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
int period = getResources().getInteger( int period = getResourceForDefaultDataSubId().getInteger(
com.android.internal.R.integer.config_mobile_hotspot_provision_check_period); com.android.internal.R.integer.config_mobile_hotspot_provision_check_period);
long periodMs = period * MS_PER_HOUR; long periodMs = period * MS_PER_HOUR;
long firstTime = SystemClock.elapsedRealtime() + periodMs; long firstTime = SystemClock.elapsedRealtime() + periodMs;
@@ -347,7 +348,7 @@ public class TetherService extends Service {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.d(TAG, "Got provision result " + intent); if (DEBUG) Log.d(TAG, "Got provision result " + intent);
String provisionResponse = getResources().getString( String provisionResponse = getResourceForDefaultDataSubId().getString(
com.android.internal.R.string.config_mobile_hotspot_provision_response); com.android.internal.R.string.config_mobile_hotspot_provision_response);
if (provisionResponse.equals(intent.getAction())) { if (provisionResponse.equals(intent.getAction())) {
@@ -385,19 +386,27 @@ public class TetherService extends Service {
}; };
@VisibleForTesting @VisibleForTesting
void setUsageStatsManagerWrapper(UsageStatsManagerWrapper wrapper) { void setTetherServiceWrapper(TetherServiceWrapper wrapper) {
mUsageManagerWrapper = wrapper; mWrapper = wrapper;
}
private TetherServiceWrapper getTetherServiceWrapper() {
if (mWrapper == null) {
mWrapper = new TetherServiceWrapper(this);
}
return mWrapper;
} }
/** /**
* A static helper class used for tests. UsageStatsManager cannot be mocked out becasue * A static helper class used for tests. UsageStatsManager cannot be mocked out because
* it's marked final. This class can be mocked out instead. * it's marked final. Static method SubscriptionManager#getResourcesForSubId also cannot
* be mocked. This class can be mocked out instead.
*/ */
@VisibleForTesting @VisibleForTesting
public static class UsageStatsManagerWrapper { public static class TetherServiceWrapper {
private final UsageStatsManager mUsageStatsManager; private final UsageStatsManager mUsageStatsManager;
UsageStatsManagerWrapper(Context context) { TetherServiceWrapper(Context context) {
mUsageStatsManager = (UsageStatsManager) mUsageStatsManager = (UsageStatsManager)
context.getSystemService(Context.USAGE_STATS_SERVICE); context.getSystemService(Context.USAGE_STATS_SERVICE);
} }
@@ -405,5 +414,15 @@ public class TetherService extends Service {
void setAppInactive(String packageName, boolean isInactive) { void setAppInactive(String packageName, boolean isInactive) {
mUsageStatsManager.setAppInactive(packageName, isInactive); mUsageStatsManager.setAppInactive(packageName, isInactive);
} }
int getDefaultDataSubscriptionId() {
return SubscriptionManager.getDefaultDataSubscriptionId();
}
}
@VisibleForTesting
Resources getResourceForDefaultDataSubId() {
final int subId = getTetherServiceWrapper().getDefaultDataSubscriptionId();
return Utils.getResourcesForSubId(this, subId);
} }
} }

View File

@@ -27,6 +27,8 @@ import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
@@ -83,7 +85,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
private TetherService mService; private TetherService mService;
private MockResources mResources; private MockResources mResources;
private FakeUsageStatsManagerWrapper mUsageStatsManagerWrapper; private MockTetherServiceWrapper mWrapper;
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;
@@ -125,7 +127,7 @@ 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); mWrapper = new MockTetherServiceWrapper(mContext);
ResolveInfo systemAppResolveInfo = new ResolveInfo(); ResolveInfo systemAppResolveInfo = new ResolveInfo();
ActivityInfo systemActivityInfo = new ActivityInfo(); ActivityInfo systemActivityInfo = new ActivityInfo();
@@ -146,6 +148,8 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
resolvers.add(systemAppResolveInfo); resolvers.add(systemAppResolveInfo);
when(mPackageManager.queryBroadcastReceivers( when(mPackageManager.queryBroadcastReceivers(
any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers); any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers);
setupService();
getService().setTetherServiceWrapper(mWrapper);
} }
@Override @Override
@@ -171,16 +175,13 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
} }
public void testStartKeepsProvisionAppActive() { public void testStartKeepsProvisionAppActive() {
setupService();
getService().setUsageStatsManagerWrapper(mUsageStatsManagerWrapper);
runProvisioningForType(TETHERING_WIFI); runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI)); assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR)); assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
assertFalse(mUsageStatsManagerWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME)); assertFalse(mWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME));
// Non-system handler of the intent action should stay idle. // Non-system handler of the intent action should stay idle.
assertTrue(mUsageStatsManagerWrapper.isAppInactive(FAKE_PACKAGE_NAME)); assertTrue(mWrapper.isAppInactive(FAKE_PACKAGE_NAME));
} }
public void testScheduleRechecks() { public void testScheduleRechecks() {
@@ -419,11 +420,11 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
} }
} }
private static class FakeUsageStatsManagerWrapper private static class MockTetherServiceWrapper
extends TetherService.UsageStatsManagerWrapper { extends TetherService.TetherServiceWrapper {
private final Set<String> mActivePackages; private final Set<String> mActivePackages;
FakeUsageStatsManagerWrapper(Context context) { MockTetherServiceWrapper(Context context) {
super(context); super(context);
mActivePackages = new HashSet<>(); mActivePackages = new HashSet<>();
} }
@@ -440,5 +441,10 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
boolean isAppInactive(String packageName) { boolean isAppInactive(String packageName) {
return !mActivePackages.contains(packageName); return !mActivePackages.contains(packageName);
} }
@Override
int getDefaultDataSubscriptionId() {
return INVALID_SUBSCRIPTION_ID;
}
} }
} }