Android 13 网络 Adb 分析研究
一、前言
通过代码分析发现Android13 上对 网络adb 进行了限制!
Android13原生代码要求:必现连接上某个wifi,才能进行adb ,并且切换wifi或者关闭wifi都是会停止adb。
并且Android13 上 wifi adb 端口号每次是变化的,这个也是很不方便的!
如果要做成Android11 或者之前一样,设备连接WiFi/有线网络后电脑可以直接进行adb连接,就要对系统代码进行适配修改。
之前以为设置端口号和persist.adb.tls_server.enable 属性就ok了,但是还是有些小bug,还是要完全研究一遍具体流程。
之前已经发过 adb默认端口号设置:
https://blog.csdn.net/wenzhi20102321/article/details/131056174
默认adb实现简单分析:
https://blog.csdn.net/wenzhi20102321/article/details/131774893
默认adb开启分析:
https://blog.csdn.net/wenzhi20102321/article/details/132382549
后面两个文章都是有进行了简单研究和参考价值,当时整个流程还是可以更深入了解一些,所以特意再写一篇。
这个也是全网第一个比较全面分析 Android12以上的wifi adb 代码的文章了,需要的可以点赞收藏。
下面几个分析到的Android13 的adb相关源码文件:
https://download.csdn.net/download/wenzhi20102321/88306366
二、默认adb 代码实现
关键:
1、mk 设置系统属性:persist.adb.tls_server.enable=1
2、写死端口号 5555
3、注释若干判断Wifi情况停止adb的代码
1、修改的目录:
packages\modules\adb\daemon\adb_wifi.cpp
framework\base\services\core\java\com\android\server\adb\AdbDebuggingManager.java
//修改前面两个文件就可以实现adb了,后面的文件试辅助分析的。
//虽然 SettingsProvider 也有加载 Settings属性 Settings.Global.ADB_WIFI_ENABLED ,
//但是 prop那个属性更优先,所以可以不用考虑这里默认情况
framework\base\packages\SettingsProvider\src\com\android\providers\settings\SettingsProvider.java
//增加分析定位文件,系统服务启动后会判断 属性persist.adb.tls_server.enable 进行相关操作
//如果属性设置不生效,可以在这里添加打印日志查看过程
framework\base\services\core\java\com\android\server\adb\AdbService.java
2、具体修改:
(1)在XXX_device.mk 添加属性
persist.adb.tls_server.enable = 1
手动添加,也是会记忆的!
//设置
setprop persist.adb.tls_server.enable 1
//查询
getprop persist.adb.tls_server.enable
//可以查看其他adb相关属性
getprop | grep adb
(2)设置固定端口号
+++ b/release/packages/modules/adb/daemon/adb_wifi.cpp
@@ -160,7 +160,8 @@ static void enable_wifi_debugging() {
if (sTlsServer != nullptr) {
delete sTlsServer;
}
- sTlsServer = new TlsServer(0);
+ // default port 0 means random,change to 5555 ,by liwenzhi
+ sTlsServer = new TlsServer(5555);
if (!sTlsServer->Start()) {
LOG(ERROR) << "Failed to start TlsServer";
delete sTlsServer;
固定端口号,必须是这里设置,使用service.adb.tls.port属性设置其实是没用的!
(3)去除判断网络后,设置 ADB_WIFI_ENABLED 为 0 的代码
去吃wifi网络判断,是能有线网adb和wifi 修改后还是正常adb 的关键。
一个是初始化的时候判断,另外一个是监听网络变化的时候判断,都去掉就行。
+++ b/release/frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java
public class AdbDebuggingManager {
case MSG_ADBDWIFI_ENABLE: {
if (mAdbWifiEnabled) {
break;
}
//not to check network state ,change by liwenzhi //(1)去除下面一大段判断网络和监听网络的代码
/** AdbConnectionInfo currentInfo = getCurrentWifiApInfo();
if (currentInfo == null) {
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0); //关闭 adb wifi
break;
}
if (!verifyWifiNetwork(currentInfo.getBSSID(),
currentInfo.getSSID())) {
// This means that the network is not in the list of trusted networks.
// We'll give user a prompt on whether to allow wireless debugging on
// the current wifi network.
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0);
break;
}
setAdbConnectionInfo(currentInfo); **/
//no listener network change for disable adb_wifi,by liwenzhi
/** IntentFilter intentFilter =
new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mContext.registerReceiver(mBroadcastReceiver, intentFilter); **/
SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
case MSG_ADBDWIFI_DISABLE:
if (!mAdbWifiEnabled) {
break;
}
mAdbWifiEnabled = false;
setAdbConnectionInfo(null);
//no need unregisterReceiver, because no listener network,chenge by liwenzhi,//(2)监听已经注释,不需要再注销监听
//mContext.unregisterReceiver(mBroadcastReceiver);
case MSG_ADBWIFI_ALLOW:
if (mAdbWifiEnabled) {
break;
}
String bssid = (String) msg.obj;
boolean alwaysAllow = msg.arg1 == 1;
if (alwaysAllow) {
mAdbKeyStore.addTrustedNetwork(bssid);
}
// Let's check again to make sure we didn't switch networks while verifying
// the wifi bssid.
//no to check network ,change by liwenzhi //(3)不需要判断网络
/** AdbConnectionInfo newInfo = getCurrentWifiApInfo();
if (newInfo == null || !bssid.equals(newInfo.getBSSID())) {
break;
}
setAdbConnectionInfo(newInfo); **/
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 1);
//no listener network change for disable adb_wifi,by liwenzhi //(4)不需要要监听网络变化
/** IntentFilter intentFilter =
new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mContext.registerReceiver(mBroadcastReceiver, intentFilter); **/
SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
从上面代码看到未连接wifi的情况,getCurrentWifiApInfo 获取为null,会执行关闭wifi adb!
并且还有很多网络开关变化和网络状态变化的判断。
三、日志分析查看
日志分析查看主要是:AdbService.java、AdbDebuggingManager.java、adb_wifi.cpp
AdbService 的日志默认是关闭模式的,需要设置成true,并且如果要看里面数据具体值,相关属性的日志需要自己添加打印出来。
AdbDebuggingManager 是有相关异常过程日志的
adb_wifi 该文件的打印,TAG 是adbd, 不管有没有打开adb,整个系统是一直有这个 adbd 的相关打印的,每秒大概有十几行日志!
这里查看打印相关日志多个关键字的信息命令:
可能每个系统的日志都不一样,这里因供参考:
logcat | grep -E "lwz|AdbService|changed to|adb wifi|AdbDebuggingManager"
lwz 是我自己加的关键字。
通过日志查看,正常开启的情况大概日志过程是:
01-01 08:00:22.756 496 511 I adbd : Waiting for persist.adb.tls_server.enable=1
08-16 15:13:50.123 762 762 D SystemServerTiming: StartAdbService
08-16 15:13:51.528 762 762 D AdbService: systemReady //修改 DEBUG = true 才看到的日志
08-16 15:13:51.528 762 762 D AdbService: lwz systemReady= persist.adb.tls_server.enable = 1 //自己加的日志打印
08-16 15:13:51.528 762 762 D AdbService: lwz systemReady mIsAdbWifiEnabled= true //自己加的日志打印,确认查看服务启动是否打开 adb
08-16 15:13:58.993 762 799 D AdbService: setAdbEnabled(true), mIsAdbUsbEnabled=true, mIsAdbWifiEnabled=true, transportType=0
08-16 15:13:58.994 762 762 D AdbService: lwz onChange shouldEnable = true
08-16 15:13:58.995 762 799 D AdbService: setAdbEnabled(true), mIsAdbUsbEnabled=true, mIsAdbWifiEnabled=true, transportType=1
08-16 15:13:59.015 762 802 D ActivityManagerTiming: OnBootPhase_1000_com.android.server.adb.AdbService$Lifecycle
08-16 15:13:59.016 762 802 V ActivityManagerTiming: OnBootPhase_1000_com.android.server.adb.AdbService$Lifecycle took to complete: 1ms
08-16 15:13:59.016 762 799 D AdbService: boot completed
08-16 15:13:59.033 496 511 I adbd : persist.adb.tls_server.enable changed to 1 //正常开启adb的日志
08-16 15:13:59.056 496 511 I adbd : adb wifi started on port 5555
08-16 15:13:59.058 496 511 I adbd : Waiting for persist.adb.tls_server.enable=0
如果未屏蔽网络判断,添加打印日志查看过程:
08-18 16:51:20.104 762 762 D SystemServerTiming: OnBootPhase_550_com.android.server.adb.AdbService$Lifecycle
08-18 16:51:20.104 762 762 D AdbService: systemReady
08-18 16:51:20.105 762 762 D AdbService: lwz systemReady mIsAdbWifiEnabled= true //这里说明,prop 属性已经设置了
08-18 16:51:26.248 762 798 I AdbDebuggingManager: Not connected to any wireless network. Not enabling adbwifi. //这里提示没网络,会执行关闭adb
08-18 16:51:26.586 762 762 D AdbService: lwz onChange shouldEnable = false
08-18 16:51:27.411 762 762 D AdbService: lwz onChange shouldEnable = false
08-18 16:51:27.971 762 798 D AdbService: setAdbEnabled(true), mIsAdbUsbEnabled=true, mIsAdbWifiEnabled=true, transportType=0
08-18 16:51:27.972 762 798 D AdbService: setAdbEnabled(false), mIsAdbUsbEnabled=true, mIsAdbWifiEnabled=true, transportType=1 //关闭adb
08-18 16:51:27.973 510 517 I adbd : persist.adb.tls_server.enable changed to 0 //到这里 persist.adb.tls_server.enable 属性又变成了 0
08-18 16:51:27.973 510 517 I adbd : adb wifi stopped
08-18 16:51:27.981 762 798 D AdbService: Broadcasting enable = false, type = 1
这个也是为啥配置了那个 persist.adb.tls_server.enable =1 属性后,系统启动发现获取属性还是0 ,并且wifi adb未打开。
如果打开日志开关,并且没添加自定义日志,是不会有上面这么多日志显示的。
如果代码和属性都适配了,但是还是没有默认adb ,那么就是要好好梳理代码或者多添加日志分析查看了。
四、代码流程
其实就是看 AdbService.java、AdbDebuggingManager.java、adb_wifi.cpp 这三个类之间的流程就差不多了。
adb_wifi.cpp 这类是Androi11以及之前的版本是没有的,其他的Java类是一直有的。
packages\modules\adb 这个目录也是Android12才开始有的
1、adb_wifi 底层启动
里面的日志是跑在比较前面的,比SystemServer 更早。
也是为啥设置了 persist.adb.tls_server.enable=1 能够直接使能网络adb的原因。
正常开启和关闭adb 是有相关日志的。
具体启动adb 还是靠上层调用了接口到底层才会进行开启的。
这里看一段最重要的代码
const char kWifiPortProp[] = "service.adb.tls.port"; //(1)adb 端口号属性
const char kWifiEnabledProp[] = "persist.adb.tls_server.enable"; //(2)adb prop 开关属性
//(3)底层开启adb 具体实现
static void enable_wifi_debugging() {
start_mdnsd();
if (sTlsServer != nullptr) {
delete sTlsServer;
}
sTlsServer = new TlsServer(5555); //(4)写死端口号,不写死会随机生成
if (!sTlsServer->Start()) {
LOG(ERROR) << "Failed to start TlsServer";
delete sTlsServer;
sTlsServer = nullptr;
return;
}
// Start mdns connect service for discovery
register_adb_secure_connect_service(sTlsServer->port());
//(5)开启 adb 后,这里是会有打印的,并且对端口号属性进行了赋值
//所以代码中设置端口号的prop 数值是没啥意义的
LOG(INFO) << "lwz adb wifi started on port " << sTlsServer->port();
SetProperty(kWifiPortProp, std::to_string(sTlsServer->port()));
}
//(6)底层关闭adb 具体实现
static void disable_wifi_debugging() {
if (sTlsServer != nullptr) {
delete sTlsServer;
sTlsServer = nullptr;
}
if (is_adb_secure_connect_service_registered()) {
unregister_adb_secure_connect_service();
}
kick_all_tcp_tls_transports();
//(7)关闭 adb 后,这里是会有打印的,并且对端口号属性进行了赋值
//所以代码中设置端口号的prop 数值是没啥意义的
LOG(INFO) << "adb wifi stopped";
SetProperty(kWifiPortProp, "");
}
//(8)关键:这个逻辑不难,刚开始看懵了!!
// Watches for the #kWifiEnabledProp property to toggle the TlsServer
static void start_wifi_enabled_observer() {
std::thread([]() {
bool wifi_enabled = false;
while (true) { // (9)这里不会阻塞,WaitForProperty 会等待属性设置,否则一直等待状态
std::string toggled_val = wifi_enabled ? "0" : "1";
LOG(INFO) << "lwz Waiting for " << kWifiEnabledProp << "=" << toggled_val; //(10)正常开机会打印这个,等待进入1,即等待开启状态
if (WaitForProperty(kWifiEnabledProp, toggled_val)) { //底层的等待状态,等待某个属性变成某个值
wifi_enabled = !wifi_enabled;
// (11)prop 属性变化,这里会有打印
//上面是while true,这里修改后,马上又进入了 “Waiting for”下一次属性变化的监听
LOG(INFO) << kWifiEnabledProp << " changed to " << toggled_val;
if (wifi_enabled) {
enable_wifi_debugging(); //(12)开启adb
} else {
disable_wifi_debugging(); //(13)关闭adb
}
}
}
}).detach();
}
上面13 个主要的点就是,adb cpp里面的重要流程。
其他更具体和底层的这里不进行研究分析。
参考别人写的adb 的底层线程逻辑:
https://blog.csdn.net/qq_35970872/article/details/78912611
Android13 上也有相关的底层逻辑,代码路径:
packages\modules\adb\transport.cpp
里面有线程一直在读取数据,具体逻辑我也看不懂,就不分析研究了!
2、adb 上层启动
AdbService 是SystemServer 执行 startOtherServices 里面启动的服务。
AdbService extends IAdbManager.Stub //具体暴露接口可以看 IAdbManager
AdbDebuggingManager 是一个管理adbDebug的类,在 AdbService 里面实例化,其实就是分化了一下具体执行的代码。
很多无法进入adb wifi 的情况都是在AdbDebuggingManager 拒绝的,并且重新设置了 Global属性 和 Prop 属性为0
(1)SystemServce.java 启动AdbServices代码
framework\base\services\java\com\android\server\SystemServer.java
/**
* Entry point to {@code system_server}.
*/
public final class SystemServer implements Dumpable {
private static final String ADB_SERVICE_CLASS =
"com.android.server.adb.AdbService$Lifecycle";
/**
* The main entry point from zygote.
*/
public static void main(String[] args) { //(1)java 入口方法
new SystemServer().run();
}
private void run() { //(2)启动上层系统相关服务
t.traceBegin("StartServices");
startBootstrapServices(t); //启动核心服务,电源管理、AMS、WMS、PMS等服务
startCoreServices(t); //启动关键服务,电池状态信息等服务
startOtherServices(t); //(3)启动其他服务(最多),蓝牙,wifi,通知,adb等服务
startApexServices(t); //启动app相关服务
}
private void startOtherServices(@NonNull TimingsTraceAndSlog t) { //(4)启动其他服务
t.traceBegin("startOtherServices");
// Start ADB Debugging Service
t.traceBegin("StartAdbService");
try {
mSystemServiceManager.startService(ADB_SERVICE_CLASS); //启动蓝牙相关服务
} catch (Throwable e) {
Slog.e(TAG, "Failure starting AdbService");
}
t.traceEnd();
}
}
(2)AdbServices.java 服务启动后关键代码
这个AdbService 不是具体的服务(不是四大组件里面的Service),而是通过AIDL绑定的服务,
别的类可以通过这个服务的接口对象IXXX/Manager调用里面的实现。
有个特殊的是这里有 继承了 SystemService 能监听系统启动完成。
framework\base\services\core\java\com\android\server\adb\AdbService.java
public class AdbService extends IAdbManager.Stub { //(1)不是普通Service
private static final boolean DEBUG = true; //打印默认为false,可以修改true 打开她
private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config";
private static final String WIFI_PERSISTENT_CONFIG_PROPERTY = "persist.adb.tls_server.enable";
private AdbService(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
mDebuggingManager = new AdbDebuggingManager(context); //(2)从这里看就知道 AdbDebuggingManager 不是 AdbServices 的暴露Manager
registerContentObservers(); //(3)监听 Settings.Global.ADB_WIFI_ENABLED 属性变化
LocalServices.addService(AdbManagerInternal.class, new AdbManagerInternalImpl());
}
/**
* Manages the service lifecycle for {@code AdbService} in {@code SystemServer}.
*/
public static class Lifecycle extends SystemService { //(4)监听系统启动
private AdbService mAdbService;
public Lifecycle(Context context) {
super(context);
}
@Override
public void onStart() {
mAdbService = new AdbService(getContext()); //(5)系统启动,创建对象
publishBinderService(Context.ADB_SERVICE, mAdbService);
}
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { //这个消息其实是SystemServer在启动OtherServie中间代码发出的。
mAdbService.systemReady(); //(6)系统关键服务启动完成,调用。这里比开机广播早。
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) { // 里面的 bootCompleted 方法也是重新调用了开关Wifi adb,不过不一定会跑这里。我这系统代码没看到跑这里。
FgThread.getHandler().sendMessage(obtainMessage(
AdbService::bootCompleted, mAdbService));
}
}
}
/**
* Called in response to {@code SystemService.PHASE_ACTIVITY_MANAGER_READY} from {@code
* SystemServer}.
*/
public void systemReady() { //(7)系统关键服务启动完成
if (DEBUG) Slog.d(TAG, "systemReady");
/*
* Use the normal bootmode persistent prop to maintain state of adb across
* all boot modes.
*/
//(8)判断Usb调试 是否打开
mIsAdbUsbEnabled = containsFunction(
SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""), //USB_PERSISTENT_CONFIG_PROPERTY=sys.usb.config
UsbManager.USB_FUNCTION_ADB); // USB_FUNCTION_ADB=adb
boolean shouldEnableAdbUsb = mIsAdbUsbEnabled
|| SystemProperties.getBoolean(
TestHarnessModeService.TEST_HARNESS_MODE_PROPERTY, false); //属性: persist.sys.test_harness
// 可以添加打印查看prop属性,
Slog.d(TAG, "lwz systemReady= " + WIFI_PERSISTENT_CONFIG_PROPERTY + " = " + SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));
// (9)判断Wifi adb 是否打开,persist.adb.tls_server.enable 属性是否为1
mIsAdbWifiEnabled = "1".equals(SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));
// 可以添加打印查看是否是打开wifiadb状态,
Slog.d(TAG, "lwz systemReady mIsAdbWifiEnabled= " + mIsAdbWifiEnabled);
// make sure the ADB_ENABLED setting value matches the current state
try {
//(10)保存Settings 属性后会有重新调用 setAdbEnabled,因为这里进行了监听
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_ENABLED, shouldEnableAdbUsb ? 1 : 0);
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, mIsAdbWifiEnabled ? 1 : 0);
} catch (SecurityException e) {
// If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
Slog.d(TAG, "ADB_ENABLED is restricted.");
}
}
/**
* Called in response to {@code SystemService.PHASE_BOOT_COMPLETED} from {@code SystemServer}.
*/
public void bootCompleted() { //开机完成后,调用设置方法,这边不一定调用到!
if (DEBUG) Slog.d(TAG, "boot completed + mIsAdbWifiEnabled" + mIsAdbWifiEnabled);
if (mDebuggingManager != null) {
mDebuggingManager.setAdbEnabled(mIsAdbUsbEnabled, AdbTransportType.USB);
mDebuggingManager.setAdbEnabled(mIsAdbWifiEnabled, AdbTransportType.WIFI);
}
}
}
// (11)监听Settings属性变化
private void registerContentObservers() {
try {
// register observer to listen for settings changes
mObserver = new AdbSettingsObserver();
//(12)注册监听usb开关和wifi adb开关
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
false, mObserver);
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED),
false, mObserver);
} catch (Exception e) {
Slog.e(TAG, "Error in registerContentObservers", e);
}
}
// (13)Settings属性 内部监听类,这里说明代码中修改 ADB_WIFI_ENABLED 属性或者adb shell中动态修改属性,这里也是能收到的
private class AdbSettingsObserver extends ContentObserver {
private final Uri mAdbUsbUri = Settings.Global.getUriFor(Settings.Global.ADB_ENABLED);
private final Uri mAdbWifiUri = Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED);
AdbSettingsObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange, @NonNull Uri uri, @UserIdInt int userId) {
if (mAdbUsbUri.equals(uri)) {
boolean shouldEnable = (Settings.Global.getInt(mContentResolver,
Settings.Global.ADB_ENABLED, 0) > 0);
FgThread.getHandler().sendMessage(obtainMessage(
AdbService::setAdbEnabled, AdbService.this, shouldEnable,
AdbTransportType.USB));
} else if (mAdbWifiUri.equals(uri)) { // (14)ADB_WIFI_ENABLED 属性监听回调
boolean shouldEnable = (Settings.Global.getInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0) > 0);
// (15)自己添加的打印,打印一下开关状态值
Slog.d(TAG, "lwz onChange shouldEnable = " + shouldEnable);
// (16)系统属性值变化后,执行 AdbService.setAdbEnabled 方法
FgThread.getHandler().sendMessage(obtainMessage(
AdbService::setAdbEnabled, AdbService.this, shouldEnable,
AdbTransportType.WIFI));
}
}
}
//(17) 执行usb 开关和adb开关的方法
private void setAdbEnabled(boolean enable, byte transportType) { //transportType ,usb =1,wifi = 1
if (DEBUG) {
Slog.d(TAG, "setAdbEnabled(" + enable + "), mIsAdbUsbEnabled=" + mIsAdbUsbEnabled
+ ", mIsAdbWifiEnabled=" + mIsAdbWifiEnabled + ", transportType="
+ transportType);
}
if (transportType == AdbTransportType.USB && enable != mIsAdbUsbEnabled) {
mIsAdbUsbEnabled = enable;
} else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) {
mIsAdbWifiEnabled = enable;
if (mIsAdbWifiEnabled) {
if (!AdbProperties.secure().orElse(false) && mDebuggingManager == null) {
// Start adbd. If this is secure adb, then we defer enabling adb over WiFi.
SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
mConnectionPortPoller =
new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);
mConnectionPortPoller.start(); // (18) AdbConnectionPortPoller 是一个线程对象,不清楚为啥要启动这个线程,底层也有线程!里面没看到做非常重要的事情。
}
} else {
// Stop adb over WiFi.
SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "0");
if (mConnectionPortPoller != null) {
mConnectionPortPoller.cancelAndWait(); //停止线程
mConnectionPortPoller = null;
}
}
} else {
// No change
return;
}
if (enable) {
startAdbd(); //这里的start 和 stop 无关紧要,不用关注
} else {
stopAdbd();
}
。。。。
// (19)其实这里调用 DebuggingManager 方法才是最关键的,其他都是kalife
if (mDebuggingManager != null) {
mDebuggingManager.setAdbEnabled(enable, transportType);
}
}
//这个的startAdbd 只设置了一个属性,没看到上层有判断使用,可能底层有读取这个属性
private void startAdbd() {
SystemProperties.set(CTL_START, ADBD);
}
//这个的stopAdbd 只设置了一个属性,
private void stopAdbd() {
if (!mIsAdbUsbEnabled && !mIsAdbWifiEnabled) {
SystemProperties.set(CTL_STOP, ADBD);
}
}
下面就是关键代码,AdbDebuggingManager 的分析
framework\base\services\core\java\com\android\server\adb\AdbDebuggingManager.java
private static final String TAG = "AdbDebuggingManager";
private static final boolean DEBUG = false; //打印默认为false,调试可以修改为true,查看相关日志
public void setAdbEnabled(boolean enabled, byte transportType) {
if (transportType == AdbTransportType.USB) {
mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MESSAGE_ADB_ENABLED
: AdbDebuggingHandler.MESSAGE_ADB_DISABLED);
} else if (transportType == AdbTransportType.WIFI) {
mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MSG_ADBDWIFI_ENABLE
: AdbDebuggingHandler.MSG_ADBDWIFI_DISABLE);
}
}
public void handleMessage(Message msg) {
initKeyStore();
switch (msg.what) {
case MESSAGE_ADB_ENABLED:
...
case MESSAGE_ADB_DISABLED:
...
case MSG_ADBDWIFI_ENABLE: { //(1)收到打开wifiadb 消息
if (mAdbWifiEnabled) { //(2) 已经打开的情况不用继续打开
break;
}
//not to check network state ,change by liwenzhi
// (3) 注释未打开wifi和未连接wifi情况下,调用关闭adb wifi 的代码
/** AdbConnectionInfo currentInfo = getCurrentWifiApInfo(); //这里是校验当前网络是否连接wifi
if (currentInfo == null) {
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0); //(4)未连接wifi,关闭wifi adb的情况
break;
}
if (!verifyWifiNetwork(currentInfo.getBSSID(),
currentInfo.getSSID())) { //这里是校验,当前连接的网络是否是上次连接的那个网络
// This means that the network is not in the list of trusted networks.
// We'll give user a prompt on whether to allow wireless debugging on
// the current wifi network.
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0); //(5)切换到其他网络,关闭wifi adb的情况
break;
}
//这个是保存当前连接的wifi,就是为了区分下次连接的wifi是否和上次一致
setAdbConnectionInfo(currentInfo); **/
//no listener network change for disable adb_wifi,by liwenzhi
// (6) 注释网络变化的监听,只要网络变化都会导致关闭wifi adb
/** IntentFilter intentFilter =
new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mContext.registerReceiver(mBroadcastReceiver, intentFilter); **/
SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
mConnectionPortPoller =
new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);
mConnectionPortPoller.start();
startAdbDebuggingThread(); //这线程主要是为了一直监听获取outputStream和inputStream数据,这里好像会记录每一个连接的adb设备,
mAdbWifiEnabled = true;
if (DEBUG) Slog.i(TAG, "adb start wireless adb");
break;
case MSG_ADBDWIFI_DISABLE: //关闭wifi adb
if (!mAdbWifiEnabled) { //已经关闭的情况不用管
break;
}
mAdbWifiEnabled = false;
setAdbConnectionInfo(null); //设置保存的连接wifi信息为null
mContext.unregisterReceiver(mBroadcastReceiver); //如果上面监听注释了,这里也要注释
if (mThread != null) {
mThread.sendResponse(MSG_DISABLE_ADBDWIFI);
}
onAdbdWifiServerDisconnected(-1); //这里主要是发送通知和发送广播
stopAdbDebuggingThread(); //停止相关线程
break;
}
}
// (7)自定义handler内部类,内部包含接收网络变化自定义广播接收器
class AdbDebuggingHandler extends Handler {
private NotificationManager mNotificationManager;
private boolean mAdbNotificationShown;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// We only care about when wifi is disabled, and when there is a wifi network
// change.
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { // (8)监听wifi开关变化
int state = intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
if (state == WifiManager.WIFI_STATE_DISABLED) { // (9)wifi关闭的情况,关闭wifi adb
Slog.i(TAG, "Wifi disabled. Disabling adbwifi.");
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0);
}
} else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { // (10)监听wifi连接情况变化
// We only care about wifi type connections
NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// Check for network disconnect
if (!networkInfo.isConnected()) { // (10)发生连接变化后,如果不是连接状态,就关闭wifi adb
Slog.i(TAG, "Network disconnected. Disabling adbwifi.");
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0);
return;
}
WifiManager wifiManager =
(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo == null || wifiInfo.getNetworkId() == -1) { // (11)发生连接变化后,如果信息状态不对,就关闭wifi adb
Slog.i(TAG, "Not connected to any wireless network."
+ " Not enabling adbwifi.");
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0);
}
// Check for network change
String bssid = wifiInfo.getBSSID();
if (bssid == null || bssid.isEmpty()) { // (12)发生连接变化后,如果信息ssid不对,就关闭wifi adb
Slog.e(TAG, "Unable to get the wifi ap's BSSID. Disabling adbwifi.");
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0);
}
synchronized (mAdbConnectionInfo) {
if (!bssid.equals(mAdbConnectionInfo.getBSSID())) { // (12)发生连接变化后,如果和上次连接的wifi不同,就关闭wifi adb
Slog.i(TAG, "Detected wifi network change. Disabling adbwifi.");
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_WIFI_ENABLED, 0);
}
}
}
}
}
};
从上面代码可以看到 很多情况都有设置了ADB_WIFI_ENABLED 关闭的行为。
如果没有强制的安全要求,是可以把这些关闭的,目前测试还未发现啥问题。
这里设置了 Settings.Global.ADB_WIFI_ENABLED 属性代码,那么哪里会处理?
再往上看一下发现 AdbService 里面是有监听这个属性变化的,
然后调用 setAdbEnabled 方法,里面有设置prop属性哦,
接着调用了 AdbDebuggingManager.setAdbEnabled ,进行很相关线程启动,属性判断,网络判断等操作!
3、上层adb 相关流程
系统prop属性:persist.adb.tls_server.enable 0/1
Settings.GLOBAL属性:adb_wifi_enabled 0/1
(1)系统刚启动的情况
1、adb_wifi.cpp 优先启动,start_wifi_enabled_observer方法进入等待 prop 属性改变状态
2、SystemServer 启动 AdbService
3、AdbService.systemReady方法判断prop属性,执行是否开启adb,设置Settings.GLOBAL值
4、因为 AdbService 已经监听了 Settings.GLOBAL值的变化,所以会调用监听到变化,先设置prop方法,再执行setAdbEnabled 方法
5、接着调用 AdbDebuggingManager.setAdbEnabled ,进行很相关线程启动,属性判断,网络判断等操作!
6、如果网络未开启或者未连接等情况,AdbDebuggingManager 会设置 Settings.GLOBAL.ADB_WIFI_ENABLED 为0
7、AdbService 监听监听到Settings属性变化,又调用了 setAdbEnabled 关闭wifi adb
所以未屏蔽 AdbDebuggingManager 判断网络情况的代码就会出现:
设置属性 persist.adb.tls_server.enable = 1,系统启动后,发现还是为0;
设置属性 Settings.GLOBAL.ADB_WIFI_ENABLED =1 ,系统启动后,发现还是为0;
adb或者代码中,手动设置 ADB_WIFI_ENABLED =1 属性后,等下看,属性还是 0 ;
(2)直接设置Settings属性的情况
1、AdbService 监听监听到Settings属性变化,设置prop属性值,调用了 setAdbEnabled 方法
2、接着调用 AdbDebuggingManager.setAdbEnabled ,进行很相关线程启动,属性判断,网络判断等操作!
3、未屏蔽网络变化的情况,可能会导致 设置 Settings.GLOBAL.ADB_WIFI_ENABLED 为0
AdbService 监听监听到Settings属性变化,重新设置prop属性值
注意这里即使未屏蔽网络判断的代码,设置Settings.GLOBAL.ADB_WIFI_ENABLED = 1,
系统是会先调用开启adb,但是又马上关闭adb的,这个在 adb_wifi.cpp 是可以看到相关日志的。
(3)直接设置prop属性的情况
1、adb_wifi.cpp 的 start_wifi_enabled_observer 方法接收到prop属性变化
2、如果是开启就创建对应Server,随机生成端口号,设置端口号prop属性 service.adb.tls.port
3、如果关闭就删除Server,并且端口号属性设置空字符串
可以看到设置prop 属性是不经过java代码的;
如果未屏蔽网络相关判断,设置prop开启wifi adb,那么重启设备或者网络变化都是会导致wifi adb关闭的。
端口号是在开启adb的时候设置在系统的,只修改prop端口号属性是没有效果的。
默认流程所有有可能是:
1、系统默认启动,未设置prop属性,未屏蔽网络判断
SystemServer --> AdbService.systemReady --> 读取prop --> 设置GLOBAL值 -->
onChange --> setAdbEnabled -- > 设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(false)
2、系统启动:只设置prop属性,未屏蔽网络判断
SystemServer --> AdbService.systemReady --> 读取prop --> 设置GLOBAL值 -->
onChange --> setAdbEnabled -- > 设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(true)
-- > 判断到网络未连接 --> 设置GLOBAL值 -->
onChange --> setAdbEnabled -- > 设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(false)
3、系统启动:设置prop属性,并且屏蔽网络判断
SystemServer --> AdbService.systemReady --> 读取prop --> 设置GLOBAL值 -->
onChange --> setAdbEnabled -- >设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(true)
4、后期设置 Settings.GLOBAL.ADB_WIFI_ENABLED =1 属性值,未屏蔽网络判断
Settings.GLOBAL.ADB_WIFI_ENABLED = 1 -->
AdbService.onChange --> setAdbEnabled -- > 设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(true)
-- > 判断到网络未连接 --> 设置GLOBAL值 -->
onChange --> setAdbEnabled -- > 设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(false)
5、后期设置 Settings.GLOBAL.ADB_WIFI_ENABLED =1 属性值,屏蔽网络判断
Settings.GLOBAL.ADB_WIFI_ENABLED = 1 -->
AdbService.onChange --> setAdbEnabled -- >设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(true)
6、后期设置 persist.adb.tls_server.enable =1 属性值, 不管屏不屏蔽网络变化,都是一样的
设置prop属性( -->adb_wifi.cpp 会收到属性变化) --> 启动adb ,设置端口号
但是最后一种情况,如果没有屏蔽网络变化,就会很不稳定,因为网络变化,就会关闭 wifi adb。
7、未屏蔽网络判断,网络改变情况
AdbDebuggingManager 广播接收到网络变化 --> 设置GLOBAL值 -->
AdbService.onChange --> setAdbEnabled -- > 设置prop属性( -->adb_wifi.cpp 会收到属性变化) 并且调用 AdbDebuggingManager.setAdbEnabled(false)
这里也有个简单结论:
设置默认 Settings.GLOBAL.ADB_WIFI_ENABLED 的值是没用的,系统流程会给他重新设置 0
如果未屏蔽网络变化的代码,即使设置了prop属性和GLOBAL属性也是没有意义的,系统流程也是会给它设置成 0
五、如果修改后依然无法网络adb连接分析
(1)查看adb默认值
getprop persist.adb.tls_server.enable //查看prop属性
settings get global adb_wifi_enabled //查看Settings 属性
setprop persist.adb.tls_server.enable 1 //设置prop属性
settings put global adb_wifi_enabled 1 //设置Settings 属性
如果设置 adb_wifi_enabled 1 ,等下查询马上又变成0 ,那么就是未去除网络变化的监听和判断。
(2)查看是否去除了限制adb的网络判断代码
这个就要看 AdbDebuggingManager 里面的代码了。
1、查看是否去除了网络变化的监听
WifiManager.WIFI_STATE_CHANGED_ACTION
WifiManager.NETWORK_STATE_CHANGED_ACTION
2、查看是否对 getCurrentWifiApInfo() 的判断进行了屏蔽
3、查看是否去除了执行:Settings.Global.putInt(mContentResolver,Settings.Global.ADB_WIFI_ENABLED, 0);
(3)查看是否打印了底层具体执行adb_wifi.cpp adb 开关的处理
//开启wifi 的日志
LOG(INFO) << "adb wifi started on port " << sTlsServer->port();
//停止wifi adb的日志
LOG(INFO) << "adb wifi stopped";
所以查看关键字"adb wifi"可以看到日志。
logcat | grep "adb wifi"
日志如下:
console:/ # logcat | grep "adb wifi"
09-05 21:09:31.755 668 712 I adbd : adb wifi stopped //关闭日志
09-05 21:09:48.326 668 712 I adbd : adb wifi started on port 5555 //开启日志,并且会打印 端口号
(4)还是有问题,只能在代码流程上添加日志了
1、打开 AdbService 和 AdbDebuggingManager 的日志开关
2、AdbService.systemReady()添加打印默认属性
Slog.d(TAG, "lwz systemReady= " + WIFI_PERSISTENT_CONFIG_PROPERTY + " = " + SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));
Slog.d(TAG, "lwz systemReady mIsAdbWifiEnabled= " + mIsAdbWifiEnabled);
3、AdbSettingsObserver.onChange 打印Settings属性变化后的值
Slog.d(TAG, "lwz onChange shouldEnable = " + shouldEnable);
AdbDebuggingManager 也可以看情况添加一下日志,但是里面关闭 wifi adb的情况基本是有打印的。
这是通过命令logcat 打印多个关键字,就能看到问题原因了。
logcat | grep -E "AdbService|AdbDebuggingManager|adb wifi|XXX" //XXX 是自己定义的
(5)device offline
连接之后提示设备离线,那么可能是电脑的adb 版本和 Android设备不匹配,一般换成adb 高的版本就行,也有可能需要换成adb 低的版本。
六、其他
1、adb 相关属性
(1) prop属性:persist.adb.tls_server.enable
系统启动后,AdbService 会判断该属性决定后续是否执行开启adb。
(2)prop属性:service.adb.tls.port
该属性是 adb_wifi.cpp 使能adb的时候设置的. 后续让你知道它的端口号。
所以设置这个属性值是没有意义的。
在 adb_wifi.cpp,初始化 TlsServer 设置固定端口 5555,那么这个属性一直就是 5555. 如果未设置就是随机的5位数。
(3)Settings属性:Settings.Global.ADB_WIFI_ENABLED 具体名称是 “adb_wifi_enabled”
同时在 AdbService 是有监听 这个Global 属性的变化,关联上 AdbDebuggingManager ,设置 adb 使能。
查询和设置命令:
//查询属性;
setttings get global adb_wifi_enabled
//设置属性 0/1:
setttings put global adb_wifi_enabled 1
该属性是系统上层设置的一个值,原本主要用来记录adb wifi 的开关状态。
因为Android13 会判断当前wifi是否是信任的,切换wifi后设置这个属性是无效的。
但是如果修改了上面去除网络限制对策后,直接设置Global属性,是会正常开关adb的。
如果未去除网络限制对策,你会发现 adb_wifi_enabled 无法设置成1,
因为 AdbDebuggingManager 在开启的是会还会判断网络情况,如果没有网络会设置为 0 .
2、AdbService.java、AdbDebuggingManager.java、adb_wifi.cpp 的关系
(1) adb_wifi 是底层init/cpp 启动的服务
里面的日志是跑在比较前面的,比SystemServer 更早。
正常开启和关闭adb 是有相关日志的。
(2)AdbService启动时机
AdbService 是SystemServer 执行 startOtherServices 里面启动的服务。
AdbService extends IAdbManager.Stub //具体暴露接口可以看 IAdbManager
(3)AdbDebuggingManager 是一个管理adbDebug的类,
该类在 AdbService 里面实例化,其实就是分化了一下具体执行的代码。
很多无法进入adb wifi 的情况都是在AdbDebuggingManager 拒绝的,并且重新设置了 Global属性 和 Prop 属性为0
AdbDebuggingManager 并不是普通的暴露给其他类使用的SDK类,只是一个普通类,并且里面监听了网络变化广播,是可以收到网络变化的。
适配了去除网络限制上面代码后,就应用而言,使用 Settings.Global.ADB_WIFI_ENABLED 控制和或者当前 网络adb状态最合适的。
虽然使用prop 属性也能生效,但是系统应用Settings判断的是Settings.Global.ADB_WIFI_ENABLED的值是否为1,
会出现adb状态显示不同步的情况。文章来源:https://www.toymoban.com/news/detail-705480.html
别人分析的user版本不能使用adb问题(版本不是最新的,写的比较复杂):
https://blog.csdn.net/kc58236582/article/details/53502177/文章来源地址https://www.toymoban.com/news/detail-705480.html
到了这里,关于Android 13 网络 Adb相关流程深入分析研究的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!