diff options
author | Mathew Inwood <mathewi@google.com> | 2019-06-24 15:14:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-06-24 15:14:33 +0000 |
commit | 7e391faa2f06a28efcc926f39a9a3e9a44bcb2e1 (patch) | |
tree | aa5e24ef737a48160a26b301132276756805aef3 | |
parent | 5cca1c7bc6f5acc00645302dc5a3ca7ffbf09b82 (diff) | |
parent | 063f83fd94108a561750992b08a0cac800b7c021 (diff) |
Merge "Platform Compatibility framework: annotations & basic API."
-rw-r--r-- | luni/src/main/java/android/compat/Compatibility.java | 109 | ||||
-rw-r--r-- | luni/src/main/java/android/compat/annotation/ChangeId.java | 51 | ||||
-rw-r--r-- | luni/src/main/java/android/compat/annotation/Disabled.java | 41 | ||||
-rw-r--r-- | luni/src/main/java/android/compat/annotation/EnabledAfter.java | 49 | ||||
-rw-r--r-- | mmodules/core_platform_api/api/platform/current-api.txt | 30 | ||||
-rw-r--r-- | mmodules/intracoreapi/api/intra/current-api.txt | 23 | ||||
-rw-r--r-- | non_openjdk_java_files.bp | 4 |
7 files changed, 307 insertions, 0 deletions
diff --git a/luni/src/main/java/android/compat/Compatibility.java b/luni/src/main/java/android/compat/Compatibility.java new file mode 100644 index 0000000000..baf46bf950 --- /dev/null +++ b/luni/src/main/java/android/compat/Compatibility.java @@ -0,0 +1,109 @@ +/* + * 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.compat; + +import android.compat.annotation.ChangeId; + +import libcore.api.CorePlatformApi; +import libcore.api.IntraCoreApi; + +/** + * Internal APIs for logging and gating compatibility changes. + * + * @see ChangeId + * + * @hide + */ +@CorePlatformApi +@IntraCoreApi +public final class Compatibility { + + private Compatibility() {} + + /** + * Reports that a compatibility change is affecting the current process now. + * + * <p>Calls to this method from a non-app process are ignored. This allows code implementing + * APIs that are used by apps and by other code (e.g. the system server) to report changes + * regardless of the process it's running in. When called in a non-app process, this method is + * a no-op. + * + * <p>Note: for changes that are gated using {@link #isChangeEnabled(long)}, you do not need to + * call this API directly. The change will be reported for you in the case that + * {@link #isChangeEnabled(long)} returns {@code true}. + * + * @param changeId The ID of the compatibility change taking effect. + */ + @CorePlatformApi + @IntraCoreApi + public static void reportChange(@ChangeId long changeId) { + sCallbacks.reportChange(changeId); + } + + /** + * Query if a given compatibility change is enabled for the current process. This method should + * only be called by code running inside a process of the affected app. + * + * <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. + * + * <p>When this method returns {@code true}, it will also report the change as + * {@link #reportChange(long)} would, so there is no need to call that method directly. + * + * @param changeId The ID of the compatibility change in question. + * @return {@code true} if the change is enabled for the current app. + */ + @CorePlatformApi + @IntraCoreApi + public static boolean isChangeEnabled(@ChangeId long changeId) { + return sCallbacks.isChangeEnabled(changeId); + } + + private volatile static Callbacks sCallbacks = new Callbacks(); + + @CorePlatformApi + public static void setCallbacks(Callbacks callbacks) { + sCallbacks = callbacks; + } + + /** + * Base class for compatibility API implementations. The default implementation logs a warning + * to logcat. + * + * This is provided as a class rather than an interface to allow new methods to be added without + * breaking @CorePlatformApi binary compatibility. + */ + @CorePlatformApi + public static class Callbacks { + @CorePlatformApi + protected Callbacks() { + } + @CorePlatformApi + protected void reportChange(long changeId) { + System.logW(String.format( + "No Compatibility callbacks set! Reporting change %d", changeId)); + } + @CorePlatformApi + protected boolean isChangeEnabled(long changeId) { + System.logW(String.format( + "No Compatibility callbacks set! Querying change %d", changeId)); + return true; + } + } + +} diff --git a/luni/src/main/java/android/compat/annotation/ChangeId.java b/luni/src/main/java/android/compat/annotation/ChangeId.java new file mode 100644 index 0000000000..ea91223fd2 --- /dev/null +++ b/luni/src/main/java/android/compat/annotation/ChangeId.java @@ -0,0 +1,51 @@ +/* + * 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.compat.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import libcore.api.CorePlatformApi; +import libcore.api.IntraCoreApi; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Indicates that a field is a compatibility change ID. + * + * <p>A compatibility change is a change to the Android platform that may impact app behavior, + * relative to previous releases of Android. A change ID is a unique {@code long} identifying one + * such change. Compatibility change IDs should be defined as a {@code static final long}: + * + * <pre>{@code + * @ChangeId + * public static final long MY_CHANGE_ID = 123456789l; + * }</pre> + * + * <p>The value of the constant is the ID of an issue in <a href="https://issuetracker.google.com/"> + * buganizer</a>. + * + * @hide + */ +@Retention(CLASS) +@Target({FIELD, PARAMETER}) +@CorePlatformApi +@IntraCoreApi +public @interface ChangeId { +} diff --git a/luni/src/main/java/android/compat/annotation/Disabled.java b/luni/src/main/java/android/compat/annotation/Disabled.java new file mode 100644 index 0000000000..4779a24f7e --- /dev/null +++ b/luni/src/main/java/android/compat/annotation/Disabled.java @@ -0,0 +1,41 @@ +/* + * 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.compat.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import libcore.api.CorePlatformApi; +import libcore.api.IntraCoreApi; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Used to indicate that a compatibility {@link ChangeId change} is disabled for all apps. + * + * <p>This annotation should only be applied to change ID constants that are also annotated with + * {@link ChangeId}. In any other context, this annotation will have no effect. + * + * @hide + */ +@Retention(CLASS) +@Target({FIELD}) +@CorePlatformApi +@IntraCoreApi +public @interface Disabled { +} diff --git a/luni/src/main/java/android/compat/annotation/EnabledAfter.java b/luni/src/main/java/android/compat/annotation/EnabledAfter.java new file mode 100644 index 0000000000..aeb62fdf1a --- /dev/null +++ b/luni/src/main/java/android/compat/annotation/EnabledAfter.java @@ -0,0 +1,49 @@ +/* + * 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.compat.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import libcore.api.CorePlatformApi; +import libcore.api.IntraCoreApi; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Used to indicate that a compatibility {@link ChangeId change} is enabled only for apps with a + * {@code targetSdkVersion} of <em>greater than</em> the given value. + * + * <p>This annotation should only be applied to change ID constants that are also annotated with + * {@link ChangeId}. In any other context, this annotation will have no effect. + * + * @hide + */ +@Retention(CLASS) +@Target({FIELD}) +@CorePlatformApi +@IntraCoreApi +public @interface EnabledAfter { + /** + * @return The maximum {@code targetSdkVersion} for which this change does not apply. Apps with + * a {@code targetSdkVersion} of greater than this value will get the change. + */ + @CorePlatformApi + @IntraCoreApi + int targetSdkVersion(); +} diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt index d59d230de1..52c2bc54b6 100644 --- a/mmodules/core_platform_api/api/platform/current-api.txt +++ b/mmodules/core_platform_api/api/platform/current-api.txt @@ -1,4 +1,34 @@ // Signature format: 2.0 +package android.compat { + + public final class Compatibility { + method public static boolean isChangeEnabled(@android.compat.annotation.ChangeId long); + method public static void reportChange(@android.compat.annotation.ChangeId long); + method public static void setCallbacks(android.compat.Compatibility.Callbacks); + } + + public static class Compatibility.Callbacks { + ctor protected Compatibility.Callbacks(); + method protected boolean isChangeEnabled(long); + method protected void reportChange(long); + } + +} + +package android.compat.annotation { + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER}) public @interface ChangeId { + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD}) public @interface Disabled { + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD}) public @interface EnabledAfter { + method public abstract int targetSdkVersion(); + } + +} + package android.icu.impl { public class CalendarAstronomer { diff --git a/mmodules/intracoreapi/api/intra/current-api.txt b/mmodules/intracoreapi/api/intra/current-api.txt index 4250d3fc9a..4eeebc27da 100644 --- a/mmodules/intracoreapi/api/intra/current-api.txt +++ b/mmodules/intracoreapi/api/intra/current-api.txt @@ -1,4 +1,27 @@ // Signature format: 2.0 +package android.compat { + + @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class Compatibility { + method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static boolean isChangeEnabled(@android.compat.annotation.ChangeId long); + method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static void reportChange(@android.compat.annotation.ChangeId long); + } + +} + +package android.compat.annotation { + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PARAMETER}) @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public @interface ChangeId { + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD}) @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public @interface Disabled { + } + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD}) @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public @interface EnabledAfter { + method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public abstract int targetSdkVersion(); + } + +} + package com.android.org.conscrypt { @libcore.api.IntraCoreApi public class DESEDESecretKeyFactory extends javax.crypto.SecretKeyFactorySpi { diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp index 982c02a442..caf3c996d8 100644 --- a/non_openjdk_java_files.bp +++ b/non_openjdk_java_files.bp @@ -1,6 +1,10 @@ filegroup { name: "non_openjdk_javadoc_files", srcs: [ + "luni/src/main/java/android/compat/annotation/ChangeId.java", + "luni/src/main/java/android/compat/annotation/Disabled.java", + "luni/src/main/java/android/compat/annotation/EnabledAfter.java", + "luni/src/main/java/android/compat/Compatibility.java", "luni/src/main/java/android/system/ErrnoException.java", "luni/src/main/java/android/system/GaiException.java", "luni/src/main/java/android/system/IcmpHeaders.java", |