Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17b7fa70 authored by Ray Essick's avatar Ray Essick Committed by Android (Google) Code Review
Browse files

Merge "trim packagename if sideloaded, get versioncode" into oc-mr1-dev

parents b45ee924 fa149560
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,7 @@ const int MediaAnalyticsItem::EnabledProperty_default = 1;
MediaAnalyticsItem::MediaAnalyticsItem()
MediaAnalyticsItem::MediaAnalyticsItem()
    : mPid(-1),
    : mPid(-1),
      mUid(-1),
      mUid(-1),
      mPkgVersionCode(0),
      mSessionID(MediaAnalyticsItem::SessionIDNone),
      mSessionID(MediaAnalyticsItem::SessionIDNone),
      mTimestamp(0),
      mTimestamp(0),
      mFinalized(0),
      mFinalized(0),
@@ -70,6 +71,7 @@ MediaAnalyticsItem::MediaAnalyticsItem()
MediaAnalyticsItem::MediaAnalyticsItem(MediaAnalyticsItem::Key key)
MediaAnalyticsItem::MediaAnalyticsItem(MediaAnalyticsItem::Key key)
    : mPid(-1),
    : mPid(-1),
      mUid(-1),
      mUid(-1),
      mPkgVersionCode(0),
      mSessionID(MediaAnalyticsItem::SessionIDNone),
      mSessionID(MediaAnalyticsItem::SessionIDNone),
      mTimestamp(0),
      mTimestamp(0),
      mFinalized(0),
      mFinalized(0),
+134 −63
Original line number Original line Diff line number Diff line
@@ -257,14 +257,15 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
            break;
            break;
    }
    }



    // Overwrite package name and version if the caller was untrusted.
    // Overwrite package name and version if the caller was untrusted.
    if (!isTrusted) {
    if (!isTrusted) {
      item->setPkgName(getPkgName(item->getUid(), true));
      setPkgInfo(item, item->getUid(), true, true);
      item->setPkgVersionCode(0);
    } else if (item->getPkgName().empty()) {
    } else if (item->getPkgName().empty()) {
      // Only overwrite the package name if it was empty. Trust whatever
      // empty, so fill out both parts
      // version code was provided by the trusted caller.
      setPkgInfo(item, item->getUid(), true, true);
      item->setPkgName(getPkgName(uid, true));
    } else {
      // trusted, provided a package, do nothing
    }
    }


    ALOGV("given uid %d; sanitized uid: %d sanitized pkg: %s "
    ALOGV("given uid %d; sanitized uid: %d sanitized pkg: %s "
@@ -800,31 +801,46 @@ void MediaAnalyticsService::summarize(MediaAnalyticsItem *item) {


}
}


// mapping uids to package names
// how long we hold package info before we re-fetch it
#define PKG_EXPIRATION_NS (30*60*1000000000ll)   // 30 minutes, in nsecs


// give me the package name, perhaps going to find it
// give me the package name, perhaps going to find it
AString MediaAnalyticsService::getPkgName(uid_t uid, bool addIfMissing) {
void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion) {
    ssize_t i = mPkgMappings.indexOfKey(uid);
    ALOGV("asking for packagename to go with uid=%d", uid);
    if (i >= 0) {

        AString pkg = mPkgMappings.valueAt(i);
    if (!setName && !setVersion) {
        ALOGV("returning pkg '%s' for uid %d", pkg.c_str(), uid);
        // setting nothing? strange
        return pkg;
        return;
    }
    }


    AString pkg;
    nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
    struct UidToPkgMap mapping;
    mapping.uid = (-1);


    if (addIfMissing == false) {
    ssize_t i = mPkgMappings.indexOfKey(uid);
        return pkg;
    if (i >= 0) {
        mapping = mPkgMappings.valueAt(i);
        ALOGV("Expiration? uid %d expiration %" PRId64 " now %" PRId64,
              uid, mapping.expiration, now);
        if (mapping.expiration < now) {
            // purge our current entry and re-query
            ALOGV("entry for uid %d expired, now= %" PRId64 "", uid, now);
            mPkgMappings.removeItemsAt(i, 1);
            // could cheat and use a goto back to the top of the routine.
            // a good compiler should recognize the local tail recursion...
            return setPkgInfo(item, uid, setName, setVersion);
        }
        }
    } else {
        AString pkg;
        std::string installer = "";
        int32_t versionCode = 0;


        struct passwd *pw = getpwuid(uid);
        struct passwd *pw = getpwuid(uid);
        if (pw) {
        if (pw) {
            pkg = pw->pw_name;
            pkg = pw->pw_name;
    } else {
        pkg = "-";
        }
        }


    // find the proper value
        // find the proper value -- should we cache this binder??


        sp<IBinder> binder = NULL;
        sp<IBinder> binder = NULL;
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IServiceManager> sm = defaultServiceManager();
@@ -839,13 +855,14 @@ AString MediaAnalyticsService::getPkgName(uid_t uid, bool addIfMissing) {


        if (binder != NULL) {
        if (binder != NULL) {
            sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
            sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
            binder::Status status;


            std::vector<int> uids;
            std::vector<int> uids;
            std::vector<std::string> names;
            std::vector<std::string> names;


            uids.push_back(uid);
            uids.push_back(uid);


        binder::Status status = package_mgr->getNamesForUids(uids, &names);
            status = package_mgr->getNamesForUids(uids, &names);
            if (!status.isOk()) {
            if (!status.isOk()) {
                ALOGE("package_native::getNamesForUids failed: %s",
                ALOGE("package_native::getNamesForUids failed: %s",
                      status.exceptionMessage().c_str());
                      status.exceptionMessage().c_str());
@@ -854,31 +871,85 @@ AString MediaAnalyticsService::getPkgName(uid_t uid, bool addIfMissing) {
                    pkg = names[0].c_str();
                    pkg = names[0].c_str();
                }
                }
            }
            }

            // strip any leading "shared:" strings that came back
            if (pkg.startsWith("shared:")) {
                pkg.erase(0, 7);
            }

            // determine how pkg was installed and the versionCode
            //
            if (pkg.empty()) {
                // 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 {
                String16 pkgName16(pkg.c_str());
                status = package_mgr->getInstallerForPackage(pkgName16, &installer);
                if (!status.isOk()) {
                    ALOGE("package_native::getInstallerForPackage failed: %s",
                          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("package_native::getVersionCodeForPackage failed: %s",
                          status.exceptionMessage().c_str());
                    }
                }
                }


    // XXX determine whether package was side-loaded or from playstore.
    // for privacy, we only list apps loaded from playstore.


    // Sanitize the package name for ":"
                ALOGV("package '%s' installed by '%s' versioncode %d / %08x",
    // as an example, we get "shared:android.uid.systemui"
                      pkg.c_str(), installer.c_str(), versionCode, versionCode);
    // replace : with something benign (I'm going to use !)

    if (!pkg.empty()) {
                if (strncmp(installer.c_str(), "com.android.", 12) == 0) {
        int n = pkg.size();
                        // from play store, we keep info
        char *p = (char *) pkg.c_str();
                } else if (strncmp(installer.c_str(), "com.google.", 11) == 0) {
        for (int i = 0 ; i < n; i++) {
                        // some google source, we keep info
            if (p[i] == ':') {
                } else if (strcmp(installer.c_str(), "preload") == 0) {
                p[i] = '!';
                        // preloads, we keep the info
                } else if (installer.c_str()[0] == '\0') {
                        // sideload (no installer); do not report
                        pkg = "";
                        versionCode = 0;
                } else {
                        // unknown installer; do not report
                        pkg = "";
                        versionCode = 0;
                }
                }
            }
            }
        }
        }


        // add it to the map, to save a subsequent lookup
        // add it to the map, to save a subsequent lookup
        if (!pkg.empty()) {
        if (!pkg.empty()) {
            Mutex::Autolock _l(mLock_mappings);
            ALOGV("Adding uid %d pkg '%s'", uid, pkg.c_str());
            ALOGV("Adding uid %d pkg '%s'", uid, pkg.c_str());
        mPkgMappings.add(uid, pkg);
            ssize_t i = mPkgMappings.indexOfKey(uid);
            if (i < 0) {
                mapping.uid = uid;
                mapping.pkg = pkg;
                mapping.installer = installer.c_str();
                mapping.versionCode = versionCode;
                mapping.expiration = now + PKG_EXPIRATION_NS;
                ALOGV("expiration for uid %d set to %" PRId64 "", uid, mapping.expiration);

                mPkgMappings.add(uid, mapping);
            }
        }
    }
    }


    return pkg;
    if (mapping.uid != (uid_t)(-1)) {
        if (setName) {
            item->setPkgName(mapping.pkg);
        }
        if (setVersion) {
            item->setPkgVersionCode(mapping.versionCode);
        }
    }
}
}


} // namespace android
} // namespace android
+6 −2
Original line number Original line Diff line number Diff line
@@ -62,6 +62,7 @@ class MediaAnalyticsService : public BnMediaAnalyticsService
    // partitioned a bit so we don't over serialize
    // partitioned a bit so we don't over serialize
    mutable Mutex           mLock;
    mutable Mutex           mLock;
    mutable Mutex           mLock_ids;
    mutable Mutex           mLock_ids;
    mutable Mutex           mLock_mappings;


    // limit how many records we'll retain
    // limit how many records we'll retain
    // by count (in each queue (open, finalized))
    // by count (in each queue (open, finalized))
@@ -135,10 +136,13 @@ class MediaAnalyticsService : public BnMediaAnalyticsService
    struct UidToPkgMap {
    struct UidToPkgMap {
        uid_t uid;
        uid_t uid;
        AString pkg;
        AString pkg;
        AString installer;
        int32_t versionCode;
        nsecs_t expiration;
    };
    };


    KeyedVector<uid_t,AString>  mPkgMappings;
    KeyedVector<uid_t,struct UidToPkgMap>  mPkgMappings;
    AString getPkgName(uid_t uid, bool addIfMissing);
    void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);


};
};