Loading packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +2 −1 Original line number Diff line number Diff line Loading @@ -369,9 +369,10 @@ public class Tethering { mActiveDataSubId = subId; updateConfiguration(); mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId); // To avoid launching unexpected provisioning checks, ignore re-provisioning // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() // ill be triggered again when CarrierConfig is loaded. // will be triggered again when CarrierConfig is loaded. if (mEntitlementMgr.getCarrierConfig(mConfig) != null) { mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); } else { Loading packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java +33 −9 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.Intent; import android.content.res.Resources; import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; Loading @@ -54,6 +55,9 @@ import com.android.networkstack.tethering.R; public class TetheringNotificationUpdater { private static final String TAG = TetheringNotificationUpdater.class.getSimpleName(); private static final String CHANNEL_ID = "TETHERING_STATUS"; private static final String WIFI_DOWNSTREAM = "WIFI"; private static final String USB_DOWNSTREAM = "USB"; private static final String BLUETOOTH_DOWNSTREAM = "BT"; private static final boolean NOTIFY_DONE = true; private static final boolean NO_NOTIFY = false; // Id to update and cancel tethering notification. Must be unique within the tethering app. Loading @@ -65,14 +69,22 @@ public class TetheringNotificationUpdater { private final Context mContext; private final NotificationManager mNotificationManager; private final NotificationChannel mChannel; // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2. // This value has to be made 1 2 and 4, and OR'd with the others. // WARNING : the constructor is called on a different thread. Thread safety therefore // relies on this value being initialized to 0, and not any other value. If you need // to change this, you will need to change the thread where the constructor is invoked, // or to introduce synchronization. // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2. // This value has to be made 1 2 and 4, and OR'd with the others. private int mDownstreamTypesMask = DOWNSTREAM_NONE; // WARNING : this value is not able to being initialized to 0 and must have volatile because // telephony service is not guaranteed that is up before tethering service starts. If telephony // is up later than tethering, TetheringNotificationUpdater will use incorrect and valid // subscription id(0) to query resources. Therefore, initialized subscription id must be // INVALID_SUBSCRIPTION_ID. private volatile int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; public TetheringNotificationUpdater(@NonNull final Context context) { mContext = context; mNotificationManager = (NotificationManager) context.createContextAsUser(UserHandle.ALL, 0) Loading @@ -91,6 +103,18 @@ public class TetheringNotificationUpdater { updateNotification(); } /** Called when active data subscription id changed */ public void onActiveDataSubscriptionIdChanged(final int subId) { if (mActiveDataSubId == subId) return; mActiveDataSubId = subId; updateNotification(); } @VisibleForTesting Resources getResourcesForSubId(@NonNull final Context c, final int subId) { return SubscriptionManager.getResourcesForSubId(c, subId); } private void updateNotification() { final boolean tetheringInactive = mDownstreamTypesMask <= DOWNSTREAM_NONE; Loading @@ -115,11 +139,11 @@ public class TetheringNotificationUpdater { int downstreamTypesMask = DOWNSTREAM_NONE; final String[] downstreams = types.split("\\|"); for (String downstream : downstreams) { if ("USB".equals(downstream.trim())) { if (USB_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_USB); } else if ("WIFI".equals(downstream.trim())) { } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_WIFI); } else if ("BT".equals(downstream.trim())) { } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } } Loading @@ -135,8 +159,7 @@ public class TetheringNotificationUpdater { * @return {@link android.util.SparseArray} with downstream types and icon id info. */ @NonNull private SparseArray<Integer> getIcons(@ArrayRes int id) { final Resources res = mContext.getResources(); private SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) { final String[] array = res.getStringArray(id); final SparseArray<Integer> icons = new SparseArray<>(); for (String config : array) { Loading @@ -161,8 +184,9 @@ public class TetheringNotificationUpdater { } private boolean setupNotification() { final Resources res = mContext.getResources(); final SparseArray<Integer> downstreamIcons = getIcons(R.array.tethering_notification_icons); final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); final SparseArray<Integer> downstreamIcons = getIcons(R.array.tethering_notification_icons, res); final int iconId = downstreamIcons.get(mDownstreamTypesMask, NO_ICON_ID); if (iconId == NO_ICON_ID) return NO_NOTIFY; Loading packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,6 @@ public class TetheringTest { private PhoneStateListener mPhoneStateListener; private InterfaceConfigurationParcel mInterfaceConfiguration; private class TestContext extends BroadcastInterceptingContext { TestContext(Context base) { super(base); Loading Loading @@ -1399,6 +1398,7 @@ public class TetheringTest { mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); assertEquals(fakeSubId, newConfig.activeDataSubId); verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId)); } @Test Loading Loading
packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +2 −1 Original line number Diff line number Diff line Loading @@ -369,9 +369,10 @@ public class Tethering { mActiveDataSubId = subId; updateConfiguration(); mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId); // To avoid launching unexpected provisioning checks, ignore re-provisioning // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() // ill be triggered again when CarrierConfig is loaded. // will be triggered again when CarrierConfig is loaded. if (mEntitlementMgr.getCarrierConfig(mConfig) != null) { mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); } else { Loading
packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java +33 −9 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.Intent; import android.content.res.Resources; import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; Loading @@ -54,6 +55,9 @@ import com.android.networkstack.tethering.R; public class TetheringNotificationUpdater { private static final String TAG = TetheringNotificationUpdater.class.getSimpleName(); private static final String CHANNEL_ID = "TETHERING_STATUS"; private static final String WIFI_DOWNSTREAM = "WIFI"; private static final String USB_DOWNSTREAM = "USB"; private static final String BLUETOOTH_DOWNSTREAM = "BT"; private static final boolean NOTIFY_DONE = true; private static final boolean NO_NOTIFY = false; // Id to update and cancel tethering notification. Must be unique within the tethering app. Loading @@ -65,14 +69,22 @@ public class TetheringNotificationUpdater { private final Context mContext; private final NotificationManager mNotificationManager; private final NotificationChannel mChannel; // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2. // This value has to be made 1 2 and 4, and OR'd with the others. // WARNING : the constructor is called on a different thread. Thread safety therefore // relies on this value being initialized to 0, and not any other value. If you need // to change this, you will need to change the thread where the constructor is invoked, // or to introduce synchronization. // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2. // This value has to be made 1 2 and 4, and OR'd with the others. private int mDownstreamTypesMask = DOWNSTREAM_NONE; // WARNING : this value is not able to being initialized to 0 and must have volatile because // telephony service is not guaranteed that is up before tethering service starts. If telephony // is up later than tethering, TetheringNotificationUpdater will use incorrect and valid // subscription id(0) to query resources. Therefore, initialized subscription id must be // INVALID_SUBSCRIPTION_ID. private volatile int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; public TetheringNotificationUpdater(@NonNull final Context context) { mContext = context; mNotificationManager = (NotificationManager) context.createContextAsUser(UserHandle.ALL, 0) Loading @@ -91,6 +103,18 @@ public class TetheringNotificationUpdater { updateNotification(); } /** Called when active data subscription id changed */ public void onActiveDataSubscriptionIdChanged(final int subId) { if (mActiveDataSubId == subId) return; mActiveDataSubId = subId; updateNotification(); } @VisibleForTesting Resources getResourcesForSubId(@NonNull final Context c, final int subId) { return SubscriptionManager.getResourcesForSubId(c, subId); } private void updateNotification() { final boolean tetheringInactive = mDownstreamTypesMask <= DOWNSTREAM_NONE; Loading @@ -115,11 +139,11 @@ public class TetheringNotificationUpdater { int downstreamTypesMask = DOWNSTREAM_NONE; final String[] downstreams = types.split("\\|"); for (String downstream : downstreams) { if ("USB".equals(downstream.trim())) { if (USB_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_USB); } else if ("WIFI".equals(downstream.trim())) { } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_WIFI); } else if ("BT".equals(downstream.trim())) { } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } } Loading @@ -135,8 +159,7 @@ public class TetheringNotificationUpdater { * @return {@link android.util.SparseArray} with downstream types and icon id info. */ @NonNull private SparseArray<Integer> getIcons(@ArrayRes int id) { final Resources res = mContext.getResources(); private SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) { final String[] array = res.getStringArray(id); final SparseArray<Integer> icons = new SparseArray<>(); for (String config : array) { Loading @@ -161,8 +184,9 @@ public class TetheringNotificationUpdater { } private boolean setupNotification() { final Resources res = mContext.getResources(); final SparseArray<Integer> downstreamIcons = getIcons(R.array.tethering_notification_icons); final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); final SparseArray<Integer> downstreamIcons = getIcons(R.array.tethering_notification_icons, res); final int iconId = downstreamIcons.get(mDownstreamTypesMask, NO_ICON_ID); if (iconId == NO_ICON_ID) return NO_NOTIFY; Loading
packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,6 @@ public class TetheringTest { private PhoneStateListener mPhoneStateListener; private InterfaceConfigurationParcel mInterfaceConfiguration; private class TestContext extends BroadcastInterceptingContext { TestContext(Context base) { super(base); Loading Loading @@ -1399,6 +1398,7 @@ public class TetheringTest { mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); assertEquals(fakeSubId, newConfig.activeDataSubId); verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId)); } @Test Loading