From 6cd9d4d18e97fda7b7eeb9e0f8a5ea2ff0040e1e Mon Sep 17 00:00:00 2001 From: Andrei Onea Date: Wed, 17 Jul 2019 19:03:10 +0100 Subject: [PATCH 1/2] Make PlatformCompat a Binder class This allows PlatformCompat to be called from anywhere in the platform. In follow-up CLs, we'll define permissions for each method and/or filtering rules to prevent abuse from apps. Test: m Bug: 137769727 Change-Id: I19e5fbfefcf59e0b53b197ea8e9e3cb78439b4c4 Merged-In: I19e5fbfefcf59e0b53b197ea8e9e3cb78439b4c4 --- services/core/Android.bp | 9 +++ .../server/compat/IPlatformCompat.aidl | 57 +++++++++++++++++++ .../android/server/compat/PlatformCompat.java | 52 ++++++++--------- .../java/com/android/server/SystemServer.java | 6 ++ 4 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 services/core/java/com/android/server/compat/IPlatformCompat.aidl diff --git a/services/core/Android.bp b/services/core/Android.bp index 5ddb68701814a..018945aeb0c23 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -12,6 +12,7 @@ java_library_static { }, srcs: [ "java/**/*.java", + ":platformcompat_aidl", ":dumpstate_aidl", ":installd_aidl", ":storaged_aidl", @@ -78,3 +79,11 @@ prebuilt_etc { name: "gps_debug.conf", src: "java/com/android/server/location/gps_debug.conf", } + +filegroup { + name: "platformcompat_aidl", + srcs: [ + "java/com/android/server/compat/IPlatformCompat.aidl", + ], + path: "java", +} \ No newline at end of file diff --git a/services/core/java/com/android/server/compat/IPlatformCompat.aidl b/services/core/java/com/android/server/compat/IPlatformCompat.aidl new file mode 100644 index 0000000000000..8ab08f9047cbc --- /dev/null +++ b/services/core/java/com/android/server/compat/IPlatformCompat.aidl @@ -0,0 +1,57 @@ +/* + * 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.server.compat; + +import android.content.pm.ApplicationInfo; + +/** + * System private API for talking with the PlatformCompat service. + * {@hide} + */ +interface IPlatformCompat +{ + + /** + * Reports that a compatibility change is affecting an app process now. + * + *

Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)}, + * you do not need to call this API directly. The change will be reported for you in the case + * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}. + * + * @param changeId The ID of the compatibility change taking effect. + * @param appInfo Representing the affected app. + */ + void reportChange(long changeId, in ApplicationInfo appInfo); + + /** + * Query if a given compatibility change is enabled for an app process. This method should + * be called when implementing functionality on behalf of the affected app. + * + *

If this method returns {@code true}, the calling code should implement the compatibility + * change, resulting in differing behaviour compared to earlier releases. If this method returns + * {@code false}, the calling code should behave as it did in earlier releases. + * + *

When this method returns {@code true}, it will also report the change as + * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method + * directly. + * + * @param changeId The ID of the compatibility change in question. + * @param appInfo Representing the app in question. + * @return {@code true} if the change is enabled for the current app. + */ + boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo); +} \ No newline at end of file diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 456d15e4fba80..09e818dacae1f 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -16,52 +16,46 @@ package com.android.server.compat; +import android.content.Context; import android.content.pm.ApplicationInfo; import android.util.Slog; +import com.android.internal.util.DumpUtils; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * System server internal API for gating and reporting compatibility changes. */ -public class PlatformCompat { +public class PlatformCompat extends IPlatformCompat.Stub { private static final String TAG = "Compatibility"; - /** - * Reports that a compatibility change is affecting an app process now. - * - *

Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)}, - * you do not need to call this API directly. The change will be reported for you in the case - * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}. - * - * @param changeId The ID of the compatibility change taking effect. - * @param appInfo Representing the affected app. - */ - public static void reportChange(long changeId, ApplicationInfo appInfo) { + private final Context mContext; + + public PlatformCompat(Context context) { + mContext = context; + } + + @Override + public void reportChange(long changeId, ApplicationInfo appInfo) { Slog.d(TAG, "Compat change reported: " + changeId + "; UID " + appInfo.uid); // TODO log via StatsLog } - /** - * Query if a given compatibility change is enabled for an app process. This method should - * be called when implementing functionality on behalf of the affected app. - * - *

If this method returns {@code true}, the calling code should implement the compatibility - * change, resulting in differing behaviour compared to earlier releases. If this method returns - * {@code false}, the calling code should behave as it did in earlier releases. - * - *

When this method returns {@code true}, it will also report the change as - * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method - * directly. - * - * @param changeId The ID of the compatibility change in question. - * @param appInfo Representing the app in question. - * @return {@code true} if the change is enabled for the current app. - */ - public static boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { + @Override + public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { reportChange(changeId, appInfo); return true; } return false; } + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; + // TODO: Dump info about compatibility changes. + } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index dab160338a763..10db049a3e632 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -79,6 +79,7 @@ import com.android.server.audio.AudioService; import com.android.server.broadcastradio.BroadcastRadioService; import com.android.server.camera.CameraServiceProxy; import com.android.server.clipboard.ClipboardService; +import com.android.server.compat.PlatformCompat; import com.android.server.connectivity.IpConnectivityMetrics; import com.android.server.coverage.CoverageService; import com.android.server.devicepolicy.DevicePolicyManagerService; @@ -975,6 +976,11 @@ public final class SystemServer { traceBeginAndSlog("PinnerService"); mSystemServiceManager.startService(PinnerService.class); traceEnd(); + + traceBeginAndSlog("PlatformCompat"); + ServiceManager.addService("platform_compat", new PlatformCompat(context)); + traceEnd(); + } catch (RuntimeException e) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting core service", e); From c61bf0ca10b545f56ac8020788795f9d1b96d72a Mon Sep 17 00:00:00 2001 From: Andrei Onea Date: Wed, 10 Jul 2019 16:43:09 +0100 Subject: [PATCH 2/2] Dump PlatformCompat overrides to dumpsys Dump info related to compat flags. Test: adb shell am compat enable 42 foo.bar; \ dumpsys platform_compat Bug: 137183175 Change-Id: Ic429731a3364dab5902caeb12f48fecf2e49bb65 Merged-In: Ic429731a3364dab5902caeb12f48fecf2e49bb65 --- .../android/server/compat/CompatConfig.java | 19 +++++++++++++++++++ .../android/server/compat/PlatformCompat.java | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index bcf1d80781a6c..c59b0652af156 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -24,6 +24,7 @@ import android.util.LongSparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import java.io.PrintWriter; /** * This class maintains state relating to platform compatibility changes. * @@ -169,4 +170,22 @@ public final class CompatConfig { return overrideExists; } + /** + * Dumps the current list of compatibility config information. + * + * @param pw The {@link PrintWriter} instance to which the information will be dumped. + */ + public void dumpConfig(PrintWriter pw) { + synchronized (mChanges) { + if (mChanges.size() == 0) { + pw.println("No compat overrides."); + return; + } + for (int i = 0; i < mChanges.size(); ++i) { + CompatChange c = mChanges.valueAt(i); + pw.println(c.toString()); + } + } + } + } diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 09e818dacae1f..3eea194fd73e1 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -56,6 +56,6 @@ public class PlatformCompat extends IPlatformCompat.Stub { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; - // TODO: Dump info about compatibility changes. + CompatConfig.get().dumpConfig(pw); } }