From 6d09ca8663deea6b27917c5bf21223ae41c2b1df Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Fri, 1 May 2015 16:42:55 -0700 Subject: [PATCH 1/6] libgui: Clear frame number while freeing slot Clears the frame number of a slot when it is freed, since it is used to determine if a released buffer is stale. Bug: 20445852 Change-Id: I02415e7b25a1eafe7414d6eb1cedf62ac5543cd9 --- libs/gui/BufferQueueConsumer.cpp | 4 +++- libs/gui/BufferQueueCore.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 2deef0e77..336ddb667 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -306,6 +306,8 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || releaseFence == NULL) { + BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, + releaseFence.get()); return BAD_VALUE; } @@ -344,7 +346,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, mSlots[slot].mNeedsCleanupOnRelease = false; return STALE_BUFFER_SLOT; } else { - BQ_LOGV("releaseBuffer: attempted to release buffer slot %d " + BQ_LOGE("releaseBuffer: attempted to release buffer slot %d " "but its state was %d", slot, mSlots[slot].mBufferState); return BAD_VALUE; } diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index d0f7afad4..37171edd1 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -214,6 +214,7 @@ void BufferQueueCore::freeBufferLocked(int slot) { } mSlots[slot].mBufferState = BufferSlot::FREE; mSlots[slot].mAcquireCalled = false; + mSlots[slot].mFrameNumber = 0; // Destroy fence as BufferQueue now takes ownership if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { From 37c6aaad742fc893b61b9306cd021b7de3c2bc40 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Thu, 7 May 2015 10:50:59 -0700 Subject: [PATCH 2/6] Fix broken NDK sensor manager API. Change-Id: I21bb8b0dcfd3f1c812753a9fd77dea792e7155f2 --- include/android/sensor.h | 24 ++++++++++++++++ include/gui/SensorManager.h | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/include/android/sensor.h b/include/android/sensor.h index 969677f6d..1be623221 100644 --- a/include/android/sensor.h +++ b/include/android/sensor.h @@ -192,6 +192,30 @@ typedef ASensorRef const* ASensorList; /*****************************************************************************/ +/* + * Get a reference to the sensor manager. ASensorManager is a singleton + * per package as different packages may have access to different sensors. + * + * Deprecated: Use ASensorManager_getInstanceForPackage(const char*) instead. + * + * Example: + * + * ASensorManager* sensorManager = ASensorManager_getInstance(); + * + */ +__attribute__ ((deprecated)) ASensorManager* ASensorManager_getInstance(); + +/* + * Get a reference to the sensor manager. ASensorManager is a singleton + * per package as different packages may have access to different sensors. + * + * Example: + * + * ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz"); + * + */ +ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName); + /* * Returns the list of available sensors. */ diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h index d0c63d4bc..4c34e1247 100644 --- a/include/gui/SensorManager.h +++ b/include/gui/SensorManager.h @@ -17,10 +17,14 @@ #ifndef ANDROID_GUI_SENSOR_MANAGER_H #define ANDROID_GUI_SENSOR_MANAGER_H +#include + #include #include #include +#include +#include #include #include @@ -47,6 +51,56 @@ class SensorManager : public ASensorManager { public: + static SensorManager& getInstanceForPackage(const String16& packageName) { + Mutex::Autolock _l(sLock); + + SensorManager* sensorManager; + std::map::iterator iterator = + sPackageInstances.find(packageName); + + if (iterator != sPackageInstances.end()) { + sensorManager = iterator->second; + } else { + String16 opPackageName = packageName; + + // It is possible that the calling code has no access to the package name. + // In this case we will get the packages for the calling UID and pick the + // first one for attributing the app op. This will work correctly for + // runtime permissions as for legacy apps we will toggle the app op for + // all packages in the UID. The caveat is that the operation may be attributed + // to the wrong package and stats based on app ops may be slightly off. + if (opPackageName.size() <= 0) { + sp binder = defaultServiceManager()->getService(String16("permission")); + if (binder != 0) { + const uid_t uid = IPCThreadState::self()->getCallingUid(); + Vector packages; + interface_cast(binder)->getPackagesForUid(uid, packages); + if (!packages.isEmpty()) { + opPackageName = packages[0]; + } else { + ALOGE("No packages for calling UID"); + } + } else { + ALOGE("Cannot get permission service"); + } + } + + sensorManager = new SensorManager(opPackageName); + + // If we had no package name, we looked it up from the UID and the sensor + // manager instance we created should also be mapped to the empty package + // name, to avoid looking up the packages for a UID and get the same result. + if (packageName.size() <= 0) { + sPackageInstances.insert(std::make_pair(String16(), sensorManager)); + } + + // Stash the per package sensor manager. + sPackageInstances.insert(std::make_pair(opPackageName, sensorManager)); + } + + return *sensorManager; + } + SensorManager(const String16& opPackageName); ~SensorManager(); @@ -62,6 +116,9 @@ private: status_t assertStateLocked() const; private: + static Mutex sLock; + static std::map sPackageInstances; + mutable Mutex mLock; mutable sp mSensorServer; mutable Sensor const** mSensorList; From 8a715c64eb0242f22e4ce0135fbf007ffb233971 Mon Sep 17 00:00:00 2001 From: Michael Lentine Date: Thu, 28 May 2015 16:48:08 -0700 Subject: [PATCH 3/6] Revert "Modify EGL to disconnect the window when the surface gets destroyed." This reverts commit 00699fa64197cc72a160d69e1f0003cdd43dc136. --- libs/gui/BufferQueueProducer.cpp | 4 ++-- opengl/libs/EGL/eglApi.cpp | 9 --------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 2cf7433b4..e318484d4 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -914,8 +914,8 @@ status_t BufferQueueProducer::disconnect(int api) { mCore->mSidebandStream.clear(); mCore->mDequeueCondition.broadcast(); listener = mCore->mConsumerListener; - } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { - BQ_LOGE("disconnect(P): still connected to another API " + } else { + BQ_LOGE("disconnect(P): connected to another API " "(cur=%d req=%d)", mCore->mConnectedApi, api); status = BAD_VALUE; } diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 8dd052cb6..544463133 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -562,15 +562,6 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) return setError(EGL_BAD_SURFACE, EGL_FALSE); egl_surface_t * const s = get_surface(surface); - ANativeWindow* window = s->win.get(); - if (window) { - int result = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); - if (result != OK) { - ALOGE("eglDestroySurface: native_window_api_disconnect (win=%p) " - "failed (%#x)", - window, result); - } - } EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface); if (result == EGL_TRUE) { _s.terminate(); From 5a373bb9b0ffb9a58686079c971aaa4d8788218f Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 29 Jul 2015 09:36:05 +0000 Subject: [PATCH 4/6] Revert "Bug fix in SensorManager." This reverts commit 869eb2089ec8a6286b944bfcff57e4cbe0c7e207. Change-Id: I4fb865e3b18bbb011fa4e4b4732336930c3a45ae --- include/gui/SensorManager.h | 4 +--- libs/gui/SensorManager.cpp | 11 +++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h index 9794d4e08..37960673c 100644 --- a/include/gui/SensorManager.h +++ b/include/gui/SensorManager.h @@ -101,6 +101,7 @@ public: return *sensorManager; } + SensorManager(const String16& opPackageName); ~SensorManager(); ssize_t getSensorList(Sensor const* const** list) const; @@ -112,7 +113,6 @@ private: // DeathRecipient interface void sensorManagerDied(); - SensorManager(const String16& opPackageName); status_t assertStateLocked() const; private: @@ -127,8 +127,6 @@ private: const String16 mOpPackageName; }; -android::Mutex android::SensorManager::sLock; -std::map android::SensorManager::sPackageInstances; // ---------------------------------------------------------------------------- }; // namespace android diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index ead535e63..dd3778137 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -59,13 +59,12 @@ void SensorManager::sensorManagerDied() status_t SensorManager::assertStateLocked() const { if (mSensorServer == NULL) { + // try for one second const String16 name("sensorservice"); - // try 10 times before giving up ... - for (int i = 0; i < 10; ++i) { + for (int i=0 ; i<4 ; i++) { status_t err = getService(name, &mSensorServer); if (err == NAME_NOT_FOUND) { - // Sleep for 1 second before retrying. - sleep(1); + usleep(250000); continue; } if (err != NO_ERROR) { @@ -74,10 +73,6 @@ status_t SensorManager::assertStateLocked() const { break; } - if (mSensorServer == NULL) { - ALOGE("FATAL getsensorservice returned` NULL"); - } - class DeathObserver : public IBinder::DeathRecipient { SensorManager& mSensorManger; virtual void binderDied(const wp& who) { From 38b4b28c19c38a6043c6d914f4315926dcb9d94d Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 14 Sep 2015 16:33:11 -0700 Subject: [PATCH 5/6] Installd: Allow different behavior before bootcomplete Check dev.bootcomplete in dex2oat(). Use the information for two changes. Only switch to the background when we're post bootcomplete. This will ensure better utilization after upgrades. Add a second dex2oat-threads property that is used pre bootcomplete. A separation of these phases allows using less cores when the device is up, freeing up resources for other purposes, e.g., avoid jank. The precedence during boot is the boot property, or the image property if the former doesn't exist, or the default property as a fallback. Bug: 23898216 Bug: 24004256 Change-Id: I5063f3fc4b437cbe88c4e94584e01c1c78eccc4d --- cmds/installd/commands.cpp | 55 +++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index 7090b3677..769cd341f 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -746,7 +746,7 @@ static bool check_boolean_property(const char* property_name, bool default_value static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, const char* output_file_name, int swap_fd, const char *pkgname, const char *instruction_set, - bool vm_safe_mode, bool debuggable) + bool vm_safe_mode, bool debuggable, bool post_bootcomplete) { static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; @@ -770,8 +770,24 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, dex2oat_compiler_filter_flag, NULL) > 0; char dex2oat_threads_buf[PROPERTY_VALUE_MAX]; - bool have_dex2oat_threads_flag = property_get("dalvik.vm.dex2oat-threads", dex2oat_threads_buf, - NULL) > 0; + bool have_dex2oat_threads_flag = false; + if (!post_bootcomplete) { + have_dex2oat_threads_flag = property_get("dalvik.vm.boot-dex2oat-threads", + dex2oat_threads_buf, + NULL) > 0; + // If there's no boot property, fall back to the image property. + if (!have_dex2oat_threads_flag) { + have_dex2oat_threads_flag = property_get("dalvik.vm.image-dex2oat-threads", + dex2oat_threads_buf, + NULL) > 0; + } + // If there's neither, fall back to the default property. + } + if (!have_dex2oat_threads_flag) { + have_dex2oat_threads_flag = property_get("dalvik.vm.dex2oat-threads", + dex2oat_threads_buf, + NULL) > 0; + } char dex2oat_threads_arg[PROPERTY_VALUE_MAX + 2]; if (have_dex2oat_threads_flag) { sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf); @@ -1065,6 +1081,27 @@ static bool calculate_odex_file_path(char path[PKG_PATH_MAX], return true; } +static bool IsPostBootComplete() { + char dev_bootcomplete_prop_buf[PROPERTY_VALUE_MAX]; + if (property_get("dev.bootcomplete", dev_bootcomplete_prop_buf, "0") > 0) { + return (strcmp(dev_bootcomplete_prop_buf, "1") == 0); + } + return false; +} + +static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) { + if (set_to_bg) { + if (set_sched_policy(0, SP_BACKGROUND) < 0) { + ALOGE("set_sched_policy failed: %s\n", strerror(errno)); + exit(70); + } + if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { + ALOGE("setpriority failed: %s\n", strerror(errno)); + exit(71); + } + } +} + int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgname, const char *instruction_set, int dexopt_needed, bool vm_safe_mode, bool debuggable, const char* oat_dir) @@ -1076,6 +1113,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *input_file; char in_odex_path[PKG_PATH_MAX]; int res, input_fd=-1, out_fd=-1, swap_fd=-1; + bool post_bootcomplete = IsPostBootComplete(); // Early best-effort check whether we can fit the the path into our buffers. // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run @@ -1198,14 +1236,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, ALOGE("capset failed: %s\n", strerror(errno)); exit(66); } - if (set_sched_policy(0, SP_BACKGROUND) < 0) { - ALOGE("set_sched_policy failed: %s\n", strerror(errno)); - exit(70); - } - if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { - ALOGE("setpriority failed: %s\n", strerror(errno)); - exit(71); - } + SetDex2OatAndPatchOatScheduling(post_bootcomplete); if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) { ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno)); exit(67); @@ -1222,7 +1253,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, input_file_name++; } run_dex2oat(input_fd, out_fd, input_file_name, out_path, swap_fd, pkgname, - instruction_set, vm_safe_mode, debuggable); + instruction_set, vm_safe_mode, debuggable, post_bootcomplete); } else { ALOGE("Invalid dexopt needed: %d\n", dexopt_needed); exit(73); From fa2d40f750e0770cc890eeed5d5f6f41f9be5f50 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 21 Sep 2015 13:21:30 -0700 Subject: [PATCH 6/6] Installd: Take boot status as dexopt parameter Expect the boot status explicitly as a parameter so that we do not have to rely on dev.bootcomplete, which isn't meaningfully set when the device needs the decryption screen on boot. Bug: 23898216 Change-Id: I9b34298caf70b1e5d40970cc0d04c469016a80a7 --- cmds/installd/commands.cpp | 15 +++------------ cmds/installd/installd.cpp | 6 +++--- cmds/installd/installd.h | 2 +- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index 769cd341f..d4aa7d31b 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -1081,14 +1081,6 @@ static bool calculate_odex_file_path(char path[PKG_PATH_MAX], return true; } -static bool IsPostBootComplete() { - char dev_bootcomplete_prop_buf[PROPERTY_VALUE_MAX]; - if (property_get("dev.bootcomplete", dev_bootcomplete_prop_buf, "0") > 0) { - return (strcmp(dev_bootcomplete_prop_buf, "1") == 0); - } - return false; -} - static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) { if (set_to_bg) { if (set_sched_policy(0, SP_BACKGROUND) < 0) { @@ -1104,7 +1096,7 @@ static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) { int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgname, const char *instruction_set, int dexopt_needed, - bool vm_safe_mode, bool debuggable, const char* oat_dir) + bool vm_safe_mode, bool debuggable, const char* oat_dir, bool boot_complete) { struct utimbuf ut; struct stat input_stat; @@ -1113,7 +1105,6 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *input_file; char in_odex_path[PKG_PATH_MAX]; int res, input_fd=-1, out_fd=-1, swap_fd=-1; - bool post_bootcomplete = IsPostBootComplete(); // Early best-effort check whether we can fit the the path into our buffers. // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run @@ -1236,7 +1227,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, ALOGE("capset failed: %s\n", strerror(errno)); exit(66); } - SetDex2OatAndPatchOatScheduling(post_bootcomplete); + SetDex2OatAndPatchOatScheduling(boot_complete); if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) { ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno)); exit(67); @@ -1253,7 +1244,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, input_file_name++; } run_dex2oat(input_fd, out_fd, input_file_name, out_path, swap_fd, pkgname, - instruction_set, vm_safe_mode, debuggable, post_bootcomplete); + instruction_set, vm_safe_mode, debuggable, boot_complete); } else { ALOGE("Invalid dexopt needed: %d\n", dexopt_needed); exit(73); diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index 13e316868..f67e8384d 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -48,9 +48,9 @@ static int do_install(char **arg, char reply[REPLY_MAX] __unused) static int do_dexopt(char **arg, char reply[REPLY_MAX] __unused) { /* apk_path, uid, is_public, pkgname, instruction_set, - * dexopt_needed, vm_safe_mode, debuggable, oat_dir */ + * dexopt_needed, vm_safe_mode, debuggable, oat_dir, boot_complete */ return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]), - atoi(arg[6]), atoi(arg[7]), arg[8]); + atoi(arg[6]), atoi(arg[7]), arg[8], atoi(arg[9])); } static int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] __unused) @@ -194,7 +194,7 @@ struct cmdinfo { struct cmdinfo cmds[] = { { "ping", 0, do_ping }, { "install", 5, do_install }, - { "dexopt", 9, do_dexopt }, + { "dexopt", 10, do_dexopt }, { "markbootcomplete", 1, do_mark_boot_complete }, { "movedex", 3, do_move_dex }, { "rmdex", 2, do_rm_dex }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 7ec579382..24b908465 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -243,7 +243,7 @@ int get_size(const char *uuid, const char *pkgname, int userid, int free_cache(const char *uuid, int64_t free_size); int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName, const char *instruction_set, int dexopt_needed, bool vm_safe_mode, - bool debuggable, const char* oat_dir); + bool debuggable, const char* oat_dir, bool boot_complete); int mark_boot_complete(const char *instruction_set); int movefiles(); int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId);