1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.compat;
18 
19 import android.content.pm.ApplicationInfo;
20 import com.android.internal.compat.IOverrideValidator;
21 import java.util.Map;
22 
23 parcelable CompatibilityChangeConfig;
24 parcelable CompatibilityOverrideConfig;
25 parcelable CompatibilityOverridesByPackageConfig;
26 parcelable CompatibilityOverridesToRemoveByPackageConfig;
27 parcelable CompatibilityOverridesToRemoveConfig;
28 parcelable CompatibilityChangeInfo;
29 /**
30  * Platform private API for talking with the PlatformCompat service.
31  *
32  * <p>Should be used for gating and logging from non-app processes.
33  *
34  * <p>Note: for app processes please use {@code android.compat.Compatibility} API.
35  *
36  * {@hide}
37  */
38 interface IPlatformCompat {
39 
40     /**
41      * Reports that a compatibility change is affecting an app process now.
42      *
43      * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)},
44      * you do not need to call this API directly. The change will be reported for you.
45      *
46      * @param changeId the ID of the compatibility change taking effect
47      * @param appInfo  representing the affected app
48      * @throws SecurityException if logging is not allowed
49      */
50     @EnforcePermission("LOG_COMPAT_CHANGE")
reportChange(long changeId, in ApplicationInfo appInfo)51     void reportChange(long changeId, in ApplicationInfo appInfo);
52 
53     /**
54      * Reports that a compatibility change is affecting an app process now.
55      *
56      * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, String)},
57      * you do not need to call this API directly. The change will be reported for you.
58      *
59      * @param changeId    the ID of the compatibility change taking effect
60      * @param userId      the ID of the user that the operation is done for
61      * @param packageName the package name of the app in question
62      * @throws SecurityException if logging is not allowed
63      */
64     @EnforcePermission("LOG_COMPAT_CHANGE")
reportChangeByPackageName(long changeId, in String packageName, int userId)65     void reportChangeByPackageName(long changeId, in String packageName, int userId);
66 
67     /**
68      * Reports that a compatibility change is affecting an app process now.
69      *
70      * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, int)},
71      * you do not need to call this API directly. The change will be reported for you.
72      *
73      * @param changeId the ID of the compatibility change taking effect
74      * @param uid      the UID of the app in question
75      * @throws SecurityException if logging is not allowed
76      */
77     @EnforcePermission("LOG_COMPAT_CHANGE")
reportChangeByUid(long changeId, int uid)78     void reportChangeByUid(long changeId, int uid);
79 
80     /**
81      * Queries if a given compatibility change is enabled for an app process. This method should
82      * be called when implementing functionality on behalf of the affected app.
83      *
84      * <p>If this method returns {@code true}, the calling code should implement the compatibility
85      * change, resulting in differing behaviour compared to earlier releases. If this method returns
86      * {@code false}, the calling code should behave as it did in earlier releases.
87      *
88      * <p>It will also report the change as {@link #reportChange(long, ApplicationInfo)} would, so
89      * there is no need to call that method directly.
90      *
91      * @param changeId the ID of the compatibility change in question
92      * @param appInfo  representing the app in question
93      * @return {@code true} if the change is enabled for the current app
94      * @throws SecurityException if logging or reading compat confis is not allowed
95      */
96     @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
isChangeEnabled(long changeId, in ApplicationInfo appInfo)97     boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo);
98 
99     /**
100      * Queries if a given compatibility change is enabled for an app process. This method should
101      * be called when implementing functionality on behalf of the affected app.
102      *
103      * <p>Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a package name
104      * and userId instead of an {@link ApplicationInfo}
105      * object, and finds an app info object based on the package name. Returns {@code true} if
106      * there is no installed package by that name.
107      *
108      * <p>If this method returns {@code true}, the calling code should implement the compatibility
109      * change, resulting in differing behaviour compared to earlier releases. If this method
110      * returns
111      * {@code false}, the calling code should behave as it did in earlier releases.
112      *
113      * <p>It will also report the change as {@link #reportChange(long, String)} would, so there is
114      * no need to call that method directly.
115      *
116      * @param changeId    the ID of the compatibility change in question
117      * @param packageName the package name of the app in question
118      * @param userId      the ID of the user that the operation is done for
119      * @return {@code true} if the change is enabled for the current app
120      * @throws SecurityException if logging or reading compat confis is not allowed
121      */
122     @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
isChangeEnabledByPackageName(long changeId, in String packageName, int userId)123     boolean isChangeEnabledByPackageName(long changeId, in String packageName, int userId);
124 
125     /**
126      * Queries if a given compatibility change is enabled for an app process. This method should
127      * be called when implementing functionality on behalf of the affected app.
128      *
129      * <p>Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a uid
130      * instead of an {@link ApplicationInfo} object, and finds an app info object based on the
131      * uid (or objects if there's more than one package associated with the UID).
132      * Returns {@code true} if there are no installed packages for the required UID, or if the
133      * change is enabled for ALL of the installed packages associated with the provided UID. Please
134      * use a more specific API if you want a different behaviour for multi-package UIDs.
135      *
136      * <p>If this method returns {@code true}, the calling code should implement the compatibility
137      * change, resulting in differing behaviour compared to earlier releases. If this method
138      * returns {@code false}, the calling code should behave as it did in earlier releases.
139      *
140      * <p>It will also report the change as {@link #reportChange(long, int)} would, so there is
141      * no need to call that method directly.
142      *
143      * @param changeId the ID of the compatibility change in question
144      * @param uid      the UID of the app in question
145      * @return {@code true} if the change is enabled for the current app
146      * @throws SecurityException if logging or reading compat confis is not allowed
147      */
148     @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
isChangeEnabledByUid(long changeId, int uid)149     boolean isChangeEnabledByUid(long changeId, int uid);
150 
151     /**
152      * Adds overrides to compatibility changes.
153      *
154      * <p>Kills the app to allow the changes to take effect.
155      *
156      * @param overrides   parcelable containing the compat change overrides to be applied
157      * @param packageName the package name of the app whose changes will be overridden
158      * @throws SecurityException if overriding changes is not permitted
159      */
160     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
setOverrides(in CompatibilityChangeConfig overrides, in String packageName)161     void setOverrides(in CompatibilityChangeConfig overrides, in String packageName);
162 
163     /**
164      * Adds overrides to compatibility changes on release builds for multiple apps.
165      *
166      * <p>The caller to this API needs to hold
167      * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
168      * in {@code overridesByPackage} need to annotated with {@link
169      * android.compat.annotation.Overridable}.
170      *
171      * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
172      * be {@code false}.
173      *
174      * <p>Note that this does not kill the app, and therefore overrides read from the app process
175      * will not be updated. Overrides read from the system process do take effect.
176      *
177      * @param overridesByPackage parcelable containing the compat change overrides to be applied
178      *                           on specific apps by their package name
179      * @throws SecurityException if overriding changes is not permitted
180      */
181     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
putAllOverridesOnReleaseBuilds(in CompatibilityOverridesByPackageConfig overridesByPackage)182     void putAllOverridesOnReleaseBuilds(in CompatibilityOverridesByPackageConfig overridesByPackage);
183 
184     /**
185      * Adds overrides to compatibility changes on release builds.
186      *
187      * <p>The caller to this API needs to hold
188      * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
189      * in {@code overrides} need to annotated with {@link android.compat.annotation.Overridable}.
190      *
191      * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
192      * be {@code false}.
193      *
194      * <p>Note that this does not kill the app, and therefore overrides read from the app process
195      * will not be updated. Overrides read from the system process do take effect.
196      *
197      * @param overrides   parcelable containing the compat change overrides to be applied
198      * @param packageName the package name of the app whose changes will be overridden
199      * @throws SecurityException if overriding changes is not permitted
200      */
201     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
putOverridesOnReleaseBuilds(in CompatibilityOverrideConfig overrides, in String packageName)202     void putOverridesOnReleaseBuilds(in CompatibilityOverrideConfig overrides, in String packageName);
203 
204     /**
205      * Adds overrides to compatibility changes.
206      *
207      * <p>Does not kill the app, to be only used in tests.
208      *
209      * @param overrides   parcelable containing the compat change overrides to be applied
210      * @param packageName the package name of the app whose changes will be overridden
211      * @throws SecurityException if overriding changes is not permitted.
212      */
213     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName)214     void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName);
215 
216     /**
217      * Restores the default behaviour for the given change and app.
218      *
219      * <p>Kills the app to allow the changes to take effect.
220      *
221      * @param changeId    the ID of the change that was overridden
222      * @param packageName the app package name that was overridden
223      * @return {@code true} if an override existed
224      * @throws SecurityException if overriding changes is not permitted
225      */
226     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
clearOverride(long changeId, String packageName)227     boolean clearOverride(long changeId, String packageName);
228 
229     /**
230      * Restores the default behaviour for the given change and app.
231      *
232      * <p>Does not kill the app; to be only used in tests.
233      *
234      * @param changeId    the ID of the change that was overridden
235      * @param packageName the app package name that was overridden
236      * @return {@code true} if an override existed
237      * @throws SecurityException if overriding changes is not permitted
238      */
239     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
clearOverrideForTest(long changeId, String packageName)240     boolean clearOverrideForTest(long changeId, String packageName);
241 
242     /**
243      * Restores the default behaviour for compatibility changes on release builds for multiple apps.
244      *
245      * <p>The caller to this API needs to hold
246      * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
247      * in {@code overridesToRemoveByPackage} need to annotated with {@link
248      * android.compat.annotation.Overridable}.
249      *
250      * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
251      * be {@code false}.
252      *
253      * <p>Note that this does not kill the app, and therefore overrides read from the app process
254      * will not be updated. Overrides read from the system process do take effect.
255      *
256      * @param overridesToRemoveByPackage parcelable containing the compat change overrides to be
257      *                                   removed for specific apps by their package name
258      * @throws SecurityException if overriding changes is not permitted
259      */
260     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
removeAllOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveByPackageConfig overridesToRemoveByPackage)261     void removeAllOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveByPackageConfig overridesToRemoveByPackage);
262 
263     /**
264      * Restores the default behaviour for compatibility changes on release builds.
265      *
266      * <p>The caller to this API needs to hold
267      * {@code android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD} and all change ids
268      * in {@code overridesToRemove} need to annotated with
269      * {@link android.compat.annotation.Overridable}.
270      *
271      * A release build in this definition means that {@link android.os.Build#IS_DEBUGGABLE} needs to
272      * be {@code false}.
273      *
274      * <p>Note that this does not kill the app, and therefore overrides read from the app process
275      * will not be updated. Overrides read from the system process do take effect.
276      *
277      * @param overridesToRemove   parcelable containing the compat change overrides to be removed
278      * @param packageName         the package name of the app whose changes will be restored to the
279      *                            default behaviour
280      * @throws SecurityException if overriding changes is not permitted
281      */
282     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
removeOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveConfig overridesToRemove, in String packageName)283     void removeOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveConfig overridesToRemove, in String packageName);
284 
285     /**
286      * Enables all compatibility changes that have enabledSinceTargetSdk ==
287      * {@param targetSdkVersion} for an app, subject to the policy.
288      *
289      * <p>Kills the app to allow the changes to take effect.
290      *
291      * @param packageName      The package name of the app whose compatibility changes will be
292      *                         enabled.
293      * @param targetSdkVersion The targetSdkVersion for filtering the changes to be enabled.
294      * @return The number of changes that were enabled.
295      * @throws SecurityException if overriding changes is not permitted.
296      */
297     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
enableTargetSdkChanges(in String packageName, int targetSdkVersion)298     int enableTargetSdkChanges(in String packageName, int targetSdkVersion);
299 
300     /**
301      * Disables all compatibility changes that have enabledAfterTargetSdk ==
302      * {@param targetSdkVersion} for an app, subject to the policy.
303      *
304      * <p>Kills the app to allow the changes to take effect.
305      *
306      * @param packageName      the package name of the app whose compatibility changes will be
307      *                         disabled
308      * @param targetSdkVersion the targetSdkVersion for filtering the changes to be disabled
309      * @return the number of changes that were disabled
310      * @throws SecurityException if overriding changes is not permitted.
311      */
312     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
disableTargetSdkChanges(in String packageName, int targetSdkVersion)313     int disableTargetSdkChanges(in String packageName, int targetSdkVersion);
314 
315     /**
316      * Restores the default behaviour for the given app.
317      *
318      * <p>Kills the app to allow the changes to take effect.
319      *
320      * @param packageName the package name of the app whose overrides will be cleared
321      * @throws SecurityException if overriding changes is not permitted
322      */
323     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
clearOverrides(in String packageName)324     void clearOverrides(in String packageName);
325 
326     /**
327      * Restores the default behaviour for the given app.
328      *
329      * <p>Does not kill the app; to be only used in tests.
330      *
331      * @param packageName the package name of the app whose overrides will be cleared
332      * @throws SecurityException if overriding changes is not permitted
333      */
334     @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
clearOverridesForTest(in String packageName)335     void clearOverridesForTest(in String packageName);
336 
337     /**
338      * Get configs for an application.
339      *
340      * @param appInfo the application whose config will be returned
341      * @return a {@link CompatibilityChangeConfig}, representing whether a change is enabled for
342      * the given app or not
343      */
344     @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
getAppConfig(in ApplicationInfo appInfo)345     CompatibilityChangeConfig getAppConfig(in ApplicationInfo appInfo);
346 
347     /**
348      * List all compatibility changes.
349      *
350      * @return an array of {@link CompatibilityChangeInfo} known to the service
351      */
352     @EnforcePermission("READ_COMPAT_CHANGE_CONFIG")
listAllChanges()353     CompatibilityChangeInfo[] listAllChanges();
354 
355     /**
356      * List the compatibility changes that should be present in the UI.
357      * Filters out certain changes like e.g. logging only.
358      *
359      * @return an array of {@link CompatibilityChangeInfo}
360      */
361     @RequiresNoPermission
listUIChanges()362     CompatibilityChangeInfo[] listUIChanges();
363 
364     /**
365      * Gets an instance that can determine whether a changeid can be overridden for a package name.
366      */
367     @RequiresNoPermission
getOverrideValidator()368     IOverrideValidator getOverrideValidator();
369 }
370