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

Commit f030c7e3 authored by Anna Trostanetski's avatar Anna Trostanetski Committed by Android (Google) Code Review
Browse files

Merge "Reset app reporting on app launch."

parents 20990ad6 8e437d45
Loading
Loading
Loading
Loading
+33 −11
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ import android.util.StatsLog;

import com.android.internal.annotations.GuardedBy;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@@ -36,12 +38,10 @@ public final class ChangeReporter {
    private int mSource;

    private final class ChangeReport {
        int mUid;
        long mChangeId;
        int mState;

        ChangeReport(int uid, long changeId, int state) {
            mUid = uid;
        ChangeReport(long changeId, int state) {
            mChangeId = changeId;
            mState = state;
        }
@@ -51,41 +51,63 @@ public final class ChangeReporter {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            ChangeReport that = (ChangeReport) o;
            return mUid == that.mUid
                    && mChangeId == that.mChangeId
            return mChangeId == that.mChangeId
                    && mState == that.mState;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mUid, mChangeId, mState);
            return Objects.hash(mChangeId, mState);
        }
    }

    // Maps uid to a set of ChangeReports (that were reported for that uid).
    @GuardedBy("mReportedChanges")
    private Set<ChangeReport> mReportedChanges =  new HashSet<>();
    private final Map<Integer, Set<ChangeReport>> mReportedChanges;

    public ChangeReporter(int source) {
        mSource = source;
        mReportedChanges =  new HashMap<>();
    }

    /**
     * Report the change to stats log.
     * Report the change to stats log and to the debug log if the change was not previously
     * logged already.
     *
     * @param uid      affected by the change
     * @param changeId the reported change id
     * @param state    of the reported change - enabled/disabled/only logged
     */
    public void reportChange(int uid, long changeId, int state) {
        ChangeReport report = new ChangeReport(uid, changeId, state);
        ChangeReport report = new ChangeReport(changeId, state);
        synchronized (mReportedChanges) {
            if (!mReportedChanges.contains(report)) {
            Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid);
            if (reportedChangesForUid == null) {
                mReportedChanges.put(uid, new HashSet<ChangeReport>());
                reportedChangesForUid = mReportedChanges.get(uid);
            }
            if (!reportedChangesForUid.contains(report)) {
                debugLog(uid, changeId, state);
                StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId,
                        state, mSource);
                mReportedChanges.add(report);
                reportedChangesForUid.add(report);
            }

        }
    }

    /**
     * Clears the saved information about a given uid. Requests to report uid again will be reported
     * regardless to the past reports.
     *
     * <p> Only intended to be called from PlatformCompat.
     *
     * @param uid to reset
     */
    public void resetReportedChanges(int uid) {
        synchronized (mReportedChanges) {
            mReportedChanges.remove(uid);
        }
    }

    private void debugLog(int uid, long changeId, int state) {
+10 −0
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
import com.android.server.appop.AppOpsService;
import com.android.server.compat.CompatConfig;
import com.android.server.compat.PlatformCompat;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.firewall.IntentFirewall;
import com.android.server.job.JobSchedulerInternal;
@@ -1575,6 +1576,8 @@ public class ActivityManagerService extends IActivityManager.Stub
    // Encapsulates the global setting "hidden_api_blacklist_exemptions"
    final HiddenApiSettings mHiddenApiBlacklist;
    private final PlatformCompat mPlatformCompat;
    PackageManagerInternal mPackageManagerInt;
    PermissionManagerServiceInternal mPermissionManagerInt;
@@ -2427,6 +2430,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mFactoryTest = FACTORY_TEST_OFF;
        mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
        mInternal = new LocalService();
        mPlatformCompat = null;
    }
    // Note: This method is invoked on the main thread but may need to attach various
@@ -2563,6 +2567,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
        mPlatformCompat = (PlatformCompat) ServiceManager.getService(
                Context.PLATFORM_COMPAT_SERVICE);
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
@@ -5044,6 +5051,9 @@ public class ActivityManagerService extends IActivityManager.Stub
            mAtmInternal.preBindApplication(app.getWindowProcessController());
            final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
            long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info);
            if (mPlatformCompat != null) {
                mPlatformCompat.resetReporting(app.info);
            }
            if (app.isolatedEntryPoint != null) {
                // This is an isolated process which should just call an entry point instead of
                // being bound to an application.
+9 −0
Original line number Diff line number Diff line
@@ -105,6 +105,15 @@ public class PlatformCompat extends IPlatformCompat.Stub {
        CompatConfig.get().dumpConfig(pw);
    }

    /**
     * Clears information stored about events reported on behalf of an app.
     * To be called once upon app start or end. A second call would be a no-op.
     * @param appInfo the app to reset
     */
    public void resetReporting(ApplicationInfo appInfo) {
        mChangeReporter.resetReportedChanges(appInfo.uid);
    }

    private ApplicationInfo getApplicationInfo(String packageName) {
        try {
            return mContext.getPackageManager().getApplicationInfo(packageName, 0);