Loading packages/Tethering/res/values/config.xml +0 −45 Original line number Diff line number Diff line Loading @@ -158,51 +158,6 @@ <!-- ComponentName of the service used to run no ui tether provisioning. --> <string translatable="false" name="config_wifi_tether_enable">com.android.settings/.wifi.tether.TetherService</string> <!-- Enable tethering notification --> <!-- Icons for showing tether enable notification. Each item should have two elements and be separated with ";". The first element is downstream types which is one of tethering. This element has to be made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream types and use "," to separate each combinations. Such as USB|BT,WIFI|USB|BT The second element is icon for the item. This element has to be composed by <package name>:drawable/<resource name>. Such as 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general 2. android:drawable/xxx So the entire string of each item would be USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general NOTE: One config can be separated into two or more for readability. Such as WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx can be separated into WIFI|USB;android:drawable/xxx WIFI|BT;android:drawable/xxx USB|BT;android:drawable/xxx WIFI|USB|BT;android:drawable/xxx Notification will not show if the downstream type isn't listed in array. Empty array means disable notifications. --> <!-- In AOSP, hotspot is configured to no notification by default. Because status bar has showed an icon on the right side already --> <string-array translatable="false" name="tethering_notification_icons"> <item>USB;com.android.networkstack.tethering:drawable/stat_sys_tether_usb</item> <item>BT;com.android.networkstack.tethering:drawable/stat_sys_tether_bluetooth</item> <item>WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general</item> </string-array> <!-- String for tether enable notification title. --> <string name="tethering_notification_title">@string/tethered_notification_title</string> <!-- String for tether enable notification message. --> <string name="tethering_notification_message">@string/tethered_notification_message</string> <!-- No upstream notification is shown when there is a downstream but no upstream that is able to do the tethering. --> <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to Loading packages/Tethering/res/values/overlayable.xml +0 −38 Original line number Diff line number Diff line Loading @@ -32,44 +32,6 @@ <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="string" name="config_wifi_tether_enable"/> <!-- Configuration values for TetheringNotificationUpdater --> <!-- Icons for showing tether enable notification. Each item should have two elements and be separated with ";". The first element is downstream types which is one of tethering. This element has to be made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream types and use "," to separate each combinations. Such as USB|BT,WIFI|USB|BT The second element is icon for the item. This element has to be composed by <package name>:drawable/<resource name>. Such as 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general 2. android:drawable/xxx So the entire string of each item would be USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general NOTE: One config can be separated into two or more for readability. Such as WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx can be separated into WIFI|USB;android:drawable/xxx WIFI|BT;android:drawable/xxx USB|BT;android:drawable/xxx WIFI|USB|BT;android:drawable/xxx Notification will not show if the downstream type isn't listed in array. Empty array means disable notifications. --> <item type="array" name="tethering_notification_icons"/> <!-- String for tether enable notification title. --> <item type="string" name="tethering_notification_title"/> <!-- String for tether enable notification message. --> <item type="string" name="tethering_notification_message"/> <!-- Params from config.xml that can be overlaid --> </policy> </overlayable> Loading packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java +0 −100 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ package com.android.networkstack.tethering; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.text.TextUtils.isEmpty; import android.app.Notification; Loading @@ -39,10 +36,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; import android.util.SparseArray; import androidx.annotation.ArrayRes; import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.annotation.IntRange; Loading Loading @@ -77,9 +72,6 @@ public class TetheringNotificationUpdater { private static final boolean NO_NOTIFY = false; @VisibleForTesting static final int EVENT_SHOW_NO_UPSTREAM = 1; // Id to update and cancel enable notification. Must be unique within the tethering app. @VisibleForTesting static final int ENABLE_NOTIFICATION_ID = 1000; // Id to update and cancel restricted notification. Must be unique within the tethering app. @VisibleForTesting static final int RESTRICTED_NOTIFICATION_ID = 1001; Loading Loading @@ -120,7 +112,6 @@ public class TetheringNotificationUpdater { @Retention(RetentionPolicy.SOURCE) @IntDef(value = { ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID Loading Loading @@ -223,7 +214,6 @@ public class TetheringNotificationUpdater { final boolean tetheringActiveChanged = (downstreamTypes == DOWNSTREAM_NONE) != (mDownstreamTypesMask == DOWNSTREAM_NONE); final boolean subIdChanged = subId != mActiveDataSubId; final boolean downstreamChanged = downstreamTypes != mDownstreamTypesMask; final boolean upstreamChanged = noUpstream != mNoUpstream; final boolean roamingChanged = isRoaming != mRoaming; final boolean updateAll = tetheringActiveChanged || subIdChanged; Loading @@ -232,19 +222,10 @@ public class TetheringNotificationUpdater { mNoUpstream = noUpstream; mRoaming = isRoaming; if (updateAll || downstreamChanged) updateEnableNotification(); if (updateAll || upstreamChanged) updateNoUpstreamNotification(); if (updateAll || roamingChanged) updateRoamingNotification(); } private void updateEnableNotification() { final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; if (tetheringInactive || setupNotification() == NO_NOTIFY) { clearNotification(ENABLE_NOTIFICATION_ID); } } private void updateNoUpstreamNotification() { final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; Loading Loading @@ -310,64 +291,6 @@ public class TetheringNotificationUpdater { NO_UPSTREAM_NOTIFICATION_ID, null /* pendingIntent */, action); } /** * Returns the downstream types mask which convert from given string. * * @param types This string has to be made by "WIFI", "USB", "BT", and OR'd with the others. * * @return downstream types mask value. */ @VisibleForTesting @IntRange(from = 0, to = 7) int getDownstreamTypesMask(@NonNull final String types) { int downstreamTypesMask = DOWNSTREAM_NONE; final String[] downstreams = types.split("\\|"); for (String downstream : downstreams) { if (USB_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_USB); } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_WIFI); } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } } return downstreamTypesMask; } /** * Returns the icons {@link android.util.SparseArray} which get from given string-array resource * id. * * @param id String-array resource id * * @return {@link android.util.SparseArray} with downstream types and icon id info. */ @NonNull @VisibleForTesting 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) { if (isEmpty(config)) continue; final String[] elements = config.split(";"); if (elements.length != 2) { Log.wtf(TAG, "Unexpected format in Tethering notification configuration : " + config); continue; } final String[] types = elements[0].split(","); for (String type : types) { int mask = getDownstreamTypesMask(type); if (mask == DOWNSTREAM_NONE) continue; icons.put(mask, res.getIdentifier( elements[1].trim(), null /* defType */, null /* defPackage */)); } } return icons; } private boolean setupRoamingNotification() { final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); final boolean upstreamRoamingNotification = Loading Loading @@ -403,29 +326,6 @@ public class TetheringNotificationUpdater { return NOTIFY_DONE; } private boolean setupNotification() { 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; final String title = res.getString(R.string.tethering_notification_title); final String message = res.getString(R.string.tethering_notification_message); if (isEmpty(title) || isEmpty(message)) return NO_NOTIFY; final PendingIntent pi = PendingIntent.getActivity( mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 0 /* requestCode */, new Intent(Settings.ACTION_TETHER_SETTINGS), Intent.FLAG_ACTIVITY_NEW_TASK, null /* options */); showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID, pi, new Action[0]); return NOTIFY_DONE; } private void showNotification(@DrawableRes final int iconId, @NonNull final String title, @NonNull final String message, @NotificationId final int id, @Nullable PendingIntent pi, @NonNull final Action... actions) { Loading packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt +39 −168 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/Tethering/res/values/config.xml +0 −45 Original line number Diff line number Diff line Loading @@ -158,51 +158,6 @@ <!-- ComponentName of the service used to run no ui tether provisioning. --> <string translatable="false" name="config_wifi_tether_enable">com.android.settings/.wifi.tether.TetherService</string> <!-- Enable tethering notification --> <!-- Icons for showing tether enable notification. Each item should have two elements and be separated with ";". The first element is downstream types which is one of tethering. This element has to be made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream types and use "," to separate each combinations. Such as USB|BT,WIFI|USB|BT The second element is icon for the item. This element has to be composed by <package name>:drawable/<resource name>. Such as 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general 2. android:drawable/xxx So the entire string of each item would be USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general NOTE: One config can be separated into two or more for readability. Such as WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx can be separated into WIFI|USB;android:drawable/xxx WIFI|BT;android:drawable/xxx USB|BT;android:drawable/xxx WIFI|USB|BT;android:drawable/xxx Notification will not show if the downstream type isn't listed in array. Empty array means disable notifications. --> <!-- In AOSP, hotspot is configured to no notification by default. Because status bar has showed an icon on the right side already --> <string-array translatable="false" name="tethering_notification_icons"> <item>USB;com.android.networkstack.tethering:drawable/stat_sys_tether_usb</item> <item>BT;com.android.networkstack.tethering:drawable/stat_sys_tether_bluetooth</item> <item>WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general</item> </string-array> <!-- String for tether enable notification title. --> <string name="tethering_notification_title">@string/tethered_notification_title</string> <!-- String for tether enable notification message. --> <string name="tethering_notification_message">@string/tethered_notification_message</string> <!-- No upstream notification is shown when there is a downstream but no upstream that is able to do the tethering. --> <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to Loading
packages/Tethering/res/values/overlayable.xml +0 −38 Original line number Diff line number Diff line Loading @@ -32,44 +32,6 @@ <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="string" name="config_wifi_tether_enable"/> <!-- Configuration values for TetheringNotificationUpdater --> <!-- Icons for showing tether enable notification. Each item should have two elements and be separated with ";". The first element is downstream types which is one of tethering. This element has to be made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream types and use "," to separate each combinations. Such as USB|BT,WIFI|USB|BT The second element is icon for the item. This element has to be composed by <package name>:drawable/<resource name>. Such as 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general 2. android:drawable/xxx So the entire string of each item would be USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general NOTE: One config can be separated into two or more for readability. Such as WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx can be separated into WIFI|USB;android:drawable/xxx WIFI|BT;android:drawable/xxx USB|BT;android:drawable/xxx WIFI|USB|BT;android:drawable/xxx Notification will not show if the downstream type isn't listed in array. Empty array means disable notifications. --> <item type="array" name="tethering_notification_icons"/> <!-- String for tether enable notification title. --> <item type="string" name="tethering_notification_title"/> <!-- String for tether enable notification message. --> <item type="string" name="tethering_notification_message"/> <!-- Params from config.xml that can be overlaid --> </policy> </overlayable> Loading
packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java +0 −100 Original line number Diff line number Diff line Loading @@ -17,9 +17,6 @@ package com.android.networkstack.tethering; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.text.TextUtils.isEmpty; import android.app.Notification; Loading @@ -39,10 +36,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; import android.util.SparseArray; import androidx.annotation.ArrayRes; import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.annotation.IntRange; Loading Loading @@ -77,9 +72,6 @@ public class TetheringNotificationUpdater { private static final boolean NO_NOTIFY = false; @VisibleForTesting static final int EVENT_SHOW_NO_UPSTREAM = 1; // Id to update and cancel enable notification. Must be unique within the tethering app. @VisibleForTesting static final int ENABLE_NOTIFICATION_ID = 1000; // Id to update and cancel restricted notification. Must be unique within the tethering app. @VisibleForTesting static final int RESTRICTED_NOTIFICATION_ID = 1001; Loading Loading @@ -120,7 +112,6 @@ public class TetheringNotificationUpdater { @Retention(RetentionPolicy.SOURCE) @IntDef(value = { ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID Loading Loading @@ -223,7 +214,6 @@ public class TetheringNotificationUpdater { final boolean tetheringActiveChanged = (downstreamTypes == DOWNSTREAM_NONE) != (mDownstreamTypesMask == DOWNSTREAM_NONE); final boolean subIdChanged = subId != mActiveDataSubId; final boolean downstreamChanged = downstreamTypes != mDownstreamTypesMask; final boolean upstreamChanged = noUpstream != mNoUpstream; final boolean roamingChanged = isRoaming != mRoaming; final boolean updateAll = tetheringActiveChanged || subIdChanged; Loading @@ -232,19 +222,10 @@ public class TetheringNotificationUpdater { mNoUpstream = noUpstream; mRoaming = isRoaming; if (updateAll || downstreamChanged) updateEnableNotification(); if (updateAll || upstreamChanged) updateNoUpstreamNotification(); if (updateAll || roamingChanged) updateRoamingNotification(); } private void updateEnableNotification() { final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; if (tetheringInactive || setupNotification() == NO_NOTIFY) { clearNotification(ENABLE_NOTIFICATION_ID); } } private void updateNoUpstreamNotification() { final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; Loading Loading @@ -310,64 +291,6 @@ public class TetheringNotificationUpdater { NO_UPSTREAM_NOTIFICATION_ID, null /* pendingIntent */, action); } /** * Returns the downstream types mask which convert from given string. * * @param types This string has to be made by "WIFI", "USB", "BT", and OR'd with the others. * * @return downstream types mask value. */ @VisibleForTesting @IntRange(from = 0, to = 7) int getDownstreamTypesMask(@NonNull final String types) { int downstreamTypesMask = DOWNSTREAM_NONE; final String[] downstreams = types.split("\\|"); for (String downstream : downstreams) { if (USB_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_USB); } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_WIFI); } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) { downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } } return downstreamTypesMask; } /** * Returns the icons {@link android.util.SparseArray} which get from given string-array resource * id. * * @param id String-array resource id * * @return {@link android.util.SparseArray} with downstream types and icon id info. */ @NonNull @VisibleForTesting 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) { if (isEmpty(config)) continue; final String[] elements = config.split(";"); if (elements.length != 2) { Log.wtf(TAG, "Unexpected format in Tethering notification configuration : " + config); continue; } final String[] types = elements[0].split(","); for (String type : types) { int mask = getDownstreamTypesMask(type); if (mask == DOWNSTREAM_NONE) continue; icons.put(mask, res.getIdentifier( elements[1].trim(), null /* defType */, null /* defPackage */)); } } return icons; } private boolean setupRoamingNotification() { final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); final boolean upstreamRoamingNotification = Loading Loading @@ -403,29 +326,6 @@ public class TetheringNotificationUpdater { return NOTIFY_DONE; } private boolean setupNotification() { 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; final String title = res.getString(R.string.tethering_notification_title); final String message = res.getString(R.string.tethering_notification_message); if (isEmpty(title) || isEmpty(message)) return NO_NOTIFY; final PendingIntent pi = PendingIntent.getActivity( mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 0 /* requestCode */, new Intent(Settings.ACTION_TETHER_SETTINGS), Intent.FLAG_ACTIVITY_NEW_TASK, null /* options */); showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID, pi, new Action[0]); return NOTIFY_DONE; } private void showNotification(@DrawableRes final int iconId, @NonNull final String title, @NonNull final String message, @NotificationId final int id, @Nullable PendingIntent pi, @NonNull final Action... actions) { Loading
packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt +39 −168 File changed.Preview size limit exceeded, changes collapsed. Show changes