diff options
Diffstat (limited to 'cmds')
-rw-r--r-- | cmds/am/src/com/android/commands/am/Am.java | 55 | ||||
-rw-r--r-- | cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java | 32 | ||||
-rw-r--r-- | cmds/bu/src/com/android/commands/bu/Backup.java | 14 | ||||
-rw-r--r-- | cmds/idmap/create.cpp | 2 | ||||
-rw-r--r-- | cmds/idmap/idmap.cpp | 42 | ||||
-rw-r--r-- | cmds/idmap/inspect.cpp | 299 | ||||
-rw-r--r-- | cmds/media/src/com/android/commands/media/Media.java | 166 | ||||
-rw-r--r-- | cmds/pm/src/com/android/commands/pm/Pm.java | 85 | ||||
-rw-r--r-- | cmds/screencap/screencap.cpp | 13 |
9 files changed, 465 insertions, 243 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 6b55b7b..127b0fc 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -32,9 +32,11 @@ import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Configuration; import android.graphics.Rect; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -42,10 +44,15 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; +import android.text.TextUtils; import android.util.AndroidException; import android.view.IWindowManager; +import android.view.View; + import com.android.internal.os.BaseCommand; +import dalvik.system.VMRuntime; + import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -94,7 +101,11 @@ public class Am extends BaseCommand { " am broadcast [--user <USER_ID> | all | current] <INTENT>\n" + " am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" + " [--user <USER_ID> | current]\n" + - " [--no-window-animation] <COMPONENT>\n" + + " [--no-window-animation]\n" + + " [--abi <ABI>]\n : Launch the instrumented process with the " + + " selected ABI. This assumes that the process supports the" + + " selected ABI." + + " <COMPONENT>\n" + " am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" + " am profile stop [--user <USER_ID> current] [<PROCESS>]\n" + " am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" + @@ -116,6 +127,7 @@ public class Am extends BaseCommand { " am stack info <STACK_ID>\n" + " am lock-task <TASK_ID>\n" + " am lock-task stop\n" + + " am get-config\n" + "\n" + "am start: start an Activity. Options are:\n" + " -D: enable debugging\n" + @@ -222,6 +234,9 @@ public class Am extends BaseCommand { "\n" + "am lock-task: bring <TASK_ID> to the front and don't allow other tasks to run\n" + "\n" + + "am get-config: retrieve the configuration and any recent configurations\n" + + " of the device\n" + + "\n" + "<INTENT> specifications include these flags and arguments:\n" + " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" + @@ -316,6 +331,8 @@ public class Am extends BaseCommand { runStack(); } else if (op.equals("lock-task")) { runLockTask(); + } else if (op.equals("get-config")) { + runGetConfig(); } else { showError("Error: unknown command '" + op + "'"); } @@ -835,6 +852,7 @@ public class Am extends BaseCommand { Bundle args = new Bundle(); String argKey = null, argValue = null; IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); + String abi = null; String opt; while ((opt=nextOption()) != null) { @@ -853,6 +871,8 @@ public class Am extends BaseCommand { no_window_animation = true; } else if (opt.equals("--user")) { userId = parseUserArg(nextArgRequired()); + } else if (opt.equals("--abi")) { + abi = nextArgRequired(); } else { System.err.println("Error: Unknown option: " + opt); return; @@ -883,7 +903,23 @@ public class Am extends BaseCommand { wm.setAnimationScale(1, 0.0f); } - if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId)) { + if (abi != null) { + final String[] supportedAbis = Build.SUPPORTED_ABIS; + boolean matched = false; + for (String supportedAbi : supportedAbis) { + if (supportedAbi.equals(abi)) { + matched = true; + break; + } + } + + if (!matched) { + throw new AndroidException( + "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi); + } + } + + if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId, abi)) { throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString()); } @@ -1672,4 +1708,19 @@ public class Am extends BaseCommand { } catch (RemoteException e) { } } + + private void runGetConfig() throws Exception { + try { + Configuration config = mAm.getConfiguration(); + if (config == null) { + System.err.println("Activity manager has no configuration"); + return; + } + + System.out.println("config: " + Configuration.resourceQualifierString(config)); + System.out.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS)); + + } catch (RemoteException e) { + } + } } diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java index db3d8bb..d683851 100644 --- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java +++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java @@ -23,6 +23,7 @@ import android.app.backup.IRestoreSession; import android.os.RemoteException; import android.os.ServiceManager; +import java.util.ArrayList; import java.util.HashSet; public final class Bmgr { @@ -102,6 +103,11 @@ public final class Bmgr { return; } + if ("fullbackup".equals(op)) { + doFullTransportBackup(); + return; + } + System.err.println("Unknown command"); showUsage(); } @@ -165,6 +171,24 @@ public final class Bmgr { } } + private void doFullTransportBackup() { + System.out.println("Performing full transport backup"); + + String pkg; + ArrayList<String> allPkgs = new ArrayList<String>(); + while ((pkg = nextArg()) != null) { + allPkgs.add(pkg); + } + if (allPkgs.size() > 0) { + try { + mBmgr.fullTransportBackup(allPkgs.toArray(new String[allPkgs.size()])); + } catch (RemoteException e) { + System.err.println(e.toString()); + System.err.println(BMGR_NOT_RUNNING_ERR); + } + } + } + private void doTransport() { try { String which = nextArg(); @@ -453,6 +477,7 @@ public final class Bmgr { System.err.println(" bmgr restore PACKAGE"); System.err.println(" bmgr run"); System.err.println(" bmgr wipe TRANSPORT PACKAGE"); + System.err.println(" bmgr fullbackup PACKAGE..."); System.err.println(""); System.err.println("The 'backup' command schedules a backup pass for the named package."); System.err.println("Note that the backup pass will effectively be a no-op if the package"); @@ -468,11 +493,11 @@ public final class Bmgr { System.err.println(""); System.err.println("The 'list transports' command reports the names of the backup transports"); System.err.println("currently available on the device. These names can be passed as arguments"); - System.err.println("to the 'transport' and 'wipe' commands. The currently selected transport"); + System.err.println("to the 'transport' and 'wipe' commands. The currently active transport"); System.err.println("is indicated with a '*' character."); System.err.println(""); System.err.println("The 'list sets' command reports the token and name of each restore set"); - System.err.println("available to the device via the current transport."); + System.err.println("available to the device via the currently active transport."); System.err.println(""); System.err.println("The 'transport' command designates the named transport as the currently"); System.err.println("active one. This setting is persistent across reboots."); @@ -500,5 +525,8 @@ public final class Bmgr { System.err.println("erased from the given transport's storage. The next backup operation"); System.err.println("that the given application performs will rewrite its entire data set."); System.err.println("Transport names to use here are those reported by 'list transports'."); + System.err.println(""); + System.err.println("The 'fullbackup' command induces a full-data stream backup for one or more"); + System.err.println("packages. The data is sent via the currently active transport."); } } diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java index 2673031..ffc0f87 100644 --- a/cmds/bu/src/com/android/commands/bu/Backup.java +++ b/cmds/bu/src/com/android/commands/bu/Backup.java @@ -20,6 +20,7 @@ import android.app.backup.IBackupManager; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; +import android.system.OsConstants; import android.util.Log; import java.io.IOException; @@ -50,13 +51,11 @@ public final class Backup { return; } - int socketFd = Integer.parseInt(nextArg()); - String arg = nextArg(); if (arg.equals("backup")) { - doFullBackup(socketFd); + doFullBackup(OsConstants.STDOUT_FILENO); } else if (arg.equals("restore")) { - doFullRestore(socketFd); + doFullRestore(OsConstants.STDIN_FILENO); } else { Log.e(TAG, "Invalid operation '" + arg + "'"); } @@ -70,6 +69,7 @@ public final class Backup { boolean doEverything = false; boolean doWidgets = false; boolean allIncludesSystem = true; + boolean doCompress = true; String arg; while ((arg = nextArg()) != null) { @@ -96,6 +96,10 @@ public final class Backup { doWidgets = false; } else if ("-all".equals(arg)) { doEverything = true; + } else if ("-compress".equals(arg)) { + doCompress = true; + } else if ("-nocompress".equals(arg)) { + doCompress = false; } else { Log.w(TAG, "Unknown backup flag " + arg); continue; @@ -120,7 +124,7 @@ public final class Backup { fd = ParcelFileDescriptor.adoptFd(socketFd); String[] packArray = new String[packages.size()]; mBackupManager.fullBackup(fd, saveApks, saveObbs, saveShared, doWidgets, - doEverything, allIncludesSystem, packages.toArray(packArray)); + doEverything, allIncludesSystem, doCompress, packages.toArray(packArray)); } catch (RemoteException e) { Log.e(TAG, "Unable to invoke backup manager for backup"); } finally { diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp index ae35f7b..593a197 100644 --- a/cmds/idmap/create.cpp +++ b/cmds/idmap/create.cpp @@ -105,7 +105,7 @@ fail: uint32_t cached_target_crc, cached_overlay_crc; String8 cached_target_path, cached_overlay_path; - if (!ResTable::getIdmapInfo(buf, N, &cached_target_crc, &cached_overlay_crc, + if (!ResTable::getIdmapInfo(buf, N, NULL, &cached_target_crc, &cached_overlay_crc, &cached_target_path, &cached_overlay_path)) { return true; } diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp index 46c0edc..90cfa2c 100644 --- a/cmds/idmap/idmap.cpp +++ b/cmds/idmap/idmap.cpp @@ -66,26 +66,32 @@ EXAMPLES \n\ Display an idmap file: \n\ \n\ $ adb shell idmap --inspect /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\ - SECTION ENTRY VALUE OFFSET COMMENT \n\ - IDMAP HEADER magic 0x706d6469 0x0 \n\ - base crc 0x484aa77f 0x1 \n\ - overlay crc 0x03c66fa5 0x2 \n\ - base path .......... 0x03-0x42 /system/app/target.apk \n\ - overlay path .......... 0x43-0x82 /vendor/overlay/overlay.apk \n\ - DATA HEADER types count 0x00000003 0x83 \n\ - padding 0x00000000 0x84 \n\ - type offset 0x00000004 0x85 absolute offset 0x87, xml \n\ - type offset 0x00000007 0x86 absolute offset 0x8a, string \n\ - DATA BLOCK entry count 0x00000001 0x87 \n\ - entry offset 0x00000000 0x88 \n\ - entry 0x7f020000 0x89 xml/integer \n\ - DATA BLOCK entry count 0x00000002 0x8a \n\ - entry offset 0x00000000 0x8b \n\ - entry 0x7f030000 0x8c string/str \n\ - entry 0x7f030001 0x8d string/str2 \n\ + SECTION ENTRY VALUE COMMENT \n\ + IDMAP HEADER magic 0x706d6469 \n\ + base crc 0xb65a383f \n\ + overlay crc 0x7b9675e8 \n\ + base path .......... /path/to/target.apk \n\ + overlay path .......... /path/to/overlay.apk \n\ + DATA HEADER target pkg 0x0000007f \n\ + types count 0x00000003 \n\ + DATA BLOCK target type 0x00000002 \n\ + overlay type 0x00000002 \n\ + entry count 0x00000001 \n\ + entry offset 0x00000000 \n\ + entry 0x00000000 drawable/drawable \n\ + DATA BLOCK target type 0x00000003 \n\ + overlay type 0x00000003 \n\ + entry count 0x00000001 \n\ + entry offset 0x00000000 \n\ + entry 0x00000000 xml/integer \n\ + DATA BLOCK target type 0x00000004 \n\ + overlay type 0x00000004 \n\ + entry count 0x00000001 \n\ + entry offset 0x00000000 \n\ + entry 0x00000000 raw/lorem_ipsum \n\ \n\ In this example, the overlay package provides three alternative resource values:\n\ - xml/integer, string/str and string/str2.\n\ + drawable/drawable, xml/integer, and raw/lorem_ipsum \n\ \n\ NOTES \n\ This tool and its expected invocation from installd is modelled on dexopt."; diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp index a59f5d3..b9ac8a5 100644 --- a/cmds/idmap/inspect.cpp +++ b/cmds/idmap/inspect.cpp @@ -10,92 +10,108 @@ using namespace android; -#define NEXT(b, i, o) do { if (buf.next(&i, &o) < 0) { return -1; } } while (0) - namespace { - static const uint32_t IDMAP_MAGIC = 0x706d6469; + static const uint32_t IDMAP_MAGIC = 0x504D4449; static const size_t PATH_LENGTH = 256; - static const uint32_t IDMAP_HEADER_SIZE = (3 + 2 * (PATH_LENGTH / sizeof(uint32_t))); void printe(const char *fmt, ...); class IdmapBuffer { private: - char *buf_; + const char* buf_; size_t len_; - mutable size_t pos_; + size_t pos_; public: - IdmapBuffer() : buf_((char *)MAP_FAILED), len_(0), pos_(0) {} + IdmapBuffer() : buf_((const char *)MAP_FAILED), len_(0), pos_(0) {} ~IdmapBuffer() { if (buf_ != MAP_FAILED) { - munmap(buf_, len_); + munmap(const_cast<char*>(buf_), len_); } } - int init(const char *idmap_path) - { + status_t init(const char *idmap_path) { struct stat st; int fd; if (stat(idmap_path, &st) < 0) { printe("failed to stat idmap '%s': %s\n", idmap_path, strerror(errno)); - return -1; + return UNKNOWN_ERROR; } len_ = st.st_size; if ((fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY))) < 0) { printe("failed to open idmap '%s': %s\n", idmap_path, strerror(errno)); - return -1; + return UNKNOWN_ERROR; } - if ((buf_ = (char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { + if ((buf_ = (const char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { close(fd); printe("failed to mmap idmap: %s\n", strerror(errno)); - return -1; + return UNKNOWN_ERROR; } close(fd); - return 0; + return NO_ERROR; } - int next(uint32_t *i, uint32_t *offset) const - { + status_t nextUint32(uint32_t* i) { if (!buf_) { printe("failed to read next uint32_t: buffer not initialized\n"); - return -1; + return UNKNOWN_ERROR; } - if (pos_ + 4 > len_) { + + if (pos_ + sizeof(uint32_t) > len_) { printe("failed to read next uint32_t: end of buffer reached at pos=0x%08x\n", pos_); - return -1; + return UNKNOWN_ERROR; + } + + if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x3) != 0) { + printe("failed to read next uint32_t: not aligned on 4-byte boundary\n"); + return UNKNOWN_ERROR; } - *offset = pos_ / sizeof(uint32_t); - char a = buf_[pos_++]; - char b = buf_[pos_++]; - char c = buf_[pos_++]; - char d = buf_[pos_++]; - *i = (d << 24) | (c << 16) | (b << 8) | a; - return 0; + + *i = dtohl(*reinterpret_cast<const uint32_t*>(buf_ + pos_)); + pos_ += sizeof(uint32_t); + return NO_ERROR; } - int nextPath(char *b, uint32_t *offset_start, uint32_t *offset_end) const - { + status_t nextUint16(uint16_t* i) { + if (!buf_) { + printe("failed to read next uint16_t: buffer not initialized\n"); + return UNKNOWN_ERROR; + } + + if (pos_ + sizeof(uint16_t) > len_) { + printe("failed to read next uint16_t: end of buffer reached at pos=0x%08x\n", + pos_); + return UNKNOWN_ERROR; + } + + if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x1) != 0) { + printe("failed to read next uint32_t: not aligned on 2-byte boundary\n"); + return UNKNOWN_ERROR; + } + + *i = dtohs(*reinterpret_cast<const uint16_t*>(buf_ + pos_)); + pos_ += sizeof(uint16_t); + return NO_ERROR; + } + + status_t nextPath(char *b) { if (!buf_) { printe("failed to read next path: buffer not initialized\n"); - return -1; + return UNKNOWN_ERROR; } if (pos_ + PATH_LENGTH > len_) { printe("failed to read next path: end of buffer reached at pos=0x%08x\n", pos_); - return -1; + return UNKNOWN_ERROR; } memcpy(b, buf_ + pos_, PATH_LENGTH); - *offset_start = pos_ / sizeof(uint32_t); pos_ += PATH_LENGTH; - *offset_end = pos_ / sizeof(uint32_t) - 1; - return 0; + return NO_ERROR; } }; - void printe(const char *fmt, ...) - { + void printe(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -104,44 +120,37 @@ namespace { va_end(ap); } - void print_header() - { - printf("SECTION ENTRY VALUE OFFSET COMMENT\n"); + void print_header() { + printf("SECTION ENTRY VALUE COMMENT\n"); } - void print(const char *section, const char *subsection, uint32_t value, uint32_t offset, - const char *fmt, ...) - { + void print(const char *section, const char *subsection, uint32_t value, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - printf("%-12s %-12s 0x%08x 0x%-4x ", section, subsection, value, offset); + printf("%-12s %-12s 0x%08x ", section, subsection, value); vprintf(fmt, ap); printf("\n"); va_end(ap); } - void print_path(const char *section, const char *subsection, uint32_t offset_start, - uint32_t offset_end, const char *fmt, ...) - { + void print_path(const char *section, const char *subsection, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - printf("%-12s %-12s .......... 0x%02x-0x%02x ", section, subsection, offset_start, - offset_end); + printf("%-12s %-12s .......... ", section, subsection); vprintf(fmt, ap); printf("\n"); va_end(ap); } - int resource_metadata(const AssetManager& am, uint32_t res_id, - String8 *package, String8 *type, String8 *name) - { + status_t resource_metadata(const AssetManager& am, uint32_t res_id, + String8 *package, String8 *type, String8 *name) { const ResTable& rt = am.getResources(); struct ResTable::resource_name data; if (!rt.getResourceName(res_id, false, &data)) { printe("failed to get resource name id=0x%08x\n", res_id); - return -1; + return UNKNOWN_ERROR; } if (package) { *package = String8(String16(data.package, data.packageLen)); @@ -152,140 +161,150 @@ namespace { if (name) { *name = String8(String16(data.name, data.nameLen)); } - return 0; - } - - int package_id(const AssetManager& am) - { - return (am.getResources().getBasePackageId(0)) << 24; + return NO_ERROR; } - int parse_idmap_header(const IdmapBuffer& buf, AssetManager& am) - { - uint32_t i, o, e; + status_t parse_idmap_header(IdmapBuffer& buf, AssetManager& am) { + uint32_t i; char path[PATH_LENGTH]; - NEXT(buf, i, o); + status_t err = buf.nextUint32(&i); + if (err != NO_ERROR) { + return err; + } + if (i != IDMAP_MAGIC) { printe("not an idmap file: actual magic constant 0x%08x does not match expected magic " "constant 0x%08x\n", i, IDMAP_MAGIC); - return -1; + return UNKNOWN_ERROR; } + print_header(); - print("IDMAP HEADER", "magic", i, o, ""); + print("IDMAP HEADER", "magic", i, ""); + + err = buf.nextUint32(&i); + if (err != NO_ERROR) { + return err; + } + print("", "version", i, ""); - NEXT(buf, i, o); - print("", "base crc", i, o, ""); + err = buf.nextUint32(&i); + if (err != NO_ERROR) { + return err; + } + print("", "base crc", i, ""); - NEXT(buf, i, o); - print("", "overlay crc", i, o, ""); + err = buf.nextUint32(&i); + if (err != NO_ERROR) { + return err; + } + print("", "overlay crc", i, ""); - if (buf.nextPath(path, &o, &e) < 0) { + err = buf.nextPath(path); + if (err != NO_ERROR) { // printe done from IdmapBuffer::nextPath - return -1; + return err; } - print_path("", "base path", o, e, "%s", path); + print_path("", "base path", "%s", path); + if (!am.addAssetPath(String8(path), NULL)) { printe("failed to add '%s' as asset path\n", path); - return -1; + return UNKNOWN_ERROR; } - if (buf.nextPath(path, &o, &e) < 0) { + err = buf.nextPath(path); + if (err != NO_ERROR) { // printe done from IdmapBuffer::nextPath - return -1; + return err; } - print_path("", "overlay path", o, e, "%s", path); + print_path("", "overlay path", "%s", path); - return 0; + return NO_ERROR; } - int parse_data_header(const IdmapBuffer& buf, const AssetManager& am, Vector<uint32_t>& types) - { - uint32_t i, o; - const uint32_t numeric_package = package_id(am); + status_t parse_data(IdmapBuffer& buf, const AssetManager& am) { + const uint32_t packageId = am.getResources().getBasePackageId(0); - NEXT(buf, i, o); - print("DATA HEADER", "types count", i, o, ""); - const uint32_t N = i; + uint16_t data16; + status_t err = buf.nextUint16(&data16); + if (err != NO_ERROR) { + return err; + } + print("DATA HEADER", "target pkg", static_cast<uint32_t>(data16), ""); - for (uint32_t j = 0; j < N; ++j) { - NEXT(buf, i, o); - if (i == 0) { - print("", "padding", i, o, ""); - } else { - String8 type; - const uint32_t numeric_type = (j + 1) << 16; - const uint32_t res_id = numeric_package | numeric_type; - if (resource_metadata(am, res_id, NULL, &type, NULL) < 0) { - // printe done from resource_metadata - return -1; - } - print("", "type offset", i, o, "absolute offset 0x%02x, %s", - i + IDMAP_HEADER_SIZE, type.string()); - types.add(numeric_type); - } + err = buf.nextUint16(&data16); + if (err != NO_ERROR) { + return err; } + print("", "types count", static_cast<uint32_t>(data16), ""); - return 0; - } + uint32_t typeCount = static_cast<uint32_t>(data16); + while (typeCount > 0) { + typeCount--; + + err = buf.nextUint16(&data16); + if (err != NO_ERROR) { + return err; + } + const uint32_t targetTypeId = static_cast<uint32_t>(data16); + print("DATA BLOCK", "target type", targetTypeId, ""); - int parse_data_block(const IdmapBuffer& buf, const AssetManager& am, size_t numeric_type) - { - uint32_t i, o, n, id_offset; - const uint32_t numeric_package = package_id(am); - - NEXT(buf, i, o); - print("DATA BLOCK", "entry count", i, o, ""); - n = i; - - NEXT(buf, i, o); - print("", "entry offset", i, o, ""); - id_offset = i; - - for ( ; n > 0; --n) { - String8 type, name; - - NEXT(buf, i, o); - if (i == 0) { - print("", "padding", i, o, ""); - } else { - uint32_t res_id = numeric_package | numeric_type | id_offset; - if (resource_metadata(am, res_id, NULL, &type, &name) < 0) { - // printe done from resource_metadata - return -1; + err = buf.nextUint16(&data16); + if (err != NO_ERROR) { + return err; + } + print("", "overlay type", static_cast<uint32_t>(data16), ""); + + err = buf.nextUint16(&data16); + if (err != NO_ERROR) { + return err; + } + const uint32_t entryCount = static_cast<uint32_t>(data16); + print("", "entry count", entryCount, ""); + + err = buf.nextUint16(&data16); + if (err != NO_ERROR) { + return err; + } + const uint32_t entryOffset = static_cast<uint32_t>(data16); + print("", "entry offset", entryOffset, ""); + + for (uint32_t i = 0; i < entryCount; i++) { + uint32_t data32; + err = buf.nextUint32(&data32); + if (err != NO_ERROR) { + return err; } - print("", "entry", i, o, "%s/%s", type.string(), name.string()); + + uint32_t resID = (packageId << 24) | (targetTypeId << 16) | (entryOffset + i); + String8 type; + String8 name; + err = resource_metadata(am, resID, NULL, &type, &name); + if (err != NO_ERROR) { + return err; + } + print("", "entry", data32, "%s/%s", type.string(), name.string()); } - ++id_offset; } - return 0; + return NO_ERROR; } } -int idmap_inspect(const char *idmap_path) -{ +int idmap_inspect(const char *idmap_path) { IdmapBuffer buf; if (buf.init(idmap_path) < 0) { // printe done from IdmapBuffer::init return EXIT_FAILURE; } AssetManager am; - if (parse_idmap_header(buf, am) < 0) { + if (parse_idmap_header(buf, am) != NO_ERROR) { // printe done from parse_idmap_header return EXIT_FAILURE; } - Vector<uint32_t> types; - if (parse_data_header(buf, am, types) < 0) { + if (parse_data(buf, am) != NO_ERROR) { // printe done from parse_data_header return EXIT_FAILURE; } - const size_t N = types.size(); - for (size_t i = 0; i < N; ++i) { - if (parse_data_block(buf, am, types.itemAt(i)) < 0) { - // printe done from parse_data_block - return EXIT_FAILURE; - } - } return EXIT_SUCCESS; } diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java index 92c6a51..4e91361 100644 --- a/cmds/media/src/com/android/commands/media/Media.java +++ b/cmds/media/src/com/android/commands/media/Media.java @@ -17,12 +17,19 @@ package com.android.commands.media; -import android.app.PendingIntent; +import android.app.ActivityManager; import android.content.Context; -import android.graphics.Bitmap; -import android.media.IAudioService; -import android.media.IRemoteControlDisplay; +import android.media.MediaMetadata; +import android.media.session.ISessionController; +import android.media.session.ISessionManager; +import android.media.session.MediaController; +import android.media.session.MediaSessionInfo; +import android.media.session.PlaybackState; +import android.media.session.RouteInfo; import android.os.Bundle; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -30,16 +37,17 @@ import android.util.AndroidException; import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; + import com.android.internal.os.BaseCommand; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; +import java.util.List; public class Media extends BaseCommand { - - private IAudioService mAudioService; + private ISessionManager mSessionService; /** * Command-line entry point. @@ -54,29 +62,35 @@ public class Media extends BaseCommand { out.println( "usage: media [subcommand] [options]\n" + " media dispatch KEY\n" + - " media remote-display\n" + + " media list-sessions\n" + + " media monitor <sessionId>\n" + "\n" + - "media dispatch: dispatch a media key to the current media client.\n" + + "media dispatch: dispatch a media key to the system.\n" + " KEY may be: play, pause, play-pause, mute, headsethook,\n" + - " stop, next, previous, rewind, recordm fast-forword.\n" + - "media remote-display: monitor remote display updates.\n" + " stop, next, previous, rewind, record, fast-forword.\n" + + "media list-sessions: print a list of the current sessions.\n" + + "media monitor: monitor updates to the specified session.\n" + + " Use the sessionId from list-sessions.\n" ); } public void onRun() throws Exception { - mAudioService = IAudioService.Stub.asInterface(ServiceManager.checkService( - Context.AUDIO_SERVICE)); - if (mAudioService == null) { + mSessionService = ISessionManager.Stub.asInterface(ServiceManager.checkService( + Context.MEDIA_SESSION_SERVICE)); + if (mSessionService == null) { System.err.println(NO_SYSTEM_ERROR_CODE); - throw new AndroidException("Can't connect to audio service; is the system running?"); + throw new AndroidException( + "Can't connect to media session service; is the system running?"); } String op = nextArgRequired(); if (op.equals("dispatch")) { runDispatch(); - } else if (op.equals("remote-display")) { - runRemoteDisplay(); + } else if (op.equals("list-sessions")) { + runListSessions(); + } else if (op.equals("monitor")) { + runMonitor(); } else { showError("Error: unknown command '" + op + "'"); return; @@ -85,11 +99,39 @@ public class Media extends BaseCommand { private void sendMediaKey(KeyEvent event) { try { - mAudioService.dispatchMediaKeyEvent(event); + mSessionService.dispatchMediaKeyEvent(event, false); } catch (RemoteException e) { } } + private void runMonitor() throws Exception { + String id = nextArgRequired(); + if (id == null) { + showError("Error: must include a session id"); + return; + } + boolean success = false; + try { + List<IBinder> sessions = mSessionService + .getSessions(null, ActivityManager.getCurrentUser()); + for (IBinder session : sessions) { + MediaController controller = MediaController.fromBinder(ISessionController.Stub + .asInterface(session)); + if (controller != null && controller.getSessionInfo().getId().equals(id)) { + ControllerMonitor monitor = new ControllerMonitor(controller); + monitor.run(); + success = true; + break; + } + } + } catch (Exception e) { + System.out.println("***Error monitoring session*** " + e.getMessage()); + } + if (!success) { + System.out.println("No session found with id " + id); + } + } + private void runDispatch() throws Exception { String cmd = nextArgRequired(); int keycode; @@ -127,65 +169,49 @@ public class Media extends BaseCommand { KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD)); } - class RemoteDisplayMonitor extends IRemoteControlDisplay.Stub { - RemoteDisplayMonitor() { - } + class ControllerMonitor extends MediaController.Callback { + private final MediaController mController; - - @Override - public void setCurrentClientId(int clientGeneration, PendingIntent clientMediaIntent, - boolean clearing) { - System.out.println("New client: id=" + clientGeneration - + " intent=" + clientMediaIntent + " clearing=" + clearing); + public ControllerMonitor(MediaController controller) { + mController = controller; } - @Override - public void setEnabled(boolean enabled) { - System.out.println("New enable state= " + (enabled ? "enabled" : "disabled")); + public void onSessionEvent(String event, Bundle extras) { + System.out.println("onSessionEvent event=" + event + ", extras=" + extras); } @Override - public void setPlaybackState(int generationId, int state, long stateChangeTimeMs, - long currentPosMs, float speed) { - System.out.println("New state: id=" + generationId + " state=" + state - + " time=" + stateChangeTimeMs + " pos=" + currentPosMs + " speed=" + speed); + public void onRouteChanged(RouteInfo route) { + System.out.println("onRouteChanged " + route); } @Override - public void setTransportControlInfo(int generationId, int transportControlFlags, - int posCapabilities) { - System.out.println("New control info: id=" + generationId - + " flags=0x" + Integer.toHexString(transportControlFlags) - + " cap=0x" + Integer.toHexString(posCapabilities)); + public void onPlaybackStateChanged(PlaybackState state) { + System.out.println("onPlaybackStateChanged " + state); } @Override - public void setMetadata(int generationId, Bundle metadata) { - System.out.println("New metadata: id=" + generationId - + " data=" + metadata); - } - - @Override - public void setArtwork(int generationId, Bitmap artwork) { - System.out.println("New artwork: id=" + generationId - + " art=" + artwork); - } - - @Override - public void setAllMetadata(int generationId, Bundle metadata, Bitmap artwork) { - System.out.println("New metadata+artwork: id=" + generationId - + " data=" + metadata + " art=" + artwork); + public void onMetadataChanged(MediaMetadata metadata) { + String mmString = metadata == null ? null : "title=" + metadata + .getString(MediaMetadata.METADATA_KEY_TITLE); + System.out.println("onMetadataChanged " + mmString); } void printUsageMessage() { - System.out.println("Monitoring remote control displays... available commands:"); + System.out.println("V2Monitoring session " + mController.getSessionInfo().getId() + + "... available commands:"); System.out.println("(q)uit: finish monitoring"); } void run() throws RemoteException { printUsageMessage(); - - mAudioService.registerRemoteControlDisplay(this, 0, 0); + HandlerThread cbThread = new HandlerThread("MediaCb") { + @Override + protected void onLooperPrepared() { + mController.addCallback(ControllerMonitor.this); + } + }; + cbThread.start(); try { InputStreamReader converter = new InputStreamReader(System.in); @@ -209,17 +235,35 @@ public class Media extends BaseCommand { printUsageMessage(); } } - } catch (IOException e) { e.printStackTrace(); } finally { - mAudioService.unregisterRemoteControlDisplay(this); + cbThread.getLooper().quit(); + try { + mController.removeCallback(this); + } catch (Exception e) { + // ignoring + } } } } - private void runRemoteDisplay() throws Exception { - RemoteDisplayMonitor monitor = new RemoteDisplayMonitor(); - monitor.run(); + private void runListSessions() { + System.out.println("Sessions:"); + try { + List<IBinder> sessions = mSessionService + .getSessions(null, ActivityManager.getCurrentUser()); + for (IBinder session : sessions) { + MediaController controller = MediaController.fromBinder(ISessionController.Stub + .asInterface(session)); + if (controller != null) { + MediaSessionInfo info = controller.getSessionInfo(); + System.out.println(" id=" + info.getId() + ", package=" + + info.getPackageName()); + } + } + } catch (Exception e) { + System.out.println("***Error listing sessions***"); + } } } diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 5454b46..f85a7dc 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -39,6 +39,7 @@ import android.content.pm.VerificationParams; import android.content.res.AssetManager; import android.content.res.Resources; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.IUserManager; import android.os.Process; @@ -63,6 +64,7 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import com.android.internal.content.PackageHelper; +import com.android.internal.util.ArrayUtils; public final class Pm { IPackageManager mPm; @@ -823,6 +825,7 @@ public final class Pm { byte[] tag = null; String originatingUriString = null; String referrer = null; + String abi = null; while ((opt=nextOption()) != null) { if (opt.equals("-l")) { @@ -893,12 +896,34 @@ public final class Pm { System.err.println("Error: must supply argument for --referrer"); return; } + } else if (opt.equals("--abi")) { + abi = nextOptionData(); + if (abi == null) { + System.err.println("Error: must supply argument for --abi"); + return; + } } else { System.err.println("Error: Unknown option: " + opt); return; } } + if (abi != null) { + final String[] supportedAbis = Build.SUPPORTED_ABIS; + boolean matched = false; + for (String supportedAbi : supportedAbis) { + if (supportedAbi.equals(abi)) { + matched = true; + break; + } + } + + if (!matched) { + System.err.println("Error: abi " + abi + " not supported on this device."); + return; + } + } + final ContainerEncryptionParams encryptionParams; if (algo != null || iv != null || key != null || macAlgo != null || macKey != null || tag != null) { @@ -976,8 +1001,9 @@ public final class Pm { VerificationParams verificationParams = new VerificationParams(verificationURI, originatingURI, referrerURI, VerificationParams.NO_UID, null); - mPm.installPackageWithVerificationAndEncryptionEtc(apkURI, null, obs, installFlags, - installerPackageName, verificationParams, encryptionParams); + mPm.installPackageWithVerificationEncryptionAndAbiOverrideEtc(apkURI, null, + obs, installFlags, installerPackageName, verificationParams, + encryptionParams, abi); synchronized (obs) { while (!obs.finished) { @@ -1146,12 +1172,22 @@ public final class Pm { } private void runUninstall() { - int unInstallFlags = PackageManager.DELETE_ALL_USERS; + int unInstallFlags = 0; + int userId = UserHandle.USER_ALL; String opt; while ((opt=nextOption()) != null) { if (opt.equals("-k")) { unInstallFlags |= PackageManager.DELETE_KEEP_DATA; + } else if (opt.equals("--user")) { + String param = nextArg(); + if (isNumber(param)) { + userId = Integer.parseInt(param); + } else { + showUsage(); + System.err.println("Error: Invalid user: " + param); + return; + } } else { System.err.println("Error: Unknown option: " + opt); return; @@ -1164,7 +1200,34 @@ public final class Pm { showUsage(); return; } - boolean result = deletePackage(pkg, unInstallFlags); + + if (userId == UserHandle.USER_ALL) { + userId = UserHandle.USER_OWNER; + unInstallFlags |= PackageManager.DELETE_ALL_USERS; + } else { + PackageInfo info; + try { + info = mPm.getPackageInfo(pkg, 0, userId); + } catch (RemoteException e) { + System.err.println(e.toString()); + System.err.println(PM_NOT_RUNNING_ERR); + return; + } + if (info == null) { + System.err.println("Failure - not installed for " + userId); + return; + } + final boolean isSystem = + (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + // If we are being asked to delete a system app for just one + // user set flag so it disables rather than reverting to system + // version of the app. + if (isSystem) { + unInstallFlags |= PackageManager.DELETE_SYSTEM_APP; + } + } + + boolean result = deletePackage(pkg, unInstallFlags, userId); if (result) { System.out.println("Success"); } else { @@ -1172,10 +1235,10 @@ public final class Pm { } } - private boolean deletePackage(String pkg, int unInstallFlags) { + private boolean deletePackage(String pkg, int unInstallFlags, int userId) { PackageDeleteObserver obs = new PackageDeleteObserver(); try { - mPm.deletePackageAsUser(pkg, obs, UserHandle.USER_OWNER, unInstallFlags); + mPm.deletePackageAsUser(pkg, obs, userId, unInstallFlags); synchronized (obs) { while (!obs.finished) { @@ -1487,6 +1550,12 @@ public final class Pm { if (info != null && info.applicationInfo != null) { System.out.print("package:"); System.out.println(info.applicationInfo.sourceDir); + if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) { + for (String splitSourceDir : info.applicationInfo.splitSourceDirs) { + System.out.print("package:"); + System.out.println(splitSourceDir); + } + } } } catch (RemoteException e) { System.err.println(e.toString()); @@ -1571,7 +1640,7 @@ public final class Pm { System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]"); System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]"); System.err.println(" [--originating-uri <URI>] [--referrer <URI>] PATH"); - System.err.println(" pm uninstall [-k] PACKAGE"); + System.err.println(" pm uninstall [-k] [--user USER_ID] PACKAGE"); System.err.println(" pm clear [--user USER_ID] PACKAGE"); System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT"); System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT"); @@ -1585,7 +1654,7 @@ public final class Pm { System.err.println(" pm get-install-location"); System.err.println(" pm set-permission-enforced PERMISSION [true|false]"); System.err.println(" pm trim-caches DESIRED_FREE_SPACE"); - System.err.println(" pm create-user [--relatedTo USER_ID] [--managed] USER_NAME"); + System.err.println(" pm create-user [--profileOf USER_ID] [--managed] USER_NAME"); System.err.println(" pm remove-user USER_ID"); System.err.println(" pm get-max-users"); System.err.println(""); diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index 2efe4d3..6b2a0e2 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -52,13 +52,13 @@ static void usage(const char* pname) ); } -static SkBitmap::Config flinger2skia(PixelFormat f) +static SkColorType flinger2skia(PixelFormat f) { switch (f) { case PIXEL_FORMAT_RGB_565: - return SkBitmap::kRGB_565_Config; + return kRGB_565_SkColorType; default: - return SkBitmap::kARGB_8888_Config; + return kN32_SkColorType; } } @@ -141,7 +141,7 @@ int main(int argc, char** argv) ScreenshotClient screenshot; sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId); - if (display != NULL && screenshot.update(display, false) == NO_ERROR) { + if (display != NULL && screenshot.update(display, Rect(), false) == NO_ERROR) { base = screenshot.getPixels(); w = screenshot.getWidth(); h = screenshot.getHeight(); @@ -174,9 +174,10 @@ int main(int argc, char** argv) if (base) { if (png) { + const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f), + kPremul_SkAlphaType); SkBitmap b; - b.setConfig(flinger2skia(f), w, h, s*bytesPerPixel(f)); - b.setPixels((void*)base); + b.installPixels(info, const_cast<void*>(base), s*bytesPerPixel(f)); SkDynamicMemoryWStream stream; SkImageEncoder::EncodeStream(&stream, b, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality); |