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

Commit 788abd7c authored by Mark Chien's avatar Mark Chien Committed by Gerrit Code Review
Browse files

Merge changes from topics "pass-res", "remove-isProvisioningNeeded"

* changes:
  Protect invalid entitlement app configuration
  Pass entitlement configuration to Settings for entitlement check
parents 280471d6 b39a7b35
Loading
Loading
Loading
Loading
+0 −33
Original line number Diff line number Diff line
@@ -19,42 +19,9 @@ import static android.os.UserManager.DISALLOW_CONFIG_TETHERING;

import android.content.Context;
import android.net.ConnectivityManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.telephony.CarrierConfigManager;

import androidx.annotation.VisibleForTesting;

public class TetherUtil {

    @VisibleForTesting
    static boolean isEntitlementCheckRequired(Context context) {
        final CarrierConfigManager configManager = (CarrierConfigManager) context
             .getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (configManager == null || configManager.getConfig() == null) {
            // return service default
            return true;
        }
        return configManager.getConfig().getBoolean(CarrierConfigManager
             .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
    }

    public static boolean isProvisioningNeeded(Context context) {
        // Keep in sync with other usage of config_mobile_hotspot_provision_app.
        // ConnectivityManager#enforceTetherChangePermission
        String[] provisionApp = context.getResources().getStringArray(
                com.android.internal.R.array.config_mobile_hotspot_provision_app);
        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)
                || provisionApp == null) {
            return false;
        }
        // Check carrier config for entitlement checks
        if (isEntitlementCheckRequired(context) == false) {
            return false;
        }
        return (provisionApp.length == 2);
    }

    public static boolean isTetherAvailable(Context context) {
        final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
        final boolean tetherConfigDisallowed = RestrictedLockUtilsInternal
+0 −7
Original line number Diff line number Diff line
@@ -59,13 +59,6 @@ public class TetherUtilTest {
                .when(mContext).getSystemService(Context.USER_SERVICE);
    }

    @Test
    public void isEntitlementCheckRequired_noConfigManager_returnTrue() {
        doReturn(null).when(mContext).getSystemService(Context.CARRIER_CONFIG_SERVICE);

        assertThat(TetherUtil.isEntitlementCheckRequired(mContext)).isTrue();
    }

    @Test
    public void isTetherAvailable_supported_configDisallowed_hasUserRestriction_returnTrue() {
        setupIsTetherAvailable(true, true, true);
+34 −4
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ public final class TetheringConstants {
    private TetheringConstants() { }

    /**
     * Extra used for communicating with the TetherService. Includes the type of tethering to
     * enable if any.
     * Extra used for communicating with the TetherService and TetherProvisioningActivity.
     * Includes the type of tethering to enable if any.
     */
    public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
    /**
@@ -56,8 +56,38 @@ public final class TetheringConstants {
     */
    public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
    /**
     * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
     * which will receive provisioning results. Can be left empty.
     * Extra used for communicating with the TetherService and TetherProvisioningActivity.
     * Contains the {@link ResultReceiver} which will receive provisioning results.
     * Can not be empty.
     */
    public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";

    /**
     * Extra used for communicating with the TetherService and TetherProvisioningActivity.
     * Contains the subId of current active cellular upstream.
     * @hide
     */
    public static final String EXTRA_TETHER_SUBID = "android.net.extra.TETHER_SUBID";

    /**
     * Extra used for telling TetherProvisioningActivity the entitlement package name and class
     * name to start UI entitlement check.
     * @hide
     */
    public static final String EXTRA_TETHER_UI_PROVISIONING_APP_NAME =
            "android.net.extra.TETHER_UI_PROVISIONING_APP_NAME";

    /**
     * Extra used for telling TetherService the intent action to start silent entitlement check.
     * @hide
     */
    public static final String EXTRA_TETHER_SILENT_PROVISIONING_ACTION =
            "android.net.extra.TETHER_SILENT_PROVISIONING_ACTION";

    /**
     * Extra used for TetherService to receive the response of provisioning check.
     * @hide
     */
    public static final String EXTRA_TETHER_PROVISIONING_RESPONSE =
            "android.net.extra.TETHER_PROVISIONING_RESPONSE";
}
+21 −12
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ package com.android.networkstack.tethering;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_INVALID;
@@ -69,7 +73,6 @@ public class EntitlementManager {
    protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
    private static final String ACTION_PROVISIONING_ALARM =
            "com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM";
    private static final String EXTRA_SUBID = "subId";

    private final ComponentName mSilentProvisioningService;
    private static final int MS_PER_HOUR = 60 * 60 * 1000;
@@ -197,9 +200,9 @@ public class EntitlementManager {
        // till upstream change to cellular.
        if (mUsingCellularAsUpstream) {
            if (showProvisioningUi) {
                runUiTetherProvisioning(downstreamType, config.activeDataSubId);
                runUiTetherProvisioning(downstreamType, config);
            } else {
                runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
                runSilentTetherProvisioning(downstreamType, config);
            }
            mNeedReRunProvisioningUi = false;
        } else {
@@ -262,9 +265,9 @@ public class EntitlementManager {
            if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
                if (mNeedReRunProvisioningUi) {
                    mNeedReRunProvisioningUi = false;
                    runUiTetherProvisioning(downstream, config.activeDataSubId);
                    runUiTetherProvisioning(downstream, config);
                } else {
                    runSilentTetherProvisioning(downstream, config.activeDataSubId);
                    runSilentTetherProvisioning(downstream, config);
                }
            }
        }
@@ -361,7 +364,7 @@ public class EntitlementManager {
     * @param subId default data subscription ID.
     */
    @VisibleForTesting
    protected void runSilentTetherProvisioning(int type, int subId) {
    protected Intent runSilentTetherProvisioning(int type, final TetheringConfiguration config) {
        if (DBG) mLog.i("runSilentTetherProvisioning: " + type);
        // For silent provisioning, settings would stop tethering when entitlement fail.
        ResultReceiver receiver = buildProxyReceiver(type, false/* notifyFail */, null);
@@ -369,17 +372,20 @@ public class EntitlementManager {
        Intent intent = new Intent();
        intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
        intent.putExtra(EXTRA_RUN_PROVISION, true);
        intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, config.provisioningAppNoUi);
        intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, config.provisioningResponse);
        intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
        intent.putExtra(EXTRA_SUBID, subId);
        intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
        intent.setComponent(mSilentProvisioningService);
        // Only admin user can change tethering and SilentTetherProvisioning don't need to
        // show UI, it is fine to always start setting's background service as system user.
        mContext.startService(intent);
        return intent;
    }

    private void runUiTetherProvisioning(int type, int subId) {
    private void runUiTetherProvisioning(int type, final TetheringConfiguration config) {
        ResultReceiver receiver = buildProxyReceiver(type, true/* notifyFail */, null);
        runUiTetherProvisioning(type, subId, receiver);
        runUiTetherProvisioning(type, config, receiver);
    }

    /**
@@ -389,17 +395,20 @@ public class EntitlementManager {
     * @param receiver to receive entitlement check result.
     */
    @VisibleForTesting
    protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) {
    protected Intent runUiTetherProvisioning(int type, final TetheringConfiguration config,
            ResultReceiver receiver) {
        if (DBG) mLog.i("runUiTetherProvisioning: " + type);

        Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING_UI);
        intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
        intent.putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, config.provisioningApp);
        intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
        intent.putExtra(EXTRA_SUBID, subId);
        intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // Only launch entitlement UI for system user. Entitlement UI should not appear for other
        // user because only admin user is allowed to change tethering.
        mContext.startActivity(intent);
        return intent;
    }

    // Not needed to check if this don't run on the handler thread because it's private.
@@ -631,7 +640,7 @@ public class EntitlementManager {
            receiver.send(cacheValue, null);
        } else {
            ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
            runUiTetherProvisioning(downstream, config.activeDataSubId, proxy);
            runUiTetherProvisioning(downstream, config, proxy);
        }
    }
}
+24 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.networkstack.tethering;

import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.NETWORK_STACK;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.usb.UsbManager.USB_CONFIGURED;
import static android.hardware.usb.UsbManager.USB_CONNECTED;
@@ -71,6 +72,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import android.net.EthernetManager;
@@ -110,7 +112,6 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -811,11 +812,30 @@ public class Tethering {
        }
    }

    private boolean isProvisioningNeededButUnavailable() {
        return isTetherProvisioningRequired() && !doesEntitlementPackageExist();
    }

    boolean isTetherProvisioningRequired() {
        final TetheringConfiguration cfg = mConfig;
        return mEntitlementMgr.isTetherProvisioningRequired(cfg);
    }

    private boolean doesEntitlementPackageExist() {
        // provisioningApp must contain package and class name.
        if (mConfig.provisioningApp.length != 2) {
            return false;
        }

        final PackageManager pm = mContext.getPackageManager();
        try {
            pm.getPackageInfo(mConfig.provisioningApp[0], GET_ACTIVITIES);
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
        return true;
    }

    // TODO: Figure out how to update for local hotspot mode interfaces.
    private void sendTetherStateChangedBroadcast() {
        if (!isTetheringSupported()) return;
@@ -2175,14 +2195,14 @@ public class Tethering {
    // gservices could set the secure setting to 1 though to enable it on a build where it
    // had previously been turned off.
    boolean isTetheringSupported() {
        final int defaultVal =
                SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
        final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1;
        final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
        final boolean tetherEnabledInSettings = tetherSupported
                && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);

        return tetherEnabledInSettings && hasTetherableConfiguration();
        return tetherEnabledInSettings && hasTetherableConfiguration()
                && !isProvisioningNeededButUnavailable();
    }

    void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
Loading