Loading proto/src/system_messages.proto +4 −0 Original line number Original line Diff line number Diff line Loading @@ -255,6 +255,10 @@ message SystemMessage { // Inform the user a foreground service while-in-use permission is restricted. // Inform the user a foreground service while-in-use permission is restricted. NOTE_FOREGROUND_SERVICE_WHILE_IN_USE_PERMISSION = 61; NOTE_FOREGROUND_SERVICE_WHILE_IN_USE_PERMISSION = 61; // Display the Android Debug Protocol status // Package: android NOTE_ADB_WIFI_ACTIVE = 62; // ADD_NEW_IDS_ABOVE_THIS_LINE // ADD_NEW_IDS_ABOVE_THIS_LINE // Legacy IDs with arbitrary values appear below // Legacy IDs with arbitrary values appear below // Legacy IDs existed as stable non-conflicting constants prior to the O release // Legacy IDs existed as stable non-conflicting constants prior to the O release Loading services/core/java/com/android/server/adb/AdbDebuggingManager.java +1209 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/adb/AdbService.java +130 −16 Original line number Original line Diff line number Diff line Loading @@ -21,8 +21,10 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.content.ContentResolver; import android.content.ContentResolver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.database.ContentObserver; import android.debug.AdbManager; import android.debug.AdbManagerInternal; import android.debug.AdbManagerInternal; import android.debug.AdbTransportType; import android.debug.AdbTransportType; import android.debug.IAdbManager; import android.debug.IAdbManager; Loading @@ -34,6 +36,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.IBinder; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemProperties; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings; import android.service.adb.AdbServiceDumpProto; import android.service.adb.AdbServiceDumpProto; import android.sysprop.AdbProperties; import android.sysprop.AdbProperties; Loading @@ -44,6 +47,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.LocalServices; Loading @@ -54,12 +58,34 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.Collections; import java.util.Collections; import java.util.Map; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** /** * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization * of devices allowed to connect to ADB. * of devices allowed to connect to ADB. */ */ public class AdbService extends IAdbManager.Stub { public class AdbService extends IAdbManager.Stub { /** * Adb native daemon. */ static final String ADBD = "adbd"; /** * Command to start native service. */ static final String CTL_START = "ctl.start"; /** * Command to start native service. */ static final String CTL_STOP = "ctl.stop"; // The tcp port adb is currently using AtomicInteger mConnectionPort = new AtomicInteger(-1); private final AdbConnectionPortListener mPortListener = new AdbConnectionPortListener(); private AdbDebuggingManager.AdbConnectionPortPoller mConnectionPortPoller; /** /** * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}. * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}. */ */ Loading Loading @@ -129,9 +155,8 @@ public class AdbService extends IAdbManager.Stub { mIsAdbUsbEnabled = containsFunction( mIsAdbUsbEnabled = containsFunction( SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""), SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""), UsbManager.USB_FUNCTION_ADB); UsbManager.USB_FUNCTION_ADB); // TODO(joshuaduong): Read the adb wifi state from a persistent system mIsAdbWifiEnabled = "1".equals( // property (persist.sys.adb.wifi). SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0")); mIsAdbWifiEnabled = false; // register observer to listen for settings changes // register observer to listen for settings changes mObserver = new AdbSettingsObserver(); mObserver = new AdbSettingsObserver(); Loading Loading @@ -189,6 +214,7 @@ public class AdbService extends IAdbManager.Stub { * May also contain vendor-specific default functions for testing purposes. * May also contain vendor-specific default functions for testing purposes. */ */ private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"; 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 final Context mContext; private final Context mContext; private final ContentResolver mContentResolver; private final ContentResolver mContentResolver; Loading Loading @@ -245,8 +271,9 @@ public class AdbService extends IAdbManager.Stub { } } @Override @Override public void allowDebugging(boolean alwaysAllow, String publicKey) { public void allowDebugging(boolean alwaysAllow, @NonNull String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); Preconditions.checkStringNotEmpty(publicKey); if (mDebuggingManager != null) { if (mDebuggingManager != null) { mDebuggingManager.allowDebugging(alwaysAllow, publicKey); mDebuggingManager.allowDebugging(alwaysAllow, publicKey); } } Loading Loading @@ -296,53 +323,118 @@ public class AdbService extends IAdbManager.Stub { } } @Override @Override public void allowWirelessDebugging(boolean alwaysAllow, String bssid) { public void allowWirelessDebugging(boolean alwaysAllow, @NonNull String bssid) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED Preconditions.checkStringNotEmpty(bssid); if (mDebuggingManager != null) { mDebuggingManager.allowWirelessDebugging(alwaysAllow, bssid); } } } @Override @Override public void denyWirelessDebugging() { public void denyWirelessDebugging() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { mDebuggingManager.denyWirelessDebugging(); } } } @Override @Override public Map<String, PairDevice> getPairedDevices() { public Map<String, PairDevice> getPairedDevices() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { return mDebuggingManager.getPairedDevices(); } return null; return null; } } @Override @Override public void unpairDevice(String fingerprint) { public void unpairDevice(@NonNull String fingerprint) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED Preconditions.checkStringNotEmpty(fingerprint); if (mDebuggingManager != null) { mDebuggingManager.unpairDevice(fingerprint); } } } @Override @Override public void enablePairingByPairingCode() { public void enablePairingByPairingCode() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { mDebuggingManager.enablePairingByPairingCode(); } } } @Override @Override public void enablePairingByQrCode(String serviceName, String password) { public void enablePairingByQrCode(@NonNull String serviceName, @NonNull String password) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkStringNotEmpty(password); if (mDebuggingManager != null) { mDebuggingManager.enablePairingByQrCode(serviceName, password); } } } @Override @Override public void disablePairing() { public void disablePairing() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { mDebuggingManager.disablePairing(); } } } @Override @Override public int getAdbWirelessPort() { public int getAdbWirelessPort() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { return 0; return mDebuggingManager.getAdbWirelessPort(); } // If ro.adb.secure=0 return mConnectionPort.get(); } /** * This listener is only used when ro.adb.secure=0. Otherwise, AdbDebuggingManager will * do this. */ class AdbConnectionPortListener implements AdbDebuggingManager.AdbConnectionPortListener { public void onPortReceived(int port) { if (port > 0 && port <= 65535) { mConnectionPort.set(port); } else { mConnectionPort.set(-1); // Turn off wifi debugging, since the server did not start. try { Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, 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."); } } broadcastPortInfo(mConnectionPort.get()); } } private void broadcastPortInfo(int port) { Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION); intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, (port >= 0) ? AdbManager.WIRELESS_STATUS_CONNECTED : AdbManager.WIRELESS_STATUS_DISCONNECTED); intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); Slog.i(TAG, "sent port broadcast port=" + port); } private void startAdbd() { SystemProperties.set(CTL_START, ADBD); } private void stopAdbd() { if (!mIsAdbUsbEnabled && !mIsAdbWifiEnabled) { SystemProperties.set(CTL_STOP, ADBD); } } } private void setAdbEnabled(boolean enable, byte transportType) { private void setAdbEnabled(boolean enable, byte transportType) { Loading @@ -356,11 +448,33 @@ public class AdbService extends IAdbManager.Stub { mIsAdbUsbEnabled = enable; mIsAdbUsbEnabled = enable; } else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) { } else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) { mIsAdbWifiEnabled = enable; 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(); } } else { // Stop adb over WiFi. SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"); if (mConnectionPortPoller != null) { mConnectionPortPoller.cancelAndWait(); mConnectionPortPoller = null; } } } else { } else { // No change // No change return; return; } } if (enable) { startAdbd(); } else { stopAdbd(); } for (IAdbTransport transport : mTransports.values()) { for (IAdbTransport transport : mTransports.values()) { try { try { transport.onAdbEnabled(enable, transportType); transport.onAdbEnabled(enable, transportType); Loading services/core/jni/Android.bp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ cc_library_static { "BroadcastRadio/regions.cpp", "BroadcastRadio/regions.cpp", "stats/PowerStatsPuller.cpp", "stats/PowerStatsPuller.cpp", "stats/SubsystemSleepStatePuller.cpp", "stats/SubsystemSleepStatePuller.cpp", "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_ConsumerIrService.cpp", "com_android_server_ConsumerIrService.cpp", Loading Loading @@ -86,6 +87,8 @@ cc_library_static { cc_defaults { cc_defaults { name: "libservices.core-libs", name: "libservices.core-libs", shared_libs: [ shared_libs: [ "libadb_pairing_server", "libadb_pairing_connection", "libandroid_runtime", "libandroid_runtime", "libandroidfw", "libandroidfw", "libaudioclient", "libaudioclient", Loading services/core/jni/com_android_server_adb_AdbDebuggingManager.cpp 0 → 100644 +168 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2019 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. */ #define LOG_TAG "AdbDebuggingManager-JNI" #define LOG_NDEBUG 0 #include <algorithm> #include <condition_variable> #include <mutex> #include <optional> #include <random> #include <string> #include <vector> #include <adb/pairing/pairing_server.h> #include <android-base/properties.h> #include <utils/Log.h> #include <nativehelper/JNIHelp.h> #include "jni.h" namespace android { // ---------------------------------------------------------------------------- namespace { template <class T, class N> class JSmartWrapper { public: JSmartWrapper(JNIEnv* env, T* jData) : mEnv(env), mJData(jData) {} virtual ~JSmartWrapper() = default; const N* data() const { return mRawData; } jsize size() const { return mSize; } protected: N* mRawData = nullptr; JNIEnv* mEnv = nullptr; T* mJData = nullptr; jsize mSize = 0; }; // JSmartWrapper class JStringUTFWrapper : public JSmartWrapper<jstring, const char> { public: explicit JStringUTFWrapper(JNIEnv* env, jstring* str) : JSmartWrapper(env, str) { mRawData = env->GetStringUTFChars(*str, NULL); mSize = env->GetStringUTFLength(*str); } virtual ~JStringUTFWrapper() { if (data()) { mEnv->ReleaseStringUTFChars(*mJData, mRawData); } } }; // JStringUTFWrapper struct ServerDeleter { void operator()(PairingServerCtx* p) { pairing_server_destroy(p); } }; using PairingServerPtr = std::unique_ptr<PairingServerCtx, ServerDeleter>; struct PairingResultWaiter { std::mutex mutex_; std::condition_variable cv_; std::optional<bool> is_valid_; PeerInfo peer_info_; static void ResultCallback(const PeerInfo* peer_info, void* opaque) { auto* p = reinterpret_cast<PairingResultWaiter*>(opaque); { std::unique_lock<std::mutex> lock(p->mutex_); if (peer_info) { memcpy(&(p->peer_info_), peer_info, sizeof(PeerInfo)); } p->is_valid_ = (peer_info != nullptr); } p->cv_.notify_one(); } }; PairingServerPtr sServer; std::unique_ptr<PairingResultWaiter> sWaiter; } // namespace static jint native_pairing_start(JNIEnv* env, jobject thiz, jstring guid, jstring password) { // Server-side only sends its GUID on success. PeerInfo system_info = {}; system_info.type = ADB_DEVICE_GUID; JStringUTFWrapper guidWrapper(env, &guid); memcpy(system_info.data, guidWrapper.data(), guidWrapper.size()); JStringUTFWrapper passwordWrapper(env, &password); // Create the pairing server sServer = PairingServerPtr( pairing_server_new_no_cert(reinterpret_cast<const uint8_t*>(passwordWrapper.data()), passwordWrapper.size(), &system_info, 0)); sWaiter.reset(new PairingResultWaiter); uint16_t port = pairing_server_start(sServer.get(), sWaiter->ResultCallback, sWaiter.get()); if (port == 0) { ALOGE("Failed to start pairing server"); return -1; } return port; } static void native_pairing_cancel(JNIEnv* /* env */, jclass /* clazz */) { if (sServer != nullptr) { sServer.reset(); } } static jboolean native_pairing_wait(JNIEnv* env, jobject thiz) { ALOGI("Waiting for pairing server to complete"); std::unique_lock<std::mutex> lock(sWaiter->mutex_); if (!sWaiter->is_valid_.has_value()) { sWaiter->cv_.wait(lock, [&]() { return sWaiter->is_valid_.has_value(); }); } if (!*(sWaiter->is_valid_)) { return JNI_FALSE; } std::string peer_public_key = reinterpret_cast<char*>(sWaiter->peer_info_.data); // Write to PairingThread's member variables jclass clazz = env->GetObjectClass(thiz); jfieldID mPublicKey = env->GetFieldID(clazz, "mPublicKey", "Ljava/lang/String;"); jstring jpublickey = env->NewStringUTF(peer_public_key.c_str()); env->SetObjectField(thiz, mPublicKey, jpublickey); return JNI_TRUE; } // ---------------------------------------------------------------------------- static const JNINativeMethod gPairingThreadMethods[] = { /* name, signature, funcPtr */ {"native_pairing_start", "(Ljava/lang/String;Ljava/lang/String;)I", (void*)native_pairing_start}, {"native_pairing_cancel", "()V", (void*)native_pairing_cancel}, {"native_pairing_wait", "()Z", (void*)native_pairing_wait}, }; int register_android_server_AdbDebuggingManager(JNIEnv* env) { int res = jniRegisterNativeMethods(env, "com/android/server/adb/AdbDebuggingManager$PairingThread", gPairingThreadMethods, NELEM(gPairingThreadMethods)); (void)res; // Faked use when LOG_NDEBUG. LOG_FATAL_IF(res < 0, "Unable to register native methods."); return 0; } } /* namespace android */ Loading
proto/src/system_messages.proto +4 −0 Original line number Original line Diff line number Diff line Loading @@ -255,6 +255,10 @@ message SystemMessage { // Inform the user a foreground service while-in-use permission is restricted. // Inform the user a foreground service while-in-use permission is restricted. NOTE_FOREGROUND_SERVICE_WHILE_IN_USE_PERMISSION = 61; NOTE_FOREGROUND_SERVICE_WHILE_IN_USE_PERMISSION = 61; // Display the Android Debug Protocol status // Package: android NOTE_ADB_WIFI_ACTIVE = 62; // ADD_NEW_IDS_ABOVE_THIS_LINE // ADD_NEW_IDS_ABOVE_THIS_LINE // Legacy IDs with arbitrary values appear below // Legacy IDs with arbitrary values appear below // Legacy IDs existed as stable non-conflicting constants prior to the O release // Legacy IDs existed as stable non-conflicting constants prior to the O release Loading
services/core/java/com/android/server/adb/AdbDebuggingManager.java +1209 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/adb/AdbService.java +130 −16 Original line number Original line Diff line number Diff line Loading @@ -21,8 +21,10 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.content.ContentResolver; import android.content.ContentResolver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.database.ContentObserver; import android.debug.AdbManager; import android.debug.AdbManagerInternal; import android.debug.AdbManagerInternal; import android.debug.AdbTransportType; import android.debug.AdbTransportType; import android.debug.IAdbManager; import android.debug.IAdbManager; Loading @@ -34,6 +36,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.IBinder; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemProperties; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings; import android.service.adb.AdbServiceDumpProto; import android.service.adb.AdbServiceDumpProto; import android.sysprop.AdbProperties; import android.sysprop.AdbProperties; Loading @@ -44,6 +47,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.LocalServices; Loading @@ -54,12 +58,34 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.Collections; import java.util.Collections; import java.util.Map; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** /** * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization * of devices allowed to connect to ADB. * of devices allowed to connect to ADB. */ */ public class AdbService extends IAdbManager.Stub { public class AdbService extends IAdbManager.Stub { /** * Adb native daemon. */ static final String ADBD = "adbd"; /** * Command to start native service. */ static final String CTL_START = "ctl.start"; /** * Command to start native service. */ static final String CTL_STOP = "ctl.stop"; // The tcp port adb is currently using AtomicInteger mConnectionPort = new AtomicInteger(-1); private final AdbConnectionPortListener mPortListener = new AdbConnectionPortListener(); private AdbDebuggingManager.AdbConnectionPortPoller mConnectionPortPoller; /** /** * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}. * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}. */ */ Loading Loading @@ -129,9 +155,8 @@ public class AdbService extends IAdbManager.Stub { mIsAdbUsbEnabled = containsFunction( mIsAdbUsbEnabled = containsFunction( SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""), SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""), UsbManager.USB_FUNCTION_ADB); UsbManager.USB_FUNCTION_ADB); // TODO(joshuaduong): Read the adb wifi state from a persistent system mIsAdbWifiEnabled = "1".equals( // property (persist.sys.adb.wifi). SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0")); mIsAdbWifiEnabled = false; // register observer to listen for settings changes // register observer to listen for settings changes mObserver = new AdbSettingsObserver(); mObserver = new AdbSettingsObserver(); Loading Loading @@ -189,6 +214,7 @@ public class AdbService extends IAdbManager.Stub { * May also contain vendor-specific default functions for testing purposes. * May also contain vendor-specific default functions for testing purposes. */ */ private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"; 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 final Context mContext; private final Context mContext; private final ContentResolver mContentResolver; private final ContentResolver mContentResolver; Loading Loading @@ -245,8 +271,9 @@ public class AdbService extends IAdbManager.Stub { } } @Override @Override public void allowDebugging(boolean alwaysAllow, String publicKey) { public void allowDebugging(boolean alwaysAllow, @NonNull String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); Preconditions.checkStringNotEmpty(publicKey); if (mDebuggingManager != null) { if (mDebuggingManager != null) { mDebuggingManager.allowDebugging(alwaysAllow, publicKey); mDebuggingManager.allowDebugging(alwaysAllow, publicKey); } } Loading Loading @@ -296,53 +323,118 @@ public class AdbService extends IAdbManager.Stub { } } @Override @Override public void allowWirelessDebugging(boolean alwaysAllow, String bssid) { public void allowWirelessDebugging(boolean alwaysAllow, @NonNull String bssid) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED Preconditions.checkStringNotEmpty(bssid); if (mDebuggingManager != null) { mDebuggingManager.allowWirelessDebugging(alwaysAllow, bssid); } } } @Override @Override public void denyWirelessDebugging() { public void denyWirelessDebugging() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { mDebuggingManager.denyWirelessDebugging(); } } } @Override @Override public Map<String, PairDevice> getPairedDevices() { public Map<String, PairDevice> getPairedDevices() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { return mDebuggingManager.getPairedDevices(); } return null; return null; } } @Override @Override public void unpairDevice(String fingerprint) { public void unpairDevice(@NonNull String fingerprint) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED Preconditions.checkStringNotEmpty(fingerprint); if (mDebuggingManager != null) { mDebuggingManager.unpairDevice(fingerprint); } } } @Override @Override public void enablePairingByPairingCode() { public void enablePairingByPairingCode() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { mDebuggingManager.enablePairingByPairingCode(); } } } @Override @Override public void enablePairingByQrCode(String serviceName, String password) { public void enablePairingByQrCode(@NonNull String serviceName, @NonNull String password) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkStringNotEmpty(password); if (mDebuggingManager != null) { mDebuggingManager.enablePairingByQrCode(serviceName, password); } } } @Override @Override public void disablePairing() { public void disablePairing() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { mDebuggingManager.disablePairing(); } } } @Override @Override public int getAdbWirelessPort() { public int getAdbWirelessPort() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null); // TODO(joshuaduong): NOT IMPLEMENTED if (mDebuggingManager != null) { return 0; return mDebuggingManager.getAdbWirelessPort(); } // If ro.adb.secure=0 return mConnectionPort.get(); } /** * This listener is only used when ro.adb.secure=0. Otherwise, AdbDebuggingManager will * do this. */ class AdbConnectionPortListener implements AdbDebuggingManager.AdbConnectionPortListener { public void onPortReceived(int port) { if (port > 0 && port <= 65535) { mConnectionPort.set(port); } else { mConnectionPort.set(-1); // Turn off wifi debugging, since the server did not start. try { Settings.Global.putInt(mContentResolver, Settings.Global.ADB_WIFI_ENABLED, 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."); } } broadcastPortInfo(mConnectionPort.get()); } } private void broadcastPortInfo(int port) { Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION); intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, (port >= 0) ? AdbManager.WIRELESS_STATUS_CONNECTED : AdbManager.WIRELESS_STATUS_DISCONNECTED); intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); Slog.i(TAG, "sent port broadcast port=" + port); } private void startAdbd() { SystemProperties.set(CTL_START, ADBD); } private void stopAdbd() { if (!mIsAdbUsbEnabled && !mIsAdbWifiEnabled) { SystemProperties.set(CTL_STOP, ADBD); } } } private void setAdbEnabled(boolean enable, byte transportType) { private void setAdbEnabled(boolean enable, byte transportType) { Loading @@ -356,11 +448,33 @@ public class AdbService extends IAdbManager.Stub { mIsAdbUsbEnabled = enable; mIsAdbUsbEnabled = enable; } else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) { } else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) { mIsAdbWifiEnabled = enable; 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(); } } else { // Stop adb over WiFi. SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"); if (mConnectionPortPoller != null) { mConnectionPortPoller.cancelAndWait(); mConnectionPortPoller = null; } } } else { } else { // No change // No change return; return; } } if (enable) { startAdbd(); } else { stopAdbd(); } for (IAdbTransport transport : mTransports.values()) { for (IAdbTransport transport : mTransports.values()) { try { try { transport.onAdbEnabled(enable, transportType); transport.onAdbEnabled(enable, transportType); Loading
services/core/jni/Android.bp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ cc_library_static { "BroadcastRadio/regions.cpp", "BroadcastRadio/regions.cpp", "stats/PowerStatsPuller.cpp", "stats/PowerStatsPuller.cpp", "stats/SubsystemSleepStatePuller.cpp", "stats/SubsystemSleepStatePuller.cpp", "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_ConsumerIrService.cpp", "com_android_server_ConsumerIrService.cpp", Loading Loading @@ -86,6 +87,8 @@ cc_library_static { cc_defaults { cc_defaults { name: "libservices.core-libs", name: "libservices.core-libs", shared_libs: [ shared_libs: [ "libadb_pairing_server", "libadb_pairing_connection", "libandroid_runtime", "libandroid_runtime", "libandroidfw", "libandroidfw", "libaudioclient", "libaudioclient", Loading
services/core/jni/com_android_server_adb_AdbDebuggingManager.cpp 0 → 100644 +168 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2019 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. */ #define LOG_TAG "AdbDebuggingManager-JNI" #define LOG_NDEBUG 0 #include <algorithm> #include <condition_variable> #include <mutex> #include <optional> #include <random> #include <string> #include <vector> #include <adb/pairing/pairing_server.h> #include <android-base/properties.h> #include <utils/Log.h> #include <nativehelper/JNIHelp.h> #include "jni.h" namespace android { // ---------------------------------------------------------------------------- namespace { template <class T, class N> class JSmartWrapper { public: JSmartWrapper(JNIEnv* env, T* jData) : mEnv(env), mJData(jData) {} virtual ~JSmartWrapper() = default; const N* data() const { return mRawData; } jsize size() const { return mSize; } protected: N* mRawData = nullptr; JNIEnv* mEnv = nullptr; T* mJData = nullptr; jsize mSize = 0; }; // JSmartWrapper class JStringUTFWrapper : public JSmartWrapper<jstring, const char> { public: explicit JStringUTFWrapper(JNIEnv* env, jstring* str) : JSmartWrapper(env, str) { mRawData = env->GetStringUTFChars(*str, NULL); mSize = env->GetStringUTFLength(*str); } virtual ~JStringUTFWrapper() { if (data()) { mEnv->ReleaseStringUTFChars(*mJData, mRawData); } } }; // JStringUTFWrapper struct ServerDeleter { void operator()(PairingServerCtx* p) { pairing_server_destroy(p); } }; using PairingServerPtr = std::unique_ptr<PairingServerCtx, ServerDeleter>; struct PairingResultWaiter { std::mutex mutex_; std::condition_variable cv_; std::optional<bool> is_valid_; PeerInfo peer_info_; static void ResultCallback(const PeerInfo* peer_info, void* opaque) { auto* p = reinterpret_cast<PairingResultWaiter*>(opaque); { std::unique_lock<std::mutex> lock(p->mutex_); if (peer_info) { memcpy(&(p->peer_info_), peer_info, sizeof(PeerInfo)); } p->is_valid_ = (peer_info != nullptr); } p->cv_.notify_one(); } }; PairingServerPtr sServer; std::unique_ptr<PairingResultWaiter> sWaiter; } // namespace static jint native_pairing_start(JNIEnv* env, jobject thiz, jstring guid, jstring password) { // Server-side only sends its GUID on success. PeerInfo system_info = {}; system_info.type = ADB_DEVICE_GUID; JStringUTFWrapper guidWrapper(env, &guid); memcpy(system_info.data, guidWrapper.data(), guidWrapper.size()); JStringUTFWrapper passwordWrapper(env, &password); // Create the pairing server sServer = PairingServerPtr( pairing_server_new_no_cert(reinterpret_cast<const uint8_t*>(passwordWrapper.data()), passwordWrapper.size(), &system_info, 0)); sWaiter.reset(new PairingResultWaiter); uint16_t port = pairing_server_start(sServer.get(), sWaiter->ResultCallback, sWaiter.get()); if (port == 0) { ALOGE("Failed to start pairing server"); return -1; } return port; } static void native_pairing_cancel(JNIEnv* /* env */, jclass /* clazz */) { if (sServer != nullptr) { sServer.reset(); } } static jboolean native_pairing_wait(JNIEnv* env, jobject thiz) { ALOGI("Waiting for pairing server to complete"); std::unique_lock<std::mutex> lock(sWaiter->mutex_); if (!sWaiter->is_valid_.has_value()) { sWaiter->cv_.wait(lock, [&]() { return sWaiter->is_valid_.has_value(); }); } if (!*(sWaiter->is_valid_)) { return JNI_FALSE; } std::string peer_public_key = reinterpret_cast<char*>(sWaiter->peer_info_.data); // Write to PairingThread's member variables jclass clazz = env->GetObjectClass(thiz); jfieldID mPublicKey = env->GetFieldID(clazz, "mPublicKey", "Ljava/lang/String;"); jstring jpublickey = env->NewStringUTF(peer_public_key.c_str()); env->SetObjectField(thiz, mPublicKey, jpublickey); return JNI_TRUE; } // ---------------------------------------------------------------------------- static const JNINativeMethod gPairingThreadMethods[] = { /* name, signature, funcPtr */ {"native_pairing_start", "(Ljava/lang/String;Ljava/lang/String;)I", (void*)native_pairing_start}, {"native_pairing_cancel", "()V", (void*)native_pairing_cancel}, {"native_pairing_wait", "()Z", (void*)native_pairing_wait}, }; int register_android_server_AdbDebuggingManager(JNIEnv* env) { int res = jniRegisterNativeMethods(env, "com/android/server/adb/AdbDebuggingManager$PairingThread", gPairingThreadMethods, NELEM(gPairingThreadMethods)); (void)res; // Faked use when LOG_NDEBUG. LOG_FATAL_IF(res < 0, "Unable to register native methods."); return 0; } } /* namespace android */