diff options
-rw-r--r-- | cmds/statsd/src/atoms.proto | 39 | ||||
-rw-r--r-- | core/java/android/app/AppCompatCallbacks.java | 20 | ||||
-rw-r--r-- | core/java/com/android/internal/compat/ChangeReporter.java | 73 | ||||
-rw-r--r-- | services/core/java/com/android/server/compat/PlatformCompat.java | 21 |
4 files changed, 145 insertions, 8 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index b50ec8a84b40..f8a3ede769df 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -335,6 +335,8 @@ message Atom { UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225; UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226; CameraActionEvent camera_action_event = 227; + AppCompatibilityChangeReported app_compatibility_change_reported = + 228 [(allow_from_any_uid) = true]; } // Pulled events will start at field 10000. @@ -7170,7 +7172,6 @@ message FrameTimingHistogram { repeated int64 frame_counts = 2; } - /** * Information about camera facing and API level usage. * Logged from: @@ -7195,3 +7196,39 @@ message CameraActionEvent { } optional Facing facing = 4; } + +/** + * 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; + +} diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java index 17697dba9ccd..08c97eb284e3 100644 --- a/core/java/android/app/AppCompatCallbacks.java +++ b/core/java/android/app/AppCompatCallbacks.java @@ -19,6 +19,9 @@ package android.app; import android.compat.Compatibility; import android.os.Process; import android.util.Log; +import android.util.StatsLog; + +import com.android.internal.compat.ChangeReporter; import java.util.Arrays; @@ -28,10 +31,10 @@ import java.util.Arrays; * @hide */ public final class AppCompatCallbacks extends Compatibility.Callbacks { - private static final String TAG = "Compatibility"; private final long[] mDisabledChanges; + private final ChangeReporter mChangeReporter; /** * Install this class into the current process. @@ -45,20 +48,29 @@ public final class AppCompatCallbacks extends Compatibility.Callbacks { private AppCompatCallbacks(long[] disabledChanges) { mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length); Arrays.sort(mDisabledChanges); + mChangeReporter = new ChangeReporter(); } protected void reportChange(long changeId) { - Log.d(TAG, "Compat change reported: " + changeId + "; UID " + Process.myUid()); - // TODO log via StatsLog + reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); } protected boolean isChangeEnabled(long changeId) { if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) { // Not present in the disabled array - reportChange(changeId); + reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; } + reportChange(changeId, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); 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); + } + } diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java new file mode 100644 index 000000000000..1ce071bd005a --- /dev/null +++ b/core/java/com/android/internal/compat/ChangeReporter.java @@ -0,0 +1,73 @@ +/* + * 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); + } +} diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index fc38735509f0..81e507cd24cf 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -19,7 +19,9 @@ package com.android.server.compat; import android.content.Context; import android.content.pm.ApplicationInfo; import android.util.Slog; +import android.util.StatsLog; +import com.android.internal.compat.ChangeReporter; import com.android.internal.compat.IPlatformCompat; import com.android.internal.util.DumpUtils; @@ -34,23 +36,27 @@ public class PlatformCompat extends IPlatformCompat.Stub { private static final String TAG = "Compatibility"; private final Context mContext; + private final ChangeReporter mChangeReporter; public PlatformCompat(Context context) { mContext = context; + mChangeReporter = new ChangeReporter(); } @Override public void reportChange(long changeId, ApplicationInfo appInfo) { - Slog.d(TAG, "Compat change reported: " + changeId + "; UID " + appInfo.uid); - // TODO log via StatsLog + reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); } @Override public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { - reportChange(changeId, appInfo); + reportChange(changeId, appInfo, + StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; } + reportChange(changeId, appInfo, + StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); return false; } @@ -59,4 +65,13 @@ public class PlatformCompat extends IPlatformCompat.Stub { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; 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); + } } |