Merge "Adds a -P option so dumpstate can report its progress."
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 0e77850..be9709a 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -26,6 +26,7 @@
#include <string.h>
#include <sys/sendfile.h>
#include <time.h>
+#include <unistd.h>
#include <zlib.h>
#include <binder/IBinder.h>
@@ -214,6 +215,9 @@
static const char* k_tracePath =
"/sys/kernel/debug/tracing/trace";
+static const char* k_traceStreamPath =
+ "/sys/kernel/debug/tracing/trace_pipe";
+
static const char* k_traceMarkerPath =
"/sys/kernel/debug/tracing/trace_marker";
@@ -732,6 +736,31 @@
setTracingEnabled(false);
}
+// Read data from the tracing pipe and forward to stdout
+static void streamTrace()
+{
+ char trace_data[4096];
+ int traceFD = open(k_traceStreamPath, O_RDWR);
+ if (traceFD == -1) {
+ fprintf(stderr, "error opening %s: %s (%d)\n", k_traceStreamPath,
+ strerror(errno), errno);
+ return;
+ }
+ while (!g_traceAborted) {
+ ssize_t bytes_read = read(traceFD, trace_data, 4096);
+ if (bytes_read > 0) {
+ write(STDOUT_FILENO, trace_data, bytes_read);
+ fflush(stdout);
+ } else {
+ if (!g_traceAborted) {
+ fprintf(stderr, "read returned %zd bytes err %d (%s)\n",
+ bytes_read, errno, strerror(errno));
+ }
+ break;
+ }
+ }
+}
+
// Read the current kernel trace and write it to stdout.
static void dumpTrace()
{
@@ -878,6 +907,10 @@
" --async_dump dump the current contents of circular trace buffer\n"
" --async_stop stop tracing and dump the current contents of circular\n"
" trace buffer\n"
+ " --stream stream trace to stdout as it enters the trace buffer\n"
+ " Note: this can take significant CPU time, and is best\n"
+ " used for measuring things that are not affected by\n"
+ " CPU performance, like pagecache usage.\n"
" --list_categories\n"
" list the available tracing categories\n"
);
@@ -889,6 +922,7 @@
bool traceStart = true;
bool traceStop = true;
bool traceDump = true;
+ bool traceStream = false;
if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
showHelp(argv[0]);
@@ -903,6 +937,7 @@
{"async_stop", no_argument, 0, 0 },
{"async_dump", no_argument, 0, 0 },
{"list_categories", no_argument, 0, 0 },
+ {"stream", no_argument, 0, 0 },
{ 0, 0, 0, 0 }
};
@@ -969,6 +1004,9 @@
async = true;
traceStart = false;
traceStop = false;
+ } else if (!strcmp(long_options[option_index].name, "stream")) {
+ traceStream = true;
+ traceDump = false;
} else if (!strcmp(long_options[option_index].name, "list_categories")) {
listSupportedCategories();
exit(0);
@@ -994,8 +1032,10 @@
ok &= startTrace();
if (ok && traceStart) {
- printf("capturing trace...");
- fflush(stdout);
+ if (!traceStream) {
+ printf("capturing trace...");
+ fflush(stdout);
+ }
// We clear the trace after starting it because tracing gets enabled for
// each CPU individually in the kernel. Having the beginning of the trace
@@ -1005,7 +1045,7 @@
ok = clearTrace();
writeClockSyncMarker();
- if (ok && !async) {
+ if (ok && !async && !traceStream) {
// Sleep to allow the trace to be captured.
struct timespec timeLeft;
timeLeft.tv_sec = g_traceDurationSeconds;
@@ -1016,6 +1056,10 @@
}
} while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR);
}
+
+ if (traceStream) {
+ streamTrace();
+ }
}
// Stop the trace and restore the default settings.
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 61f8365..f8ea394 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -322,7 +322,7 @@
dump_file("KERNEL SYNC", "/d/sync");
run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
- run_command("LIBRANK", 10, "librank", NULL);
+ run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL);
do_dmesg();
diff --git a/data/etc/android.hardware.type.automotive.xml b/data/etc/android.hardware.type.automotive.xml
new file mode 100644
index 0000000..a9b4b05
--- /dev/null
+++ b/data/etc/android.hardware.type.automotive.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- These features determine that the device running android is a car. -->
+<permissions>
+ <feature name="android.hardware.type.automotive" />
+</permissions>
diff --git a/data/etc/car_core_hardware.xml b/data/etc/car_core_hardware.xml
new file mode 100644
index 0000000..8ed8460
--- /dev/null
+++ b/data/etc/car_core_hardware.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- These are the hardware components that all handheld devices
+ must include. Devices with optional hardware must also include extra
+ hardware files, per the comments below.
+
+ Handheld devices include phones, mobile Internet devices (MIDs),
+ Personal Media Players (PMPs), small tablets (7" or less), and similar
+ devices.
+-->
+<permissions>
+ <feature name="android.hardware.audio.output" />
+ <feature name="android.hardware.camera" />
+ <feature name="android.hardware.location" />
+ <feature name="android.hardware.location.network" />
+ <feature name="android.hardware.sensor.compass" />
+ <feature name="android.hardware.sensor.accelerometer" />
+ <feature name="android.hardware.bluetooth" />
+ <feature name="android.hardware.touchscreen" />
+ <feature name="android.hardware.microphone" />
+ <feature name="android.hardware.screen.landscape" />
+ <!-- Feature to specify if the device is a car -->
+ <feature name="android.hardware.type.automotive" />
+
+ <!-- basic system services -->
+ <feature name="android.software.app_widgets" />
+ <feature name="android.software.connectionservice" />
+ <feature name="android.software.voice_recognizers" notLowRam="true" />
+ <feature name="android.software.backup" />
+ <feature name="android.software.home_screen" />
+ <feature name="android.software.input_methods" />
+ <feature name="android.software.print" />
+
+ <!-- Feature to specify if the device supports adding device admins. -->
+ <feature name="android.software.device_admin" />
+
+ <!-- Feature to specify if the device support managed users. -->
+ <feature name="android.software.managed_users" />
+
+ <!-- devices with GPS must include android.hardware.location.gps.xml -->
+ <!-- devices with an autofocus camera and/or flash must include either
+ android.hardware.camera.autofocus.xml or
+ android.hardware.camera.autofocus-flash.xml -->
+ <!-- devices with a front facing camera must include
+ android.hardware.camera.front.xml -->
+ <!-- devices with WiFi must also include android.hardware.wifi.xml -->
+ <!-- devices that support multitouch must include the most appropriate one
+ of these files:
+
+ If only partial (non-independent) pointers are supported:
+ android.hardware.touchscreen.multitouch.xml
+
+ If up to 4 independently tracked pointers are supported:
+ include android.hardware.touchscreen.multitouch.distinct.xml
+
+ If 5 or more independently tracked pointers are supported:
+ include android.hardware.touchscreen.multitouch.jazzhand.xml
+
+ ONLY ONE of the above should be included. -->
+ <!-- devices with an ambient light sensor must also include
+ android.hardware.sensor.light.xml -->
+ <!-- devices with a proximity sensor must also include
+ android.hardware.sensor.proximity.xml -->
+ <!-- GSM phones must also include android.hardware.telephony.gsm.xml -->
+ <!-- CDMA phones must also include android.hardware.telephony.cdma.xml -->
+ <!-- Devices that have low-latency audio stacks suitable for apps like
+ VoIP may include android.hardware.audio.low_latency.xml. ONLY apps
+ that meet the requirements specified in the CDD may include this. -->
+</permissions>
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index b6106ba..16a4790 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -20,6 +20,7 @@
#include <vector>
#include <cutils/native_handle.h>
+#include <nativehelper/ScopedFd.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/String16.h>
@@ -154,6 +155,17 @@
// will be closed once the parcel is destroyed.
status_t writeDupFileDescriptor(int fd);
+ // Place a file descriptor into the parcel. This will not affect the
+ // semantics of the smart file descriptor. A new descriptor will be
+ // created, and will be closed when the parcel is destroyed.
+ status_t writeUniqueFileDescriptor(
+ const ScopedFd& fd);
+
+ // Place a vector of file desciptors into the parcel. Each descriptor is
+ // dup'd as in writeDupFileDescriptor
+ status_t writeUniqueFileDescriptorVector(
+ const std::vector<ScopedFd>& val);
+
// Writes a blob to the parcel.
// If the blob is small, then it is stored in-place, otherwise it is
// transferred by way of an anonymous shared memory region. Prefer sending
@@ -250,6 +262,15 @@
// in the parcel, which you do not own -- use dup() to get your own copy.
int readFileDescriptor() const;
+ // Retrieve a smart file descriptor from the parcel.
+ status_t readUniqueFileDescriptor(
+ ScopedFd* val) const;
+
+
+ // Retrieve a vector of smart file descriptors from the parcel.
+ status_t readUniqueFileDescriptorVector(
+ std::vector<ScopedFd>* val) const;
+
// Reads a blob from the parcel.
// The caller should call release() on the blob after reading its contents.
status_t readBlob(size_t len, ReadableBlob* outBlob) const;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a101d90..13ecc87 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1006,12 +1006,20 @@
return -errno;
}
status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
- if (err) {
+ if (err != OK) {
close(dupFd);
}
return err;
}
+status_t Parcel::writeUniqueFileDescriptor(const ScopedFd& fd) {
+ return writeDupFileDescriptor(fd.get());
+}
+
+status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<ScopedFd>& val) {
+ return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
+}
+
status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
{
if (len > INT32_MAX) {
@@ -1625,16 +1633,36 @@
int Parcel::readFileDescriptor() const
{
const flat_binder_object* flat = readObject(true);
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_FD:
- //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
- return flat->handle;
- }
+
+ if (flat && flat->type == BINDER_TYPE_FD) {
+ return flat->handle;
}
+
return BAD_TYPE;
}
+status_t Parcel::readUniqueFileDescriptor(ScopedFd* val) const
+{
+ int got = readFileDescriptor();
+
+ if (got == BAD_TYPE) {
+ return BAD_TYPE;
+ }
+
+ val->reset(dup(got));
+
+ if (val->get() < 0) {
+ return BAD_VALUE;
+ }
+
+ return OK;
+}
+
+
+status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const {
+ return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
+}
+
status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
{
int32_t blobType;