diff options
32 files changed, 945 insertions, 75 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 50f7b6df36..111146c442 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -1505,7 +1505,10 @@ int main(int argc, char *argv[]) { if (is_redirecting) { ds.bugreport_dir_ = dirname(use_outfile); - ds.base_name_ = basename(use_outfile); + std::string build_id = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD"); + std::string device_name = android::base::GetProperty("ro.product.device", "UNKNOWN_DEVICE"); + ds.base_name_ = android::base::StringPrintf("%s-%s-%s", basename(use_outfile), + device_name.c_str(), build_id.c_str()); if (do_add_date) { char date[80]; strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_)); diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 45ebbf8bef..ede31fcecf 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -1029,7 +1029,7 @@ static std::string toString(std::vector<int64_t> values) { #endif static void collectQuotaStats(const std::string& device, int32_t userId, - int32_t appId, struct stats* stats, struct stats* extStats ATTRIBUTE_UNUSED) { + int32_t appId, struct stats* stats, struct stats* extStats) { if (device.empty()) return; struct dqblk dq; @@ -1056,13 +1056,28 @@ static void collectQuotaStats(const std::string& device, int32_t userId, } } else { #if MEASURE_DEBUG - LOG(DEBUG) << "quotactl() for GID " << cacheGid << " " << dq.dqb_curspace; + LOG(DEBUG) << "quotactl() for GID " << cacheGid << " " << dq.dqb_curspace; #endif stats->cacheSize += dq.dqb_curspace; } } - int sharedGid = multiuser_get_shared_app_gid(uid); + int extGid = multiuser_get_ext_gid(userId, appId); + if (extGid != -1) { + if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), extGid, + reinterpret_cast<char*>(&dq)) != 0) { + if (errno != ESRCH) { + PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << extGid; + } + } else { +#if MEASURE_DEBUG + LOG(DEBUG) << "quotactl() for GID " << extGid << " " << dq.dqb_curspace; +#endif + extStats->dataSize += dq.dqb_curspace; + } + } + + int sharedGid = multiuser_get_shared_gid(userId, appId); if (sharedGid != -1) { if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), sharedGid, reinterpret_cast<char*>(&dq)) != 0) { @@ -1071,15 +1086,11 @@ static void collectQuotaStats(const std::string& device, int32_t userId, } } else { #if MEASURE_DEBUG - LOG(DEBUG) << "quotactl() for GID " << sharedGid << " " << dq.dqb_curspace; + LOG(DEBUG) << "quotactl() for GID " << sharedGid << " " << dq.dqb_curspace; #endif stats->codeSize += dq.dqb_curspace; } } - -#if MEASURE_EXTERNAL - // TODO: measure using external GIDs -#endif } static void collectManualStats(const std::string& path, struct stats* stats) { @@ -1165,6 +1176,40 @@ static void collectManualStatsForUser(const std::string& path, struct stats* sta closedir(d); } +static void collectManualExternalStatsForUser(const std::string& path, struct stats* stats) { + FTS *fts; + FTSENT *p; + char *argv[] = { (char*) path.c_str(), nullptr }; + if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_XDEV, NULL))) { + PLOG(ERROR) << "Failed to fts_open " << path; + return; + } + while ((p = fts_read(fts)) != NULL) { + switch (p->fts_info) { + case FTS_D: + if (p->fts_level == 4 + && !strcmp(p->fts_name, "cache") + && !strcmp(p->fts_parent->fts_parent->fts_name, "data") + && !strcmp(p->fts_parent->fts_parent->fts_parent->fts_name, "Android")) { + p->fts_number = 1; + } + p->fts_number = p->fts_parent->fts_number; + // Fall through to count the directory + case FTS_DEFAULT: + case FTS_F: + case FTS_SL: + case FTS_SLNONE: + int64_t size = (p->fts_statp->st_blocks * 512); + if (p->fts_number == 1) { + stats->cacheSize += size; + } + stats->dataSize += size; + break; + } + } + fts_close(fts); +} + binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, int32_t flags, int32_t appId, const std::vector<int64_t>& ceDataInodes, @@ -1251,14 +1296,12 @@ binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::stri calculate_tree_size(refProfilePath, &stats.codeSize); ATRACE_END(); -#if MEASURE_EXTERNAL ATRACE_BEGIN("external"); auto extPath = create_data_media_package_path(uuid_, userId, pkgname, "data"); collectManualStats(extPath, &extStats); auto mediaPath = create_data_media_package_path(uuid_, userId, pkgname, "media"); calculate_tree_size(mediaPath, &extStats.dataSize); ATRACE_END(); -#endif } ATRACE_BEGIN("dalvik"); @@ -1307,17 +1350,28 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str const char* uuid_ = uuid ? uuid->c_str() : nullptr; - ATRACE_BEGIN("obb"); - auto obbPath = create_data_path(uuid_) + "/media/obb"; - calculate_tree_size(obbPath, &extStats.codeSize); - ATRACE_END(); - auto device = findQuotaDeviceForUuid(uuid); if (device.empty()) { flags &= ~FLAG_USE_QUOTA; } if (flags & FLAG_USE_QUOTA) { + struct dqblk dq; + + ATRACE_BEGIN("obb"); + if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), AID_MEDIA_OBB, + reinterpret_cast<char*>(&dq)) != 0) { + if (errno != ESRCH) { + PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << AID_MEDIA_OBB; + } + } else { +#if MEASURE_DEBUG + LOG(DEBUG) << "quotactl() for GID " << AID_MEDIA_OBB << " " << dq.dqb_curspace; +#endif + extStats.codeSize += dq.dqb_curspace; + } + ATRACE_END(); + ATRACE_BEGIN("code"); calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true); ATRACE_END(); @@ -1336,11 +1390,20 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true); ATRACE_END(); -#if MEASURE_EXTERNAL ATRACE_BEGIN("external"); - // TODO: measure external storage paths - ATRACE_END(); + uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW); + if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid, + reinterpret_cast<char*>(&dq)) != 0) { + if (errno != ESRCH) { + PLOG(ERROR) << "Failed to quotactl " << device << " for UID " << uid; + } + } else { +#if MEASURE_DEBUG + LOG(DEBUG) << "quotactl() for UID " << uid << " " << dq.dqb_curspace; #endif + extStats.dataSize += dq.dqb_curspace; + } + ATRACE_END(); ATRACE_BEGIN("dalvik"); calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize, @@ -1361,6 +1424,11 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str } ATRACE_END(); } else { + ATRACE_BEGIN("obb"); + auto obbPath = create_data_path(uuid_) + "/media/obb"; + calculate_tree_size(obbPath, &extStats.codeSize); + ATRACE_END(); + ATRACE_BEGIN("code"); calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize); ATRACE_END(); @@ -1379,11 +1447,14 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str calculate_tree_size(refProfilePath, &stats.codeSize); ATRACE_END(); -#if MEASURE_EXTERNAL ATRACE_BEGIN("external"); - // TODO: measure external storage paths - ATRACE_END(); + auto dataMediaPath = create_data_media_path(uuid_, userId); + collectManualExternalStatsForUser(dataMediaPath, &extStats); +#if MEASURE_DEBUG + LOG(DEBUG) << "Measured external data " << extStats.dataSize << " cache " + << extStats.cacheSize; #endif + ATRACE_END(); ATRACE_BEGIN("dalvik"); calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize); diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h index f2f0cbb030..5e396c7f37 100644 --- a/cmds/installd/utils.h +++ b/cmds/installd/utils.h @@ -31,7 +31,6 @@ #include <installd_constants.h> #define MEASURE_DEBUG 0 -#define MEASURE_EXTERNAL 0 namespace android { namespace installd { diff --git a/data/etc/android.hardware.telephony.carrierlock.xml b/data/etc/android.hardware.telephony.carrierlock.xml new file mode 100644 index 0000000000..50b1fe956f --- /dev/null +++ b/data/etc/android.hardware.telephony.carrierlock.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 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. +--> + +<!-- Feature for devices with telephony carrier restriction mechanism. --> +<permissions> + <feature name="android.hardware.telephony.carrierlock" /> +</permissions> diff --git a/include/android/configuration.h b/include/android/configuration.h index b469e7e213..c9f63aee7d 100644 --- a/include/android/configuration.h +++ b/include/android/configuration.h @@ -267,6 +267,36 @@ enum { ACONFIGURATION_SCREENROUND_NO = 0x1, ACONFIGURATION_SCREENROUND_YES = 0x2, + /** Wide color gamut: not specified. */ + ACONFIGURATION_WIDE_COLOR_GAMUT_ANY = 0x00, + /** + * Wide color gamut: value that corresponds to + * <a href="@dacRoot/guide/topics/resources/providing-resources.html#WideColorGamutQualifier">no + * nowidecg</a> resource qualifier specified. + */ + ACONFIGURATION_WIDE_COLOR_GAMUT_NO = 0x1, + /** + * Wide color gamut: value that corresponds to + * <a href="@dacRoot/guide/topics/resources/providing-resources.html#WideColorGamutQualifier"> + * widecg</a> resource qualifier specified. + */ + ACONFIGURATION_WIDE_COLOR_GAMUT_YES = 0x2, + + /** HDR: not specified. */ + ACONFIGURATION_HDR_ANY = 0x00, + /** + * HDR: value that corresponds to + * <a href="@dacRoot/guide/topics/resources/providing-resources.html#HDRQualifier"> + * lowdr</a> resource qualifier specified. + */ + ACONFIGURATION_HDR_NO = 0x1, + /** + * HDR: value that corresponds to + * <a href="@dacRoot/guide/topics/resources/providing-resources.html#HDRQualifier"> + * highdr</a> resource qualifier specified. + */ + ACONFIGURATION_HDR_YES = 0x2, + /** UI mode: not specified. */ ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00, /** @@ -431,6 +461,12 @@ enum { ACONFIGURATION_LAYOUTDIR = 0x4000, ACONFIGURATION_SCREEN_ROUND = 0x8000, /** + * Bit mask for + * <a href="@dacRoot/guide/topics/resources/providing-resources.html#WideColorGamutQualifier">wide color gamut</a> + * and <a href="@dacRoot/guide/topics/resources/providing-resources.html#HDRQualifier">HDR</a> configurations. + */ + ACONFIGURATION_COLORIMETRY = 0x10000, + /** * Constant used to to represent MNC (Mobile Network Code) zero. * 0 cannot be used, since it is used to represent an undefined MNC. */ diff --git a/include/binder/Status.h b/include/binder/Status.h index dd61616f24..c3738f8b29 100644 --- a/include/binder/Status.h +++ b/include/binder/Status.h @@ -62,6 +62,7 @@ public: EX_NETWORK_MAIN_THREAD = -6, EX_UNSUPPORTED_OPERATION = -7, EX_SERVICE_SPECIFIC = -8, + EX_PARCELABLE = -9, // This is special and Java specific; see Parcel.java. EX_HAS_REPLY_HEADER = -128, diff --git a/include/gui/ISensorEventConnection.h b/include/gui/ISensorEventConnection.h index 857444b60b..2ccd832c52 100644 --- a/include/gui/ISensorEventConnection.h +++ b/include/gui/ISensorEventConnection.h @@ -40,6 +40,7 @@ public: nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0; virtual status_t setEventRate(int handle, nsecs_t ns) = 0; virtual status_t flush() = 0; + virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h index 737c430af4..0c36c9920f 100644 --- a/include/gui/ISensorServer.h +++ b/include/gui/ISensorServer.h @@ -25,6 +25,8 @@ #include <binder/IInterface.h> +struct native_handle; +typedef struct native_handle native_handle_t; namespace android { // ---------------------------------------------------------------------------- @@ -43,6 +45,9 @@ public: virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName, int mode, const String16& opPackageName) = 0; virtual int32_t isDataInjectionEnabled() = 0; + + virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName, + uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h index 750683559d..d886b2bc85 100644 --- a/include/gui/Sensor.h +++ b/include/gui/Sensor.h @@ -91,6 +91,8 @@ public: bool isWakeUpSensor() const; bool isDynamicSensor() const; bool hasAdditionalInfo() const; + int32_t getHighestDirectReportRateLevel() const; + bool isDirectChannelTypeSupported(int32_t sharedMemType) const; int32_t getReportingMode() const; // Note that after setId() has been called, getUuid() no longer diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h index 6c6230f9e5..5b34ff4b8c 100644 --- a/include/gui/SensorManager.h +++ b/include/gui/SensorManager.h @@ -34,10 +34,15 @@ #include <gui/SensorEventQueue.h> +#include <unordered_map> + // ---------------------------------------------------------------------------- // Concrete types for the NDK struct ASensorManager { }; +struct native_handle; +typedef struct native_handle native_handle_t; + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- @@ -59,6 +64,9 @@ public: Sensor const* getDefaultSensor(int type); sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0); bool isDataInjectionEnabled(); + int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData); + void destroyDirectChannel(int channelNativeHandle); + int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel); private: // DeathRecipient interface @@ -77,6 +85,8 @@ private: Vector<Sensor> mSensors; sp<IBinder::DeathRecipient> mDeathObserver; const String16 mOpPackageName; + std::unordered_map<int, sp<ISensorEventConnection>> mDirectConnection; + int32_t mDirectConnectionHandle; }; // ---------------------------------------------------------------------------- diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp index 8466863865..006f7f94e9 100644 --- a/libs/binder/Status.cpp +++ b/libs/binder/Status.cpp @@ -104,6 +104,16 @@ status_t Status::readFromParcel(const Parcel& parcel) { if (mException == EX_SERVICE_SPECIFIC) { status = parcel.readInt32(&mErrorCode); + } else if (mException == EX_PARCELABLE) { + // Skip over the blob of Parcelable data + const int32_t header_start = parcel.dataPosition(); + int32_t header_size; + status = parcel.readInt32(&header_size); + if (status != OK) { + setFromStatusT(status); + return status; + } + parcel.setDataPosition(header_start + header_size); } if (status != OK) { setFromStatusT(status); @@ -127,11 +137,12 @@ status_t Status::writeToParcel(Parcel* parcel) const { return status; } status = parcel->writeString16(String16(mMessage)); - if (mException != EX_SERVICE_SPECIFIC) { - // We have no more information to write. - return status; + if (mException == EX_SERVICE_SPECIFIC) { + status = parcel->writeInt32(mErrorCode); + } else if (mException == EX_PARCELABLE) { + // Sending Parcelable blobs currently not supported + status = parcel->writeInt32(0); } - status = parcel->writeInt32(mErrorCode); return status; } diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp index 59ecee7501..8af51c534b 100644 --- a/libs/gui/ISensorEventConnection.cpp +++ b/libs/gui/ISensorEventConnection.cpp @@ -34,7 +34,8 @@ enum { GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION, ENABLE_DISABLE, SET_EVENT_RATE, - FLUSH_SENSOR + FLUSH_SENSOR, + CONFIGURE_CHANNEL }; class BpSensorEventConnection : public BpInterface<ISensorEventConnection> @@ -85,6 +86,15 @@ public: remote()->transact(FLUSH_SENSOR, data, &reply); return reply.readInt32(); } + + virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) { + Parcel data, reply; + data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor()); + data.writeInt32(handle); + data.writeInt32(rateLevel); + remote()->transact(CONFIGURE_CHANNEL, data, &reply); + return reply.readInt32(); + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -131,6 +141,15 @@ status_t BnSensorEventConnection::onTransact( reply->writeInt32(result); return NO_ERROR; } + case CONFIGURE_CHANNEL: { + CHECK_INTERFACE(ISensorEventConnection, data, reply); + int handle = data.readInt32(); + int rateLevel = data.readInt32(); + status_t result = configureChannel(handle, rateLevel); + reply->writeInt32(result); + return NO_ERROR; + } + } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp index 07c507a082..aea7403636 100644 --- a/libs/gui/ISensorServer.cpp +++ b/libs/gui/ISensorServer.cpp @@ -17,6 +17,7 @@ #include <stdint.h> #include <sys/types.h> +#include <cutils/native_handle.h> #include <utils/Errors.h> #include <utils/RefBase.h> #include <utils/Vector.h> @@ -37,6 +38,7 @@ enum { CREATE_SENSOR_EVENT_CONNECTION, ENABLE_DATA_INJECTION, GET_DYNAMIC_SENSOR_LIST, + CREATE_SENSOR_DIRECT_CONNECTION, }; class BpSensorServer : public BpInterface<ISensorServer> @@ -101,6 +103,19 @@ public: remote()->transact(ENABLE_DATA_INJECTION, data, &reply); return reply.readInt32(); } + + virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName, + uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) { + Parcel data, reply; + data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); + data.writeString16(opPackageName); + data.writeUint32(size); + data.writeInt32(type); + data.writeInt32(format); + data.writeNativeHandle(resource); + remote()->transact(CREATE_SENSOR_DIRECT_CONNECTION, data, &reply); + return interface_cast<ISensorEventConnection>(reply.readStrongBinder()); + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -153,6 +168,20 @@ status_t BnSensorServer::onTransact( } return NO_ERROR; } + case CREATE_SENSOR_DIRECT_CONNECTION: { + CHECK_INTERFACE(ISensorServer, data, reply); + const String16& opPackageName = data.readString16(); + uint32_t size = data.readUint32(); + int32_t type = data.readInt32(); + int32_t format = data.readInt32(); + native_handle_t *resource = data.readNativeHandle(); + sp<ISensorEventConnection> ch = + createSensorDirectConnection(opPackageName, size, type, format, resource); + native_handle_close(resource); + native_handle_delete(resource); + reply->writeStrongBinder(IInterface::asBinder(ch)); + return NO_ERROR; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp index 9cb203598a..2fd29d5d7f 100644 --- a/libs/gui/Sensor.cpp +++ b/libs/gui/Sensor.cpp @@ -300,7 +300,15 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi // Feature flags // Set DYNAMIC_SENSOR_MASK and ADDITIONAL_INFO_MASK flag here. Compatible with HAL 1_3. if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) { - mFlags |= (hwSensor.flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK)); + mFlags |= hwSensor.flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK); + } + // Set DIRECT_REPORT_MASK and DIRECT_CHANNEL_MASK flags. Compatible with HAL 1_3. + if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) { + // only on continuous sensors direct report mode is defined + if ((mFlags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) { + mFlags |= hwSensor.flags + & (SENSOR_FLAG_MASK_DIRECT_REPORT | SENSOR_FLAG_MASK_DIRECT_CHANNEL); + } } // Set DATA_INJECTION flag here. Defined in HAL 1_4. if (halVersion >= SENSORS_DEVICE_API_VERSION_1_4) { @@ -410,6 +418,21 @@ bool Sensor::hasAdditionalInfo() const { return (mFlags & SENSOR_FLAG_ADDITIONAL_INFO) != 0; } +int32_t Sensor::getHighestDirectReportRateLevel() const { + return ((mFlags & SENSOR_FLAG_MASK_DIRECT_REPORT) >> SENSOR_FLAG_SHIFT_DIRECT_REPORT); +} + +bool Sensor::isDirectChannelTypeSupported(int32_t sharedMemType) const { + switch (sharedMemType) { + case SENSOR_DIRECT_MEM_TYPE_ASHMEM: + return mFlags & SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM; + case SENSOR_DIRECT_MEM_TYPE_GRALLOC: + return mFlags & SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC; + default: + return false; + } +} + int32_t Sensor::getReportingMode() const { return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT); } diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index 57c3073bf4..46eaf286ce 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> +#include <cutils/native_handle.h> #include <utils/Errors.h> #include <utils/RefBase.h> #include <utils/Singleton.h> @@ -89,7 +90,7 @@ SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) } SensorManager::SensorManager(const String16& opPackageName) - : mSensorList(0), mOpPackageName(opPackageName) { + : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) { // okay we're not locked here, but it's not needed during construction assertStateLocked(); } @@ -237,5 +238,62 @@ bool SensorManager::isDataInjectionEnabled() { return false; } +int SensorManager::createDirectChannel( + size_t size, int channelType, const native_handle_t *resourceHandle) { + Mutex::Autolock _l(mLock); + if (assertStateLocked() != NO_ERROR) { + return NO_INIT; + } + + switch (channelType) { + case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { + sp<ISensorEventConnection> conn = + mSensorServer->createSensorDirectConnection(mOpPackageName, + static_cast<uint32_t>(size), + static_cast<int32_t>(channelType), + SENSOR_DIRECT_FMT_SENSORS_EVENT, resourceHandle); + if (conn == nullptr) { + return NO_MEMORY; + } + int nativeHandle = mDirectConnectionHandle++; + mDirectConnection.emplace(nativeHandle, conn); + return nativeHandle; + } + case SENSOR_DIRECT_MEM_TYPE_GRALLOC: + LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__); + return BAD_VALUE; + default: + ALOGE("Bad channel shared memory type %d", channelType); + return BAD_VALUE; + } +} + +void SensorManager::destroyDirectChannel(int channelNativeHandle) { + Mutex::Autolock _l(mLock); + if (assertStateLocked() == NO_ERROR) { + mDirectConnection.erase(channelNativeHandle); + } +} + +int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel) { + Mutex::Autolock _l(mLock); + if (assertStateLocked() != NO_ERROR) { + return NO_INIT; + } + + auto i = mDirectConnection.find(channelNativeHandle); + if (i == mDirectConnection.end()) { + ALOGE("Cannot find the handle in client direct connection table"); + return BAD_VALUE; + } + + int ret; + ret = i->second->configureChannel(sensorHandle, rateLevel); + ALOGE_IF(ret < 0, "SensorManager::configureChannel (%d, %d) returns %d", + static_cast<int>(sensorHandle), static_cast<int>(rateLevel), + static_cast<int>(ret)); + return ret; +} + // ---------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 27697aba2c..01d7bbbd6b 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -15,6 +15,7 @@ */ //#define LOG_NDEBUG 0 +#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <array> #include <ctype.h> @@ -29,6 +30,7 @@ #include <android/dlext.h> #include <cutils/properties.h> #include <log/log.h> +#include <utils/Trace.h> #include <EGL/egl.h> @@ -100,6 +102,11 @@ checkGlesEmulationStatus(void) return atoi(prop); } +static void* do_dlopen(const char* path, int mode) { + ATRACE_CALL(); + return dlopen(path, mode); +} + // ---------------------------------------------------------------------------- Loader::driver_t::driver_t(void* gles) @@ -163,7 +170,7 @@ Loader::~Loader() { } static void* load_wrapper(const char* path) { - void* so = dlopen(path, RTLD_NOW | RTLD_LOCAL); + void* so = do_dlopen(path, RTLD_NOW | RTLD_LOCAL); ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror()); return so; } @@ -210,6 +217,8 @@ static void setEmulatorGlesValue(void) { void* Loader::open(egl_connection_t* cnx) { + ATRACE_CALL(); + void* dso; driver_t* hnd = 0; @@ -255,6 +264,8 @@ void Loader::init_api(void* dso, __eglMustCastToProperFunctionPointerType* curr, getProcAddressType getProcAddress) { + ATRACE_CALL(); + const ssize_t SIZE = 256; char scrap[SIZE]; while (*api) { @@ -307,6 +318,7 @@ void Loader::init_api(void* dso, } static void* load_system_driver(const char* kind) { + ATRACE_CALL(); class MatchFile { public: static String8 find(const char* kind) { @@ -422,7 +434,7 @@ static void* load_system_driver(const char* kind) { } const char* const driver_absolute_path = absolutePath.string(); - void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL); + void* dso = do_dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL); if (dso == 0) { const char* err = dlerror(); ALOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown"); @@ -434,12 +446,18 @@ static void* load_system_driver(const char* kind) { return dso; } +static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) { + ATRACE_CALL(); + return android_dlopen_ext(path, mode, info); +} + static const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{ "ro.hardware.egl", "ro.board.platform", }}; static void* load_updated_driver(const char* kind, android_namespace_t* ns) { + ATRACE_CALL(); const android_dlextinfo dlextinfo = { .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = ns, @@ -450,7 +468,7 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) { if (property_get(key, prop, nullptr) > 0) { String8 name; name.appendFormat("lib%s_%s.so", kind, prop); - so = android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW, + so = do_android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW, &dlextinfo); if (so) return so; @@ -462,6 +480,8 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) { void *Loader::load_driver(const char* kind, egl_connection_t* cnx, uint32_t mask) { + ATRACE_CALL(); + void* dso = nullptr; if (mGetDriverNamespace) { android_namespace_t* ns = mGetDriverNamespace(); diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 97343a19c4..b38b4c2a58 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -267,6 +267,7 @@ static inline EGLContext getContext() { return egl_tls_t::getContext(); } EGLDisplay eglGetDisplay(EGLNativeDisplayType display) { + ATRACE_CALL(); clearError(); uintptr_t index = reinterpret_cast<uintptr_t>(display); diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index a32f0378be..d7df40c086 100644 --- a/opengl/libs/EGL/egl_display.cpp +++ b/opengl/libs/EGL/egl_display.cpp @@ -15,6 +15,7 @@ */ #define __STDC_LIMIT_MACROS 1 +#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <string.h> @@ -26,6 +27,7 @@ #include "egl_tls.h" #include "Loader.h" #include <cutils/properties.h> +#include <utils/Trace.h> // ---------------------------------------------------------------------------- namespace android { @@ -103,6 +105,7 @@ EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) { EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) { Mutex::Autolock _l(lock); + ATRACE_CALL(); // get our driver loader Loader& loader(Loader::getInstance()); diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk index 86af0ef18b..c41630a20b 100644 --- a/services/sensorservice/Android.mk +++ b/services/sensorservice/Android.mk @@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \ OrientationSensor.cpp \ RecentEventLogger.cpp \ RotationVectorSensor.cpp \ + SensorDirectConnection.cpp \ SensorEventConnection.cpp \ SensorFusion.cpp \ SensorInterface.cpp \ diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp index 0245b2697a..41ad918a12 100644 --- a/services/sensorservice/SensorDevice.cpp +++ b/services/sensorservice/SensorDevice.cpp @@ -14,23 +14,27 @@ * limitations under the License. */ -#include <inttypes.h> -#include <math.h> -#include <stdint.h> -#include <sys/types.h> -#include <utils/Atomic.h> -#include <utils/Errors.h> -#include <utils/Singleton.h> +#include "SensorDevice.h" +#include "SensorService.h" + #include <binder/BinderService.h> #include <binder/Parcel.h> #include <binder/IServiceManager.h> - +#include <cutils/ashmem.h> #include <hardware/sensors.h> +#include <utils/Atomic.h> +#include <utils/Errors.h> +#include <utils/Singleton.h> -#include "SensorDevice.h" -#include "SensorService.h" +#include <inttypes.h> +#include <math.h> +#include <sys/mman.h> +#include <stdint.h> +#include <sys/types.h> +#include <sstream> +#include <unistd.h> namespace android { // --------------------------------------------------------------------------- @@ -386,7 +390,7 @@ void SensorDevice::enableAllSensors() { void SensorDevice::disableAllSensors() { Mutex::Autolock _l(mLock); - for (size_t i = 0; i< mActivationCount.size(); ++i) { + for (size_t i = 0; i< mActivationCount.size(); ++i) { const Info& info = mActivationCount.valueAt(i); // Check if this sensor has been activated previously and disable it. if (info.batchParams.size() > 0) { @@ -486,6 +490,29 @@ void SensorDevice::notifyConnectionDestroyed(void* ident) { mDisabledClients.remove(ident); } +int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) { + Mutex::Autolock _l(mLock); + + int32_t channelHandle = mSensorDevice->register_direct_channel( + mSensorDevice, memory, -1 /*channel_handle*/); + return channelHandle; +} + +void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { + Mutex::Autolock _l(mLock); + + mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle); +} + +int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, + const struct sensors_direct_cfg_t *config) { + Mutex::Autolock _l(mLock); + + int32_t ret = mSensorDevice->config_direct_report( + mSensorDevice, sensorHandle, channelHandle, config); + ALOGE_IF(ret < 0, "SensorDevice::configureDirectChannel ret %d", ret); + return ret; +} // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h index 0bb0752169..b6886a20fc 100644 --- a/services/sensorservice/SensorDevice.h +++ b/services/sensorservice/SensorDevice.h @@ -26,6 +26,7 @@ #include <stdint.h> #include <sys/types.h> +#include <string> #ifdef ENABLE_TREBLE #include <map> @@ -57,6 +58,12 @@ public: status_t setDelay(void* ident, int handle, int64_t ns); status_t flush(void* ident, int handle); status_t setMode(uint32_t mode); + + int32_t registerDirectChannel(const sensors_direct_mem_t *memory); + void unregisterDirectChannel(int32_t channelHandle); + int32_t configureDirectChannel(int32_t sensorHandle, + int32_t channelHandle, const struct sensors_direct_cfg_t *config); + void disableAllSensors(); void enableAllSensors(); void autoDisable(void *ident, int handle); diff --git a/services/sensorservice/SensorDeviceTreble.cpp b/services/sensorservice/SensorDeviceTreble.cpp index 37f0f6c644..2877589af4 100644 --- a/services/sensorservice/SensorDeviceTreble.cpp +++ b/services/sensorservice/SensorDeviceTreble.cpp @@ -29,16 +29,9 @@ #include <sensors/convert.h> -using android::hardware::sensors::V1_0::ISensors; using android::hardware::hidl_vec; -using Event = android::hardware::sensors::V1_0::Event; -using SensorInfo = android::hardware::sensors::V1_0::SensorInfo; -using SensorType = android::hardware::sensors::V1_0::SensorType; -using DynamicSensorInfo = android::hardware::sensors::V1_0::DynamicSensorInfo; -using SensorInfo = android::hardware::sensors::V1_0::SensorInfo; -using Result = android::hardware::sensors::V1_0::Result; - +using namespace android::hardware::sensors::V1_0; using namespace android::hardware::sensors::V1_0::implementation; namespace android { @@ -504,6 +497,90 @@ void SensorDevice::notifyConnectionDestroyed(void* ident) { mDisabledClients.remove(ident); } +int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) { + Mutex::Autolock _l(mLock); + + SharedMemType type; + switch (memory->type) { + case SENSOR_DIRECT_MEM_TYPE_ASHMEM: + type = SharedMemType::ASHMEM; + break; + case SENSOR_DIRECT_MEM_TYPE_GRALLOC: + type = SharedMemType::GRALLOC; + break; + default: + return BAD_VALUE; + } + + SharedMemFormat format; + if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { + return BAD_VALUE; + } + format = SharedMemFormat::SENSORS_EVENT; + + SharedMemInfo mem = { + .type = type, + .format = format, + .size = static_cast<uint32_t>(memory->size), + .memoryHandle = memory->handle, + }; + + int32_t ret; + mSensors->registerDirectChannel(mem, + [&ret](auto result, auto channelHandle) { + if (result == Result::OK) { + ret = channelHandle; + } else { + ret = StatusFromResult(result); + } + }); + return ret; +} + +void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { + Mutex::Autolock _l(mLock); + mSensors->unregisterDirectChannel(channelHandle); +} + +int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, + int32_t channelHandle, const struct sensors_direct_cfg_t *config) { + Mutex::Autolock _l(mLock); + + RateLevel rate; + switch(config->rate_level) { + case SENSOR_DIRECT_RATE_STOP: + rate = RateLevel::STOP; + break; + case SENSOR_DIRECT_RATE_NORMAL: + rate = RateLevel::NORMAL; + break; + case SENSOR_DIRECT_RATE_FAST: + rate = RateLevel::FAST; + break; + case SENSOR_DIRECT_RATE_VERY_FAST: + rate = RateLevel::VERY_FAST; + break; + default: + return BAD_VALUE; + } + + int32_t ret; + mSensors->configDirectReport(sensorHandle, channelHandle, rate, + [&ret, rate] (auto result, auto token) { + if (rate == RateLevel::STOP) { + ret = StatusFromResult(result); + } else { + if (result == Result::OK) { + ret = token; + } else { + ret = StatusFromResult(result); + } + } + }); + + return ret; +} + void SensorDevice::convertToSensorEvent( const Event &src, sensors_event_t *dst) { ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent( diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp new file mode 100644 index 0000000000..662f320f56 --- /dev/null +++ b/services/sensorservice/SensorDirectConnection.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2016 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. + */ + +#include "SensorDevice.h" +#include "SensorDirectConnection.h" +#include <hardware/sensors.h> + +#include <sys/stat.h> + +#define UNUSED(x) (void)(x) + +namespace android { + +SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorService>& service, + uid_t uid, const sensors_direct_mem_t *mem, int32_t halChannelHandle, + const String16& opPackageName) + : mService(service), mUid(uid), mMem(*mem), + mHalChannelHandle(halChannelHandle), + mOpPackageName(opPackageName) { + ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection"); +} + +SensorService::SensorDirectConnection::~SensorDirectConnection() { + ALOGD_IF(DEBUG_CONNECTIONS, "~SensorDirectConnection %p", this); + + stopAll(); + mService->cleanupConnection(this); + if (mMem.handle != nullptr) { + native_handle_close(mMem.handle); + native_handle_delete(const_cast<struct native_handle*>(mMem.handle)); + } +} + +void SensorService::SensorDirectConnection::onFirstRef() { +} + +void SensorService::SensorDirectConnection::dump(String8& result) const { + Mutex::Autolock _l(mConnectionLock); + result.appendFormat("\tPackage %s, HAL channel handle %d, total sensor activated %zu\n", + String8(mOpPackageName).string(), getHalChannelHandle(), mActivated.size()); + for (auto &i : mActivated) { + result.appendFormat("\t\tSensor %#08x, rate %d\n", i.first, i.second); + } +} + +sp<BitTube> SensorService::SensorDirectConnection::getSensorChannel() const { + return nullptr; +} + +status_t SensorService::SensorDirectConnection::enableDisable( + int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, + int reservedFlags) { + // SensorDirectConnection does not support enableDisable, parameters not used + UNUSED(handle); + UNUSED(enabled); + UNUSED(samplingPeriodNs); + UNUSED(maxBatchReportLatencyNs); + UNUSED(reservedFlags); + return INVALID_OPERATION; +} + +status_t SensorService::SensorDirectConnection::setEventRate( + int handle, nsecs_t samplingPeriodNs) { + // SensorDirectConnection does not support setEventRate, parameters not used + UNUSED(handle); + UNUSED(samplingPeriodNs); + return INVALID_OPERATION; +} + +status_t SensorService::SensorDirectConnection::flush() { + // SensorDirectConnection does not support flush + return INVALID_OPERATION; +} + +int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int rateLevel) { + + if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) { + stopAll(); + return NO_ERROR; + } + + if (mService->isOperationRestricted(mOpPackageName)) { + return PERMISSION_DENIED; + } + + sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle); + if (si == nullptr) { + return NAME_NOT_FOUND; + } + + const Sensor& s = si->getSensor(); + if (!SensorService::canAccessSensor(s, "config direct channel", mOpPackageName)) { + return PERMISSION_DENIED; + } + + if (s.getHighestDirectReportRateLevel() == 0 + || rateLevel > s.getHighestDirectReportRateLevel() + || !s.isDirectChannelTypeSupported(mMem.type)) { + return INVALID_OPERATION; + } + + struct sensors_direct_cfg_t config = { + .rate_level = rateLevel + }; + + Mutex::Autolock _l(mConnectionLock); + SensorDevice& dev(SensorDevice::getInstance()); + int ret = dev.configureDirectChannel(handle, getHalChannelHandle(), &config); + + if (rateLevel == SENSOR_DIRECT_RATE_STOP) { + if (ret == NO_ERROR) { + mActivated.erase(handle); + } else if (ret > 0) { + ret = UNKNOWN_ERROR; + } + } else { + if (ret > 0) { + mActivated[handle] = rateLevel; + } + } + + return ret; +} + +void SensorService::SensorDirectConnection::stopAll(bool backupRecord) { + + struct sensors_direct_cfg_t config = { + .rate_level = SENSOR_DIRECT_RATE_STOP + }; + + Mutex::Autolock _l(mConnectionLock); + SensorDevice& dev(SensorDevice::getInstance()); + for (auto &i : mActivated) { + dev.configureDirectChannel(i.first, getHalChannelHandle(), &config); + } + + if (backupRecord && mActivatedBackup.empty()) { + mActivatedBackup = mActivated; + } + mActivated.clear(); +} + +void SensorService::SensorDirectConnection::recoverAll() { + stopAll(false); + + Mutex::Autolock _l(mConnectionLock); + SensorDevice& dev(SensorDevice::getInstance()); + + // recover list of report from backup + mActivated = mActivatedBackup; + mActivatedBackup.clear(); + + // re-enable them + for (auto &i : mActivated) { + struct sensors_direct_cfg_t config = { + .rate_level = i.second + }; + dev.configureDirectChannel(i.first, getHalChannelHandle(), &config); + } +} + +int32_t SensorService::SensorDirectConnection::getHalChannelHandle() const { + return mHalChannelHandle; +} + +bool SensorService::SensorDirectConnection::isEquivalent(const sensors_direct_mem_t *mem) const { + bool ret = false; + + if (mMem.type == mem->type) { + switch (mMem.type) { + case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { + struct stat s1, s2; + int fd1, fd2; + fd1 = mMem.handle->data[0]; + fd2 = mem->handle->data[1]; + if (fstat(fd1, &s1) < 0 || fstat(fd2, &s2) < 0 || s1.st_ino == s2.st_ino) { + ret = true; + } + } + case SENSOR_DIRECT_MEM_TYPE_GRALLOC: + LOG_FATAL("%s: Implement GRALLOC or remove", __FUNCTION__); + ret = true; + default: + ALOGE("Unexpected mem type %d", mMem.type); + ret = true; + } + } + return ret; +} + +} // namespace android + diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h new file mode 100644 index 0000000000..692ef0dcc4 --- /dev/null +++ b/services/sensorservice/SensorDirectConnection.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2016 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_SENSOR_DIRECT_CONNECTION_H +#define ANDROID_SENSOR_DIRECT_CONNECTION_H + +#include <stdint.h> +#include <sys/types.h> + +#include <binder/BinderService.h> + +#include <gui/Sensor.h> +#include <gui/BitTube.h> +#include <gui/ISensorServer.h> +#include <gui/ISensorEventConnection.h> + +#include "SensorService.h" + +namespace android { + +class SensorService; +class BitTube; + +class SensorService::SensorDirectConnection: public BnSensorEventConnection { +public: + SensorDirectConnection(const sp<SensorService>& service, uid_t uid, + const sensors_direct_mem_t *mem, int32_t halChannelHandle, + const String16& opPackageName); + void dump(String8& result) const; + uid_t getUid() const { return mUid; } + int32_t getHalChannelHandle() const; + bool isEquivalent(const sensors_direct_mem_t *mem) const; + + // stop all active sensor report. if backupRecord is set to false, + // those report can be recovered by recoverAll + // called by SensorService when enter restricted mode + void stopAll(bool clearRecord = false); + + // recover sensor reports previously stopped by stopAll(true) + // called by SensorService when return to NORMAL mode. + void recoverAll(); + +protected: + virtual ~SensorDirectConnection(); + // ISensorEventConnection functions + virtual void onFirstRef(); + virtual sp<BitTube> getSensorChannel() const; + virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs, + nsecs_t maxBatchReportLatencyNs, int reservedFlags); + virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs); + virtual status_t flush(); + virtual int32_t configureChannel(int handle, int rateLevel); + +private: + const sp<SensorService> mService; + const uid_t mUid; + const sensors_direct_mem_t mMem; + const int32_t mHalChannelHandle; + const String16 mOpPackageName; + + mutable Mutex mConnectionLock; + std::unordered_map<int, int> mActivated; + std::unordered_map<int, int> mActivatedBackup; +}; + +} // namepsace android + +#endif // ANDROID_SENSOR_DIRECT_CONNECTION_H + diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp index f2f1444125..d84d36ebb6 100644 --- a/services/sensorservice/SensorEventConnection.cpp +++ b/services/sensorservice/SensorEventConnection.cpp @@ -23,6 +23,8 @@ #include "SensorEventConnection.h" #include "SensorDevice.h" +#define UNUSED(x) (void)(x) + namespace android { SensorService::SensorEventConnection::SensorEventConnection( @@ -524,6 +526,13 @@ status_t SensorService::SensorEventConnection::flush() { return mService->flushSensor(this, mOpPackageName); } +int32_t SensorService::SensorEventConnection::configureChannel(int handle, int rateLevel) { + // SensorEventConnection does not support configureChannel, parameters not used + UNUSED(handle); + UNUSED(rateLevel); + return INVALID_OPERATION; +} + int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) { if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) { { diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h index 883c16e23b..cd81dddab5 100644 --- a/services/sensorservice/SensorEventConnection.h +++ b/services/sensorservice/SensorEventConnection.h @@ -74,6 +74,8 @@ private: nsecs_t maxBatchReportLatencyNs, int reservedFlags); virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs); virtual status_t flush(); + virtual int32_t configureChannel(int handle, int rateLevel); + // Count the number of flush complete events which are about to be dropped in the buffer. // Increment mPendingFlushEventsToSend in mSensorInfo. These flush complete events will be sent // separately before the next batch of events. diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp index e0101c1f1a..31c8251c35 100644 --- a/services/sensorservice/SensorList.cpp +++ b/services/sensorservice/SensorList.cpp @@ -124,7 +124,7 @@ std::string SensorList::dump() const { forEachSensor([&result] (const Sensor& s) -> bool { result.appendFormat( "%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32 - ") | perm: %s\n\t", + ") | perm: %s\n", s.getHandle(), s.getName().string(), s.getVendor().string(), @@ -133,17 +133,18 @@ std::string SensorList::dump() const { s.getType(), s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a"); + result.append("\t"); const int reportingMode = s.getReportingMode(); if (reportingMode == AREPORTING_MODE_CONTINUOUS) { - result.append(" continuous | "); + result.append("continuous | "); } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) { - result.append(" on-change | "); + result.append("on-change | "); } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) { - result.append(" one-shot | "); + result.append("one-shot | "); } else if (reportingMode == AREPORTING_MODE_SPECIAL_TRIGGER) { - result.append(" special-trigger | "); + result.append("special-trigger | "); } else { - result.append(" unknown-mode | "); + result.append("unknown-mode | "); } if (s.getMaxDelay() > 0) { @@ -178,8 +179,19 @@ std::string SensorList::dump() const { if (s.hasAdditionalInfo()) { result.appendFormat("has-additional-info, "); } - result.append("\n"); + + if (s.getHighestDirectReportRateLevel() > SENSOR_DIRECT_RATE_STOP) { + result.appendFormat("\thighest rate level = %d, support shared mem: ", + s.getHighestDirectReportRateLevel()); + if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_ASHMEM)) { + result.append("ashmem, "); + } + if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC)) { + result.append("gralloc, "); + } + result.append("\n"); + } return true; }); return std::string(result.string()); diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 2e447367cd..143a3c5746 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -21,6 +21,7 @@ #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> +#include <cutils/ashmem.h> #include <gui/SensorEventQueue.h> #include <hardware/sensors.h> @@ -40,6 +41,7 @@ #include "SensorInterface.h" #include "SensorService.h" +#include "SensorDirectConnection.h" #include "SensorEventAckReceiver.h" #include "SensorEventConnection.h" #include "SensorRecord.h" @@ -337,7 +339,16 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (mCurrentOperatingMode != NORMAL) { return INVALID_OPERATION; } + mCurrentOperatingMode = RESTRICTED; + // temporarily stop all sensor direct report + for (auto &i : mDirectConnections) { + sp<SensorDirectConnection> connection(i.promote()); + if (connection != nullptr) { + connection->stopAll(true /* backupRecord */); + } + } + dev.disableAllSensors(); // Clear all pending flush connections for all active sensors. If one of the active // connections has called flush() and the underlying sensor has been disabled before a @@ -352,6 +363,13 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; dev.enableAllSensors(); + // recover all sensor direct report + for (auto &i : mDirectConnections) { + sp<SensorDirectConnection> connection(i.promote()); + if (connection != nullptr) { + connection->recoverAll(); + } + } } if (mCurrentOperatingMode == DATA_INJECTION) { resetToNormalModeLocked(); @@ -430,8 +448,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { case DATA_INJECTION: result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); } - result.appendFormat("%zd active connections\n", mActiveConnections.size()); + result.appendFormat("%zd active connections\n", mActiveConnections.size()); for (size_t i=0 ; i < mActiveConnections.size() ; i++) { sp<SensorEventConnection> connection(mActiveConnections[i].promote()); if (connection != 0) { @@ -440,6 +458,15 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { } } + result.appendFormat("%zd direct connections\n", mDirectConnections.size()); + for (size_t i = 0 ; i < mDirectConnections.size() ; i++) { + sp<SensorDirectConnection> connection(mDirectConnections[i].promote()); + if (connection != nullptr) { + result.appendFormat("Direct connection %zu:\n", i); + connection->dump(result); + } + } + result.appendFormat("Previous Registrations:\n"); // Log in the reverse chronological order. int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % @@ -936,6 +963,85 @@ int SensorService::isDataInjectionEnabled() { return (mCurrentOperatingMode == DATA_INJECTION); } +sp<ISensorEventConnection> SensorService::createSensorDirectConnection( + const String16& opPackageName, uint32_t size, int32_t type, int32_t format, + const native_handle *resource) { + Mutex::Autolock _l(mLock); + + struct sensors_direct_mem_t mem = { + .type = type, + .format = format, + .size = size, + .handle = resource, + }; + uid_t uid = IPCThreadState::self()->getCallingUid(); + + if (mem.handle == nullptr) { + ALOGE("Failed to clone resource handle"); + return nullptr; + } + + // check format + if (format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { + ALOGE("Direct channel format %d is unsupported!", format); + return nullptr; + } + + // check for duplication + for (auto &i : mDirectConnections) { + sp<SensorDirectConnection> connection(i.promote()); + if (connection != nullptr && connection->isEquivalent(&mem)) { + return nullptr; + } + } + + // check specific to memory type + switch(type) { + case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { // channel backed by ashmem + int fd = resource->data[0]; + int size2 = ashmem_get_size_region(fd); + // check size consistency + if (size2 != static_cast<int>(size)) { + ALOGE("Ashmem direct channel size mismatch, %" PRIu32 " vs %d", size, size2); + return nullptr; + } + break; + } + case SENSOR_DIRECT_MEM_TYPE_GRALLOC: + LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__); + break; + default: + ALOGE("Unknown direct connection memory type %d", type); + return nullptr; + } + + native_handle_t *clone = native_handle_clone(resource); + if (!clone) { + return nullptr; + } + + SensorDirectConnection* conn = nullptr; + SensorDevice& dev(SensorDevice::getInstance()); + int channelHandle = dev.registerDirectChannel(&mem); + + if (channelHandle <= 0) { + ALOGE("SensorDevice::registerDirectChannel returns %d", channelHandle); + } else { + mem.handle = clone; + conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName); + } + + if (conn == nullptr) { + native_handle_close(clone); + native_handle_delete(clone); + } else { + // add to list of direct connections + // sensor service should never hold pointer or sp of SensorDirectConnection object. + mDirectConnections.add(wp<SensorDirectConnection>(conn)); + } + return conn; +} + status_t SensorService::resetToNormalMode() { Mutex::Autolock _l(mLock); return resetToNormalModeLocked(); @@ -995,11 +1101,18 @@ void SensorService::cleanupConnection(SensorEventConnection* c) { dev.notifyConnectionDestroyed(c); } +void SensorService::cleanupConnection(SensorDirectConnection* c) { + Mutex::Autolock _l(mLock); + + SensorDevice& dev(SensorDevice::getInstance()); + dev.unregisterDirectChannel(c->getHalChannelHandle()); + mDirectConnections.remove(c); +} + sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { return mSensors.getInterface(handle); } - status_t SensorService::enable(const sp<SensorEventConnection>& connection, int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, const String16& opPackageName) { @@ -1013,7 +1126,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, } Mutex::Autolock _l(mLock); - if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION) + if (mCurrentOperatingMode != NORMAL && !isWhiteListedPackage(connection->getPackageName())) { return INVALID_OPERATION; } @@ -1331,5 +1444,14 @@ bool SensorService::isWhiteListedPackage(const String8& packageName) { return (packageName.contains(mWhiteListedPackage.string())); } +bool SensorService::isOperationRestricted(const String16& opPackageName) { + Mutex::Autolock _l(mLock); + if (mCurrentOperatingMode != RESTRICTED) { + String8 package(opPackageName); + return !isWhiteListedPackage(package); + } + return false; +} + }; // namespace android diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index e969d8a9c0..eeedd4a53a 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -67,9 +67,11 @@ class SensorService : { // nested class/struct for internal use class SensorEventConnection; + class SensorDirectConnection; public: void cleanupConnection(SensorEventConnection* connection); + void cleanupConnection(SensorDirectConnection* c); status_t enable(const sp<SensorEventConnection>& connection, int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, @@ -154,6 +156,8 @@ private: const String8& packageName, int requestedMode, const String16& opPackageName); virtual int isDataInjectionEnabled(); + virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName, + uint32_t size, int32_t type, int32_t format, const native_handle *resource); virtual status_t dump(int fd, const Vector<String16>& args); String8 getSensorName(int handle) const; @@ -203,6 +207,7 @@ private: // allowed to register for or call flush on sensors. Typically only cts test packages are // allowed. bool isWhiteListedPackage(const String8& packageName); + bool isOperationRestricted(const String16& opPackageName); // Reset the state of SensorService to NORMAL mode. status_t resetToNormalMode(); @@ -239,6 +244,7 @@ private: sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; wp<const SensorEventConnection> * mMapFlushEventsToConnections; std::unordered_map<int, RecentEventLogger*> mRecentEvent; + SortedVector< wp<SensorDirectConnection> > mDirectConnections; Mode mCurrentOperatingMode; // This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api index 1023182d6e..93b90d0051 100644 --- a/vulkan/api/vulkan.api +++ b/vulkan/api/vulkan.api @@ -760,7 +760,7 @@ enum VkStructureType { VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID = 1000010001, //@extension("VK_GOOGLE_display_timing") - VK_STRUCTURE_TYPE_PRESENT_TIMES_GOOGLE = 1000092000, + VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, //@extension("VK_EXT_debug_report") VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h index 28c24400b7..5d38ff91b6 100644 --- a/vulkan/include/vulkan/vulkan.h +++ b/vulkan/include/vulkan/vulkan.h @@ -242,7 +242,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003, VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, - VK_STRUCTURE_TYPE_PRESENT_TIMES_GOOGLE = 1000092000, + VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 984016e128..243ea6989c 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -108,15 +108,18 @@ int InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform) { class TimingInfo { public: - TimingInfo() {} - TimingInfo(const VkPresentTimeGOOGLE* qp) { - vals_.presentID = qp->presentID; - vals_.desiredPresentTime = qp->desiredPresentTime; - timestamp_desired_present_time_ = 0; - timestamp_actual_present_time_ = 0; - timestamp_render_complete_time_ = 0; - timestamp_composition_latch_time_ = 0; - } + TimingInfo() + : vals_{0, 0, 0, 0, 0}, + timestamp_desired_present_time_(0), + timestamp_actual_present_time_(0), + timestamp_render_complete_time_(0), + timestamp_composition_latch_time_(0) {} + TimingInfo(const VkPresentTimeGOOGLE* qp) + : vals_{qp->presentID, qp->desiredPresentTime, 0, 0, 0}, + timestamp_desired_present_time_(0), + timestamp_actual_present_time_(0), + timestamp_render_complete_time_(0), + timestamp_composition_latch_time_(0) {} bool ready() { return (timestamp_desired_present_time_ && timestamp_actual_present_time_ && @@ -1113,7 +1116,7 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: present_regions = next; break; - case VK_STRUCTURE_TYPE_PRESENT_TIMES_GOOGLE: + case VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE: present_times = reinterpret_cast<const VkPresentTimesInfoGOOGLE*>(next); break; @@ -1311,9 +1314,14 @@ VkResult GetPastPresentationTimingGOOGLE( VKAPI_ATTR VkResult GetSwapchainStatusKHR( VkDevice, - VkSwapchainKHR) { + VkSwapchainKHR swapchain_handle) { + Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); VkResult result = VK_SUCCESS; + if (swapchain.surface.swapchain_handle != swapchain_handle) { + return VK_ERROR_OUT_OF_DATE_KHR; + } + // TODO(chrisforbes): Implement this function properly return result; |