summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/dumpstate/dumpstate.cpp20
-rw-r--r--cmds/installd/commands.cpp33
-rw-r--r--cmds/installd/commands.h3
-rw-r--r--cmds/installd/installd.cpp6
-rw-r--r--libs/gui/tests/SurfaceTextureGL_test.cpp14
-rw-r--r--services/sensorservice/SensorEventConnection.cpp6
-rw-r--r--services/sensorservice/SensorEventConnection.h2
-rw-r--r--services/sensorservice/SensorRecord.cpp16
-rw-r--r--services/sensorservice/SensorRecord.h14
-rw-r--r--services/sensorservice/SensorService.cpp2
-rw-r--r--services/sensorservice/SensorService.h2
-rw-r--r--services/surfaceflinger/Android.mk26
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp9
13 files changed, 119 insertions, 34 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index d51fb774c7..17d44d2743 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -219,7 +219,8 @@ static bool dump_anrd_trace() {
struct dirent *trace;
struct stat st;
DIR *trace_dir;
- long max_ctime = 0;
+ int retry = 5;
+ long max_ctime = 0, old_mtime;
long long cur_size = 0;
const char *trace_path = "/data/misc/anrd/";
@@ -232,6 +233,13 @@ static bool dump_anrd_trace() {
pid = pid_of_process("/system/xbin/anrd");
if (pid > 0) {
+ if (stat(trace_path, &st) == 0) {
+ old_mtime = st.st_mtime;
+ } else {
+ MYLOGE("Failed to find: %s\n", trace_path);
+ return false;
+ }
+
// send SIGUSR1 to the anrd to generate a trace.
sprintf(buf, "%u", pid);
if (run_command("ANRD_DUMP", 1, "kill", "-SIGUSR1", buf, NULL)) {
@@ -239,6 +247,16 @@ static bool dump_anrd_trace() {
return false;
}
+ while (retry-- > 0 && old_mtime == st.st_mtime) {
+ sleep(1);
+ stat(trace_path, &st);
+ }
+
+ if (retry < 0 && old_mtime == st.st_mtime) {
+ MYLOGE("Failed to stat %s or trace creation timeout\n", trace_path);
+ return false;
+ }
+
// identify the trace file by its creation time.
if (!(trace_dir = opendir(trace_path))) {
MYLOGE("Can't open trace file under %s\n", trace_path);
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 2014e993e3..5b47b3e500 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -2186,6 +2186,9 @@ int move_ab(const char* apk_path, const char* instruction_set, const char* oat_d
bool art_success = true;
if (!a_image_path.empty()) {
art_success = move_ab_path(b_image_path, a_image_path);
+ if (!art_success) {
+ unlink(a_image_path.c_str());
+ }
}
success = art_success || kIgnoreAppImageFailure;
@@ -2199,5 +2202,35 @@ int move_ab(const char* apk_path, const char* instruction_set, const char* oat_d
return success ? 0 : -1;
}
+bool delete_odex(const char *apk_path, const char *instruction_set, const char *oat_dir) {
+ // Delete the oat/odex file.
+ char out_path[PKG_PATH_MAX];
+ if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_path)) {
+ return false;
+ }
+
+ // In case of a permission failure report the issue. Otherwise just print a warning.
+ auto unlink_and_check = [](const char* path) -> bool {
+ int result = unlink(path);
+ if (result != 0) {
+ if (errno == EACCES || errno == EPERM) {
+ PLOG(ERROR) << "Could not unlink " << path;
+ return false;
+ }
+ PLOG(WARNING) << "Could not unlink " << path;
+ }
+ return true;
+ };
+
+ // Delete the oat/odex file.
+ bool return_value_oat = unlink_and_check(out_path);
+
+ // Derive and delete the app image.
+ bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
+
+ // Report success.
+ return return_value_oat && return_value_art;
+}
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/commands.h b/cmds/installd/commands.h
index e990f1b695..ba275170a8 100644
--- a/cmds/installd/commands.h
+++ b/cmds/installd/commands.h
@@ -85,6 +85,9 @@ int link_file(const char *relative_path, const char *from_base, const char *to_b
// Move a B version over to the A location. Only works for oat_dir != nullptr.
int move_ab(const char *apk_path, const char *instruction_set, const char* oat_dir);
+// Delete odex files generated by dexopt.
+bool delete_odex(const char *apk_path, const char *instruction_set, const char *oat_dir);
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index facbc724ec..8f883db050 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -418,6 +418,11 @@ static int do_move_ab(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
return move_ab(arg[0], arg[1], arg[2]);
}
+static int do_delete_odex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+ // apk_path, instruction_set, oat_dir
+ return delete_odex(arg[0], arg[1], arg[2]) ? 0 : -1;
+}
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -453,6 +458,7 @@ struct cmdinfo cmds[] = {
{ "move_ab", 3, do_move_ab },
{ "merge_profiles", 2, do_merge_profiles },
{ "dump_profiles", 3, do_dump_profiles },
+ { "delete_odex", 3, do_delete_odex },
};
static int readx(int s, void *_buf, int count)
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index dddcf922f6..5311c5957e 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -115,13 +115,13 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255));
EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
- EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255));
- EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255));
- EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255));
- EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
- EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255));
- EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255));
- EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
+ EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255, 3));
+ EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255, 3));
+ EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255, 3));
+ EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255, 3));
+ EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255, 3));
+ EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255, 3));
+ EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255, 3));
}
TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index c1e1badf32..f2f1444125 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -206,7 +206,7 @@ void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t ha
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
- SensorEventConnection const * const * mapFlushEventsToConnections) {
+ wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
// filter out events not for this connection
int count = 0;
Mutex::Autolock _l(mConnectionLock);
@@ -234,7 +234,7 @@ status_t SensorService::SensorEventConnection::sendEvents(
FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
// Check if there is a pending flush_complete event for this sensor on this connection.
if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
- this == mapFlushEventsToConnections[i]) {
+ mapFlushEventsToConnections[i] == this) {
flushInfo.mFirstFlushPending = false;
ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
buffer[i].meta_data.sensor);
@@ -255,7 +255,7 @@ status_t SensorService::SensorEventConnection::sendEvents(
// from the same sensor_handle AND the current connection is mapped to the
// corresponding flush_complete_event.
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
- if (this == mapFlushEventsToConnections[i]) {
+ if (mapFlushEventsToConnections[i] == this) {
scratch[count++] = buffer[i];
}
++i;
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index b796cc05a1..883c16e23b 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -52,7 +52,7 @@ public:
bool isDataInjectionMode, const String16& opPackageName);
status_t sendEvents(sensors_event_t const* buffer, size_t count, sensors_event_t* scratch,
- SensorEventConnection const * const * mapFlushEventsToConnections = NULL);
+ wp<const SensorEventConnection> const * mapFlushEventsToConnections = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool hasOneShotSensors() const;
diff --git a/services/sensorservice/SensorRecord.cpp b/services/sensorservice/SensorRecord.cpp
index 644cfb0de3..53fb9de230 100644
--- a/services/sensorservice/SensorRecord.cpp
+++ b/services/sensorservice/SensorRecord.cpp
@@ -21,13 +21,13 @@
namespace android {
SensorService::SensorRecord::SensorRecord(
- const sp<SensorEventConnection>& connection)
+ const sp<const SensorEventConnection>& connection)
{
mConnections.add(connection);
}
bool SensorService::SensorRecord::addConnection(
- const sp<SensorEventConnection>& connection)
+ const sp<const SensorEventConnection>& connection)
{
if (mConnections.indexOf(connection) < 0) {
mConnections.add(connection);
@@ -37,16 +37,16 @@ bool SensorService::SensorRecord::addConnection(
}
bool SensorService::SensorRecord::removeConnection(
- const wp<SensorEventConnection>& connection)
+ const wp<const SensorEventConnection>& connection)
{
ssize_t index = mConnections.indexOf(connection);
if (index >= 0) {
mConnections.removeItemsAt(index, 1);
}
// Remove this connections from the queue of flush() calls made on this sensor.
- for (Vector< wp<SensorEventConnection> >::iterator it = mPendingFlushConnections.begin();
+ for (Vector< wp<const SensorEventConnection> >::iterator it = mPendingFlushConnections.begin();
it != mPendingFlushConnections.end(); ) {
- if (it->unsafe_get() == connection.unsafe_get()) {
+ if (*it == connection) {
it = mPendingFlushConnections.erase(it);
} else {
++it;
@@ -56,7 +56,7 @@ bool SensorService::SensorRecord::removeConnection(
}
void SensorService::SensorRecord::addPendingFlushConnection(
- const sp<SensorEventConnection>& connection) {
+ const sp<const SensorEventConnection>& connection) {
mPendingFlushConnections.add(connection);
}
@@ -66,10 +66,10 @@ void SensorService::SensorRecord::removeFirstPendingFlushConnection() {
}
}
-SensorService::SensorEventConnection *
+wp<const SensorService::SensorEventConnection>
SensorService::SensorRecord::getFirstPendingFlushConnection() {
if (mPendingFlushConnections.size() > 0) {
- return mPendingFlushConnections[0].unsafe_get();
+ return mPendingFlushConnections[0];
}
return NULL;
}
diff --git a/services/sensorservice/SensorRecord.h b/services/sensorservice/SensorRecord.h
index 29b970dc1f..5a35410572 100644
--- a/services/sensorservice/SensorRecord.h
+++ b/services/sensorservice/SensorRecord.h
@@ -25,20 +25,20 @@ class SensorService;
class SensorService::SensorRecord {
public:
- SensorRecord(const sp<SensorEventConnection>& connection);
- bool addConnection(const sp<SensorEventConnection>& connection);
- bool removeConnection(const wp<SensorEventConnection>& connection);
+ SensorRecord(const sp<const SensorEventConnection>& connection);
+ bool addConnection(const sp<const SensorEventConnection>& connection);
+ bool removeConnection(const wp<const SensorEventConnection>& connection);
size_t getNumConnections() const { return mConnections.size(); }
- void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
+ void addPendingFlushConnection(const sp<const SensorEventConnection>& connection);
void removeFirstPendingFlushConnection();
- SensorEventConnection * getFirstPendingFlushConnection();
+ wp<const SensorEventConnection> getFirstPendingFlushConnection();
void clearAllPendingFlushConnections();
private:
- SortedVector< wp<SensorEventConnection> > mConnections;
+ SortedVector< wp<const SensorEventConnection> > mConnections;
// A queue of all flush() calls made on this sensor. Flush complete events
// will be sent in this order.
- Vector< wp<SensorEventConnection> > mPendingFlushConnections;
+ Vector< wp<const SensorEventConnection> > mPendingFlushConnections;
};
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index d9753acaaa..2930637664 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -260,7 +260,7 @@ void SensorService::onFirstRef() {
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
mSensorEventBuffer = new sensors_event_t[minBufferSize];
mSensorEventScratch = new sensors_event_t[minBufferSize];
- mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
+ mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 1e1ea5ab4a..4a63ef0afc 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -237,7 +237,7 @@ private:
SortedVector< wp<SensorEventConnection> > mActiveConnections;
bool mWakeLockAcquired;
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
- SensorEventConnection const **mMapFlushEventsToConnections;
+ wp<const SensorEventConnection> * mMapFlushEventsToConnections;
std::unordered_map<int, RecentEventLogger*> mRecentEvent;
Mode mCurrentOperatingMode;
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index dc5e97b324..ffda035a9a 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -79,18 +79,36 @@ ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true)
LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
endif
-# See build/target/board/generic/BoardConfig.mk for a description of this setting.
+# The following two BoardConfig variables define (respectively):
+#
+# - The phase offset between hardware vsync and when apps are woken up by the
+# Choreographer callback
+# - The phase offset between hardware vsync and when SurfaceFlinger wakes up
+# to consume input
+#
+# Their values can be tuned to trade off between display pipeline latency (both
+# overall latency and the lengths of the app --> SF and SF --> display phases)
+# and frame delivery jitter (which typically manifests as "jank" or "jerkiness"
+# while interacting with the device). The default values should produce a
+# relatively low amount of jitter at the expense of roughly two frames of
+# app --> display latency, and unless significant testing is performed to avoid
+# increased display jitter (both manual investigation using systrace [1] and
+# automated testing using dumpsys gfxinfo [2] are recommended), they should not
+# be modified.
+#
+# [1] https://developer.android.com/studio/profile/systrace.html
+# [2] https://developer.android.com/training/testing/performance.html
+
ifneq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=$(VSYNC_EVENT_PHASE_OFFSET_NS)
else
- LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=0
+ LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=1000000
endif
-# See build/target/board/generic/BoardConfig.mk for a description of this setting.
ifneq ($(SF_VSYNC_EVENT_PHASE_OFFSET_NS),)
LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=$(SF_VSYNC_EVENT_PHASE_OFFSET_NS)
else
- LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=0
+ LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=1000000
endif
ifneq ($(PRESENT_TIME_OFFSET_FROM_VSYNC_NS),)
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 8bcee39b9d..cc0dfb0945 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -2305,7 +2305,14 @@ void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
break;
case Composition::SolidColor:
- hwc1Layer.compositionType = HWC_BACKGROUND;
+ // In theory the following line should work, but since the HWC1
+ // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
+ // devices may not work correctly. To be on the safe side, we
+ // fall back to client composition.
+ //
+ // hwc1Layer.compositionType = HWC_BACKGROUND;
+ hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+ hwc1Layer.flags |= HWC_SKIP_LAYER;
break;
case Composition::Cursor:
hwc1Layer.compositionType = HWC_FRAMEBUFFER;