Loading core/java/com/android/internal/compat/ChangeReporter.java +33 −11 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading @@ -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) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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. Loading services/core/java/com/android/server/compat/PlatformCompat.java +9 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
core/java/com/android/internal/compat/ChangeReporter.java +33 −11 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading @@ -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) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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. Loading
services/core/java/com/android/server/compat/PlatformCompat.java +9 −0 Original line number Diff line number Diff line Loading @@ -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); Loading