Merge "Log when binder thread pool is starved" into nyc-dev
am: 43dcac7
* commit '43dcac7500833c465c417805adc4693c60c3bb5e':
Log when binder thread pool is starved
Change-Id: I420d31273aec69eab9d8e4faa10001ef48b17aa8
diff --git a/AppOpsManager.cpp b/AppOpsManager.cpp
index 9a061a0..f3b86ae 100644
--- a/AppOpsManager.cpp
+++ b/AppOpsManager.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <mutex>
#include <binder/AppOpsManager.h>
#include <binder/Binder.h>
#include <binder/IServiceManager.h>
@@ -22,6 +23,19 @@
namespace android {
+namespace {
+
+#if defined(__BRILLO__)
+// Because Brillo has no application model, security policy is managed
+// statically (at build time) with SELinux controls.
+// As a consequence, it also never runs the AppOpsManager service.
+const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_ALLOWED;
+#else
+const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_IGNORED;
+#endif // defined(__BRILLO__)
+
+} // namespace
+
static String16 _appops("appops");
static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER;
static sp<IBinder> gToken;
@@ -39,10 +53,15 @@
{
}
+#if defined(__BRILLO__)
+// There is no AppOpsService on Brillo
+sp<IAppOpsService> AppOpsManager::getService() { return NULL; }
+#else
sp<IAppOpsService> AppOpsManager::getService()
{
+
+ std::lock_guard<Mutex> scoped_lock(mLock);
int64_t startTime = 0;
- mLock.lock();
sp<IAppOpsService> service = mService;
while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
@@ -53,7 +72,8 @@
ALOGI("Waiting for app ops service");
} else if ((uptimeMillis()-startTime) > 10000) {
ALOGW("Waiting too long for app ops service, giving up");
- return NULL;
+ service = NULL;
+ break;
}
sleep(1);
} else {
@@ -61,25 +81,30 @@
mService = service;
}
}
- mLock.unlock();
return service;
}
+#endif // defined(__BRILLO__)
int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage)
{
sp<IAppOpsService> service = getService();
- return service != NULL ? service->checkOperation(op, uid, callingPackage) : MODE_IGNORED;
+ return service != NULL
+ ? service->checkOperation(op, uid, callingPackage)
+ : APP_OPS_MANAGER_UNAVAILABLE_MODE;
}
int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
sp<IAppOpsService> service = getService();
- return service != NULL ? service->noteOperation(op, uid, callingPackage) : MODE_IGNORED;
+ return service != NULL
+ ? service->noteOperation(op, uid, callingPackage)
+ : APP_OPS_MANAGER_UNAVAILABLE_MODE;
}
int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) {
sp<IAppOpsService> service = getService();
- return service != NULL ? service->startOperation(getToken(service), op, uid, callingPackage)
- : MODE_IGNORED;
+ return service != NULL
+ ? service->startOperation(getToken(service), op, uid, callingPackage)
+ : APP_OPS_MANAGER_UNAVAILABLE_MODE;
}
void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp
index d90798f..9b5f0d7 100644
--- a/IPCThreadState.cpp
+++ b/IPCThreadState.cpp
@@ -330,6 +330,7 @@
delete st;
pthread_setspecific(gTLS, NULL);
}
+ pthread_key_delete(gTLS);
gHaveTLS = false;
}
}
diff --git a/IServiceManager.cpp b/IServiceManager.cpp
index 61f24d6..725ebdf 100644
--- a/IServiceManager.cpp
+++ b/IServiceManager.cpp
@@ -67,11 +67,6 @@
bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
{
-#ifdef __BRILLO__
- // Brillo doesn't currently run ActivityManager or support framework permissions.
- return true;
-#endif
-
sp<IPermissionController> pc;
gDefaultServiceManagerLock.lock();
pc = gPermissionController;
diff --git a/Parcel.cpp b/Parcel.cpp
index a0161b3..8898bcc 100644
--- a/Parcel.cpp
+++ b/Parcel.cpp
@@ -1112,7 +1112,7 @@
}
status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
- return readNullableTypedVector(val, &Parcel::readStrongBinder);
+ return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
}
status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
@@ -1912,13 +1912,25 @@
status_t Parcel::readStrongBinder(sp<IBinder>* val) const
{
+ status_t status = readNullableStrongBinder(val);
+ if (status == OK && !val->get()) {
+ status = UNEXPECTED_NULL;
+ }
+ return status;
+}
+
+status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
+{
return unflatten_binder(ProcessState::self(), *this, val);
}
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
- readStrongBinder(&val);
+ // Note that a lot of code in Android reads binders by hand with this
+ // method, and that code has historically been ok with getting nullptr
+ // back (while ignoring error codes).
+ readNullableStrongBinder(&val);
return val;
}
diff --git a/PersistableBundle.cpp b/PersistableBundle.cpp
index aef791c..a20359f 100644
--- a/PersistableBundle.cpp
+++ b/PersistableBundle.cpp
@@ -32,6 +32,9 @@
using android::sp;
using android::status_t;
using android::UNEXPECTED_NULL;
+using std::map;
+using std::set;
+using std::vector;
enum {
// Keep in sync with BUNDLE_MAGIC in frameworks/base/core/java/android/os/BaseBundle.java.
@@ -55,12 +58,22 @@
namespace {
template <typename T>
-bool getValue(const android::String16& key, T* out, const std::map<android::String16, T>& map) {
+bool getValue(const android::String16& key, T* out, const map<android::String16, T>& map) {
const auto& it = map.find(key);
if (it == map.end()) return false;
*out = it->second;
return true;
}
+
+template <typename T>
+set<android::String16> getKeys(const map<android::String16, T>& map) {
+ if (map.empty()) return set<android::String16>();
+ set<android::String16> keys;
+ for (const auto& key_value_pair : map) {
+ keys.emplace(key_value_pair.first);
+ }
+ return keys;
+}
} // namespace
namespace android {
@@ -188,27 +201,27 @@
mStringMap[key] = value;
}
-void PersistableBundle::putBooleanVector(const String16& key, const std::vector<bool>& value) {
+void PersistableBundle::putBooleanVector(const String16& key, const vector<bool>& value) {
erase(key);
mBoolVectorMap[key] = value;
}
-void PersistableBundle::putIntVector(const String16& key, const std::vector<int32_t>& value) {
+void PersistableBundle::putIntVector(const String16& key, const vector<int32_t>& value) {
erase(key);
mIntVectorMap[key] = value;
}
-void PersistableBundle::putLongVector(const String16& key, const std::vector<int64_t>& value) {
+void PersistableBundle::putLongVector(const String16& key, const vector<int64_t>& value) {
erase(key);
mLongVectorMap[key] = value;
}
-void PersistableBundle::putDoubleVector(const String16& key, const std::vector<double>& value) {
+void PersistableBundle::putDoubleVector(const String16& key, const vector<double>& value) {
erase(key);
mDoubleVectorMap[key] = value;
}
-void PersistableBundle::putStringVector(const String16& key, const std::vector<String16>& value) {
+void PersistableBundle::putStringVector(const String16& key, const vector<String16>& value) {
erase(key);
mStringVectorMap[key] = value;
}
@@ -238,23 +251,23 @@
return getValue(key, out, mStringMap);
}
-bool PersistableBundle::getBooleanVector(const String16& key, std::vector<bool>* out) const {
+bool PersistableBundle::getBooleanVector(const String16& key, vector<bool>* out) const {
return getValue(key, out, mBoolVectorMap);
}
-bool PersistableBundle::getIntVector(const String16& key, std::vector<int32_t>* out) const {
+bool PersistableBundle::getIntVector(const String16& key, vector<int32_t>* out) const {
return getValue(key, out, mIntVectorMap);
}
-bool PersistableBundle::getLongVector(const String16& key, std::vector<int64_t>* out) const {
+bool PersistableBundle::getLongVector(const String16& key, vector<int64_t>* out) const {
return getValue(key, out, mLongVectorMap);
}
-bool PersistableBundle::getDoubleVector(const String16& key, std::vector<double>* out) const {
+bool PersistableBundle::getDoubleVector(const String16& key, vector<double>* out) const {
return getValue(key, out, mDoubleVectorMap);
}
-bool PersistableBundle::getStringVector(const String16& key, std::vector<String16>* out) const {
+bool PersistableBundle::getStringVector(const String16& key, vector<String16>* out) const {
return getValue(key, out, mStringVectorMap);
}
@@ -262,6 +275,50 @@
return getValue(key, out, mPersistableBundleMap);
}
+set<String16> PersistableBundle::getBooleanKeys() const {
+ return getKeys(mBoolMap);
+}
+
+set<String16> PersistableBundle::getIntKeys() const {
+ return getKeys(mIntMap);
+}
+
+set<String16> PersistableBundle::getLongKeys() const {
+ return getKeys(mLongMap);
+}
+
+set<String16> PersistableBundle::getDoubleKeys() const {
+ return getKeys(mDoubleMap);
+}
+
+set<String16> PersistableBundle::getStringKeys() const {
+ return getKeys(mStringMap);
+}
+
+set<String16> PersistableBundle::getBooleanVectorKeys() const {
+ return getKeys(mBoolVectorMap);
+}
+
+set<String16> PersistableBundle::getIntVectorKeys() const {
+ return getKeys(mIntVectorMap);
+}
+
+set<String16> PersistableBundle::getLongVectorKeys() const {
+ return getKeys(mLongVectorMap);
+}
+
+set<String16> PersistableBundle::getDoubleVectorKeys() const {
+ return getKeys(mDoubleVectorMap);
+}
+
+set<String16> PersistableBundle::getStringVectorKeys() const {
+ return getKeys(mStringVectorMap);
+}
+
+set<String16> PersistableBundle::getPersistableBundleKeys() const {
+ return getKeys(mPersistableBundleMap);
+}
+
status_t PersistableBundle::writeToParcelInner(Parcel* parcel) const {
/*
* To keep this implementation in sync with writeArrayMapInternal() in
diff --git a/ProcessState.cpp b/ProcessState.cpp
index f13f49f..e45b5f1 100644
--- a/ProcessState.cpp
+++ b/ProcessState.cpp
@@ -366,6 +366,13 @@
ProcessState::~ProcessState()
{
+ if (mDriverFD >= 0) {
+ if (mVMStart != MAP_FAILED) {
+ munmap(mVMStart, BINDER_VM_SIZE);
+ }
+ close(mDriverFD);
+ }
+ mDriverFD = -1;
}
}; // namespace android
diff --git a/Status.cpp b/Status.cpp
index d3520d6..5ae6db2 100644
--- a/Status.cpp
+++ b/Status.cpp
@@ -158,5 +158,10 @@
return ret;
}
+std::stringstream& operator<< (std::stringstream& stream, const Status& s) {
+ stream << s.toString8().string();
+ return stream;
+}
+
} // namespace binder
} // namespace android
diff --git a/include/hwbinder/Parcel.h b/include/hwbinder/Parcel.h
index 2685bcc..a836ce4 100644
--- a/include/hwbinder/Parcel.h
+++ b/include/hwbinder/Parcel.h
@@ -252,6 +252,7 @@
const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const;
status_t readStrongBinder(sp<IBinder>* val) const;
+ status_t readNullableStrongBinder(sp<IBinder>* val) const;
wp<IBinder> readWeakBinder() const;
template<typename T>
@@ -268,6 +269,9 @@
template<typename T>
status_t readStrongBinder(sp<T>* val) const;
+ template<typename T>
+ status_t readNullableStrongBinder(sp<T>* val) const;
+
status_t readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
status_t readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
@@ -574,6 +578,20 @@
return ret;
}
+template<typename T>
+status_t Parcel::readNullableStrongBinder(sp<T>* val) const {
+ sp<IBinder> tmp;
+ status_t ret = readNullableStrongBinder(&tmp);
+
+ if (ret == OK) {
+ *val = interface_cast<T>(tmp);
+
+ if (val->get() == nullptr) {
+ return UNKNOWN_ERROR;
+ }
+ }
+}
+
template<typename T, typename U>
status_t Parcel::unsafeReadTypedVector(
std::vector<T>* val,
diff --git a/include/hwbinder/PersistableBundle.h b/include/hwbinder/PersistableBundle.h
index fe5619f..322fef9 100644
--- a/include/hwbinder/PersistableBundle.h
+++ b/include/hwbinder/PersistableBundle.h
@@ -18,6 +18,7 @@
#define ANDROID_PERSISTABLE_BUNDLE_H
#include <map>
+#include <set>
#include <vector>
#include <binder/Parcelable.h>
@@ -79,6 +80,19 @@
bool getStringVector(const String16& key, std::vector<String16>* out) const;
bool getPersistableBundle(const String16& key, PersistableBundle* out) const;
+ /* Getters for all keys for each value type */
+ std::set<String16> getBooleanKeys() const;
+ std::set<String16> getIntKeys() const;
+ std::set<String16> getLongKeys() const;
+ std::set<String16> getDoubleKeys() const;
+ std::set<String16> getStringKeys() const;
+ std::set<String16> getBooleanVectorKeys() const;
+ std::set<String16> getIntVectorKeys() const;
+ std::set<String16> getLongVectorKeys() const;
+ std::set<String16> getDoubleVectorKeys() const;
+ std::set<String16> getStringVectorKeys() const;
+ std::set<String16> getPersistableBundleKeys() const;
+
friend bool operator==(const PersistableBundle& lhs, const PersistableBundle& rhs) {
return (lhs.mBoolMap == rhs.mBoolMap && lhs.mIntMap == rhs.mIntMap &&
lhs.mLongMap == rhs.mLongMap && lhs.mDoubleMap == rhs.mDoubleMap &&
diff --git a/include/hwbinder/Status.h b/include/hwbinder/Status.h
index ce947fa..7253af8 100644
--- a/include/hwbinder/Status.h
+++ b/include/hwbinder/Status.h
@@ -18,6 +18,7 @@
#define ANDROID_BINDER_STATUS_H
#include <cstdint>
+#include <sstream>
#include <binder/Parcel.h>
#include <utils/String8.h>
@@ -142,11 +143,7 @@
}; // class Status
// For gtest output logging
-template<typename T>
-T& operator<< (T& stream, const Status& s) {
- stream << s.toString8().string();
- return stream;
-}
+std::stringstream& operator<< (std::stringstream& stream, const Status& s);
} // namespace binder
} // namespace android