Merge "Add AdbTransportType.aidl. Add AdbWifi internal API stubs." am: c5cb13899d

Change-Id: I362b91ae3dd8cd2b696525e23ede9f3cb6c2f5d9
This commit is contained in:
Automerger Merge Worker
2020-02-19 02:52:39 +00:00
10 changed files with 458 additions and 85 deletions

View File

@@ -31,6 +31,114 @@ import android.os.RemoteException;
public class AdbManager {
private static final String TAG = "AdbManager";
/**
* Action indicating the state change of wireless debugging. Can be either
* STATUS_CONNECTED
* STATUS_DISCONNECTED
*
* @hide
*/
public static final String WIRELESS_DEBUG_STATE_CHANGED_ACTION =
"com.android.server.adb.WIRELESS_DEBUG_STATUS";
/**
* Contains the list of paired devices.
*
* @hide
*/
public static final String WIRELESS_DEBUG_PAIRED_DEVICES_ACTION =
"com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES";
/**
* Action indicating the status of a pairing. Can be either
* WIRELESS_STATUS_FAIL
* WIRELESS_STATUS_SUCCESS
* WIRELESS_STATUS_CANCELLED
* WIRELESS_STATUS_PAIRING_CODE
* WIRELESS_STATUS_CONNECTED
*
* @hide
*/
public static final String WIRELESS_DEBUG_PAIRING_RESULT_ACTION =
"com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT";
/**
* Extra containing the PairDevice map of paired/pairing devices.
*
* @hide
*/
public static final String WIRELESS_DEVICES_EXTRA = "devices_map";
/**
* The status of the pairing/unpairing.
*
* @hide
*/
public static final String WIRELESS_STATUS_EXTRA = "status";
/**
* The PairDevice.
*
* @hide
*/
public static final String WIRELESS_PAIR_DEVICE_EXTRA = "pair_device";
/**
* The six-digit pairing code.
*
* @hide
*/
public static final String WIRELESS_PAIRING_CODE_EXTRA = "pairing_code";
/**
* The adb connection/pairing port that was opened.
*
* @hide
*/
public static final String WIRELESS_DEBUG_PORT_EXTRA = "adb_port";
/**
* Status indicating the pairing/unpairing failed.
*
* @hide
*/
public static final int WIRELESS_STATUS_FAIL = 0;
/**
* Status indicating the pairing/unpairing succeeded.
*
* @hide
*/
public static final int WIRELESS_STATUS_SUCCESS = 1;
/**
* Status indicating the pairing/unpairing was cancelled.
*
* @hide
*/
public static final int WIRELESS_STATUS_CANCELLED = 2;
/**
* Status indicating the pairing code for pairing.
*
* @hide
*/
public static final int WIRELESS_STATUS_PAIRING_CODE = 3;
/**
* Status indicating wireless debugging is connected.
*
* @hide
*/
public static final int WIRELESS_STATUS_CONNECTED = 4;
/**
* Status indicating wireless debugging is disconnected.
*
* @hide
*/
public static final int WIRELESS_STATUS_DISCONNECTED = 5;
private final Context mContext;
private final IAdbManager mService;

View File

@@ -42,7 +42,7 @@ public abstract class AdbManagerInternal {
/**
* Returns {@code true} if ADB debugging is enabled.
*/
public abstract boolean isAdbEnabled();
public abstract boolean isAdbEnabled(byte transportType);
/**
* Returns the file that contains all of the ADB keys used by the device.

View File

@@ -0,0 +1,25 @@
/*
* 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.
*/
package android.debug;
/** @hide */
@Backing(type="byte")
enum AdbTransportType {
USB,
WIFI,
}

View File

@@ -42,6 +42,62 @@ interface IAdbManager {
*/
void clearDebuggingKeys();
/**
* Allow ADB wireless debugging on the connected network. If {@code alwaysAllow}
* is {@code true}, add {@code bssid} to list of networks that the user has
* approved.
*
* @param alwaysAllow if true, add permanently to list of allowed networks
* @param bssid BSSID of the network
*/
void allowWirelessDebugging(boolean alwaysAllow, String bssid);
/**
* Deny ADB wireless debugging on the connected network.
*/
void denyWirelessDebugging();
/**
* Returns a Map<String, PairDevice> with the key fingerprint mapped to the device information.
*/
Map getPairedDevices();
/**
* Unpair the device identified by the key fingerprint it uses.
*
* @param fingerprint fingerprint of the key the device is using.
*/
void unpairDevice(String fingerprint);
/**
* Enables pairing by pairing code. The result of the enable will be sent via intent action
* {@link android.debug.AdbManager#WIRELESS_DEBUG_ENABLE_DISCOVER_ACTION}. Furthermore, the
* pairing code will also be sent in the intent as an extra
* @{link android.debug.AdbManager#WIRELESS_PAIRING_CODE_EXTRA}. Note that only one
* pairing method can be enabled at a time, either by pairing code, or by QR code.
*/
void enablePairingByPairingCode();
/**
* Enables pairing by QR code. The result of the enable will be sent via intent action
* {@link android.debug.AdbManager#WIRELESS_DEBUG_ENABLE_DISCOVER_ACTION}. Note that only one
* pairing method can be enabled at a time, either by pairing code, or by QR code.
*
* @param serviceName The MDNS service name parsed from the QR code.
* @param password The password parsed from the QR code.
*/
void enablePairingByQrCode(String serviceName, String password);
/**
* Returns the network port that adb wireless server is running on.
*/
int getAdbWirelessPort();
/**
* Disables pairing.
*/
void disablePairing();
/**
* Returns true if device supports secure Adb over Wi-Fi.
*/

View File

@@ -16,7 +16,9 @@
package android.debug;
import android.debug.AdbTransportType;
/** @hide */
interface IAdbTransport {
void onAdbEnabled(boolean enabled);
void onAdbEnabled(boolean enabled, in AdbTransportType type);
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 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 android.debug;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.annotations.Immutable;
import com.android.internal.util.Preconditions;
/**
* Contains information about the client in an ADB connection.
* @hide
*/
@Immutable
public class PairDevice implements Parcelable {
/**
* The human-readable name of the device.
*/
@NonNull private final String mName;
/**
* The device's guid.
*/
@NonNull private final String mGuid;
/**
* Indicates whether the device is currently connected to adbd.
*/
private final boolean mConnected;
public PairDevice(@NonNull String name, @NonNull String guid, boolean connected) {
Preconditions.checkStringNotEmpty(name);
Preconditions.checkStringNotEmpty(guid);
mName = name;
mGuid = guid;
mConnected = connected;
}
/**
* @return the device name.
*/
@NonNull
public String getDeviceName() {
return mName;
}
/**
* @return the device GUID.
*/
@NonNull
public String getGuid() {
return mGuid;
}
/**
* @return the adb connection state of the device.
*/
public boolean isConnected() {
return mConnected;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mName);
dest.writeString(mGuid);
dest.writeBoolean(mConnected);
}
/**
* @return Human-readable info about the object.
*/
@Override
public String toString() {
return "\n" + mName + "\n" + mGuid + "\n" + mConnected;
}
@Override
public int describeContents() {
return 0;
}
@NonNull
public static final Parcelable.Creator<PairDevice> CREATOR =
new Creator<PairDevice>() {
@Override
public PairDevice createFromParcel(Parcel source) {
return new PairDevice(source.readString(), source.readString(),
source.readBoolean());
}
@Override
public PairDevice[] newArray(int size) {
return new PairDevice[size];
}
};
}

View File

@@ -395,6 +395,9 @@
<protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
<protected-broadcast android:name="android.intent.action.ADVANCED_SETTINGS" />
<protected-broadcast android:name="android.intent.action.APPLICATION_RESTRICTIONS_CHANGED" />
<protected-broadcast android:name="com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES" />
<protected-broadcast android:name="com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT" />
<protected-broadcast android:name="com.android.server.adb.WIRELESS_DEBUG_STATUS" />
<!-- Legacy -->
<protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_START" />

View File

@@ -29,6 +29,7 @@ import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.debug.AdbProtoEnums;
import android.debug.AdbTransportType;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.Uri;
@@ -717,13 +718,21 @@ public class AdbDebuggingManager {
}
/**
* When {@code enabled} is {@code true}, this allows ADB debugging and starts the ADB hanler
* thread. When {@code enabled} is {@code false}, this disallows ADB debugging and shuts
* down the handler thread.
* When {@code enabled} is {@code true}, this allows ADB debugging and starts the ADB handler
* thread. When {@code enabled} is {@code false}, this disallows ADB debugging for the given
* @{code transportType}. See {@link IAdbTransport} for all available transport types.
* If all transport types are disabled, the ADB handler thread will shut down.
*/
public void setAdbEnabled(boolean enabled) {
mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MESSAGE_ADB_ENABLED
: AdbDebuggingHandler.MESSAGE_ADB_DISABLED);
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) {
// TODO(joshuaduong): Not implemented
} else {
throw new IllegalArgumentException(
"setAdbEnabled called with unimplemented transport type=" + transportType);
}
}
/**

View File

@@ -15,19 +15,23 @@
*/
package com.android.server.adb;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.debug.AdbManagerInternal;
import android.debug.AdbTransportType;
import android.debug.IAdbManager;
import android.debug.IAdbTransport;
import android.debug.PairDevice;
import android.hardware.usb.UsbManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
@@ -38,7 +42,6 @@ import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.dump.DualDumpOutputStream;
@@ -50,6 +53,7 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Map;
/**
* The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization
@@ -77,7 +81,8 @@ public class AdbService extends IAdbManager.Stub {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mAdbService.systemReady();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mAdbService.bootCompleted();
FgThread.getHandler().sendMessage(obtainMessage(
AdbService::bootCompleted, mAdbService));
}
}
}
@@ -94,8 +99,14 @@ public class AdbService extends IAdbManager.Stub {
}
@Override
public boolean isAdbEnabled() {
return mAdbEnabled;
public boolean isAdbEnabled(byte transportType) {
if (transportType == AdbTransportType.USB) {
return mIsAdbUsbEnabled;
} else if (transportType == AdbTransportType.WIFI) {
return mIsAdbWifiEnabled;
}
throw new IllegalArgumentException(
"isAdbEnabled called with unimplemented transport type=" + transportType);
}
@Override
@@ -109,77 +120,60 @@ public class AdbService extends IAdbManager.Stub {
}
}
private final class AdbHandler extends Handler {
AdbHandler(Looper looper) {
super(looper);
try {
/*
* Use the normal bootmode persistent prop to maintain state of adb across
* all boot modes.
*/
mAdbEnabled = containsFunction(
SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),
UsbManager.USB_FUNCTION_ADB);
private void initAdbState() {
try {
/*
* Use the normal bootmode persistent prop to maintain state of adb across
* all boot modes.
*/
mIsAdbUsbEnabled = containsFunction(
SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),
UsbManager.USB_FUNCTION_ADB);
// TODO(joshuaduong): Read the adb wifi state from a persistent system
// property (persist.sys.adb.wifi).
mIsAdbWifiEnabled = false;
// register observer to listen for settings changes
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
false, new AdbSettingsObserver());
} catch (Exception e) {
Slog.e(TAG, "Error initializing AdbHandler", e);
}
}
private boolean containsFunction(String functions, String function) {
int index = functions.indexOf(function);
if (index < 0) return false;
if (index > 0 && functions.charAt(index - 1) != ',') return false;
int charAfter = index + function.length();
if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
return true;
}
public void sendMessage(int what, boolean arg) {
removeMessages(what);
Message m = Message.obtain(this, what);
m.arg1 = (arg ? 1 : 0);
sendMessage(m);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ENABLE_ADB:
setAdbEnabled(msg.arg1 == 1);
break;
case MSG_BOOT_COMPLETED:
if (mDebuggingManager != null) {
mDebuggingManager.setAdbEnabled(mAdbEnabled);
}
break;
}
// register observer to listen for settings changes
mContentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
false, new AdbSettingsObserver());
} catch (Exception e) {
Slog.e(TAG, "Error in initAdbState", e);
}
}
private static boolean containsFunction(String functions, String function) {
int index = functions.indexOf(function);
if (index < 0) return false;
if (index > 0 && functions.charAt(index - 1) != ',') return false;
int charAfter = index + function.length();
if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
return true;
}
private class AdbSettingsObserver extends ContentObserver {
private final Uri mAdbUsbUri = Settings.Global.getUriFor(Settings.Global.ADB_ENABLED);
AdbSettingsObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
boolean enable = (Settings.Global.getInt(mContentResolver,
Settings.Global.ADB_ENABLED, 0) > 0);
mHandler.sendMessage(MSG_ENABLE_ADB, enable);
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));
}
// TODO(joshuaduong): Add condition for WIFI transport
}
}
private static final String TAG = "AdbService";
private static final boolean DEBUG = false;
private static final int MSG_ENABLE_ADB = 1;
private static final int MSG_BOOT_COMPLETED = 2;
/**
* The persistent property which stores whether adb is enabled or not.
* May also contain vendor-specific default functions for testing purposes.
@@ -188,10 +182,10 @@ public class AdbService extends IAdbManager.Stub {
private final Context mContext;
private final ContentResolver mContentResolver;
private final AdbService.AdbHandler mHandler;
private final ArrayMap<IBinder, IAdbTransport> mTransports = new ArrayMap<>();
private boolean mAdbEnabled;
private boolean mIsAdbUsbEnabled;
private boolean mIsAdbWifiEnabled;
private AdbDebuggingManager mDebuggingManager;
private AdbService(Context context) {
@@ -204,8 +198,7 @@ public class AdbService extends IAdbManager.Stub {
mDebuggingManager = new AdbDebuggingManager(context);
}
mHandler = new AdbHandler(FgThread.get().getLooper());
initAdbState();
LocalServices.addService(AdbManagerInternal.class, new AdbManagerInternalImpl());
}
@@ -219,7 +212,7 @@ public class AdbService extends IAdbManager.Stub {
// make sure the ADB_ENABLED setting value matches the current state
try {
Settings.Global.putInt(mContentResolver,
Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
Settings.Global.ADB_ENABLED, mIsAdbUsbEnabled ? 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.");
@@ -231,7 +224,10 @@ public class AdbService extends IAdbManager.Stub {
*/
public void bootCompleted() {
if (DEBUG) Slog.d(TAG, "boot completed");
mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
if (mDebuggingManager != null) {
mDebuggingManager.setAdbEnabled(mIsAdbUsbEnabled, AdbTransportType.USB);
mDebuggingManager.setAdbEnabled(mIsAdbWifiEnabled, AdbTransportType.WIFI);
}
}
@Override
@@ -285,24 +281,82 @@ public class AdbService extends IAdbManager.Stub {
PackageManager.FEATURE_CAMERA_ANY);
}
private void setAdbEnabled(boolean enable) {
if (DEBUG) Slog.d(TAG, "setAdbEnabled(" + enable + "), mAdbEnabled=" + mAdbEnabled);
@Override
public void allowWirelessDebugging(boolean alwaysAllow, String bssid) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
}
if (enable == mAdbEnabled) {
@Override
public void denyWirelessDebugging() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
}
@Override
public Map<String, PairDevice> getPairedDevices() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
return null;
}
@Override
public void unpairDevice(String fingerprint) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
}
@Override
public void enablePairingByPairingCode() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
}
@Override
public void enablePairingByQrCode(String serviceName, String password) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
}
@Override
public void disablePairing() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
}
@Override
public int getAdbWirelessPort() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
// TODO(joshuaduong): NOT IMPLEMENTED
return 0;
}
private void setAdbEnabled(boolean enable, byte transportType) {
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;
} else {
// No change
return;
}
mAdbEnabled = enable;
for (IAdbTransport transport : mTransports.values()) {
try {
transport.onAdbEnabled(enable);
transport.onAdbEnabled(enable, transportType);
} catch (RemoteException e) {
Slog.w(TAG, "Unable to send onAdbEnabled to transport " + transport.toString());
}
}
if (mDebuggingManager != null) {
mDebuggingManager.setAdbEnabled(enable);
mDebuggingManager.setAdbEnabled(enable, transportType);
}
}

View File

@@ -41,6 +41,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.debug.AdbManagerInternal;
import android.debug.AdbTransportType;
import android.debug.IAdbTransport;
import android.hardware.usb.ParcelableUsbPort;
import android.hardware.usb.UsbAccessory;
@@ -774,8 +775,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
}
@Override
public void onAdbEnabled(boolean enabled) {
mHandler.sendMessage(MSG_ENABLE_ADB, enabled);
public void onAdbEnabled(boolean enabled, byte transportType) {
if (transportType == AdbTransportType.USB) {
mHandler.sendMessage(MSG_ENABLE_ADB, enabled);
}
}
}
@@ -1169,7 +1172,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
}
protected boolean isAdbEnabled() {
return LocalServices.getService(AdbManagerInternal.class).isAdbEnabled();
return LocalServices.getService(AdbManagerInternal.class)
.isAdbEnabled(AdbTransportType.USB);
}
protected void updateAdbNotification(boolean force) {