Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c992d0f4 authored by markchien's avatar markchien
Browse files

Support entitlement check in DSDS

Get resource from preferred SIM's subId.

Bug: 122108346
Bug: 120069528
Test: atest TetherServiceTest
Change-Id: Ia4279a418dfa6cd14942b7f4d2a313156066381b
Merged-in: Ia4279a418dfa6cd14942b7f4d2a313156066381b
parent b139a4c1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -436,7 +436,7 @@
            android:exported="true"
            android:permission="android.permission.TETHER_PRIVILEGED" />

        <activity android:name="TetherProvisioningActivity"
        <activity android:name="network.TetherProvisioningActivity"
            android:exported="true"
            android:permission="android.permission.TETHER_PRIVILEGED"
            android:excludeFromRecents="true"
+10 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.provider.Settings;
import androidx.annotation.StringRes;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.Spannable;
import android.text.SpannableString;
@@ -966,4 +967,13 @@ public final class Utils extends com.android.settingslib.Utils {
            return packageManager.getDefaultActivityIcon();
        }
    }

    /** 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();
        }
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -14,17 +14,21 @@
 * limitations under the License.
 */

package com.android.settings;
package com.android.settings.network;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.telephony.SubscriptionManager;
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
 * restrictions. Specifically, the provisioning apps require
@@ -47,7 +51,9 @@ public class TetherProvisioningActivity extends Activity {

        int tetherType = getIntent().getIntExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE,
                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);

        Intent intent = new Intent(Intent.ACTION_MAIN);
+34 −15
Original line number Diff line number Diff line
@@ -32,16 +32,20 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

import com.android.settings.Utils;

import java.util.ArrayList;
import java.util.List;

@@ -65,7 +69,7 @@ public class TetherService extends Service {

    private int mCurrentTypeIndex;
    private boolean mInProvisionCheck;
    private UsageStatsManagerWrapper mUsageManagerWrapper;
    private TetherServiceWrapper mWrapper;
    private ArrayList<Integer> mCurrentTethers;
    private ArrayMap<Integer, List<ResultReceiver>> mPendingCallbacks;
    private HotspotOffReceiver mHotspotReceiver;
@@ -79,7 +83,7 @@ public class TetherService extends Service {
    public void onCreate() {
        super.onCreate();
        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);
        registerReceiver(mReceiver, new IntentFilter(provisionResponse),
                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_BLUETOOTH, new ArrayList<ResultReceiver>());
        if (mUsageManagerWrapper == null) {
            mUsageManagerWrapper = new UsageStatsManagerWrapper(this);
        }
        mHotspotReceiver = new HotspotOffReceiver(this);
    }

@@ -258,7 +259,7 @@ public class TetherService extends Service {
    }

    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);
        Intent intent = new Intent(provisionAction);
        int type = mCurrentTethers.get(index);
@@ -282,7 +283,7 @@ public class TetherService extends Service {
        for (ResolveInfo resolver : resolvers) {
            if (resolver.activityInfo.applicationInfo.isSystemApp()) {
                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);
        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);
        long periodMs = period * MS_PER_HOUR;
        long firstTime = SystemClock.elapsedRealtime() + periodMs;
@@ -347,7 +348,7 @@ public class TetherService extends Service {
        @Override
        public void onReceive(Context context, Intent 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);

            if (provisionResponse.equals(intent.getAction())) {
@@ -385,19 +386,27 @@ public class TetherService extends Service {
    };

    @VisibleForTesting
    void setUsageStatsManagerWrapper(UsageStatsManagerWrapper wrapper) {
        mUsageManagerWrapper = wrapper;
    void setTetherServiceWrapper(TetherServiceWrapper 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
     * it's marked final. This class can be mocked out instead.
     * A static helper class used for tests. UsageStatsManager cannot be mocked out because
     * it's marked final. Static method SubscriptionManager#getResourcesForSubId also cannot
     * be mocked. This class can be mocked out instead.
     */
    @VisibleForTesting
    public static class UsageStatsManagerWrapper {
    public static class TetherServiceWrapper {
        private final UsageStatsManager mUsageStatsManager;

        UsageStatsManagerWrapper(Context context) {
        TetherServiceWrapper(Context context) {
            mUsageStatsManager = (UsageStatsManager)
                    context.getSystemService(Context.USAGE_STATS_SERVICE);
        }
@@ -405,5 +414,15 @@ public class TetherService extends Service {
        void setAppInactive(String packageName, boolean isInactive) {
            mUsageStatsManager.setAppInactive(packageName, isInactive);
        }

        int getDefaultDataSubscriptionId() {
            return SubscriptionManager.getDefaultDataSubscriptionId();
        }
    }

    @VisibleForTesting
    Resources getResourceForDefaultDataSubId() {
        final int subId = getTetherServiceWrapper().getDefaultDataSubscriptionId();
        return Utils.getResourcesForSubId(this, subId);
    }
}
+15 −10
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;

import android.app.Activity;
import android.app.AlarmManager;
@@ -82,7 +83,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {

    private TetherService mService;
    private MockResources mResources;
    private FakeUsageStatsManagerWrapper mUsageStatsManagerWrapper;
    private MockTetherServiceWrapper mWrapper;
    int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
    private int mLastTetherRequestType = TETHERING_INVALID;
    private int mProvisionResponse = BOGUS_RECEIVER_RESULT;
@@ -124,7 +125,7 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
        when(mPrefs.edit()).thenReturn(mPrefEditor);
        when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn(
                mPrefEditor);
        mUsageStatsManagerWrapper = new FakeUsageStatsManagerWrapper(mContext);
        mWrapper = new MockTetherServiceWrapper(mContext);

        ResolveInfo systemAppResolveInfo = new ResolveInfo();
        ActivityInfo systemActivityInfo = new ActivityInfo();
@@ -145,6 +146,8 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
        resolvers.add(systemAppResolveInfo);
        when(mPackageManager.queryBroadcastReceivers(
                any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers);
        setupService();
        getService().setTetherServiceWrapper(mWrapper);
    }

    @Override
@@ -170,16 +173,13 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
    }

    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));
        assertFalse(mWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME));
        // 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() {
@@ -418,11 +418,11 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
        }
    }

    private static class FakeUsageStatsManagerWrapper
            extends TetherService.UsageStatsManagerWrapper {
    private static class MockTetherServiceWrapper
            extends TetherService.TetherServiceWrapper {
        private final Set<String> mActivePackages;

        FakeUsageStatsManagerWrapper(Context context) {
        MockTetherServiceWrapper(Context context) {
            super(context);
            mActivePackages = new HashSet<>();
        }
@@ -439,5 +439,10 @@ public class TetherServiceTest extends ServiceTestCase<TetherService> {
        boolean isAppInactive(String packageName) {
            return !mActivePackages.contains(packageName);
        }

        @Override
        int getDefaultDataSubscriptionId() {
            return INVALID_SUBSCRIPTION_ID;
        }
    }
}