Loading media/utils/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ cc_library { "libc_malloc_debug_backtrace", ], shared_libs: [ "libaudioutils", // for clock.h "libbinder", "libcutils", "liblog", Loading media/utils/ServiceUtilities.cpp +126 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define LOG_TAG "ServiceUtilities" #include <audio_utils/clock.h> #include <binder/AppOpsManager.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> Loading @@ -24,6 +25,7 @@ #include <iterator> #include <algorithm> #include <pwd.h> /* When performing permission checks we do not use permission cache for * runtime permissions (protection level dangerous) as they may change at Loading Loading @@ -329,4 +331,128 @@ void MediaPackageManager::dump(int fd, int spaces) const { } } // How long we hold info before we re-fetch it (24 hours) if we found it previously. static constexpr nsecs_t INFO_EXPIRATION_NS = 24 * 60 * 60 * NANOS_PER_SECOND; // Maximum info records we retain before clearing everything. static constexpr size_t INFO_CACHE_MAX = 1000; // The original code is from MediaMetricsService.cpp. mediautils::UidInfo::Info mediautils::UidInfo::getInfo(uid_t uid) { const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); struct mediautils::UidInfo::Info info; { std::lock_guard _l(mLock); auto it = mInfoMap.find(uid); if (it != mInfoMap.end()) { info = it->second; ALOGV("%s: uid %d expiration %lld now %lld", __func__, uid, (long long)info.expirationNs, (long long)now); if (info.expirationNs <= now) { // purge the stale entry and fall into re-fetching ALOGV("%s: entry for uid %d expired, now %lld", __func__, uid, (long long)now); mInfoMap.erase(it); info.uid = (uid_t)-1; // this is always fully overwritten } } } // if we did not find it in our map, look it up if (info.uid == (uid_t)(-1)) { sp<IServiceManager> sm = defaultServiceManager(); sp<content::pm::IPackageManagerNative> package_mgr; if (sm.get() == nullptr) { ALOGE("%s: Cannot find service manager", __func__); } else { sp<IBinder> binder = sm->getService(String16("package_native")); if (binder.get() == nullptr) { ALOGE("%s: Cannot find package_native", __func__); } else { package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder); } } // find package name std::string pkg; if (package_mgr != nullptr) { std::vector<std::string> names; binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names); if (!status.isOk()) { ALOGE("%s: getNamesForUids failed: %s", __func__, status.exceptionMessage().c_str()); } else { if (!names[0].empty()) { pkg = names[0].c_str(); } } } if (pkg.empty()) { struct passwd pw{}, *result; char buf[8192]; // extra buffer space - should exceed what is // required in struct passwd_pw (tested), // and even then this is only used in backup // when the package manager is unavailable. if (getpwuid_r(uid, &pw, buf, sizeof(buf), &result) == 0 && result != nullptr && result->pw_name != nullptr) { pkg = result->pw_name; } } // strip any leading "shared:" strings that came back if (pkg.compare(0, 7, "shared:") == 0) { pkg.erase(0, 7); } // determine how pkg was installed and the versionCode std::string installer; int64_t versionCode = 0; bool notFound = false; if (pkg.empty()) { pkg = std::to_string(uid); // not found notFound = true; } else if (strchr(pkg.c_str(), '.') == nullptr) { // not of form 'com.whatever...'; assume internal // so we don't need to look it up in package manager. } else if (package_mgr.get() != nullptr) { String16 pkgName16(pkg.c_str()); binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer); if (!status.isOk()) { ALOGE("%s: getInstallerForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } // skip if we didn't get an installer if (status.isOk()) { status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode); if (!status.isOk()) { ALOGE("%s: getVersionCodeForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } } ALOGV("%s: package '%s' installed by '%s' versioncode %lld", __func__, pkg.c_str(), installer.c_str(), (long long)versionCode); } // add it to the map, to save a subsequent lookup std::lock_guard _l(mLock); // first clear if we have too many cached elements. This would be rare. if (mInfoMap.size() >= INFO_CACHE_MAX) mInfoMap.clear(); // always overwrite info.uid = uid; info.package = std::move(pkg); info.installer = std::move(installer); info.versionCode = versionCode; info.expirationNs = now + (notFound ? 0 : INFO_EXPIRATION_NS); ALOGV("%s: adding uid %d package '%s' expirationNs: %lld", __func__, uid, info.package.c_str(), (long long)info.expirationNs); mInfoMap[uid] = info; } return info; } } // namespace android media/utils/include/mediautils/ServiceUtilities.h +36 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <map> #include <optional> #include <string> #include <unordered_map> #include <vector> namespace android { Loading Loading @@ -118,6 +119,40 @@ private: using Packages = std::vector<Package>; std::map<uid_t, Packages> mDebugLog; }; } namespace mediautils { /** * This class is used to retrieve (and cache) package information * for a given uid. */ class UidInfo { public: struct Info { uid_t uid = -1; // uid used for lookup. std::string package; // package name. std::string installer; // installer for the package (e.g. preload, play store). int64_t versionCode = 0; // reported version code. int64_t expirationNs = 0; // after this time in SYSTEM_TIME_REALTIME we refetch. }; /** * Returns the package information for a UID. * * The package name will be the uid if we cannot find the associated name. * * \param uid is the uid of the app or service. */ Info getInfo(uid_t uid); private: std::mutex mLock; // TODO: use concurrent hashmap with striped lock. std::unordered_map<uid_t, Info> mInfoMap; // GUARDED_BY(mLock) }; } // namespace mediautils } // namespace android #endif // ANDROID_MEDIAUTILS_SERVICEUTILITIES_H services/mediametrics/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ cc_binary { "libbinder", "liblog", "libmediametricsservice", "libmediautils", "libutils", ], Loading Loading @@ -52,6 +53,7 @@ cc_library_shared { "libbinder", "liblog", "libmediametrics", "libmediautils", "libprotobuf-cpp-lite", "libstatslog", "libutils", Loading services/mediametrics/MediaMetricsService.cpp +32 −154 Original line number Diff line number Diff line Loading @@ -57,6 +57,25 @@ nsecs_t MediaMetricsService::roundTime(nsecs_t timeNs) return (timeNs + NANOS_PER_SECOND / 2) / NANOS_PER_SECOND * NANOS_PER_SECOND; } /* static */ bool MediaMetricsService::useUidForPackage( const std::string& package, const std::string& installer) { if (strchr(package.c_str(), '.') == NULL) { return false; // not of form 'com.whatever...'; assume internal and ok } else if (strncmp(package.c_str(), "android.", 8) == 0) { return false; // android.* packages are assumed fine } else if (strncmp(installer.c_str(), "com.android.", 12) == 0) { return false; // from play store } else if (strncmp(installer.c_str(), "com.google.", 11) == 0) { return false; // some google source } else if (strcmp(installer.c_str(), "preload") == 0) { return false; // preloads } else { return true; // we're not sure where it came from, use uid only. } } MediaMetricsService::MediaMetricsService() : mMaxRecords(kMaxRecords), mMaxRecordAgeNs(kMaxRecordAgeNs), Loading Loading @@ -112,14 +131,19 @@ status_t MediaMetricsService::submitInternal(mediametrics::Item *item, bool rele break; } // Overwrite package name and version if the caller was untrusted. if (!isTrusted) { mUidInfo.setPkgInfo(item, item->getUid(), true, true); } else if (item->getPkgName().empty()) { // empty, so fill out both parts mUidInfo.setPkgInfo(item, item->getUid(), true, true); // Overwrite package name and version if the caller was untrusted or empty if (!isTrusted || item->getPkgName().empty()) { const uid_t uid = item->getUid(); mediautils::UidInfo::Info info = mUidInfo.getInfo(uid); if (useUidForPackage(info.package, info.installer)) { // remove uid information of unknown installed packages. // TODO: perhaps this can be done just before uploading to Westworld. item->setPkgName(std::to_string(uid)); item->setPkgVersionCode(0); } else { // trusted, provided a package, do nothing item->setPkgName(info.package); item->setPkgVersionCode(info.versionCode); } } ALOGV("%s: given uid %d; sanitized uid: %d sanitized pkg: %s " Loading Loading @@ -450,150 +474,4 @@ bool MediaMetricsService::isRateLimited(mediametrics::Item *) const return false; } // How long we hold package info before we re-fetch it constexpr nsecs_t PKG_EXPIRATION_NS = 30 * 60 * NANOS_PER_SECOND; // 30 minutes // give me the package name, perhaps going to find it // manages its own mutex operations internally void MediaMetricsService::UidInfo::setPkgInfo( mediametrics::Item *item, uid_t uid, bool setName, bool setVersion) { ALOGV("%s: uid=%d", __func__, uid); if (!setName && !setVersion) { return; // setting nothing? strange } const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); struct UidToPkgInfo mapping; { std::lock_guard _l(mUidInfoLock); auto it = mPkgMappings.find(uid); if (it != mPkgMappings.end()) { mapping = it->second; ALOGV("%s: uid %d expiration %lld now %lld", __func__, uid, (long long)mapping.expiration, (long long)now); if (mapping.expiration <= now) { // purge the stale entry and fall into re-fetching ALOGV("%s: entry for uid %d expired, now %lld", __func__, uid, (long long)now); mPkgMappings.erase(it); mapping.uid = (uid_t)-1; // this is always fully overwritten } } } // if we did not find it if (mapping.uid == (uid_t)(-1)) { std::string pkg; std::string installer; int64_t versionCode = 0; const struct passwd *pw = getpwuid(uid); if (pw) { pkg = pw->pw_name; } sp<IServiceManager> sm = defaultServiceManager(); sp<content::pm::IPackageManagerNative> package_mgr; if (sm.get() == nullptr) { ALOGE("%s: Cannot find service manager", __func__); } else { sp<IBinder> binder = sm->getService(String16("package_native")); if (binder.get() == nullptr) { ALOGE("%s: Cannot find package_native", __func__); } else { package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder); } } if (package_mgr != nullptr) { std::vector<int> uids; std::vector<std::string> names; uids.push_back(uid); binder::Status status = package_mgr->getNamesForUids(uids, &names); if (!status.isOk()) { ALOGE("%s: getNamesForUids failed: %s", __func__, status.exceptionMessage().c_str()); } else { if (!names[0].empty()) { pkg = names[0].c_str(); } } } // strip any leading "shared:" strings that came back if (pkg.compare(0, 7, "shared:") == 0) { pkg.erase(0, 7); } // determine how pkg was installed and the versionCode if (pkg.empty()) { pkg = std::to_string(uid); // no name for us to manage } else if (strchr(pkg.c_str(), '.') == NULL) { // not of form 'com.whatever...'; assume internal and ok } else if (strncmp(pkg.c_str(), "android.", 8) == 0) { // android.* packages are assumed fine } else if (package_mgr.get() != nullptr) { String16 pkgName16(pkg.c_str()); binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer); if (!status.isOk()) { ALOGE("%s: getInstallerForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } // skip if we didn't get an installer if (status.isOk()) { status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode); if (!status.isOk()) { ALOGE("%s: getVersionCodeForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } } ALOGV("%s: package '%s' installed by '%s' versioncode %lld", __func__, pkg.c_str(), installer.c_str(), (long long)versionCode); if (strncmp(installer.c_str(), "com.android.", 12) == 0) { // from play store, we keep info } else if (strncmp(installer.c_str(), "com.google.", 11) == 0) { // some google source, we keep info } else if (strcmp(installer.c_str(), "preload") == 0) { // preloads, we keep the info } else if (installer.c_str()[0] == '\0') { // sideload (no installer); report UID only pkg = std::to_string(uid); versionCode = 0; } else { // unknown installer; report UID only pkg = std::to_string(uid); versionCode = 0; } } else { // unvalidated by package_mgr just send uid. pkg = std::to_string(uid); } // add it to the map, to save a subsequent lookup std::lock_guard _l(mUidInfoLock); // always overwrite mapping.uid = uid; mapping.pkg = std::move(pkg); mapping.installer = std::move(installer); mapping.versionCode = versionCode; mapping.expiration = now + PKG_EXPIRATION_NS; ALOGV("%s: adding uid %d pkg '%s' expiration: %lld", __func__, uid, mapping.pkg.c_str(), (long long)mapping.expiration); mPkgMappings[uid] = mapping; } if (mapping.uid != (uid_t)(-1)) { if (setName) { item->setPkgName(mapping.pkg); } if (setVersion) { item->setPkgVersionCode(mapping.versionCode); } } } } // namespace android Loading
media/utils/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ cc_library { "libc_malloc_debug_backtrace", ], shared_libs: [ "libaudioutils", // for clock.h "libbinder", "libcutils", "liblog", Loading
media/utils/ServiceUtilities.cpp +126 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define LOG_TAG "ServiceUtilities" #include <audio_utils/clock.h> #include <binder/AppOpsManager.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> Loading @@ -24,6 +25,7 @@ #include <iterator> #include <algorithm> #include <pwd.h> /* When performing permission checks we do not use permission cache for * runtime permissions (protection level dangerous) as they may change at Loading Loading @@ -329,4 +331,128 @@ void MediaPackageManager::dump(int fd, int spaces) const { } } // How long we hold info before we re-fetch it (24 hours) if we found it previously. static constexpr nsecs_t INFO_EXPIRATION_NS = 24 * 60 * 60 * NANOS_PER_SECOND; // Maximum info records we retain before clearing everything. static constexpr size_t INFO_CACHE_MAX = 1000; // The original code is from MediaMetricsService.cpp. mediautils::UidInfo::Info mediautils::UidInfo::getInfo(uid_t uid) { const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); struct mediautils::UidInfo::Info info; { std::lock_guard _l(mLock); auto it = mInfoMap.find(uid); if (it != mInfoMap.end()) { info = it->second; ALOGV("%s: uid %d expiration %lld now %lld", __func__, uid, (long long)info.expirationNs, (long long)now); if (info.expirationNs <= now) { // purge the stale entry and fall into re-fetching ALOGV("%s: entry for uid %d expired, now %lld", __func__, uid, (long long)now); mInfoMap.erase(it); info.uid = (uid_t)-1; // this is always fully overwritten } } } // if we did not find it in our map, look it up if (info.uid == (uid_t)(-1)) { sp<IServiceManager> sm = defaultServiceManager(); sp<content::pm::IPackageManagerNative> package_mgr; if (sm.get() == nullptr) { ALOGE("%s: Cannot find service manager", __func__); } else { sp<IBinder> binder = sm->getService(String16("package_native")); if (binder.get() == nullptr) { ALOGE("%s: Cannot find package_native", __func__); } else { package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder); } } // find package name std::string pkg; if (package_mgr != nullptr) { std::vector<std::string> names; binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names); if (!status.isOk()) { ALOGE("%s: getNamesForUids failed: %s", __func__, status.exceptionMessage().c_str()); } else { if (!names[0].empty()) { pkg = names[0].c_str(); } } } if (pkg.empty()) { struct passwd pw{}, *result; char buf[8192]; // extra buffer space - should exceed what is // required in struct passwd_pw (tested), // and even then this is only used in backup // when the package manager is unavailable. if (getpwuid_r(uid, &pw, buf, sizeof(buf), &result) == 0 && result != nullptr && result->pw_name != nullptr) { pkg = result->pw_name; } } // strip any leading "shared:" strings that came back if (pkg.compare(0, 7, "shared:") == 0) { pkg.erase(0, 7); } // determine how pkg was installed and the versionCode std::string installer; int64_t versionCode = 0; bool notFound = false; if (pkg.empty()) { pkg = std::to_string(uid); // not found notFound = true; } else if (strchr(pkg.c_str(), '.') == nullptr) { // not of form 'com.whatever...'; assume internal // so we don't need to look it up in package manager. } else if (package_mgr.get() != nullptr) { String16 pkgName16(pkg.c_str()); binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer); if (!status.isOk()) { ALOGE("%s: getInstallerForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } // skip if we didn't get an installer if (status.isOk()) { status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode); if (!status.isOk()) { ALOGE("%s: getVersionCodeForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } } ALOGV("%s: package '%s' installed by '%s' versioncode %lld", __func__, pkg.c_str(), installer.c_str(), (long long)versionCode); } // add it to the map, to save a subsequent lookup std::lock_guard _l(mLock); // first clear if we have too many cached elements. This would be rare. if (mInfoMap.size() >= INFO_CACHE_MAX) mInfoMap.clear(); // always overwrite info.uid = uid; info.package = std::move(pkg); info.installer = std::move(installer); info.versionCode = versionCode; info.expirationNs = now + (notFound ? 0 : INFO_EXPIRATION_NS); ALOGV("%s: adding uid %d package '%s' expirationNs: %lld", __func__, uid, info.package.c_str(), (long long)info.expirationNs); mInfoMap[uid] = info; } return info; } } // namespace android
media/utils/include/mediautils/ServiceUtilities.h +36 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <map> #include <optional> #include <string> #include <unordered_map> #include <vector> namespace android { Loading Loading @@ -118,6 +119,40 @@ private: using Packages = std::vector<Package>; std::map<uid_t, Packages> mDebugLog; }; } namespace mediautils { /** * This class is used to retrieve (and cache) package information * for a given uid. */ class UidInfo { public: struct Info { uid_t uid = -1; // uid used for lookup. std::string package; // package name. std::string installer; // installer for the package (e.g. preload, play store). int64_t versionCode = 0; // reported version code. int64_t expirationNs = 0; // after this time in SYSTEM_TIME_REALTIME we refetch. }; /** * Returns the package information for a UID. * * The package name will be the uid if we cannot find the associated name. * * \param uid is the uid of the app or service. */ Info getInfo(uid_t uid); private: std::mutex mLock; // TODO: use concurrent hashmap with striped lock. std::unordered_map<uid_t, Info> mInfoMap; // GUARDED_BY(mLock) }; } // namespace mediautils } // namespace android #endif // ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
services/mediametrics/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ cc_binary { "libbinder", "liblog", "libmediametricsservice", "libmediautils", "libutils", ], Loading Loading @@ -52,6 +53,7 @@ cc_library_shared { "libbinder", "liblog", "libmediametrics", "libmediautils", "libprotobuf-cpp-lite", "libstatslog", "libutils", Loading
services/mediametrics/MediaMetricsService.cpp +32 −154 Original line number Diff line number Diff line Loading @@ -57,6 +57,25 @@ nsecs_t MediaMetricsService::roundTime(nsecs_t timeNs) return (timeNs + NANOS_PER_SECOND / 2) / NANOS_PER_SECOND * NANOS_PER_SECOND; } /* static */ bool MediaMetricsService::useUidForPackage( const std::string& package, const std::string& installer) { if (strchr(package.c_str(), '.') == NULL) { return false; // not of form 'com.whatever...'; assume internal and ok } else if (strncmp(package.c_str(), "android.", 8) == 0) { return false; // android.* packages are assumed fine } else if (strncmp(installer.c_str(), "com.android.", 12) == 0) { return false; // from play store } else if (strncmp(installer.c_str(), "com.google.", 11) == 0) { return false; // some google source } else if (strcmp(installer.c_str(), "preload") == 0) { return false; // preloads } else { return true; // we're not sure where it came from, use uid only. } } MediaMetricsService::MediaMetricsService() : mMaxRecords(kMaxRecords), mMaxRecordAgeNs(kMaxRecordAgeNs), Loading Loading @@ -112,14 +131,19 @@ status_t MediaMetricsService::submitInternal(mediametrics::Item *item, bool rele break; } // Overwrite package name and version if the caller was untrusted. if (!isTrusted) { mUidInfo.setPkgInfo(item, item->getUid(), true, true); } else if (item->getPkgName().empty()) { // empty, so fill out both parts mUidInfo.setPkgInfo(item, item->getUid(), true, true); // Overwrite package name and version if the caller was untrusted or empty if (!isTrusted || item->getPkgName().empty()) { const uid_t uid = item->getUid(); mediautils::UidInfo::Info info = mUidInfo.getInfo(uid); if (useUidForPackage(info.package, info.installer)) { // remove uid information of unknown installed packages. // TODO: perhaps this can be done just before uploading to Westworld. item->setPkgName(std::to_string(uid)); item->setPkgVersionCode(0); } else { // trusted, provided a package, do nothing item->setPkgName(info.package); item->setPkgVersionCode(info.versionCode); } } ALOGV("%s: given uid %d; sanitized uid: %d sanitized pkg: %s " Loading Loading @@ -450,150 +474,4 @@ bool MediaMetricsService::isRateLimited(mediametrics::Item *) const return false; } // How long we hold package info before we re-fetch it constexpr nsecs_t PKG_EXPIRATION_NS = 30 * 60 * NANOS_PER_SECOND; // 30 minutes // give me the package name, perhaps going to find it // manages its own mutex operations internally void MediaMetricsService::UidInfo::setPkgInfo( mediametrics::Item *item, uid_t uid, bool setName, bool setVersion) { ALOGV("%s: uid=%d", __func__, uid); if (!setName && !setVersion) { return; // setting nothing? strange } const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); struct UidToPkgInfo mapping; { std::lock_guard _l(mUidInfoLock); auto it = mPkgMappings.find(uid); if (it != mPkgMappings.end()) { mapping = it->second; ALOGV("%s: uid %d expiration %lld now %lld", __func__, uid, (long long)mapping.expiration, (long long)now); if (mapping.expiration <= now) { // purge the stale entry and fall into re-fetching ALOGV("%s: entry for uid %d expired, now %lld", __func__, uid, (long long)now); mPkgMappings.erase(it); mapping.uid = (uid_t)-1; // this is always fully overwritten } } } // if we did not find it if (mapping.uid == (uid_t)(-1)) { std::string pkg; std::string installer; int64_t versionCode = 0; const struct passwd *pw = getpwuid(uid); if (pw) { pkg = pw->pw_name; } sp<IServiceManager> sm = defaultServiceManager(); sp<content::pm::IPackageManagerNative> package_mgr; if (sm.get() == nullptr) { ALOGE("%s: Cannot find service manager", __func__); } else { sp<IBinder> binder = sm->getService(String16("package_native")); if (binder.get() == nullptr) { ALOGE("%s: Cannot find package_native", __func__); } else { package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder); } } if (package_mgr != nullptr) { std::vector<int> uids; std::vector<std::string> names; uids.push_back(uid); binder::Status status = package_mgr->getNamesForUids(uids, &names); if (!status.isOk()) { ALOGE("%s: getNamesForUids failed: %s", __func__, status.exceptionMessage().c_str()); } else { if (!names[0].empty()) { pkg = names[0].c_str(); } } } // strip any leading "shared:" strings that came back if (pkg.compare(0, 7, "shared:") == 0) { pkg.erase(0, 7); } // determine how pkg was installed and the versionCode if (pkg.empty()) { pkg = std::to_string(uid); // no name for us to manage } else if (strchr(pkg.c_str(), '.') == NULL) { // not of form 'com.whatever...'; assume internal and ok } else if (strncmp(pkg.c_str(), "android.", 8) == 0) { // android.* packages are assumed fine } else if (package_mgr.get() != nullptr) { String16 pkgName16(pkg.c_str()); binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer); if (!status.isOk()) { ALOGE("%s: getInstallerForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } // skip if we didn't get an installer if (status.isOk()) { status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode); if (!status.isOk()) { ALOGE("%s: getVersionCodeForPackage failed: %s", __func__, status.exceptionMessage().c_str()); } } ALOGV("%s: package '%s' installed by '%s' versioncode %lld", __func__, pkg.c_str(), installer.c_str(), (long long)versionCode); if (strncmp(installer.c_str(), "com.android.", 12) == 0) { // from play store, we keep info } else if (strncmp(installer.c_str(), "com.google.", 11) == 0) { // some google source, we keep info } else if (strcmp(installer.c_str(), "preload") == 0) { // preloads, we keep the info } else if (installer.c_str()[0] == '\0') { // sideload (no installer); report UID only pkg = std::to_string(uid); versionCode = 0; } else { // unknown installer; report UID only pkg = std::to_string(uid); versionCode = 0; } } else { // unvalidated by package_mgr just send uid. pkg = std::to_string(uid); } // add it to the map, to save a subsequent lookup std::lock_guard _l(mUidInfoLock); // always overwrite mapping.uid = uid; mapping.pkg = std::move(pkg); mapping.installer = std::move(installer); mapping.versionCode = versionCode; mapping.expiration = now + PKG_EXPIRATION_NS; ALOGV("%s: adding uid %d pkg '%s' expiration: %lld", __func__, uid, mapping.pkg.c_str(), (long long)mapping.expiration); mPkgMappings[uid] = mapping; } if (mapping.uid != (uid_t)(-1)) { if (setName) { item->setPkgName(mapping.pkg); } if (setVersion) { item->setPkgVersionCode(mapping.versionCode); } } } } // namespace android