Loading packages/Tethering/res/values/config.xml +45 −0 Original line number Original line Diff line number Diff line Loading @@ -157,4 +157,49 @@ <!-- ComponentName of the service used to run no ui tether provisioning. --> <!-- 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> <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> </resources> </resources> packages/Tethering/res/values/overlayable.xml +40 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> <resources xmlns:android="http://schemas.android.com/apk/res/android"> <overlayable name="TetheringConfig"> <overlayable name="TetheringConfig"> <policy type="product|system|vendor"> <policy type="product|system|vendor"> <!-- Params from config.xml that can be overlaid --> <item type="array" name="config_tether_usb_regexs"/> <item type="array" name="config_tether_usb_regexs"/> <item type="array" name="config_tether_ncm_regexs" /> <item type="array" name="config_tether_ncm_regexs" /> <item type="array" name="config_tether_wifi_regexs"/> <item type="array" name="config_tether_wifi_regexs"/> Loading @@ -31,6 +32,45 @@ <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="string" name="config_wifi_tether_enable"/> <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> </policy> </overlayable> </overlayable> </resources> </resources> packages/Tethering/res/values/strings.xml +7 −5 Original line number Original line Diff line number Diff line Loading @@ -15,19 +15,21 @@ --> --> <resources> <resources> <!-- Shown when the device is tethered --> <!-- Shown when the device is tethered --> <!-- Strings for tethered notification title [CHAR LIMIT=200] --> <!-- String for tethered notification title [CHAR LIMIT=200] --> <string name="tethered_notification_title">Tethering or hotspot active</string> <string name="tethered_notification_title">Tethering or hotspot active</string> <!-- Strings for tethered notification message [CHAR LIMIT=200] --> <!-- String for tethered notification message [CHAR LIMIT=200] --> <string name="tethered_notification_message">Tap to set up.</string> <string name="tethered_notification_message">Tap to set up.</string> <!-- This notification is shown when tethering has been disabled on a user's device. <!-- This notification is shown when tethering has been disabled on a user's device. The device is managed by the user's employer. Tethering can't be turned on unless the The device is managed by the user's employer. Tethering can't be turned on unless the IT administrator allows it. The noun "admin" is another reference for "IT administrator." --> IT administrator allows it. The noun "admin" is another reference for "IT administrator." --> <!-- Strings for tether disabling notification title [CHAR LIMIT=200] --> <!-- String for tether disabling notification title [CHAR LIMIT=200] --> <string name="disable_tether_notification_title">Tethering is disabled</string> <string name="disable_tether_notification_title">Tethering is disabled</string> <!-- Strings for tether disabling notification message [CHAR LIMIT=200] --> <!-- String for tether disabling notification message [CHAR LIMIT=200] --> <string name="disable_tether_notification_message">Contact your admin for details</string> <string name="disable_tether_notification_message">Contact your admin for details</string> <!-- Strings for tether notification channel name [CHAR LIMIT=200] --> <!-- This string should be consistent with the "Hotspot & tethering" text in the "Network and Internet" settings page. That is currently the tether_settings_title_all string. --> <!-- String for tether notification channel name [CHAR LIMIT=200] --> <string name="notification_channel_tethering_status">Hotspot & tethering status</string> <string name="notification_channel_tethering_status">Hotspot & tethering status</string> </resources> </resources> No newline at end of file packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +10 −110 Original line number Original line Diff line number Diff line Loading @@ -59,10 +59,8 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import android.app.Notification; import static com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.usage.NetworkStatsManager; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothPan; Loading @@ -72,7 +70,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.ConnectivityManager; import android.net.EthernetManager; import android.net.EthernetManager; Loading Loading @@ -128,7 +125,6 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; import com.android.internal.util.MessageUtils; import com.android.internal.util.State; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine; import com.android.networkstack.tethering.R; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -224,14 +220,13 @@ public class Tethering { private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ConnectedClientsTracker mConnectedClientsTracker; private final ConnectedClientsTracker mConnectedClientsTracker; private final TetheringThreadExecutor mExecutor; private final TetheringThreadExecutor mExecutor; private final TetheringNotificationUpdater mNotificationUpdater; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; // All the usage of mTetheringEventCallback should run in the same thread. // All the usage of mTetheringEventCallback should run in the same thread. private ITetheringEventCallback mTetheringEventCallback = null; private ITetheringEventCallback mTetheringEventCallback = null; private volatile TetheringConfiguration mConfig; private volatile TetheringConfiguration mConfig; private InterfaceSet mCurrentUpstreamIfaceSet; private InterfaceSet mCurrentUpstreamIfaceSet; private Notification.Builder mTetheredNotificationBuilder; private int mLastNotificationId; private boolean mRndisEnabled; // track the RNDIS function enabled state private boolean mRndisEnabled; // track the RNDIS function enabled state // True iff. WiFi tethering should be started when soft AP is ready. // True iff. WiFi tethering should be started when soft AP is ready. Loading @@ -255,6 +250,7 @@ public class Tethering { mContext = mDeps.getContext(); mContext = mDeps.getContext(); mNetd = mDeps.getINetd(mContext); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); mLooper = mDeps.getTetheringLooper(); mNotificationUpdater = mDeps.getNotificationUpdater(mContext); mPublicSync = new Object(); mPublicSync = new Object(); Loading Loading @@ -738,13 +734,10 @@ public class Tethering { final ArrayList<String> erroredList = new ArrayList<>(); final ArrayList<String> erroredList = new ArrayList<>(); final ArrayList<Integer> lastErrorList = new ArrayList<>(); final ArrayList<Integer> lastErrorList = new ArrayList<>(); boolean wifiTethered = false; boolean usbTethered = false; boolean bluetoothTethered = false; final TetheringConfiguration cfg = mConfig; final TetheringConfiguration cfg = mConfig; mTetherStatesParcel = new TetherStatesParcel(); mTetherStatesParcel = new TetherStatesParcel(); int downstreamTypesMask = DOWNSTREAM_NONE; synchronized (mPublicSync) { synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); TetherState tetherState = mTetherStates.valueAt(i); Loading @@ -758,11 +751,11 @@ public class Tethering { localOnlyList.add(iface); localOnlyList.add(iface); } else if (tetherState.lastState == IpServer.STATE_TETHERED) { } else if (tetherState.lastState == IpServer.STATE_TETHERED) { if (cfg.isUsb(iface)) { if (cfg.isUsb(iface)) { usbTethered = true; downstreamTypesMask |= (1 << TETHERING_USB); } else if (cfg.isWifi(iface)) { } else if (cfg.isWifi(iface)) { wifiTethered = true; downstreamTypesMask |= (1 << TETHERING_WIFI); } else if (cfg.isBluetooth(iface)) { } else if (cfg.isBluetooth(iface)) { bluetoothTethered = true; downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } } tetherList.add(iface); tetherList.add(iface); } } Loading Loading @@ -796,98 +789,7 @@ public class Tethering { "error", TextUtils.join(",", erroredList))); "error", TextUtils.join(",", erroredList))); } } if (usbTethered) { mNotificationUpdater.onDownstreamChanged(downstreamTypesMask); if (wifiTethered || bluetoothTethered) { showTetheredNotification(R.drawable.stat_sys_tether_general); } else { showTetheredNotification(R.drawable.stat_sys_tether_usb); } } else if (wifiTethered) { if (bluetoothTethered) { showTetheredNotification(R.drawable.stat_sys_tether_general); } else { /* We now have a status bar icon for WifiTethering, so drop the notification */ clearTetheredNotification(); } } else if (bluetoothTethered) { showTetheredNotification(R.drawable.stat_sys_tether_bluetooth); } else { clearTetheredNotification(); } } private void showTetheredNotification(int id) { showTetheredNotification(id, true); } @VisibleForTesting protected void showTetheredNotification(int id, boolean tetheringOn) { NotificationManager notificationManager = (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager == null) { return; } final NotificationChannel channel = new NotificationChannel( "TETHERING_STATUS", mContext.getResources().getString(R.string.notification_channel_tethering_status), NotificationManager.IMPORTANCE_LOW); notificationManager.createNotificationChannel(channel); if (mLastNotificationId != 0) { if (mLastNotificationId == id) { return; } notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } Intent intent = new Intent(); intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); PendingIntent pi = PendingIntent.getActivity( mContext.createContextAsUser(UserHandle.CURRENT, 0), 0, intent, 0, null); Resources r = mContext.getResources(); final CharSequence title; final CharSequence message; if (tetheringOn) { title = r.getText(R.string.tethered_notification_title); message = r.getText(R.string.tethered_notification_message); } else { title = r.getText(R.string.disable_tether_notification_title); message = r.getText(R.string.disable_tether_notification_message); } if (mTetheredNotificationBuilder == null) { mTetheredNotificationBuilder = new Notification.Builder(mContext, channel.getId()); mTetheredNotificationBuilder.setWhen(0) .setOngoing(true) .setColor(mContext.getColor( android.R.color.system_notification_accent_color)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setCategory(Notification.CATEGORY_STATUS); } mTetheredNotificationBuilder.setSmallIcon(id) .setContentTitle(title) .setContentText(message) .setContentIntent(pi); mLastNotificationId = id; notificationManager.notify(null, mLastNotificationId, mTetheredNotificationBuilder.build()); } @VisibleForTesting protected void clearTetheredNotification() { NotificationManager notificationManager = (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null && mLastNotificationId != 0) { notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } } } private class StateReceiver extends BroadcastReceiver { private class StateReceiver extends BroadcastReceiver { Loading Loading @@ -1081,12 +983,10 @@ public class Tethering { return; return; } } mWrapper.clearTetheredNotification(); // TODO: Add user restrictions notification. final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); if (newlyDisallowed && isTetheringActiveOnDevice) { if (newlyDisallowed && isTetheringActiveOnDevice) { mWrapper.showTetheredNotification( R.drawable.stat_sys_tether_general, false); mWrapper.untetherAll(); mWrapper.untetherAll(); // TODO(b/148139325): send tetheringSupported on restriction change // TODO(b/148139325): send tetheringSupported on restriction change } } Loading packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Looper; import android.os.Looper; import androidx.annotation.NonNull; import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine; import java.util.ArrayList; import java.util.ArrayList; Loading Loading @@ -101,6 +103,13 @@ public abstract class TetheringDependencies { (IBinder) context.getSystemService(Context.NETD_SERVICE)); (IBinder) context.getSystemService(Context.NETD_SERVICE)); } } /** * Get a reference to the TetheringNotificationUpdater to be used by tethering. */ public TetheringNotificationUpdater getNotificationUpdater(@NonNull final Context ctx) { return new TetheringNotificationUpdater(ctx); } /** /** * Get tethering thread looper. * Get tethering thread looper. */ */ Loading Loading
packages/Tethering/res/values/config.xml +45 −0 Original line number Original line Diff line number Diff line Loading @@ -157,4 +157,49 @@ <!-- ComponentName of the service used to run no ui tether provisioning. --> <!-- 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> <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> </resources> </resources>
packages/Tethering/res/values/overlayable.xml +40 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> <resources xmlns:android="http://schemas.android.com/apk/res/android"> <overlayable name="TetheringConfig"> <overlayable name="TetheringConfig"> <policy type="product|system|vendor"> <policy type="product|system|vendor"> <!-- Params from config.xml that can be overlaid --> <item type="array" name="config_tether_usb_regexs"/> <item type="array" name="config_tether_usb_regexs"/> <item type="array" name="config_tether_ncm_regexs" /> <item type="array" name="config_tether_ncm_regexs" /> <item type="array" name="config_tether_wifi_regexs"/> <item type="array" name="config_tether_wifi_regexs"/> Loading @@ -31,6 +32,45 @@ <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="string" name="config_mobile_hotspot_provision_response"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="integer" name="config_mobile_hotspot_provision_check_period"/> <item type="string" name="config_wifi_tether_enable"/> <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> </policy> </overlayable> </overlayable> </resources> </resources>
packages/Tethering/res/values/strings.xml +7 −5 Original line number Original line Diff line number Diff line Loading @@ -15,19 +15,21 @@ --> --> <resources> <resources> <!-- Shown when the device is tethered --> <!-- Shown when the device is tethered --> <!-- Strings for tethered notification title [CHAR LIMIT=200] --> <!-- String for tethered notification title [CHAR LIMIT=200] --> <string name="tethered_notification_title">Tethering or hotspot active</string> <string name="tethered_notification_title">Tethering or hotspot active</string> <!-- Strings for tethered notification message [CHAR LIMIT=200] --> <!-- String for tethered notification message [CHAR LIMIT=200] --> <string name="tethered_notification_message">Tap to set up.</string> <string name="tethered_notification_message">Tap to set up.</string> <!-- This notification is shown when tethering has been disabled on a user's device. <!-- This notification is shown when tethering has been disabled on a user's device. The device is managed by the user's employer. Tethering can't be turned on unless the The device is managed by the user's employer. Tethering can't be turned on unless the IT administrator allows it. The noun "admin" is another reference for "IT administrator." --> IT administrator allows it. The noun "admin" is another reference for "IT administrator." --> <!-- Strings for tether disabling notification title [CHAR LIMIT=200] --> <!-- String for tether disabling notification title [CHAR LIMIT=200] --> <string name="disable_tether_notification_title">Tethering is disabled</string> <string name="disable_tether_notification_title">Tethering is disabled</string> <!-- Strings for tether disabling notification message [CHAR LIMIT=200] --> <!-- String for tether disabling notification message [CHAR LIMIT=200] --> <string name="disable_tether_notification_message">Contact your admin for details</string> <string name="disable_tether_notification_message">Contact your admin for details</string> <!-- Strings for tether notification channel name [CHAR LIMIT=200] --> <!-- This string should be consistent with the "Hotspot & tethering" text in the "Network and Internet" settings page. That is currently the tether_settings_title_all string. --> <!-- String for tether notification channel name [CHAR LIMIT=200] --> <string name="notification_channel_tethering_status">Hotspot & tethering status</string> <string name="notification_channel_tethering_status">Hotspot & tethering status</string> </resources> </resources> No newline at end of file
packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +10 −110 Original line number Original line Diff line number Diff line Loading @@ -59,10 +59,8 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import android.app.Notification; import static com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.usage.NetworkStatsManager; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothPan; Loading @@ -72,7 +70,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.ConnectivityManager; import android.net.EthernetManager; import android.net.EthernetManager; Loading Loading @@ -128,7 +125,6 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; import com.android.internal.util.MessageUtils; import com.android.internal.util.State; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine; import com.android.networkstack.tethering.R; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -224,14 +220,13 @@ public class Tethering { private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ConnectedClientsTracker mConnectedClientsTracker; private final ConnectedClientsTracker mConnectedClientsTracker; private final TetheringThreadExecutor mExecutor; private final TetheringThreadExecutor mExecutor; private final TetheringNotificationUpdater mNotificationUpdater; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; // All the usage of mTetheringEventCallback should run in the same thread. // All the usage of mTetheringEventCallback should run in the same thread. private ITetheringEventCallback mTetheringEventCallback = null; private ITetheringEventCallback mTetheringEventCallback = null; private volatile TetheringConfiguration mConfig; private volatile TetheringConfiguration mConfig; private InterfaceSet mCurrentUpstreamIfaceSet; private InterfaceSet mCurrentUpstreamIfaceSet; private Notification.Builder mTetheredNotificationBuilder; private int mLastNotificationId; private boolean mRndisEnabled; // track the RNDIS function enabled state private boolean mRndisEnabled; // track the RNDIS function enabled state // True iff. WiFi tethering should be started when soft AP is ready. // True iff. WiFi tethering should be started when soft AP is ready. Loading @@ -255,6 +250,7 @@ public class Tethering { mContext = mDeps.getContext(); mContext = mDeps.getContext(); mNetd = mDeps.getINetd(mContext); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); mLooper = mDeps.getTetheringLooper(); mNotificationUpdater = mDeps.getNotificationUpdater(mContext); mPublicSync = new Object(); mPublicSync = new Object(); Loading Loading @@ -738,13 +734,10 @@ public class Tethering { final ArrayList<String> erroredList = new ArrayList<>(); final ArrayList<String> erroredList = new ArrayList<>(); final ArrayList<Integer> lastErrorList = new ArrayList<>(); final ArrayList<Integer> lastErrorList = new ArrayList<>(); boolean wifiTethered = false; boolean usbTethered = false; boolean bluetoothTethered = false; final TetheringConfiguration cfg = mConfig; final TetheringConfiguration cfg = mConfig; mTetherStatesParcel = new TetherStatesParcel(); mTetherStatesParcel = new TetherStatesParcel(); int downstreamTypesMask = DOWNSTREAM_NONE; synchronized (mPublicSync) { synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); TetherState tetherState = mTetherStates.valueAt(i); Loading @@ -758,11 +751,11 @@ public class Tethering { localOnlyList.add(iface); localOnlyList.add(iface); } else if (tetherState.lastState == IpServer.STATE_TETHERED) { } else if (tetherState.lastState == IpServer.STATE_TETHERED) { if (cfg.isUsb(iface)) { if (cfg.isUsb(iface)) { usbTethered = true; downstreamTypesMask |= (1 << TETHERING_USB); } else if (cfg.isWifi(iface)) { } else if (cfg.isWifi(iface)) { wifiTethered = true; downstreamTypesMask |= (1 << TETHERING_WIFI); } else if (cfg.isBluetooth(iface)) { } else if (cfg.isBluetooth(iface)) { bluetoothTethered = true; downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } } tetherList.add(iface); tetherList.add(iface); } } Loading Loading @@ -796,98 +789,7 @@ public class Tethering { "error", TextUtils.join(",", erroredList))); "error", TextUtils.join(",", erroredList))); } } if (usbTethered) { mNotificationUpdater.onDownstreamChanged(downstreamTypesMask); if (wifiTethered || bluetoothTethered) { showTetheredNotification(R.drawable.stat_sys_tether_general); } else { showTetheredNotification(R.drawable.stat_sys_tether_usb); } } else if (wifiTethered) { if (bluetoothTethered) { showTetheredNotification(R.drawable.stat_sys_tether_general); } else { /* We now have a status bar icon for WifiTethering, so drop the notification */ clearTetheredNotification(); } } else if (bluetoothTethered) { showTetheredNotification(R.drawable.stat_sys_tether_bluetooth); } else { clearTetheredNotification(); } } private void showTetheredNotification(int id) { showTetheredNotification(id, true); } @VisibleForTesting protected void showTetheredNotification(int id, boolean tetheringOn) { NotificationManager notificationManager = (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager == null) { return; } final NotificationChannel channel = new NotificationChannel( "TETHERING_STATUS", mContext.getResources().getString(R.string.notification_channel_tethering_status), NotificationManager.IMPORTANCE_LOW); notificationManager.createNotificationChannel(channel); if (mLastNotificationId != 0) { if (mLastNotificationId == id) { return; } notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } Intent intent = new Intent(); intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); PendingIntent pi = PendingIntent.getActivity( mContext.createContextAsUser(UserHandle.CURRENT, 0), 0, intent, 0, null); Resources r = mContext.getResources(); final CharSequence title; final CharSequence message; if (tetheringOn) { title = r.getText(R.string.tethered_notification_title); message = r.getText(R.string.tethered_notification_message); } else { title = r.getText(R.string.disable_tether_notification_title); message = r.getText(R.string.disable_tether_notification_message); } if (mTetheredNotificationBuilder == null) { mTetheredNotificationBuilder = new Notification.Builder(mContext, channel.getId()); mTetheredNotificationBuilder.setWhen(0) .setOngoing(true) .setColor(mContext.getColor( android.R.color.system_notification_accent_color)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setCategory(Notification.CATEGORY_STATUS); } mTetheredNotificationBuilder.setSmallIcon(id) .setContentTitle(title) .setContentText(message) .setContentIntent(pi); mLastNotificationId = id; notificationManager.notify(null, mLastNotificationId, mTetheredNotificationBuilder.build()); } @VisibleForTesting protected void clearTetheredNotification() { NotificationManager notificationManager = (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0) .getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null && mLastNotificationId != 0) { notificationManager.cancel(null, mLastNotificationId); mLastNotificationId = 0; } } } private class StateReceiver extends BroadcastReceiver { private class StateReceiver extends BroadcastReceiver { Loading Loading @@ -1081,12 +983,10 @@ public class Tethering { return; return; } } mWrapper.clearTetheredNotification(); // TODO: Add user restrictions notification. final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); if (newlyDisallowed && isTetheringActiveOnDevice) { if (newlyDisallowed && isTetheringActiveOnDevice) { mWrapper.showTetheredNotification( R.drawable.stat_sys_tether_general, false); mWrapper.untetherAll(); mWrapper.untetherAll(); // TODO(b/148139325): send tetheringSupported on restriction change // TODO(b/148139325): send tetheringSupported on restriction change } } Loading
packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Looper; import android.os.Looper; import androidx.annotation.NonNull; import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine; import java.util.ArrayList; import java.util.ArrayList; Loading Loading @@ -101,6 +103,13 @@ public abstract class TetheringDependencies { (IBinder) context.getSystemService(Context.NETD_SERVICE)); (IBinder) context.getSystemService(Context.NETD_SERVICE)); } } /** * Get a reference to the TetheringNotificationUpdater to be used by tethering. */ public TetheringNotificationUpdater getNotificationUpdater(@NonNull final Context ctx) { return new TetheringNotificationUpdater(ctx); } /** /** * Get tethering thread looper. * Get tethering thread looper. */ */ Loading