Loading services/core/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,7 @@ java_library_static { "securebox", "apache-commons-math", "apache-commons-compress", "adb_flags_lib", "battery_saver_flag_lib", "notification_flags_lib", "power_hint_flags_lib", Loading services/core/java/com/android/server/adb/AdbBroadcastReceiver.java +19 −5 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -29,14 +29,18 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; /** Monitors device Wifi and Network status in order to enable/disable ADB Wifi accordingly. */ public class AdbBroadcastReceiver extends BroadcastReceiver { /** * Monitors Wi-Fi state changes to automatically disable ADB over Wi-Fi when the device disconnects * from Wi-Fi. */ public class AdbBroadcastReceiver extends BroadcastReceiver implements AdbNetworkMonitor { private static final String TAG = AdbBroadcastReceiver.class.getSimpleName(); private final ContentResolver mContentResolver; private final Context mContext; private final AdbConnectionInfo mAdbConnectionInfo; private boolean mStarted = false; AdbBroadcastReceiver(@NonNull Context context, @NonNull AdbConnectionInfo info) { mContext = context; Loading @@ -44,14 +48,24 @@ public class AdbBroadcastReceiver extends BroadcastReceiver { mAdbConnectionInfo = info; } void register() { @Override public void register() { if (mStarted) { return; } IntentFilter intentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mContext.registerReceiver(this, intentFilter); mStarted = true; } void unregister() { @Override public void unregister() { if (!mStarted) { return; } mContext.unregisterReceiver(this); mStarted = false; } private void disableWifi(String reason) { Loading services/core/java/com/android/server/adb/AdbDebuggingManager.java +10 −6 Original line number Diff line number Diff line Loading @@ -474,8 +474,7 @@ public class AdbDebuggingManager { private NotificationManager mNotificationManager; private boolean mAdbNotificationShown; private final AdbBroadcastReceiver mBroadcastReceiver = new AdbBroadcastReceiver(mContext, mAdbConnectionInfo); private final AdbNetworkMonitor mAdbNetworkMonitor; private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; Loading Loading @@ -605,6 +604,12 @@ public class AdbDebuggingManager { thread.setHandler(this); } mThread = thread; if (com.android.server.adb.Flags.allowAdbWifiReconnect()) { mAdbNetworkMonitor = new AdbWifiNetworkMonitor(mContext, mAdbKeyStore::isTrustedNetwork); } else { mAdbNetworkMonitor = new AdbBroadcastReceiver(mContext, mAdbConnectionInfo); } } // Show when at least one device is connected. Loading Loading @@ -827,8 +832,7 @@ public class AdbDebuggingManager { } mAdbConnectionInfo.copy(currentInfo); mBroadcastReceiver.register(); mAdbNetworkMonitor.register(); ensureAdbDebuggingThreadAlive(); startTLSPortPoller(); startAdbdWifi(); Loading @@ -842,7 +846,7 @@ public class AdbDebuggingManager { } mAdbWifiEnabled = false; mAdbConnectionInfo.clear(); mBroadcastReceiver.unregister(); mAdbNetworkMonitor.unregister(); stopAdbdWifi(); onAdbdWifiServerDisconnected(-1); } Loading @@ -864,7 +868,7 @@ public class AdbDebuggingManager { } mAdbConnectionInfo.copy(newInfo); Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, 1); mBroadcastReceiver.register(); mAdbNetworkMonitor.register(); ensureAdbDebuggingThreadAlive(); startTLSPortPoller(); startAdbdWifi(); Loading services/core/java/com/android/server/adb/AdbNetworkMonitor.java 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.adb; /** * Interface for monitoring network connectivity to enable/disable ADB over Wi-Fi. * * <p>Implementations of this interface are responsible for registering and unregistering network * monitoring processes. */ public interface AdbNetworkMonitor { /** * Registers the network monitoring process. * * <p>It is safe to call this method multiple times; implementations should handle this without * side effects. */ void register(); /** * Unregisters the network monitoring process. * * <p>It is safe to call this method multiple times, even if the monitor was not previously * registered. */ void unregister(); } services/core/java/com/android/server/adb/AdbWifiNetworkMonitor.java 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.adb; import android.content.ContentResolver; import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.wifi.WifiInfo; import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; /** * Monitors Wi-Fi state changes to automatically enable ADB over Wi-Fi when the device connects to a * trusted network and disable it otherwise. */ public class AdbWifiNetworkMonitor extends ConnectivityManager.NetworkCallback implements AdbNetworkMonitor { private static final String TAG = AdbWifiNetworkMonitor.class.getSimpleName(); private final Context mContext; private final ContentResolver mContentResolver; private final IsTrustedNetworkChecker mIsTrustedNetworkChecker; /** * Stores the BSSID of the most recently processed network. * * <p>This is used to deduplicate callbacks, which may fire multiple times for the same network * change event. By comparing against the last known BSSID, we can ensure we only react to a * given network update once. */ @Nullable private String mLastBSSID; private boolean mStarted = false; @VisibleForTesting interface IsTrustedNetworkChecker { boolean isTrusted(String bssid); } AdbWifiNetworkMonitor( @NonNull Context context, @NonNull IsTrustedNetworkChecker isTrustedNetworkChecker) { // Flag is required to receive BSSID info in the callback. super(ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO); mContext = context; mContentResolver = mContext.getContentResolver(); mIsTrustedNetworkChecker = isTrustedNetworkChecker; register(); } @Override public final void register() { if (mStarted) { return; } ConnectivityManager connectivityManager = mContext.getSystemService(ConnectivityManager.class); NetworkRequest request = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); connectivityManager.registerNetworkCallback(request, this); mStarted = true; } @Override public final void unregister() { // This NetworkMonitor must remain registered even when ADB over Wi-Fi is disabled. // This allows it to automatically re-enable ADB over Wi-Fi when the device connects // to a trusted network. } @Override public final void onCapabilitiesChanged( @NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { if (networkCapabilities.getTransportInfo() instanceof WifiInfo wifiInfo) { Slog.i(TAG, "Wi-Fi network available"); processWifiConnection(wifiInfo); } else { setAdbWifiState(false, "Wi-Fi network not available. Disabling adb over Wi-Fi."); } } @Override public final void onLost(@NonNull Network network) { mLastBSSID = null; setAdbWifiState(false, "Wi-Fi network lost. Disabling adb over Wi-Fi."); } private void processWifiConnection(WifiInfo wifiInfo) { if (wifiInfo == null || wifiInfo.getNetworkId() == -1 || TextUtils.isEmpty(wifiInfo.getBSSID())) { setAdbWifiState(false, "Wi-Fi connection info is invalid. Disabling adb over Wi-Fi."); return; } if (TextUtils.equals(wifiInfo.getBSSID(), mLastBSSID)) { Slog.i(TAG, "Received the same Wi-Fi BSSID. Ignoring."); return; } mLastBSSID = wifiInfo.getBSSID(); boolean isTrusted = mIsTrustedNetworkChecker.isTrusted(wifiInfo.getBSSID()); if (isTrusted) { setAdbWifiState(true, "Connected to a trusted Wi-Fi network. Enabling adb over Wi-Fi."); } else { setAdbWifiState( false, "Connected to a non-trusted Wi-Fi network. Disabling adb over Wi-Fi."); } } @VisibleForTesting protected void setAdbWifiState(boolean enabled, String reason) { Slog.i(TAG, reason); Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, enabled ? 1 : 0); } } Loading
services/core/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,7 @@ java_library_static { "securebox", "apache-commons-math", "apache-commons-compress", "adb_flags_lib", "battery_saver_flag_lib", "notification_flags_lib", "power_hint_flags_lib", Loading
services/core/java/com/android/server/adb/AdbBroadcastReceiver.java +19 −5 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -29,14 +29,18 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; /** Monitors device Wifi and Network status in order to enable/disable ADB Wifi accordingly. */ public class AdbBroadcastReceiver extends BroadcastReceiver { /** * Monitors Wi-Fi state changes to automatically disable ADB over Wi-Fi when the device disconnects * from Wi-Fi. */ public class AdbBroadcastReceiver extends BroadcastReceiver implements AdbNetworkMonitor { private static final String TAG = AdbBroadcastReceiver.class.getSimpleName(); private final ContentResolver mContentResolver; private final Context mContext; private final AdbConnectionInfo mAdbConnectionInfo; private boolean mStarted = false; AdbBroadcastReceiver(@NonNull Context context, @NonNull AdbConnectionInfo info) { mContext = context; Loading @@ -44,14 +48,24 @@ public class AdbBroadcastReceiver extends BroadcastReceiver { mAdbConnectionInfo = info; } void register() { @Override public void register() { if (mStarted) { return; } IntentFilter intentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mContext.registerReceiver(this, intentFilter); mStarted = true; } void unregister() { @Override public void unregister() { if (!mStarted) { return; } mContext.unregisterReceiver(this); mStarted = false; } private void disableWifi(String reason) { Loading
services/core/java/com/android/server/adb/AdbDebuggingManager.java +10 −6 Original line number Diff line number Diff line Loading @@ -474,8 +474,7 @@ public class AdbDebuggingManager { private NotificationManager mNotificationManager; private boolean mAdbNotificationShown; private final AdbBroadcastReceiver mBroadcastReceiver = new AdbBroadcastReceiver(mContext, mAdbConnectionInfo); private final AdbNetworkMonitor mAdbNetworkMonitor; private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; Loading Loading @@ -605,6 +604,12 @@ public class AdbDebuggingManager { thread.setHandler(this); } mThread = thread; if (com.android.server.adb.Flags.allowAdbWifiReconnect()) { mAdbNetworkMonitor = new AdbWifiNetworkMonitor(mContext, mAdbKeyStore::isTrustedNetwork); } else { mAdbNetworkMonitor = new AdbBroadcastReceiver(mContext, mAdbConnectionInfo); } } // Show when at least one device is connected. Loading Loading @@ -827,8 +832,7 @@ public class AdbDebuggingManager { } mAdbConnectionInfo.copy(currentInfo); mBroadcastReceiver.register(); mAdbNetworkMonitor.register(); ensureAdbDebuggingThreadAlive(); startTLSPortPoller(); startAdbdWifi(); Loading @@ -842,7 +846,7 @@ public class AdbDebuggingManager { } mAdbWifiEnabled = false; mAdbConnectionInfo.clear(); mBroadcastReceiver.unregister(); mAdbNetworkMonitor.unregister(); stopAdbdWifi(); onAdbdWifiServerDisconnected(-1); } Loading @@ -864,7 +868,7 @@ public class AdbDebuggingManager { } mAdbConnectionInfo.copy(newInfo); Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, 1); mBroadcastReceiver.register(); mAdbNetworkMonitor.register(); ensureAdbDebuggingThreadAlive(); startTLSPortPoller(); startAdbdWifi(); Loading
services/core/java/com/android/server/adb/AdbNetworkMonitor.java 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.adb; /** * Interface for monitoring network connectivity to enable/disable ADB over Wi-Fi. * * <p>Implementations of this interface are responsible for registering and unregistering network * monitoring processes. */ public interface AdbNetworkMonitor { /** * Registers the network monitoring process. * * <p>It is safe to call this method multiple times; implementations should handle this without * side effects. */ void register(); /** * Unregisters the network monitoring process. * * <p>It is safe to call this method multiple times, even if the monitor was not previously * registered. */ void unregister(); }
services/core/java/com/android/server/adb/AdbWifiNetworkMonitor.java 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.adb; import android.content.ContentResolver; import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.wifi.WifiInfo; import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; /** * Monitors Wi-Fi state changes to automatically enable ADB over Wi-Fi when the device connects to a * trusted network and disable it otherwise. */ public class AdbWifiNetworkMonitor extends ConnectivityManager.NetworkCallback implements AdbNetworkMonitor { private static final String TAG = AdbWifiNetworkMonitor.class.getSimpleName(); private final Context mContext; private final ContentResolver mContentResolver; private final IsTrustedNetworkChecker mIsTrustedNetworkChecker; /** * Stores the BSSID of the most recently processed network. * * <p>This is used to deduplicate callbacks, which may fire multiple times for the same network * change event. By comparing against the last known BSSID, we can ensure we only react to a * given network update once. */ @Nullable private String mLastBSSID; private boolean mStarted = false; @VisibleForTesting interface IsTrustedNetworkChecker { boolean isTrusted(String bssid); } AdbWifiNetworkMonitor( @NonNull Context context, @NonNull IsTrustedNetworkChecker isTrustedNetworkChecker) { // Flag is required to receive BSSID info in the callback. super(ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO); mContext = context; mContentResolver = mContext.getContentResolver(); mIsTrustedNetworkChecker = isTrustedNetworkChecker; register(); } @Override public final void register() { if (mStarted) { return; } ConnectivityManager connectivityManager = mContext.getSystemService(ConnectivityManager.class); NetworkRequest request = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); connectivityManager.registerNetworkCallback(request, this); mStarted = true; } @Override public final void unregister() { // This NetworkMonitor must remain registered even when ADB over Wi-Fi is disabled. // This allows it to automatically re-enable ADB over Wi-Fi when the device connects // to a trusted network. } @Override public final void onCapabilitiesChanged( @NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { if (networkCapabilities.getTransportInfo() instanceof WifiInfo wifiInfo) { Slog.i(TAG, "Wi-Fi network available"); processWifiConnection(wifiInfo); } else { setAdbWifiState(false, "Wi-Fi network not available. Disabling adb over Wi-Fi."); } } @Override public final void onLost(@NonNull Network network) { mLastBSSID = null; setAdbWifiState(false, "Wi-Fi network lost. Disabling adb over Wi-Fi."); } private void processWifiConnection(WifiInfo wifiInfo) { if (wifiInfo == null || wifiInfo.getNetworkId() == -1 || TextUtils.isEmpty(wifiInfo.getBSSID())) { setAdbWifiState(false, "Wi-Fi connection info is invalid. Disabling adb over Wi-Fi."); return; } if (TextUtils.equals(wifiInfo.getBSSID(), mLastBSSID)) { Slog.i(TAG, "Received the same Wi-Fi BSSID. Ignoring."); return; } mLastBSSID = wifiInfo.getBSSID(); boolean isTrusted = mIsTrustedNetworkChecker.isTrusted(wifiInfo.getBSSID()); if (isTrusted) { setAdbWifiState(true, "Connected to a trusted Wi-Fi network. Enabling adb over Wi-Fi."); } else { setAdbWifiState( false, "Connected to a non-trusted Wi-Fi network. Disabling adb over Wi-Fi."); } } @VisibleForTesting protected void setAdbWifiState(boolean enabled, String reason) { Slog.i(TAG, reason); Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, enabled ? 1 : 0); } }