Merge "Remove Bluedroid kernel dump from dumpstate." into mnc-dev
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index d1451e8..fbd0032 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -317,6 +317,8 @@
run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
+ run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL);
+
run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 99da968..ebd71a0 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -1778,6 +1778,31 @@
return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */);
}
+int link_file(const char* relative_path, const char* from_base, const char* to_base) {
+ char from_path[PKG_PATH_MAX];
+ char to_path[PKG_PATH_MAX];
+ snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path);
+ snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path);
+
+ if (validate_apk_path_subdirs(from_path)) {
+ ALOGE("invalid app data sub-path '%s' (bad prefix)\n", from_path);
+ return -1;
+ }
+
+ if (validate_apk_path_subdirs(to_path)) {
+ ALOGE("invalid app data sub-path '%s' (bad prefix)\n", to_path);
+ return -1;
+ }
+
+ const int ret = link(from_path, to_path);
+ if (ret < 0) {
+ ALOGE("link(%s, %s) failed : %s", from_path, to_path, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
const char *instruction_set) {
char *file_name_start;
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index 01e7cdd..297b3a1 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -179,6 +179,12 @@
return rm_package_dir(arg[0]);
}
+static int do_link_file(char **arg, char reply[REPLY_MAX] __unused)
+{
+ /* relative_path, from_base, to_base */
+ return link_file(arg[0], arg[1], arg[2]);
+}
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -209,7 +215,8 @@
{ "idmap", 3, do_idmap },
{ "restorecondata", 4, do_restorecon_data },
{ "createoatdir", 2, do_create_oat_dir },
- { "rmpackagedir", 1, do_rm_package_dir},
+ { "rmpackagedir", 1, do_rm_package_dir },
+ { "linkfile", 3, do_link_file }
};
static int readx(int s, void *_buf, int count)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index ce6c857..744ed3a 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -203,6 +203,7 @@
int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix);
int validate_apk_path(const char *path);
+int validate_apk_path_subdirs(const char *path);
int append_and_increment(char** dst, const char* src, size_t* dst_size);
@@ -254,3 +255,4 @@
const char *instruction_set);
int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
const char *instruction_set);
+int link_file(const char *relative_path, const char *from_base, const char *to_base);
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 3f679a2..7db3fb9 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -1043,15 +1043,13 @@
}
/**
- * Check whether path points to a valid path for an APK file. Only one level of
- * subdirectory names is allowed. Returns -1 when an invalid path is encountered
- * and 0 when a valid path is encountered.
+ * Check whether path points to a valid path for an APK file. The path must
+ * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within
+ * that path. Returns -1 when an invalid path is encountered and 0 when a valid path
+ * is encountered.
*/
-int validate_apk_path(const char *path)
-{
+static int validate_apk_path_internal(const char *path, int maxSubdirs) {
const dir_rec_t* dir = NULL;
- int maxSubdirs = 1;
-
if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
dir = &android_app_dir;
} else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) {
@@ -1060,7 +1058,9 @@
dir = &android_asec_dir;
} else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) {
dir = &android_mnt_expand_dir;
- maxSubdirs = 2;
+ if (maxSubdirs < 2) {
+ maxSubdirs = 2;
+ }
} else {
return -1;
}
@@ -1068,6 +1068,14 @@
return validate_path(dir, path, maxSubdirs);
}
+int validate_apk_path(const char* path) {
+ return validate_apk_path_internal(path, 1 /* maxSubdirs */);
+}
+
+int validate_apk_path_subdirs(const char* path) {
+ return validate_apk_path_internal(path, 3 /* maxSubdirs */);
+}
+
int append_and_increment(char** dst, const char* src, size_t* dst_size) {
ssize_t ret = strlcpy(*dst, src, *dst_size);
if (ret < 0 || (size_t) ret >= *dst_size) {
diff --git a/include/android/trace.h b/include/android/trace.h
new file mode 100644
index 0000000..e42e334
--- /dev/null
+++ b/include/android/trace.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+
+#ifndef ANDROID_NATIVE_TRACE_H
+#define ANDROID_NATIVE_TRACE_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns true if tracing is enabled. Use this signal to avoid expensive computation only necessary
+ * when tracing is enabled.
+ */
+bool ATrace_isEnabled();
+
+/**
+ * Writes a tracing message to indicate that the given section of code has begun. This call must be
+ * followed by a corresponding call to endSection() on the same thread.
+ *
+ * Note: At this time the vertical bar character '|' and newline character '\n' are used internally
+ * by the tracing mechanism. If sectionName contains these characters they will be replaced with a
+ * space character in the trace.
+ */
+void ATrace_beginSection(const char* sectionName);
+
+/**
+ * Writes a tracing message to indicate that a given section of code has ended. This call must be
+ * preceeded by a corresponding call to beginSection(char*) on the same thread. Calling this method
+ * will mark the end of the most recently begun section of code, so care must be taken to ensure
+ * that beginSection / endSection pairs are properly nested and called from the same thread.
+ */
+void ATrace_endSection();
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_NATIVE_TRACE_H
diff --git a/include/media/openmax/OMX_Core.h b/include/media/openmax/OMX_Core.h
index 4fc1546..521c223 100644
--- a/include/media/openmax/OMX_Core.h
+++ b/include/media/openmax/OMX_Core.h
@@ -510,8 +510,14 @@
OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
/** Event when tunneled decoder has rendered an output
- * nData1 must contain the lower 32-bits of the buffer timestamp
- * nData2 must contain the upper 32-bits of the buffer timestamp
+ * nData1 must contain the number of timestamps returned
+ * pEventData must point to an array of the OMX_VIDEO_RENDEREVENTTYPE structs containing the
+ * render-timestamps of each frame. Component may batch rendered timestamps using this event,
+ * but must signal the event no more than 40ms after the first frame in the batch. The frames
+ * must be ordered by system timestamp inside and across batches.
+ *
+ * If component is doing frame-rate conversion, it must signal the render time of each
+ * converted frame, and must interpolate media timestamps for in-between frames.
*/
OMX_EventOutputRendered = 0x7F000001,
OMX_EventMax = 0x7FFFFFFF
diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h
index 3c97e14..34c0405 100644
--- a/include/media/openmax/OMX_VideoExt.h
+++ b/include/media/openmax/OMX_VideoExt.h
@@ -203,6 +203,12 @@
OMX_BOOL bEnableLoopFilterAcrossSlices;
} OMX_VIDEO_SLICESEGMENTSTYPE;
+/** Structure to return timestamps of rendered output frames for tunneled components */
+typedef struct OMX_VIDEO_RENDEREVENTTYPE {
+ OMX_S64 nMediaTimeUs; // timestamp of rendered video frame
+ OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered
+} OMX_VIDEO_RENDEREVENTTYPE;
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp
index 2d493c1..1339a67 100644
--- a/libs/binder/BufferedTextOutput.cpp
+++ b/libs/binder/BufferedTextOutput.cpp
@@ -49,9 +49,12 @@
status_t append(const char* txt, size_t len) {
if ((len+bufferPos) > bufferSize) {
- void* b = realloc(buffer, ((len+bufferPos)*3)/2);
+ size_t newSize = ((len+bufferPos)*3)/2;
+ if (newSize < (len+bufferPos)) return NO_MEMORY; // overflow
+ void* b = realloc(buffer, newSize);
if (!b) return NO_MEMORY;
buffer = (char*)b;
+ bufferSize = newSize;
}
memcpy(buffer+bufferPos, txt, len);
bufferPos += len;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index bae4eb5..31667d9 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -484,7 +484,8 @@
if (numObjects > 0) {
// grow objects
if (mObjectsCapacity < mObjectsSize + numObjects) {
- int newSize = ((mObjectsSize + numObjects)*3)/2;
+ size_t newSize = ((mObjectsSize + numObjects)*3)/2;
+ if (newSize < mObjectsSize) return NO_MEMORY; // overflow
binder_size_t *objects =
(binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
if (objects == (binder_size_t*)0) {
@@ -1013,6 +1014,15 @@
restart_write:
*reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
+ // remember if it's a file descriptor
+ if (val.type == BINDER_TYPE_FD) {
+ if (!mAllowFds) {
+ // fail before modifying our object index
+ return FDS_NOT_ALLOWED;
+ }
+ mHasFds = mFdsKnown = true;
+ }
+
// Need to write meta-data?
if (nullMetaData || val.binder != 0) {
mObjects[mObjectsSize] = mDataPos;
@@ -1020,14 +1030,6 @@
mObjectsSize++;
}
- // remember if it's a file descriptor
- if (val.type == BINDER_TYPE_FD) {
- if (!mAllowFds) {
- return FDS_NOT_ALLOWED;
- }
- mHasFds = mFdsKnown = true;
- }
-
return finishWrite(sizeof(flat_binder_object));
}
@@ -1037,6 +1039,7 @@
}
if (!enoughObjects) {
size_t newSize = ((mObjectsSize+2)*3)/2;
+ if (newSize < mObjectsSize) return NO_MEMORY; // overflow
binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
if (objects == NULL) return NO_MEMORY;
mObjects = objects;
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 9fcac2d..757e08a 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -901,14 +901,18 @@
// The crop is too wide
if (newWidth < currentWidth) {
- uint32_t dw = (currentWidth - newWidth) / 2;
- outCrop.left += dw;
- outCrop.right -= dw;
+ uint32_t dw = currentWidth - newWidth;
+ auto halfdw = dw / 2;
+ outCrop.left += halfdw;
+ // Not halfdw because it would subtract 1 too few when dw is odd
+ outCrop.right -= (dw - halfdw);
// The crop is too tall
} else if (newHeight < currentHeight) {
- uint32_t dh = (currentHeight - newHeight) / 2;
- outCrop.top += dh;
- outCrop.bottom -= dh;
+ uint32_t dh = currentHeight - newHeight;
+ auto halfdh = dh / 2;
+ outCrop.top += halfdh;
+ // Not halfdh because it would subtract 1 too few when dh is odd
+ outCrop.bottom -= (dh - halfdh);
}
GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]",
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index a87cc77..ffaa7e7 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -201,7 +201,8 @@
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
mPolicy(policy),
- mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
+ mPendingEvent(NULL), mLastDropReason(DROP_REASON_NOT_DROPPED),
+ mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(NULL),
mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
@@ -397,6 +398,7 @@
if (dropReason != DROP_REASON_NOT_DROPPED) {
dropInboundEventLocked(mPendingEvent, dropReason);
}
+ mLastDropReason = dropReason;
releasePendingEventLocked();
*nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
@@ -506,7 +508,9 @@
reason = "inbound event was dropped because the policy consumed it";
break;
case DROP_REASON_DISABLED:
- ALOGI("Dropped event because input dispatch is disabled.");
+ if (mLastDropReason != DROP_REASON_DISABLED) {
+ ALOGI("Dropped event because input dispatch is disabled.");
+ }
reason = "inbound event was dropped because input dispatch is disabled";
break;
case DROP_REASON_APP_SWITCH:
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 9a340c9..80eed56 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -857,6 +857,8 @@
Queue<EventEntry> mRecentQueue;
Queue<CommandEntry> mCommandQueue;
+ DropReason mLastDropReason;
+
void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
// Enqueues an inbound event. Returns true if mLooper->wake() should be called.
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index ae8b3b3..cf750ee 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -66,7 +66,7 @@
const char* SensorService::WAKE_LOCK_NAME = "SensorService";
// Permissions.
-static const String16 sDataInjectionPermission("android.permission.HARDWARE_TEST");
+static const String16 sDataInjectionPermission("android.permission.LOCATION_HARDWARE");
static const String16 sDump("android.permission.DUMP");
SensorService::SensorService()
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 02c31ff..2dad005 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -635,6 +635,7 @@
}
status_t HWComposer::prepare() {
+ Mutex::Autolock _l(mDisplayLock);
for (size_t i=0 ; i<mNumDisplays ; i++) {
DisplayData& disp(mDisplayData[i]);
if (disp.framebufferTarget) {
@@ -1145,6 +1146,7 @@
}
void HWComposer::dump(String8& result) const {
+ Mutex::Autolock _l(mDisplayLock);
if (mHwc) {
result.appendFormat("Hardware Composer state (version %08x):\n", hwcApiVersion(mHwc));
result.appendFormat(" mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 28d8c65..cc98b4c 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -354,6 +354,8 @@
// mLists[i>0] can be NULL. that display is to be ignored
struct hwc_display_contents_1* mLists[MAX_HWC_DISPLAYS];
DisplayData mDisplayData[MAX_HWC_DISPLAYS];
+ // protect mDisplayData from races between prepare and dump
+ mutable Mutex mDisplayLock;
size_t mNumDisplays;
cb_context* mCBContext;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1388ce8..a332cda 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -550,7 +550,7 @@
status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs) {
- if (configs == NULL) {
+ if ((configs == NULL) || (display.get() == NULL)) {
return BAD_VALUE;
}
@@ -3320,8 +3320,12 @@
ATRACE_CALL();
// get screen geometry
- const uint32_t hw_w = hw->getWidth();
- const uint32_t hw_h = hw->getHeight();
+ uint32_t hw_w = hw->getWidth();
+ uint32_t hw_h = hw->getHeight();
+
+ if (rotation & Transform::ROT_90) {
+ std::swap(hw_w, hw_h);
+ }
if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
ALOGE("size mismatch (%d, %d) > (%d, %d)",