blob: 7fd98e0043c95c98417066df9b7b1378f93b2210 [file] [log] [blame]
Kenny Rootf74bfde2018-01-18 15:42:48 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.adb;
17
Kenny Root47312182018-01-22 08:44:44 -050018import android.content.ContentResolver;
Kenny Rootf74bfde2018-01-18 15:42:48 -080019import android.content.Context;
Kenny Root47312182018-01-22 08:44:44 -050020import android.database.ContentObserver;
Kenny Rootdc14eb72018-10-18 10:15:22 +090021import android.debug.AdbManagerInternal;
Kenny Rootf74bfde2018-01-18 15:42:48 -080022import android.debug.IAdbManager;
Kenny Root61fd3602018-01-19 09:01:46 -050023import android.debug.IAdbTransport;
Kenny Root47312182018-01-22 08:44:44 -050024import android.hardware.usb.UsbManager;
Kenny Rootf74bfde2018-01-18 15:42:48 -080025import android.os.Binder;
Kenny Rootc96dba72018-01-22 06:31:03 -050026import android.os.Handler;
Kenny Root61fd3602018-01-19 09:01:46 -050027import android.os.IBinder;
Kenny Rootc96dba72018-01-22 06:31:03 -050028import android.os.Looper;
29import android.os.Message;
Kenny Root47312182018-01-22 08:44:44 -050030import android.os.RemoteException;
31import android.os.SystemProperties;
32import android.provider.Settings;
Kenny Roota5964c02018-01-23 20:08:39 +090033import android.service.adb.AdbServiceDumpProto;
Kiyoung Kimd8849f02018-12-27 17:17:46 +090034import android.sysprop.AdbProperties;
Kenny Root61fd3602018-01-19 09:01:46 -050035import android.util.ArrayMap;
Kenny Roota5964c02018-01-23 20:08:39 +090036import android.util.ArraySet;
Kenny Root8ebd8bf2018-01-22 06:28:25 -050037import android.util.Slog;
Kenny Roota5964c02018-01-23 20:08:39 +090038import android.util.proto.ProtoOutputStream;
39
Kenny Rootf74bfde2018-01-18 15:42:48 -080040
41import com.android.internal.util.DumpUtils;
42import com.android.internal.util.IndentingPrintWriter;
Kenny Roota5964c02018-01-23 20:08:39 +090043import com.android.internal.util.dump.DualDumpOutputStream;
Kenny Rootc96dba72018-01-22 06:31:03 -050044import com.android.server.FgThread;
Kenny Rootdc14eb72018-10-18 10:15:22 +090045import com.android.server.LocalServices;
Kenny Rootf74bfde2018-01-18 15:42:48 -080046import com.android.server.SystemService;
47
William Hester99a7d632019-02-06 17:36:37 -080048import java.io.File;
Kenny Rootf74bfde2018-01-18 15:42:48 -080049import java.io.FileDescriptor;
50import java.io.PrintWriter;
Kenny Roota5964c02018-01-23 20:08:39 +090051import java.util.Collections;
Kenny Rootf74bfde2018-01-18 15:42:48 -080052
53/**
54 * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization
55 * of devices allowed to connect to ADB.
56 */
57public class AdbService extends IAdbManager.Stub {
58 /**
59 * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}.
60 */
61 public static class Lifecycle extends SystemService {
62 private AdbService mAdbService;
63
64 public Lifecycle(Context context) {
65 super(context);
66 }
67
68 @Override
69 public void onStart() {
70 mAdbService = new AdbService(getContext());
71 publishBinderService(Context.ADB_SERVICE, mAdbService);
72 }
Kenny Root8ebd8bf2018-01-22 06:28:25 -050073
74 @Override
75 public void onBootPhase(int phase) {
76 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
77 mAdbService.systemReady();
Kenny Roota5964c02018-01-23 20:08:39 +090078 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
79 mAdbService.bootCompleted();
Kenny Root8ebd8bf2018-01-22 06:28:25 -050080 }
81 }
Kenny Rootf74bfde2018-01-18 15:42:48 -080082 }
83
Kenny Rootdc14eb72018-10-18 10:15:22 +090084 private class AdbManagerInternalImpl extends AdbManagerInternal {
Kenny Root61fd3602018-01-19 09:01:46 -050085 @Override
86 public void registerTransport(IAdbTransport transport) {
87 mTransports.put(transport.asBinder(), transport);
88 }
89
90 @Override
91 public void unregisterTransport(IAdbTransport transport) {
92 mTransports.remove(transport.asBinder());
93 }
Kenny Roota269b332018-01-19 13:24:01 -050094
95 @Override
96 public boolean isAdbEnabled() {
97 return mAdbEnabled;
98 }
William Hester99a7d632019-02-06 17:36:37 -080099
100 @Override
101 public File getAdbKeysFile() {
102 return mDebuggingManager.getUserKeyFile();
103 }
104
105 @Override
106 public File getAdbTempKeysFile() {
107 return mDebuggingManager.getAdbTempKeysFile();
108 }
Kenny Rootdc14eb72018-10-18 10:15:22 +0900109 }
110
Kenny Rootc96dba72018-01-22 06:31:03 -0500111 private final class AdbHandler extends Handler {
112 AdbHandler(Looper looper) {
113 super(looper);
114 try {
Kenny Root47312182018-01-22 08:44:44 -0500115 /*
116 * Use the normal bootmode persistent prop to maintain state of adb across
117 * all boot modes.
118 */
119 mAdbEnabled = containsFunction(
120 SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),
121 UsbManager.USB_FUNCTION_ADB);
122
123 // register observer to listen for settings changes
124 mContentResolver.registerContentObserver(
125 Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
126 false, new AdbSettingsObserver());
Kenny Rootc96dba72018-01-22 06:31:03 -0500127 } catch (Exception e) {
128 Slog.e(TAG, "Error initializing AdbHandler", e);
129 }
130 }
131
Kenny Root47312182018-01-22 08:44:44 -0500132 private boolean containsFunction(String functions, String function) {
133 int index = functions.indexOf(function);
134 if (index < 0) return false;
135 if (index > 0 && functions.charAt(index - 1) != ',') return false;
136 int charAfter = index + function.length();
137 if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
138 return true;
139 }
140
Kenny Rootc96dba72018-01-22 06:31:03 -0500141 public void sendMessage(int what, boolean arg) {
142 removeMessages(what);
143 Message m = Message.obtain(this, what);
144 m.arg1 = (arg ? 1 : 0);
145 sendMessage(m);
146 }
147
148 @Override
149 public void handleMessage(Message msg) {
150 switch (msg.what) {
Kenny Root47312182018-01-22 08:44:44 -0500151 case MSG_ENABLE_ADB:
152 setAdbEnabled(msg.arg1 == 1);
153 break;
Kenny Roota5964c02018-01-23 20:08:39 +0900154 case MSG_BOOT_COMPLETED:
155 if (mDebuggingManager != null) {
156 mDebuggingManager.setAdbEnabled(mAdbEnabled);
157 }
158 break;
Kenny Rootc96dba72018-01-22 06:31:03 -0500159 }
160 }
161 }
162
Kenny Root47312182018-01-22 08:44:44 -0500163 private class AdbSettingsObserver extends ContentObserver {
164 AdbSettingsObserver() {
165 super(null);
166 }
167
168 @Override
169 public void onChange(boolean selfChange) {
170 boolean enable = (Settings.Global.getInt(mContentResolver,
171 Settings.Global.ADB_ENABLED, 0) > 0);
172 mHandler.sendMessage(MSG_ENABLE_ADB, enable);
173 }
174 }
175
Kenny Rootf74bfde2018-01-18 15:42:48 -0800176 private static final String TAG = "AdbService";
Kenny Root8ebd8bf2018-01-22 06:28:25 -0500177 private static final boolean DEBUG = false;
Kenny Rootf74bfde2018-01-18 15:42:48 -0800178
Kenny Root47312182018-01-22 08:44:44 -0500179 private static final int MSG_ENABLE_ADB = 1;
Kenny Roota5964c02018-01-23 20:08:39 +0900180 private static final int MSG_BOOT_COMPLETED = 2;
Kenny Root47312182018-01-22 08:44:44 -0500181
182 /**
183 * The persistent property which stores whether adb is enabled or not.
184 * May also contain vendor-specific default functions for testing purposes.
185 */
186 private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config";
187
Kenny Rootf74bfde2018-01-18 15:42:48 -0800188 private final Context mContext;
Kenny Root47312182018-01-22 08:44:44 -0500189 private final ContentResolver mContentResolver;
Kenny Rootc96dba72018-01-22 06:31:03 -0500190 private final AdbService.AdbHandler mHandler;
Kenny Root61fd3602018-01-19 09:01:46 -0500191 private final ArrayMap<IBinder, IAdbTransport> mTransports = new ArrayMap<>();
Kenny Rootf74bfde2018-01-18 15:42:48 -0800192
Kenny Roota269b332018-01-19 13:24:01 -0500193 private boolean mAdbEnabled;
Kenny Roota5964c02018-01-23 20:08:39 +0900194 private AdbDebuggingManager mDebuggingManager;
Kenny Roota269b332018-01-19 13:24:01 -0500195
Kenny Rootf74bfde2018-01-18 15:42:48 -0800196 private AdbService(Context context) {
197 mContext = context;
Kenny Root47312182018-01-22 08:44:44 -0500198 mContentResolver = context.getContentResolver();
Kenny Rootdc14eb72018-10-18 10:15:22 +0900199
Kiyoung Kimd8849f02018-12-27 17:17:46 +0900200 boolean secureAdbEnabled = AdbProperties.secure().orElse(false);
Kenny Roota5964c02018-01-23 20:08:39 +0900201 boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
202 if (secureAdbEnabled && !dataEncrypted) {
203 mDebuggingManager = new AdbDebuggingManager(context);
204 }
205
Kenny Rootc96dba72018-01-22 06:31:03 -0500206 mHandler = new AdbHandler(FgThread.get().getLooper());
207
Kenny Rootdc14eb72018-10-18 10:15:22 +0900208 LocalServices.addService(AdbManagerInternal.class, new AdbManagerInternalImpl());
Kenny Rootf74bfde2018-01-18 15:42:48 -0800209 }
210
Kenny Root8ebd8bf2018-01-22 06:28:25 -0500211 /**
212 * Called in response to {@code SystemService.PHASE_ACTIVITY_MANAGER_READY} from {@code
213 * SystemServer}.
214 */
215 public void systemReady() {
216 if (DEBUG) Slog.d(TAG, "systemReady");
Kenny Root47312182018-01-22 08:44:44 -0500217
218 // make sure the ADB_ENABLED setting value matches the current state
219 try {
220 Settings.Global.putInt(mContentResolver,
221 Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
222 } catch (SecurityException e) {
223 // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
224 Slog.d(TAG, "ADB_ENABLED is restricted.");
225 }
226 }
227
Kenny Roota5964c02018-01-23 20:08:39 +0900228 /**
229 * Callend in response to {@code SystemService.PHASE_BOOT_COMPLETED} from {@code SystemServer}.
230 */
231 public void bootCompleted() {
232 if (DEBUG) Slog.d(TAG, "boot completed");
233 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
234 }
235
236 @Override
237 public void allowDebugging(boolean alwaysAllow, String publicKey) {
238 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
239 if (mDebuggingManager != null) {
240 mDebuggingManager.allowDebugging(alwaysAllow, publicKey);
241 }
242 }
243
244 @Override
245 public void denyDebugging() {
246 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
247 if (mDebuggingManager != null) {
248 mDebuggingManager.denyDebugging();
249 }
250 }
251
252 @Override
253 public void clearDebuggingKeys() {
254 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING, null);
255 if (mDebuggingManager != null) {
256 mDebuggingManager.clearDebuggingKeys();
257 } else {
258 throw new RuntimeException("Cannot clear ADB debugging keys, "
259 + "AdbDebuggingManager not enabled");
260 }
261 }
262
Kenny Root47312182018-01-22 08:44:44 -0500263 private void setAdbEnabled(boolean enable) {
264 if (DEBUG) Slog.d(TAG, "setAdbEnabled(" + enable + "), mAdbEnabled=" + mAdbEnabled);
265
266 if (enable == mAdbEnabled) {
267 return;
268 }
269 mAdbEnabled = enable;
270
271 for (IAdbTransport transport : mTransports.values()) {
272 try {
273 transport.onAdbEnabled(enable);
274 } catch (RemoteException e) {
275 Slog.w(TAG, "Unable to send onAdbEnabled to transport " + transport.toString());
276 }
277 }
Kenny Roota5964c02018-01-23 20:08:39 +0900278
279 if (mDebuggingManager != null) {
280 mDebuggingManager.setAdbEnabled(enable);
281 }
Kenny Root8ebd8bf2018-01-22 06:28:25 -0500282 }
283
Kenny Rootf74bfde2018-01-18 15:42:48 -0800284 @Override
285 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
286 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
287
288 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
289 final long ident = Binder.clearCallingIdentity();
290 try {
Kenny Roota5964c02018-01-23 20:08:39 +0900291 ArraySet<String> argsSet = new ArraySet<>();
292 Collections.addAll(argsSet, args);
293
294 boolean dumpAsProto = false;
295 if (argsSet.contains("--proto")) {
296 dumpAsProto = true;
297 }
298
299 if (argsSet.size() == 0 || argsSet.contains("-a") || dumpAsProto) {
300 DualDumpOutputStream dump;
301 if (dumpAsProto) {
302 dump = new DualDumpOutputStream(new ProtoOutputStream(fd));
303 } else {
304 pw.println("ADB MANAGER STATE (dumpsys adb):");
305
306 dump = new DualDumpOutputStream(new IndentingPrintWriter(pw, " "));
307 }
308
309 if (mDebuggingManager != null) {
310 mDebuggingManager.dump(dump, "debugging_manager",
311 AdbServiceDumpProto.DEBUGGING_MANAGER);
312 }
313
314 dump.flush();
Kenny Rootf74bfde2018-01-18 15:42:48 -0800315 } else {
316 pw.println("Dump current ADB state");
317 pw.println(" No commands available");
318 }
319 } finally {
320 Binder.restoreCallingIdentity(ident);
321 }
322 }
323}