Loading packages/Tethering/res/values/config.xml +45 −0 Original line number Diff line number Diff line Loading @@ -155,4 +155,49 @@ <!-- 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> </resources> packages/Tethering/res/values/overlayable.xml +40 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> <overlayable name="TetheringConfig"> <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_ncm_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="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> </resources> packages/Tethering/res/values/strings.xml +7 −5 Original line number Diff line number Diff line Loading @@ -15,19 +15,21 @@ --> <resources> <!-- 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> <!-- 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> <!-- 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 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> <!-- 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> <!-- 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> </resources> No newline at end of file packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +10 −110 Original line number 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.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import static com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; Loading @@ -72,7 +70,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; 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.State; import com.android.internal.util.StateMachine; import com.android.networkstack.tethering.R; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -224,14 +220,13 @@ public class Tethering { private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ConnectedClientsTracker mConnectedClientsTracker; private final TetheringThreadExecutor mExecutor; private final TetheringNotificationUpdater mNotificationUpdater; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; // All the usage of mTetheringEventCallback should run in the same thread. private ITetheringEventCallback mTetheringEventCallback = null; private volatile TetheringConfiguration mConfig; private InterfaceSet mCurrentUpstreamIfaceSet; private Notification.Builder mTetheredNotificationBuilder; private int mLastNotificationId; private boolean mRndisEnabled; // track the RNDIS function enabled state // True iff. WiFi tethering should be started when soft AP is ready. Loading @@ -255,6 +250,7 @@ public class Tethering { mContext = mDeps.getContext(); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); mNotificationUpdater = mDeps.getNotificationUpdater(mContext); mPublicSync = new Object(); Loading Loading @@ -738,13 +734,10 @@ public class Tethering { final ArrayList<String> erroredList = new ArrayList<>(); final ArrayList<Integer> lastErrorList = new ArrayList<>(); boolean wifiTethered = false; boolean usbTethered = false; boolean bluetoothTethered = false; final TetheringConfiguration cfg = mConfig; mTetherStatesParcel = new TetherStatesParcel(); int downstreamTypesMask = DOWNSTREAM_NONE; synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); Loading @@ -758,11 +751,11 @@ public class Tethering { localOnlyList.add(iface); } else if (tetherState.lastState == IpServer.STATE_TETHERED) { if (cfg.isUsb(iface)) { usbTethered = true; downstreamTypesMask |= (1 << TETHERING_USB); } else if (cfg.isWifi(iface)) { wifiTethered = true; downstreamTypesMask |= (1 << TETHERING_WIFI); } else if (cfg.isBluetooth(iface)) { bluetoothTethered = true; downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } tetherList.add(iface); } Loading Loading @@ -796,98 +789,7 @@ public class Tethering { "error", TextUtils.join(",", erroredList))); } if (usbTethered) { 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; } mNotificationUpdater.onDownstreamChanged(downstreamTypesMask); } private class StateReceiver extends BroadcastReceiver { Loading Loading @@ -1081,12 +983,10 @@ public class Tethering { return; } mWrapper.clearTetheredNotification(); // TODO: Add user restrictions notification. final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); if (newlyDisallowed && isTetheringActiveOnDevice) { mWrapper.showTetheredNotification( R.drawable.stat_sys_tether_general, false); mWrapper.untetherAll(); // TODO(b/148139325): send tetheringSupported on restriction change } Loading packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +9 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import androidx.annotation.NonNull; import com.android.internal.util.StateMachine; import java.util.ArrayList; Loading Loading @@ -101,6 +103,13 @@ public abstract class TetheringDependencies { (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. */ Loading Loading
packages/Tethering/res/values/config.xml +45 −0 Original line number Diff line number Diff line Loading @@ -155,4 +155,49 @@ <!-- 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> </resources>
packages/Tethering/res/values/overlayable.xml +40 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> <overlayable name="TetheringConfig"> <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_ncm_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="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> </resources>
packages/Tethering/res/values/strings.xml +7 −5 Original line number Diff line number Diff line Loading @@ -15,19 +15,21 @@ --> <resources> <!-- 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> <!-- 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> <!-- 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 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> <!-- 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> <!-- 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> </resources> No newline at end of file
packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +10 −110 Original line number 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.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import static com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; Loading @@ -72,7 +70,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; 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.State; import com.android.internal.util.StateMachine; import com.android.networkstack.tethering.R; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -224,14 +220,13 @@ public class Tethering { private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ConnectedClientsTracker mConnectedClientsTracker; private final TetheringThreadExecutor mExecutor; private final TetheringNotificationUpdater mNotificationUpdater; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; // All the usage of mTetheringEventCallback should run in the same thread. private ITetheringEventCallback mTetheringEventCallback = null; private volatile TetheringConfiguration mConfig; private InterfaceSet mCurrentUpstreamIfaceSet; private Notification.Builder mTetheredNotificationBuilder; private int mLastNotificationId; private boolean mRndisEnabled; // track the RNDIS function enabled state // True iff. WiFi tethering should be started when soft AP is ready. Loading @@ -255,6 +250,7 @@ public class Tethering { mContext = mDeps.getContext(); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); mNotificationUpdater = mDeps.getNotificationUpdater(mContext); mPublicSync = new Object(); Loading Loading @@ -738,13 +734,10 @@ public class Tethering { final ArrayList<String> erroredList = new ArrayList<>(); final ArrayList<Integer> lastErrorList = new ArrayList<>(); boolean wifiTethered = false; boolean usbTethered = false; boolean bluetoothTethered = false; final TetheringConfiguration cfg = mConfig; mTetherStatesParcel = new TetherStatesParcel(); int downstreamTypesMask = DOWNSTREAM_NONE; synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); Loading @@ -758,11 +751,11 @@ public class Tethering { localOnlyList.add(iface); } else if (tetherState.lastState == IpServer.STATE_TETHERED) { if (cfg.isUsb(iface)) { usbTethered = true; downstreamTypesMask |= (1 << TETHERING_USB); } else if (cfg.isWifi(iface)) { wifiTethered = true; downstreamTypesMask |= (1 << TETHERING_WIFI); } else if (cfg.isBluetooth(iface)) { bluetoothTethered = true; downstreamTypesMask |= (1 << TETHERING_BLUETOOTH); } tetherList.add(iface); } Loading Loading @@ -796,98 +789,7 @@ public class Tethering { "error", TextUtils.join(",", erroredList))); } if (usbTethered) { 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; } mNotificationUpdater.onDownstreamChanged(downstreamTypesMask); } private class StateReceiver extends BroadcastReceiver { Loading Loading @@ -1081,12 +983,10 @@ public class Tethering { return; } mWrapper.clearTetheredNotification(); // TODO: Add user restrictions notification. final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); if (newlyDisallowed && isTetheringActiveOnDevice) { mWrapper.showTetheredNotification( R.drawable.stat_sys_tether_general, false); mWrapper.untetherAll(); // TODO(b/148139325): send tetheringSupported on restriction change } Loading
packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +9 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import androidx.annotation.NonNull; import com.android.internal.util.StateMachine; import java.util.ArrayList; Loading Loading @@ -101,6 +103,13 @@ public abstract class TetheringDependencies { (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. */ Loading