Merge "Add CompatChanges API." am: 54036c0525

Change-Id: Ieade8f2b33423bad4219ab2982b876b06e355e84
This commit is contained in:
Automerger Merge Worker
2020-02-06 17:43:00 +00:00
6 changed files with 207 additions and 2 deletions

View File

@@ -979,6 +979,16 @@ package android.app.backup {
}
package android.app.compat {
public final class CompatChanges {
method public static boolean isChangeEnabled(long);
method public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
method public static boolean isChangeEnabled(long, int);
}
}
package android.app.contentsuggestions {
public final class ClassificationsRequest implements android.os.Parcelable {

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2020 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 android.app.compat;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.compat.Compatibility;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import com.android.internal.compat.IPlatformCompat;
/**
* CompatChanges APIs - to be used by platform code only (including mainline
* modules).
*
* @hide
*/
@SystemApi
public final class CompatChanges {
private CompatChanges() {}
/**
* Query if a given compatibility change is enabled for the current process. This method is
* intended to be called by code running inside a process of the affected app only.
*
* <p>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.
*
* @param changeId The ID of the compatibility change in question.
* @return {@code true} if the change is enabled for the current app.
*/
public static boolean isChangeEnabled(long changeId) {
return Compatibility.isChangeEnabled(changeId);
}
/**
* Same as {@code #isChangeEnabled(long)}, except this version should be called on behalf of an
* app from a different process that's performing work for the app.
*
* <p> Note that this involves a binder call to the system server (unless running in the system
* server). If the binder call fails, a {@code RuntimeException} will be thrown.
*
* <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it
* doesn't, a {@code RuntimeException} will be thrown.
*
* @param changeId The ID of the compatibility change in question.
* @param packageName The package name of the app in question.
* @param user The user that the operation is done for.
* @return {@code true} if the change is enabled for the current app.
*/
public static boolean isChangeEnabled(long changeId, @NonNull String packageName,
@NonNull UserHandle user) {
IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
try {
return platformCompat.isChangeEnabledByPackageName(changeId, packageName,
user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Same as {@code #isChangeEnabled(long)}, except this version should be called on behalf of an
* app from a different process that's performing work for the app.
*
* <p> Note that this involves a binder call to the system server (unless running in the system
* server). If the binder call fails, {@code RuntimeException} will be thrown.
*
* <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it
* doesn't, a {@code RuntimeException} will be thrown.
*
* <p> Returns {@code true} if there are no installed packages for the required UID, or if the
* change is enabled for ALL of the installed packages associated with the provided UID. Please
* use a more specific API if you want a different behaviour for multi-package UIDs.
*
* @param changeId The ID of the compatibility change in question.
* @param uid The UID of the app in question.
* @return {@code true} if the change is enabled for the current app.
*/
public static boolean isChangeEnabled(long changeId, int uid) {
IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
try {
return platformCompat.isChangeEnabledByUid(changeId, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}

View File

@@ -37,6 +37,7 @@ android_test {
"mockito-target-minus-junit4",
"ub-uiautomator",
"platform-test-annotations",
"platform-compat-test-rules",
"truth-prebuilt",
"print-test-util-lib",
"testng",

View File

@@ -0,0 +1,81 @@
/*
* 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 android.app.compat;
import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Process;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
/**
* {@link CompatChanges} tests.
*/
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
public class CompatChangesTest {
static final long CHANGE_ID = 1L;
private Instrumentation mInstrumentation;
@Rule
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@Before
public void setup() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
}
private String getPackageName() {
return mInstrumentation.getTargetContext().getPackageName();
}
@Test
@EnableCompatChanges(CHANGE_ID)
public void testEnabledChange() {
assertThat(CompatChanges.isChangeEnabled(CHANGE_ID)).isTrue();
assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, Process.myUid())).isTrue();
assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, getPackageName(),
UserHandle.of(UserHandle.myUserId()))).isTrue();
}
@Test
@DisableCompatChanges(CHANGE_ID)
public void testDisabledChange() {
assertThat(CompatChanges.isChangeEnabled(CHANGE_ID)).isFalse();
assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, Process.myUid())).isFalse();
assertThat(CompatChanges.isChangeEnabled(CHANGE_ID, getPackageName(),
UserHandle.of(UserHandle.myUserId()))).isFalse();
}
}

View File

@@ -21,6 +21,7 @@ import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.Context;
@@ -106,7 +107,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
@Override
public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
public boolean isChangeEnabledByPackageName(long changeId, String packageName,
@UserIdInt int userId) {
checkCompatChangeReadAndLogPermission();
ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
if (appInfo == null) {

View File

@@ -16,6 +16,8 @@
package com.android.server.compat;
import android.annotation.UserIdInt;
import com.android.internal.compat.IPlatformCompatNative;
/**
@@ -39,7 +41,8 @@ public class PlatformCompatNative extends IPlatformCompatNative.Stub {
}
@Override
public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
public boolean isChangeEnabledByPackageName(long changeId, String packageName,
@UserIdInt int userId) {
return mPlatformCompat.isChangeEnabledByPackageName(changeId, packageName, userId);
}