Loading core/res/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -608,6 +608,9 @@ <protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL" /> <!-- For tether entitlement recheck--> <protected-broadcast android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> Loading services/core/java/com/android/server/connectivity/Tethering.java +23 −72 Original line number Diff line number Diff line Loading @@ -82,7 +82,6 @@ import android.os.Handler; import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ResultReceiver; Loading Loading @@ -230,8 +229,11 @@ public class Tethering extends BaseNetworkObserver { IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog, systemProperties); // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream // permission is changed according to entitlement check result. mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED, systemProperties); mCarrierConfigChange = new VersionedBroadcastListener( "CarrierConfigChangeListener", mContext, mHandler, filter, (Intent ignored) -> { Loading Loading @@ -363,55 +365,28 @@ public class Tethering extends BaseNetworkObserver { } public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) { mEntitlementMgr.startTethering(type); if (!mEntitlementMgr.isTetherProvisioningRequired()) { enableTetheringInternal(type, true, receiver); return; } final ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); if (showProvisioningUi) { mEntitlementMgr.runUiTetherProvisioningAndEnable(type, proxyReceiver); } else { mEntitlementMgr.runSilentTetherProvisioningAndEnable(type, proxyReceiver); } mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi); enableTetheringInternal(type, true /* enabled */, receiver); } public void stopTethering(int type) { enableTetheringInternal(type, false, null); mEntitlementMgr.stopTethering(type); if (mEntitlementMgr.isTetherProvisioningRequired()) { // There are lurking bugs where the notion of "provisioning required" or // "tethering supported" may change without notifying tethering properly, then // tethering can't shutdown correctly. // TODO: cancel re-check all the time if (mDeps.isTetheringSupported()) { mEntitlementMgr.cancelTetherProvisioningRechecks(type); } } enableTetheringInternal(type, false /* disabled */, null); mEntitlementMgr.stopProvisioningIfNeeded(type); } /** * Enables or disables tethering for the given type. This should only be called once * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks * for the specified interface. * Enables or disables tethering for the given type. If provisioning is required, it will * schedule provisioning rechecks for the specified interface. */ private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) { boolean isProvisioningRequired = enable && mEntitlementMgr.isTetherProvisioningRequired(); int result; switch (type) { case TETHERING_WIFI: result = setWifiTethering(enable); if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) { mEntitlementMgr.scheduleProvisioningRechecks(type); } sendTetherResult(receiver, result); break; case TETHERING_USB: result = setUsbTethering(enable); if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) { mEntitlementMgr.scheduleProvisioningRechecks(type); } sendTetherResult(receiver, result); break; case TETHERING_BLUETOOTH: Loading Loading @@ -469,46 +444,11 @@ public class Tethering extends BaseNetworkObserver { ? TETHER_ERROR_NO_ERROR : TETHER_ERROR_MASTER_ERROR; sendTetherResult(receiver, result); if (enable && mEntitlementMgr.isTetherProvisioningRequired()) { mEntitlementMgr.scheduleProvisioningRechecks(TETHERING_BLUETOOTH); } adapter.closeProfileProxy(BluetoothProfile.PAN, proxy); } }, BluetoothProfile.PAN); } /** * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result * is successful before firing back up to the wrapped receiver. * * @param type The type of tethering being enabled. * @param receiver A ResultReceiver which will be called back with an int resultCode. * @return The proxy receiver. */ private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) { ResultReceiver rr = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { // If provisioning is successful, enable tethering, otherwise just send the error. if (resultCode == TETHER_ERROR_NO_ERROR) { enableTetheringInternal(type, true, receiver); } else { sendTetherResult(receiver, resultCode); } mEntitlementMgr.updateEntitlementCacheValue(type, resultCode); } }; // The following is necessary to avoid unmarshalling issues when sending the receiver // across processes. Parcel parcel = Parcel.obtain(); rr.writeToParcel(parcel,0); parcel.setDataPosition(0); ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel); parcel.recycle(); return receiverForSending; } public int tether(String iface) { return tether(iface, IpServer.STATE_TETHERED); } Loading Loading @@ -787,6 +727,7 @@ public class Tethering extends BaseNetworkObserver { if (!usbConnected && mRndisEnabled) { // Turn off tethering if it was enabled and there is a disconnect. tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB); mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB); } else if (usbConfigured && rndisEnabled) { // Tether if rndis is enabled and usb is configured. tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB); Loading @@ -813,6 +754,7 @@ public class Tethering extends BaseNetworkObserver { case WifiManager.WIFI_AP_STATE_FAILED: default: disableWifiIpServingLocked(ifname, curState); mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI); break; } } Loading Loading @@ -1090,6 +1032,8 @@ public class Tethering extends BaseNetworkObserver { // we treated the error and want now to clear it static final int CMD_CLEAR_ERROR = BASE_MASTER + 6; static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7; // Events from EntitlementManager to choose upstream again. static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8; private final State mInitialState; private final State mTetherModeAliveState; Loading Loading @@ -1504,6 +1448,7 @@ public class Tethering extends BaseNetworkObserver { } break; } case EVENT_UPSTREAM_PERMISSION_CHANGED: case CMD_UPSTREAM_CHANGED: updateUpstreamWanted(); if (!mUpstreamWanted) break; Loading Loading @@ -1694,7 +1639,8 @@ public class Tethering extends BaseNetworkObserver { } public void systemReady() { mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest()); mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(), mEntitlementMgr); } /** Get the latest value of the tethering entitlement check. */ Loading Loading @@ -1755,6 +1701,11 @@ public class Tethering extends BaseNetworkObserver { cfg.dump(pw); pw.decreaseIndent(); pw.println("Entitlement:"); pw.increaseIndent(); mEntitlementMgr.dump(pw); pw.decreaseIndent(); synchronized (mPublicSync) { pw.println("Tether state:"); pw.increaseIndent(); Loading services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java +388 −78 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +13 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static com.android.internal.R.array.config_tether_upstream_types; import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_wifi_regexs; import static com.android.internal.R.bool.config_tether_upstream_automatic; import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period; import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; import android.content.ContentResolver; Loading Loading @@ -94,6 +95,7 @@ public class TetheringConfiguration { public final String[] provisioningApp; public final String provisioningAppNoUi; public final int provisioningCheckPeriod; public final int subId; Loading Loading @@ -121,6 +123,9 @@ public class TetheringConfiguration { provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app); provisioningAppNoUi = getProvisioningAppNoUi(res); provisioningCheckPeriod = getResourceInteger(res, config_mobile_hotspot_provision_check_period, 0 /* No periodic re-check */); configLog.log(toString()); } Loading Loading @@ -311,6 +316,14 @@ public class TetheringConfiguration { } } private static int getResourceInteger(Resources res, int resId, int defaultValue) { try { return res.getInteger(resId); } catch (Resources.NotFoundException e404) { return defaultValue; } } private static boolean getEnableLegacyDhcpServer(Context ctx) { final ContentResolver cr = ctx.getContentResolver(); final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); Loading services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +2 −2 Original line number Diff line number Diff line Loading @@ -83,8 +83,8 @@ public class TetheringDependencies { * Get a reference to the EntitlementManager to be used by tethering. */ public EntitlementManager getEntitlementManager(Context ctx, StateMachine target, SharedLog log, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, target, log, systemProperties); SharedLog log, int what, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, target, log, what, systemProperties); } /** Loading Loading
core/res/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -608,6 +608,9 @@ <protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL" /> <!-- For tether entitlement recheck--> <protected-broadcast android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> Loading
services/core/java/com/android/server/connectivity/Tethering.java +23 −72 Original line number Diff line number Diff line Loading @@ -82,7 +82,6 @@ import android.os.Handler; import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ResultReceiver; Loading Loading @@ -230,8 +229,11 @@ public class Tethering extends BaseNetworkObserver { IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog, systemProperties); // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream // permission is changed according to entitlement check result. mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED, systemProperties); mCarrierConfigChange = new VersionedBroadcastListener( "CarrierConfigChangeListener", mContext, mHandler, filter, (Intent ignored) -> { Loading Loading @@ -363,55 +365,28 @@ public class Tethering extends BaseNetworkObserver { } public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) { mEntitlementMgr.startTethering(type); if (!mEntitlementMgr.isTetherProvisioningRequired()) { enableTetheringInternal(type, true, receiver); return; } final ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); if (showProvisioningUi) { mEntitlementMgr.runUiTetherProvisioningAndEnable(type, proxyReceiver); } else { mEntitlementMgr.runSilentTetherProvisioningAndEnable(type, proxyReceiver); } mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi); enableTetheringInternal(type, true /* enabled */, receiver); } public void stopTethering(int type) { enableTetheringInternal(type, false, null); mEntitlementMgr.stopTethering(type); if (mEntitlementMgr.isTetherProvisioningRequired()) { // There are lurking bugs where the notion of "provisioning required" or // "tethering supported" may change without notifying tethering properly, then // tethering can't shutdown correctly. // TODO: cancel re-check all the time if (mDeps.isTetheringSupported()) { mEntitlementMgr.cancelTetherProvisioningRechecks(type); } } enableTetheringInternal(type, false /* disabled */, null); mEntitlementMgr.stopProvisioningIfNeeded(type); } /** * Enables or disables tethering for the given type. This should only be called once * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks * for the specified interface. * Enables or disables tethering for the given type. If provisioning is required, it will * schedule provisioning rechecks for the specified interface. */ private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) { boolean isProvisioningRequired = enable && mEntitlementMgr.isTetherProvisioningRequired(); int result; switch (type) { case TETHERING_WIFI: result = setWifiTethering(enable); if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) { mEntitlementMgr.scheduleProvisioningRechecks(type); } sendTetherResult(receiver, result); break; case TETHERING_USB: result = setUsbTethering(enable); if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) { mEntitlementMgr.scheduleProvisioningRechecks(type); } sendTetherResult(receiver, result); break; case TETHERING_BLUETOOTH: Loading Loading @@ -469,46 +444,11 @@ public class Tethering extends BaseNetworkObserver { ? TETHER_ERROR_NO_ERROR : TETHER_ERROR_MASTER_ERROR; sendTetherResult(receiver, result); if (enable && mEntitlementMgr.isTetherProvisioningRequired()) { mEntitlementMgr.scheduleProvisioningRechecks(TETHERING_BLUETOOTH); } adapter.closeProfileProxy(BluetoothProfile.PAN, proxy); } }, BluetoothProfile.PAN); } /** * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result * is successful before firing back up to the wrapped receiver. * * @param type The type of tethering being enabled. * @param receiver A ResultReceiver which will be called back with an int resultCode. * @return The proxy receiver. */ private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) { ResultReceiver rr = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { // If provisioning is successful, enable tethering, otherwise just send the error. if (resultCode == TETHER_ERROR_NO_ERROR) { enableTetheringInternal(type, true, receiver); } else { sendTetherResult(receiver, resultCode); } mEntitlementMgr.updateEntitlementCacheValue(type, resultCode); } }; // The following is necessary to avoid unmarshalling issues when sending the receiver // across processes. Parcel parcel = Parcel.obtain(); rr.writeToParcel(parcel,0); parcel.setDataPosition(0); ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel); parcel.recycle(); return receiverForSending; } public int tether(String iface) { return tether(iface, IpServer.STATE_TETHERED); } Loading Loading @@ -787,6 +727,7 @@ public class Tethering extends BaseNetworkObserver { if (!usbConnected && mRndisEnabled) { // Turn off tethering if it was enabled and there is a disconnect. tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB); mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB); } else if (usbConfigured && rndisEnabled) { // Tether if rndis is enabled and usb is configured. tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB); Loading @@ -813,6 +754,7 @@ public class Tethering extends BaseNetworkObserver { case WifiManager.WIFI_AP_STATE_FAILED: default: disableWifiIpServingLocked(ifname, curState); mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI); break; } } Loading Loading @@ -1090,6 +1032,8 @@ public class Tethering extends BaseNetworkObserver { // we treated the error and want now to clear it static final int CMD_CLEAR_ERROR = BASE_MASTER + 6; static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7; // Events from EntitlementManager to choose upstream again. static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8; private final State mInitialState; private final State mTetherModeAliveState; Loading Loading @@ -1504,6 +1448,7 @@ public class Tethering extends BaseNetworkObserver { } break; } case EVENT_UPSTREAM_PERMISSION_CHANGED: case CMD_UPSTREAM_CHANGED: updateUpstreamWanted(); if (!mUpstreamWanted) break; Loading Loading @@ -1694,7 +1639,8 @@ public class Tethering extends BaseNetworkObserver { } public void systemReady() { mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest()); mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(), mEntitlementMgr); } /** Get the latest value of the tethering entitlement check. */ Loading Loading @@ -1755,6 +1701,11 @@ public class Tethering extends BaseNetworkObserver { cfg.dump(pw); pw.decreaseIndent(); pw.println("Entitlement:"); pw.increaseIndent(); mEntitlementMgr.dump(pw); pw.decreaseIndent(); synchronized (mPublicSync) { pw.println("Tether state:"); pw.increaseIndent(); Loading
services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java +388 −78 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +13 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static com.android.internal.R.array.config_tether_upstream_types; import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_wifi_regexs; import static com.android.internal.R.bool.config_tether_upstream_automatic; import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period; import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; import android.content.ContentResolver; Loading Loading @@ -94,6 +95,7 @@ public class TetheringConfiguration { public final String[] provisioningApp; public final String provisioningAppNoUi; public final int provisioningCheckPeriod; public final int subId; Loading Loading @@ -121,6 +123,9 @@ public class TetheringConfiguration { provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app); provisioningAppNoUi = getProvisioningAppNoUi(res); provisioningCheckPeriod = getResourceInteger(res, config_mobile_hotspot_provision_check_period, 0 /* No periodic re-check */); configLog.log(toString()); } Loading Loading @@ -311,6 +316,14 @@ public class TetheringConfiguration { } } private static int getResourceInteger(Resources res, int resId, int defaultValue) { try { return res.getInteger(resId); } catch (Resources.NotFoundException e404) { return defaultValue; } } private static boolean getEnableLegacyDhcpServer(Context ctx) { final ContentResolver cr = ctx.getContentResolver(); final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); Loading
services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +2 −2 Original line number Diff line number Diff line Loading @@ -83,8 +83,8 @@ public class TetheringDependencies { * Get a reference to the EntitlementManager to be used by tethering. */ public EntitlementManager getEntitlementManager(Context ctx, StateMachine target, SharedLog log, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, target, log, systemProperties); SharedLog log, int what, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, target, log, what, systemProperties); } /** Loading