Loading cmds/statsd/src/atoms.proto +39 −0 Original line number Original line Diff line number Diff line Loading @@ -319,6 +319,9 @@ message Atom { 217 [(log_from_module) = "permissioncontroller"]; 217 [(log_from_module) = "permissioncontroller"]; PermissionAppsFragmentViewed permission_apps_fragment_viewed = PermissionAppsFragmentViewed permission_apps_fragment_viewed = 218 [(log_from_module) = "permissioncontroller"]; 218 [(log_from_module) = "permissioncontroller"]; AppCompatibilityChangeReported app_compatibility_change_reported = 228 [(allow_from_any_uid) = true]; } } // Pulled events will start at field 10000. // Pulled events will start at field 10000. Loading Loading @@ -6779,3 +6782,39 @@ message PermissionAppsFragmentViewed { } } optional Category category = 6; optional Category category = 6; } } /** * Logs when a compatibility change is affecting an app. * * Logged from: * frameworks/base/core/java/android/app/AppCompatCallbacks.java and * frameworks/base/services/core/java/com/android/server/compat/PlatformCompat.java */ message AppCompatibilityChangeReported { // The UID of the app being affected by the compatibilty change. optional int32 uid = 1 [(is_uid) = true]; // The ID of the change affecting the app. optional int64 change_id = 2; enum State { UNKNOWN_STATE = 0; ENABLED = 1; DISABLED = 2; LOGGED = 3; } // The state of the change - if logged from gating whether it was enabled or disabled, or just // logged otherwise. optional State state = 3; enum Source { UNKNOWN_SOURCE = 0; APP_PROCESS = 1; SYSTEM_SERVER = 2; } // Where it was logged from. optional Source source = 4; } core/java/android/app/AppCompatCallbacks.java +16 −4 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,9 @@ package android.app; import android.compat.Compatibility; import android.compat.Compatibility; import android.os.Process; import android.os.Process; import android.util.Log; import android.util.Log; import android.util.StatsLog; import com.android.internal.compat.ChangeReporter; import java.util.Arrays; import java.util.Arrays; Loading @@ -28,10 +31,10 @@ import java.util.Arrays; * @hide * @hide */ */ public final class AppCompatCallbacks extends Compatibility.Callbacks { public final class AppCompatCallbacks extends Compatibility.Callbacks { private static final String TAG = "Compatibility"; private static final String TAG = "Compatibility"; private final long[] mDisabledChanges; private final long[] mDisabledChanges; private final ChangeReporter mChangeReporter; /** /** * Install this class into the current process. * Install this class into the current process. Loading @@ -45,20 +48,29 @@ public final class AppCompatCallbacks extends Compatibility.Callbacks { private AppCompatCallbacks(long[] disabledChanges) { private AppCompatCallbacks(long[] disabledChanges) { mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length); mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length); Arrays.sort(mDisabledChanges); Arrays.sort(mDisabledChanges); mChangeReporter = new ChangeReporter(); } } protected void reportChange(long changeId) { protected void reportChange(long changeId) { Log.d(TAG, "Compat change reported: " + changeId + "; UID " + Process.myUid()); reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); // TODO log via StatsLog } } protected boolean isChangeEnabled(long changeId) { protected boolean isChangeEnabled(long changeId) { if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) { if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) { // Not present in the disabled array // Not present in the disabled array reportChange(changeId); reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; return true; } } reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); return false; return false; } } private void reportChange(long changeId, int state) { int uid = Process.myUid(); //TODO(b/138374585): Implement rate limiting for the logs. Log.d(TAG, ChangeReporter.createLogString(uid, changeId, state)); mChangeReporter.reportChange(uid, changeId, state, /* source */StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__APP_PROCESS); } } } core/java/com/android/internal/compat/ChangeReporter.java 0 → 100644 +73 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2019 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. */ package com.android.internal.compat; import android.util.StatsLog; /** * A helper class to report changes to stats log. * * @hide */ public final class ChangeReporter { /** * Transforms StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string. * * @param state to transform * @return a string representing the state */ private static String stateToString(int state) { switch (state) { case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED: return "LOGGED"; case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED: return "ENABLED"; case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED: return "DISABLED"; default: return "UNKNOWN"; } } /** * Constructs and returns a string to be logged to logcat when a change is reported. * * @param uid affected by the change * @param changeId the reported change id * @param state of the reported change - enabled/disabled/only logged * @return string to log */ public static String createLogString(int uid, long changeId, int state) { return String.format("Compat change id reported: %d; UID %d; state: %s", changeId, uid, stateToString(state)); } /** * Report the change to stats log. * * @param uid affected by the change * @param changeId the reported change id * @param state of the reported change - enabled/disabled/only logged * @param source of the logging - app process or system server */ public void reportChange(int uid, long changeId, int state, int source) { //TODO(b/138374585): Implement rate limiting for stats log. StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId, state, source); } } services/core/java/com/android/server/compat/PlatformCompat.java +18 −3 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.server.compat; import android.content.Context; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo; import android.util.Slog; import android.util.Slog; import android.util.StatsLog; import com.android.internal.compat.ChangeReporter; import com.android.internal.compat.IPlatformCompat; import com.android.internal.compat.IPlatformCompat; import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils; Loading @@ -34,23 +36,27 @@ public class PlatformCompat extends IPlatformCompat.Stub { private static final String TAG = "Compatibility"; private static final String TAG = "Compatibility"; private final Context mContext; private final Context mContext; private final ChangeReporter mChangeReporter; public PlatformCompat(Context context) { public PlatformCompat(Context context) { mContext = context; mContext = context; mChangeReporter = new ChangeReporter(); } } @Override @Override public void reportChange(long changeId, ApplicationInfo appInfo) { public void reportChange(long changeId, ApplicationInfo appInfo) { Slog.d(TAG, "Compat change reported: " + changeId + "; UID " + appInfo.uid); reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); // TODO log via StatsLog } } @Override @Override public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { reportChange(changeId, appInfo); reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; return true; } } reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); return false; return false; } } Loading @@ -59,4 +65,13 @@ public class PlatformCompat extends IPlatformCompat.Stub { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; CompatConfig.get().dumpConfig(pw); CompatConfig.get().dumpConfig(pw); } } private void reportChange(long changeId, ApplicationInfo appInfo, int state) { int uid = appInfo.uid; //TODO(b/138374585): Implement rate limiting for the logs. Slog.d(TAG, ChangeReporter.createLogString(uid, changeId, state)); mChangeReporter.reportChange(uid, changeId, state, /* source */ StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); } } } Loading
cmds/statsd/src/atoms.proto +39 −0 Original line number Original line Diff line number Diff line Loading @@ -319,6 +319,9 @@ message Atom { 217 [(log_from_module) = "permissioncontroller"]; 217 [(log_from_module) = "permissioncontroller"]; PermissionAppsFragmentViewed permission_apps_fragment_viewed = PermissionAppsFragmentViewed permission_apps_fragment_viewed = 218 [(log_from_module) = "permissioncontroller"]; 218 [(log_from_module) = "permissioncontroller"]; AppCompatibilityChangeReported app_compatibility_change_reported = 228 [(allow_from_any_uid) = true]; } } // Pulled events will start at field 10000. // Pulled events will start at field 10000. Loading Loading @@ -6779,3 +6782,39 @@ message PermissionAppsFragmentViewed { } } optional Category category = 6; optional Category category = 6; } } /** * Logs when a compatibility change is affecting an app. * * Logged from: * frameworks/base/core/java/android/app/AppCompatCallbacks.java and * frameworks/base/services/core/java/com/android/server/compat/PlatformCompat.java */ message AppCompatibilityChangeReported { // The UID of the app being affected by the compatibilty change. optional int32 uid = 1 [(is_uid) = true]; // The ID of the change affecting the app. optional int64 change_id = 2; enum State { UNKNOWN_STATE = 0; ENABLED = 1; DISABLED = 2; LOGGED = 3; } // The state of the change - if logged from gating whether it was enabled or disabled, or just // logged otherwise. optional State state = 3; enum Source { UNKNOWN_SOURCE = 0; APP_PROCESS = 1; SYSTEM_SERVER = 2; } // Where it was logged from. optional Source source = 4; }
core/java/android/app/AppCompatCallbacks.java +16 −4 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,9 @@ package android.app; import android.compat.Compatibility; import android.compat.Compatibility; import android.os.Process; import android.os.Process; import android.util.Log; import android.util.Log; import android.util.StatsLog; import com.android.internal.compat.ChangeReporter; import java.util.Arrays; import java.util.Arrays; Loading @@ -28,10 +31,10 @@ import java.util.Arrays; * @hide * @hide */ */ public final class AppCompatCallbacks extends Compatibility.Callbacks { public final class AppCompatCallbacks extends Compatibility.Callbacks { private static final String TAG = "Compatibility"; private static final String TAG = "Compatibility"; private final long[] mDisabledChanges; private final long[] mDisabledChanges; private final ChangeReporter mChangeReporter; /** /** * Install this class into the current process. * Install this class into the current process. Loading @@ -45,20 +48,29 @@ public final class AppCompatCallbacks extends Compatibility.Callbacks { private AppCompatCallbacks(long[] disabledChanges) { private AppCompatCallbacks(long[] disabledChanges) { mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length); mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length); Arrays.sort(mDisabledChanges); Arrays.sort(mDisabledChanges); mChangeReporter = new ChangeReporter(); } } protected void reportChange(long changeId) { protected void reportChange(long changeId) { Log.d(TAG, "Compat change reported: " + changeId + "; UID " + Process.myUid()); reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); // TODO log via StatsLog } } protected boolean isChangeEnabled(long changeId) { protected boolean isChangeEnabled(long changeId) { if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) { if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) { // Not present in the disabled array // Not present in the disabled array reportChange(changeId); reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; return true; } } reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); return false; return false; } } private void reportChange(long changeId, int state) { int uid = Process.myUid(); //TODO(b/138374585): Implement rate limiting for the logs. Log.d(TAG, ChangeReporter.createLogString(uid, changeId, state)); mChangeReporter.reportChange(uid, changeId, state, /* source */StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__APP_PROCESS); } } }
core/java/com/android/internal/compat/ChangeReporter.java 0 → 100644 +73 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2019 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. */ package com.android.internal.compat; import android.util.StatsLog; /** * A helper class to report changes to stats log. * * @hide */ public final class ChangeReporter { /** * Transforms StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string. * * @param state to transform * @return a string representing the state */ private static String stateToString(int state) { switch (state) { case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED: return "LOGGED"; case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED: return "ENABLED"; case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED: return "DISABLED"; default: return "UNKNOWN"; } } /** * Constructs and returns a string to be logged to logcat when a change is reported. * * @param uid affected by the change * @param changeId the reported change id * @param state of the reported change - enabled/disabled/only logged * @return string to log */ public static String createLogString(int uid, long changeId, int state) { return String.format("Compat change id reported: %d; UID %d; state: %s", changeId, uid, stateToString(state)); } /** * Report the change to stats log. * * @param uid affected by the change * @param changeId the reported change id * @param state of the reported change - enabled/disabled/only logged * @param source of the logging - app process or system server */ public void reportChange(int uid, long changeId, int state, int source) { //TODO(b/138374585): Implement rate limiting for stats log. StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId, state, source); } }
services/core/java/com/android/server/compat/PlatformCompat.java +18 −3 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.server.compat; import android.content.Context; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo; import android.util.Slog; import android.util.Slog; import android.util.StatsLog; import com.android.internal.compat.ChangeReporter; import com.android.internal.compat.IPlatformCompat; import com.android.internal.compat.IPlatformCompat; import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils; Loading @@ -34,23 +36,27 @@ public class PlatformCompat extends IPlatformCompat.Stub { private static final String TAG = "Compatibility"; private static final String TAG = "Compatibility"; private final Context mContext; private final Context mContext; private final ChangeReporter mChangeReporter; public PlatformCompat(Context context) { public PlatformCompat(Context context) { mContext = context; mContext = context; mChangeReporter = new ChangeReporter(); } } @Override @Override public void reportChange(long changeId, ApplicationInfo appInfo) { public void reportChange(long changeId, ApplicationInfo appInfo) { Slog.d(TAG, "Compat change reported: " + changeId + "; UID " + appInfo.uid); reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); // TODO log via StatsLog } } @Override @Override public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { reportChange(changeId, appInfo); reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; return true; } } reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); return false; return false; } } Loading @@ -59,4 +65,13 @@ public class PlatformCompat extends IPlatformCompat.Stub { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; CompatConfig.get().dumpConfig(pw); CompatConfig.get().dumpConfig(pw); } } private void reportChange(long changeId, ApplicationInfo appInfo, int state) { int uid = appInfo.uid; //TODO(b/138374585): Implement rate limiting for the logs. Slog.d(TAG, ChangeReporter.createLogString(uid, changeId, state)); mChangeReporter.reportChange(uid, changeId, state, /* source */ StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); } } }