Loading core/java/android/debug/AdbManagerInternal.java +12 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.debug; import java.io.File; /** * This class allows the control of ADB-related functions that should only be called from the system * server. Loading @@ -41,4 +43,14 @@ public abstract class AdbManagerInternal { * Returns {@code true} if ADB debugging is enabled. */ public abstract boolean isAdbEnabled(); /** * Returns the file that contains all of the ADB keys used by the device. */ public abstract File getAdbKeysFile(); /** * Returns the file that contains all of the ADB keys and their last used time. */ public abstract File getAdbTempKeysFile(); } services/core/java/com/android/server/adb/AdbDebuggingManager.java +37 −23 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ public class AdbDebuggingManager { private static final String ADB_DIRECTORY = "misc/adb"; // This file contains keys that will always be allowed to connect to the device via adb. private static final String ADB_KEYS_FILE = "adb_keys"; // This file contains keys that will be allowed to connect without user interaction as long // as a subsequent connection occurs within the allowed duration. private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final int BUFFER_SIZE = 4096; private final Context mContext; Loading Loading @@ -263,7 +266,6 @@ public class AdbDebuggingManager { AdbDebuggingHandler(Looper looper) { super(looper); mAdbKeyStore = new AdbKeyStore(); } /** Loading @@ -289,6 +291,7 @@ public class AdbDebuggingManager { mThread = new AdbDebuggingThread(); mThread.start(); mAdbKeyStore = new AdbKeyStore(); break; case MESSAGE_ADB_DISABLED: Loading @@ -303,6 +306,9 @@ public class AdbDebuggingManager { mThread = null; } cancelJobToUpdateAdbKeyStore(); mAdbKeyStore = null; mConnectedKey = null; break; case MESSAGE_ADB_ALLOW: { Loading Loading @@ -532,7 +538,11 @@ public class AdbDebuggingManager { return new File(adbDir, fileName); } private File getUserKeyFile() { File getAdbTempKeysFile() { return getAdbFile(ADB_TEMP_KEYS_FILE); } File getUserKeyFile() { return getAdbFile(ADB_KEYS_FILE); } Loading Loading @@ -668,9 +678,6 @@ public class AdbDebuggingManager { private Map<String, Long> mKeyMap; private File mKeyFile; private AtomicFile mAtomicKeyFile; // This file contains keys that will be allowed to connect without user interaction as long // as a subsequent connection occurs within the allowed duration. private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final String XML_TAG_ADB_KEY = "adbKey"; private static final String XML_ATTRIBUTE_KEY = "key"; private static final String XML_ATTRIBUTE_LAST_CONNECTION = "lastConnection"; Loading Loading @@ -704,9 +711,9 @@ public class AdbDebuggingManager { */ private void initKeyFile() { if (mKeyFile == null) { mKeyFile = getAdbFile(ADB_TEMP_KEYS_FILE); mKeyFile = getAdbTempKeysFile(); } // getAdbFile can return null if the adb file cannot be obtained // getAdbTempKeysFile can return null if the adb file cannot be obtained if (mKeyFile != null) { mAtomicKeyFile = new AtomicFile(mKeyFile); } Loading Loading @@ -767,7 +774,8 @@ public class AdbDebuggingManager { public void persistKeyStore() { // if there is nothing in the key map then ensure any keys left in the key store files // are deleted as well. if (mKeyMap.size() == 0) { filterOutOldKeys(); if (mKeyMap.isEmpty()) { deleteKeyStore(); return; } Loading @@ -784,22 +792,15 @@ public class AdbDebuggingManager { keyStream = mAtomicKeyFile.startWrite(); serializer.setOutput(keyStream, StandardCharsets.UTF_8.name()); serializer.startDocument(null, true); long allowedTime = getAllowedConnectionTime(); long systemTime = System.currentTimeMillis(); Iterator keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry<String, Long> keyEntry = (Map.Entry) keyMapIterator.next(); long connectionTime = keyEntry.getValue(); if (systemTime < (connectionTime + allowedTime)) { for (Map.Entry<String, Long> keyEntry : mKeyMap.entrySet()) { serializer.startTag(null, XML_TAG_ADB_KEY); serializer.attribute(null, XML_ATTRIBUTE_KEY, keyEntry.getKey()); serializer.attribute(null, XML_ATTRIBUTE_LAST_CONNECTION, String.valueOf(keyEntry.getValue())); serializer.endTag(null, XML_TAG_ADB_KEY); } else { keyMapIterator.remove(); } } serializer.endDocument(); mAtomicKeyFile.finishWrite(keyStream); } catch (IOException e) { Loading @@ -808,6 +809,19 @@ public class AdbDebuggingManager { } } private void filterOutOldKeys() { long allowedTime = getAllowedConnectionTime(); long systemTime = System.currentTimeMillis(); Iterator<Map.Entry<String, Long>> keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry<String, Long> keyEntry = keyMapIterator.next(); long connectionTime = keyEntry.getValue(); if (allowedTime != 0 && systemTime > (connectionTime + allowedTime)) { keyMapIterator.remove(); } } } /** * Removes all of the entries in the key map and deletes the key file. */ Loading services/core/java/com/android/server/adb/AdbService.java +11 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemService; import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; Loading Loading @@ -95,6 +96,16 @@ public class AdbService extends IAdbManager.Stub { public boolean isAdbEnabled() { return mAdbEnabled; } @Override public File getAdbKeysFile() { return mDebuggingManager.getUserKeyFile(); } @Override public File getAdbTempKeysFile() { return mDebuggingManager.getAdbTempKeysFile(); } } private final class AdbHandler extends Handler { Loading services/core/java/com/android/server/testharness/TestHarnessModeService.java +75 −38 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; import android.debug.AdbManagerInternal; import android.os.BatteryManager; import android.os.Binder; import android.os.IBinder; Loading @@ -42,6 +43,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; Loading @@ -49,7 +51,6 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; import java.util.Set; Loading Loading @@ -85,6 +86,7 @@ public class TestHarnessModeService extends SystemService { break; case PHASE_BOOT_COMPLETED: disableAutoSync(); configureSettings(); break; } super.onBootPhase(phase); Loading @@ -98,47 +100,60 @@ public class TestHarnessModeService extends SystemService { return; } mShouldSetUpTestHarnessMode = true; setUpAdb(testHarnessModeData); setDeviceProvisioned(); } private void setUpAdb(byte[] testHarnessModeData) { ContentResolver cr = getContext().getContentResolver(); // Disable the TTL for ADB keys before enabling ADB Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0); PersistentData persistentData = PersistentData.fromBytes(testHarnessModeData); SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, persistentData.mEnabled ? "1" : "0"); writeAdbKeysFile(persistentData); // Clear out the data block so that we don't revert the ADB keys on every boot. getPersistentDataBlock().clearTestHarnessModeData(); } ContentResolver cr = getContext().getContentResolver(); if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) { // Enable ADB Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1); } else { // ADB is already enabled, we should restart the service so it picks up the new keys android.os.SystemService.restart("adbd"); private void disableAutoSync() { if (!mShouldSetUpTestHarnessMode) { return; } UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser(); ContentResolver .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier()); } private void configureSettings() { if (!mShouldSetUpTestHarnessMode) { return; } ContentResolver cr = getContext().getContentResolver(); Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1); Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0); Settings.Global.putInt( cr, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_ANY); Settings.Global.putInt(cr, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 1); Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); setDeviceProvisioned(); } private void disableAutoSync() { if (!mShouldSetUpTestHarnessMode) { return; } UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser(); ContentResolver .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier()); private void writeAdbKeysFile(PersistentData persistentData) { AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); writeBytesToFile(persistentData.mAdbKeys, adbManager.getAdbKeysFile().toPath()); writeBytesToFile(persistentData.mAdbTempKeys, adbManager.getAdbTempKeysFile().toPath()); // Clear out the data block so that we don't revert the ADB keys on every boot. getPersistentDataBlock().clearTestHarnessModeData(); } private void writeAdbKeysFile(PersistentData persistentData) { Path adbKeys = Paths.get("/data/misc/adb/adb_keys"); private void writeBytesToFile(byte[] keys, Path adbKeys) { try { OutputStream fileOutputStream = Files.newOutputStream(adbKeys); fileOutputStream.write(persistentData.mAdbKeys); fileOutputStream.write(keys); fileOutputStream.close(); Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(adbKeys); Loading Loading @@ -219,23 +234,22 @@ public class TestHarnessModeService extends SystemService { } private int handleEnable() { Path adbKeys = Paths.get("/data/misc/adb/adb_keys"); if (!Files.exists(adbKeys)) { AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); File adbKeys = adbManager.getAdbKeysFile(); File adbTempKeys = adbManager.getAdbTempKeysFile(); if (adbKeys == null && adbTempKeys == null) { // This should only be accessible on eng builds that haven't yet set up ADB keys getErrPrintWriter() .println("No ADB keys stored; not enabling test harness mode"); return 1; } try (InputStream inputStream = Files.newInputStream(adbKeys)) { long size = Files.size(adbKeys); byte[] adbKeysBytes = new byte[(int) size]; int numBytes = inputStream.read(adbKeysBytes); if (numBytes != size) { getErrPrintWriter().println("Failed to read all bytes of adb_keys"); return 1; } PersistentData persistentData = new PersistentData(true, adbKeysBytes); try { byte[] adbKeysBytes = getBytesFromFile(adbKeys); byte[] adbTempKeysBytes = getBytesFromFile(adbTempKeys); PersistentData persistentData = new PersistentData(true, adbKeysBytes, adbTempKeysBytes); getPersistentDataBlock().setTestHarnessModeData(persistentData.toBytes()); } catch (IOException e) { Slog.e(TAG, "Failed to store ADB keys.", e); Loading @@ -252,6 +266,22 @@ public class TestHarnessModeService extends SystemService { return 0; } private byte[] getBytesFromFile(File file) throws IOException { if (file == null || !file.exists()) { return new byte[0]; } Path path = file.toPath(); try (InputStream inputStream = Files.newInputStream(path)) { int size = (int) Files.size(path); byte[] bytes = new byte[size]; int numBytes = inputStream.read(bytes); if (numBytes != size) { throw new IOException("Failed to read the whole file"); } return bytes; } } @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); Loading Loading @@ -290,15 +320,17 @@ public class TestHarnessModeService extends SystemService { final int mVersion; final boolean mEnabled; final byte[] mAdbKeys; final byte[] mAdbTempKeys; PersistentData(boolean enabled, byte[] adbKeys) { this(VERSION_1, enabled, adbKeys); PersistentData(boolean enabled, byte[] adbKeys, byte[] adbTempKeys) { this(VERSION_1, enabled, adbKeys, adbTempKeys); } PersistentData(int version, boolean enabled, byte[] adbKeys) { PersistentData(int version, boolean enabled, byte[] adbKeys, byte[] adbTempKeys) { this.mVersion = version; this.mEnabled = enabled; this.mAdbKeys = adbKeys; this.mAdbTempKeys = adbTempKeys; } static PersistentData fromBytes(byte[] bytes) { Loading @@ -309,7 +341,10 @@ public class TestHarnessModeService extends SystemService { int adbKeysLength = is.readInt(); byte[] adbKeys = new byte[adbKeysLength]; is.readFully(adbKeys); return new PersistentData(version, enabled, adbKeys); int adbTempKeysLength = is.readInt(); byte[] adbTempKeys = new byte[adbTempKeysLength]; is.readFully(adbTempKeys); return new PersistentData(version, enabled, adbKeys, adbTempKeys); } catch (IOException e) { throw new RuntimeException(e); } Loading @@ -323,6 +358,8 @@ public class TestHarnessModeService extends SystemService { dos.writeBoolean(mEnabled); dos.writeInt(mAdbKeys.length); dos.write(mAdbKeys); dos.writeInt(mAdbTempKeys.length); dos.write(mAdbTempKeys); dos.close(); return os.toByteArray(); } catch (IOException e) { Loading Loading
core/java/android/debug/AdbManagerInternal.java +12 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.debug; import java.io.File; /** * This class allows the control of ADB-related functions that should only be called from the system * server. Loading @@ -41,4 +43,14 @@ public abstract class AdbManagerInternal { * Returns {@code true} if ADB debugging is enabled. */ public abstract boolean isAdbEnabled(); /** * Returns the file that contains all of the ADB keys used by the device. */ public abstract File getAdbKeysFile(); /** * Returns the file that contains all of the ADB keys and their last used time. */ public abstract File getAdbTempKeysFile(); }
services/core/java/com/android/server/adb/AdbDebuggingManager.java +37 −23 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ public class AdbDebuggingManager { private static final String ADB_DIRECTORY = "misc/adb"; // This file contains keys that will always be allowed to connect to the device via adb. private static final String ADB_KEYS_FILE = "adb_keys"; // This file contains keys that will be allowed to connect without user interaction as long // as a subsequent connection occurs within the allowed duration. private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final int BUFFER_SIZE = 4096; private final Context mContext; Loading Loading @@ -263,7 +266,6 @@ public class AdbDebuggingManager { AdbDebuggingHandler(Looper looper) { super(looper); mAdbKeyStore = new AdbKeyStore(); } /** Loading @@ -289,6 +291,7 @@ public class AdbDebuggingManager { mThread = new AdbDebuggingThread(); mThread.start(); mAdbKeyStore = new AdbKeyStore(); break; case MESSAGE_ADB_DISABLED: Loading @@ -303,6 +306,9 @@ public class AdbDebuggingManager { mThread = null; } cancelJobToUpdateAdbKeyStore(); mAdbKeyStore = null; mConnectedKey = null; break; case MESSAGE_ADB_ALLOW: { Loading Loading @@ -532,7 +538,11 @@ public class AdbDebuggingManager { return new File(adbDir, fileName); } private File getUserKeyFile() { File getAdbTempKeysFile() { return getAdbFile(ADB_TEMP_KEYS_FILE); } File getUserKeyFile() { return getAdbFile(ADB_KEYS_FILE); } Loading Loading @@ -668,9 +678,6 @@ public class AdbDebuggingManager { private Map<String, Long> mKeyMap; private File mKeyFile; private AtomicFile mAtomicKeyFile; // This file contains keys that will be allowed to connect without user interaction as long // as a subsequent connection occurs within the allowed duration. private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final String XML_TAG_ADB_KEY = "adbKey"; private static final String XML_ATTRIBUTE_KEY = "key"; private static final String XML_ATTRIBUTE_LAST_CONNECTION = "lastConnection"; Loading Loading @@ -704,9 +711,9 @@ public class AdbDebuggingManager { */ private void initKeyFile() { if (mKeyFile == null) { mKeyFile = getAdbFile(ADB_TEMP_KEYS_FILE); mKeyFile = getAdbTempKeysFile(); } // getAdbFile can return null if the adb file cannot be obtained // getAdbTempKeysFile can return null if the adb file cannot be obtained if (mKeyFile != null) { mAtomicKeyFile = new AtomicFile(mKeyFile); } Loading Loading @@ -767,7 +774,8 @@ public class AdbDebuggingManager { public void persistKeyStore() { // if there is nothing in the key map then ensure any keys left in the key store files // are deleted as well. if (mKeyMap.size() == 0) { filterOutOldKeys(); if (mKeyMap.isEmpty()) { deleteKeyStore(); return; } Loading @@ -784,22 +792,15 @@ public class AdbDebuggingManager { keyStream = mAtomicKeyFile.startWrite(); serializer.setOutput(keyStream, StandardCharsets.UTF_8.name()); serializer.startDocument(null, true); long allowedTime = getAllowedConnectionTime(); long systemTime = System.currentTimeMillis(); Iterator keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry<String, Long> keyEntry = (Map.Entry) keyMapIterator.next(); long connectionTime = keyEntry.getValue(); if (systemTime < (connectionTime + allowedTime)) { for (Map.Entry<String, Long> keyEntry : mKeyMap.entrySet()) { serializer.startTag(null, XML_TAG_ADB_KEY); serializer.attribute(null, XML_ATTRIBUTE_KEY, keyEntry.getKey()); serializer.attribute(null, XML_ATTRIBUTE_LAST_CONNECTION, String.valueOf(keyEntry.getValue())); serializer.endTag(null, XML_TAG_ADB_KEY); } else { keyMapIterator.remove(); } } serializer.endDocument(); mAtomicKeyFile.finishWrite(keyStream); } catch (IOException e) { Loading @@ -808,6 +809,19 @@ public class AdbDebuggingManager { } } private void filterOutOldKeys() { long allowedTime = getAllowedConnectionTime(); long systemTime = System.currentTimeMillis(); Iterator<Map.Entry<String, Long>> keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry<String, Long> keyEntry = keyMapIterator.next(); long connectionTime = keyEntry.getValue(); if (allowedTime != 0 && systemTime > (connectionTime + allowedTime)) { keyMapIterator.remove(); } } } /** * Removes all of the entries in the key map and deletes the key file. */ Loading
services/core/java/com/android/server/adb/AdbService.java +11 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemService; import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; Loading Loading @@ -95,6 +96,16 @@ public class AdbService extends IAdbManager.Stub { public boolean isAdbEnabled() { return mAdbEnabled; } @Override public File getAdbKeysFile() { return mDebuggingManager.getUserKeyFile(); } @Override public File getAdbTempKeysFile() { return mDebuggingManager.getAdbTempKeysFile(); } } private final class AdbHandler extends Handler { Loading
services/core/java/com/android/server/testharness/TestHarnessModeService.java +75 −38 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; import android.debug.AdbManagerInternal; import android.os.BatteryManager; import android.os.Binder; import android.os.IBinder; Loading @@ -42,6 +43,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; Loading @@ -49,7 +51,6 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; import java.util.Set; Loading Loading @@ -85,6 +86,7 @@ public class TestHarnessModeService extends SystemService { break; case PHASE_BOOT_COMPLETED: disableAutoSync(); configureSettings(); break; } super.onBootPhase(phase); Loading @@ -98,47 +100,60 @@ public class TestHarnessModeService extends SystemService { return; } mShouldSetUpTestHarnessMode = true; setUpAdb(testHarnessModeData); setDeviceProvisioned(); } private void setUpAdb(byte[] testHarnessModeData) { ContentResolver cr = getContext().getContentResolver(); // Disable the TTL for ADB keys before enabling ADB Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0); PersistentData persistentData = PersistentData.fromBytes(testHarnessModeData); SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, persistentData.mEnabled ? "1" : "0"); writeAdbKeysFile(persistentData); // Clear out the data block so that we don't revert the ADB keys on every boot. getPersistentDataBlock().clearTestHarnessModeData(); } ContentResolver cr = getContext().getContentResolver(); if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) { // Enable ADB Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1); } else { // ADB is already enabled, we should restart the service so it picks up the new keys android.os.SystemService.restart("adbd"); private void disableAutoSync() { if (!mShouldSetUpTestHarnessMode) { return; } UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser(); ContentResolver .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier()); } private void configureSettings() { if (!mShouldSetUpTestHarnessMode) { return; } ContentResolver cr = getContext().getContentResolver(); Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1); Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0); Settings.Global.putInt( cr, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_ANY); Settings.Global.putInt(cr, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 1); Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); setDeviceProvisioned(); } private void disableAutoSync() { if (!mShouldSetUpTestHarnessMode) { return; } UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser(); ContentResolver .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier()); private void writeAdbKeysFile(PersistentData persistentData) { AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); writeBytesToFile(persistentData.mAdbKeys, adbManager.getAdbKeysFile().toPath()); writeBytesToFile(persistentData.mAdbTempKeys, adbManager.getAdbTempKeysFile().toPath()); // Clear out the data block so that we don't revert the ADB keys on every boot. getPersistentDataBlock().clearTestHarnessModeData(); } private void writeAdbKeysFile(PersistentData persistentData) { Path adbKeys = Paths.get("/data/misc/adb/adb_keys"); private void writeBytesToFile(byte[] keys, Path adbKeys) { try { OutputStream fileOutputStream = Files.newOutputStream(adbKeys); fileOutputStream.write(persistentData.mAdbKeys); fileOutputStream.write(keys); fileOutputStream.close(); Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(adbKeys); Loading Loading @@ -219,23 +234,22 @@ public class TestHarnessModeService extends SystemService { } private int handleEnable() { Path adbKeys = Paths.get("/data/misc/adb/adb_keys"); if (!Files.exists(adbKeys)) { AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class); File adbKeys = adbManager.getAdbKeysFile(); File adbTempKeys = adbManager.getAdbTempKeysFile(); if (adbKeys == null && adbTempKeys == null) { // This should only be accessible on eng builds that haven't yet set up ADB keys getErrPrintWriter() .println("No ADB keys stored; not enabling test harness mode"); return 1; } try (InputStream inputStream = Files.newInputStream(adbKeys)) { long size = Files.size(adbKeys); byte[] adbKeysBytes = new byte[(int) size]; int numBytes = inputStream.read(adbKeysBytes); if (numBytes != size) { getErrPrintWriter().println("Failed to read all bytes of adb_keys"); return 1; } PersistentData persistentData = new PersistentData(true, adbKeysBytes); try { byte[] adbKeysBytes = getBytesFromFile(adbKeys); byte[] adbTempKeysBytes = getBytesFromFile(adbTempKeys); PersistentData persistentData = new PersistentData(true, adbKeysBytes, adbTempKeysBytes); getPersistentDataBlock().setTestHarnessModeData(persistentData.toBytes()); } catch (IOException e) { Slog.e(TAG, "Failed to store ADB keys.", e); Loading @@ -252,6 +266,22 @@ public class TestHarnessModeService extends SystemService { return 0; } private byte[] getBytesFromFile(File file) throws IOException { if (file == null || !file.exists()) { return new byte[0]; } Path path = file.toPath(); try (InputStream inputStream = Files.newInputStream(path)) { int size = (int) Files.size(path); byte[] bytes = new byte[size]; int numBytes = inputStream.read(bytes); if (numBytes != size) { throw new IOException("Failed to read the whole file"); } return bytes; } } @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); Loading Loading @@ -290,15 +320,17 @@ public class TestHarnessModeService extends SystemService { final int mVersion; final boolean mEnabled; final byte[] mAdbKeys; final byte[] mAdbTempKeys; PersistentData(boolean enabled, byte[] adbKeys) { this(VERSION_1, enabled, adbKeys); PersistentData(boolean enabled, byte[] adbKeys, byte[] adbTempKeys) { this(VERSION_1, enabled, adbKeys, adbTempKeys); } PersistentData(int version, boolean enabled, byte[] adbKeys) { PersistentData(int version, boolean enabled, byte[] adbKeys, byte[] adbTempKeys) { this.mVersion = version; this.mEnabled = enabled; this.mAdbKeys = adbKeys; this.mAdbTempKeys = adbTempKeys; } static PersistentData fromBytes(byte[] bytes) { Loading @@ -309,7 +341,10 @@ public class TestHarnessModeService extends SystemService { int adbKeysLength = is.readInt(); byte[] adbKeys = new byte[adbKeysLength]; is.readFully(adbKeys); return new PersistentData(version, enabled, adbKeys); int adbTempKeysLength = is.readInt(); byte[] adbTempKeys = new byte[adbTempKeysLength]; is.readFully(adbTempKeys); return new PersistentData(version, enabled, adbKeys, adbTempKeys); } catch (IOException e) { throw new RuntimeException(e); } Loading @@ -323,6 +358,8 @@ public class TestHarnessModeService extends SystemService { dos.writeBoolean(mEnabled); dos.writeInt(mAdbKeys.length); dos.write(mAdbKeys); dos.writeInt(mAdbTempKeys.length); dos.write(mAdbTempKeys); dos.close(); return os.toByteArray(); } catch (IOException e) { Loading