diff options
| author | Andrei Onea <andreionea@google.com> | 2019-11-28 16:55:27 +0000 |
|---|---|---|
| committer | Andrei Onea <andreionea@google.com> | 2019-12-18 15:10:25 +0000 |
| commit | 465b214383aca1cfa67de844d30c8d89fef3f777 (patch) | |
| tree | 3b698b365c7c6a3cfaac2570cca0014d5cdcb307 /core/java | |
| parent | 591e1fcfcf9aa21f47139311a3999607fe310577 (diff) | |
Enforce overriding methods for IPlatformCompat
Restrict the ability of callers to IPlatformCompat.setOverrides and
IPlatformCompat.clearOverride, depending on the type of build and/or
whether the app is debuggable.
Bug: 144552011
Test: atest PlatformCompatTest
Test: atest CompatConfigTest
Change-Id: Ibff7db73d7867735853aa2ddde7c14a12625b3dc
Diffstat (limited to 'core/java')
5 files changed, 233 insertions, 0 deletions
diff --git a/core/java/com/android/internal/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java new file mode 100644 index 000000000000..0b937fad7df1 --- /dev/null +++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java @@ -0,0 +1,34 @@ +/* + * 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.os.Build; + +/** + * Platform private class for determining the type of Android build installed. + * + */ +public class AndroidBuildClassifier { + + public boolean isDebuggableBuild() { + return Build.IS_DEBUGGABLE; + } + + public boolean isFinalBuild() { + return "REL".equals(Build.VERSION.CODENAME); + } +} diff --git a/core/java/com/android/internal/compat/IOverrideValidator.aidl b/core/java/com/android/internal/compat/IOverrideValidator.aidl new file mode 100644 index 000000000000..add4708863aa --- /dev/null +++ b/core/java/com/android/internal/compat/IOverrideValidator.aidl @@ -0,0 +1,38 @@ +/* + * 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.content.pm.ApplicationInfo; + +import com.android.internal.compat.OverrideAllowedState; + +/** + * Platform private API for determining whether a changeId can be overridden. + * + * {@hide} + */ +interface IOverrideValidator +{ + /** + * Validation function. + * @param changeId id of the change to be toggled on or off. + * @param packageName package of the app for which the change should be overridden. + * @return {@link OverrideAllowedState} specifying whether the change can be overridden for + * the given package or a reason why not. + */ + OverrideAllowedState getOverrideAllowedState(long changeId, String packageName); +} diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 7dcb12c9e72b..4c203d394759 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -17,6 +17,7 @@ package com.android.internal.compat; import android.content.pm.ApplicationInfo; +import com.android.internal.compat.IOverrideValidator; import java.util.Map; parcelable CompatibilityChangeConfig; @@ -195,4 +196,9 @@ interface IPlatformCompat * @return An array of {@link CompatChangeInfo} known to the service. */ CompatibilityChangeInfo[] listAllChanges(); + + /** + * Get an instance that can determine whether a changeid can be overridden for a package name. + */ + IOverrideValidator getOverrideValidator(); } diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.aidl b/core/java/com/android/internal/compat/OverrideAllowedState.aidl new file mode 100644 index 000000000000..10ceac786841 --- /dev/null +++ b/core/java/com/android/internal/compat/OverrideAllowedState.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +parcelable OverrideAllowedState;
\ No newline at end of file diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java new file mode 100644 index 000000000000..0c8aefebac0e --- /dev/null +++ b/core/java/com/android/internal/compat/OverrideAllowedState.java @@ -0,0 +1,136 @@ +/* + * 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.annotation.IntDef; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class contains all the possible override allowed states. + */ +public final class OverrideAllowedState implements Parcelable { + @IntDef({ + ALLOWED, + DISABLED_NOT_DEBUGGABLE, + DISABLED_NON_TARGET_SDK, + DISABLED_TARGET_SDK_TOO_HIGH, + PACKAGE_DOES_NOT_EXIST + }) + @Retention(RetentionPolicy.SOURCE) + public @interface State { + } + + /** + * Change can be overridden. + */ + public static final int ALLOWED = 0; + /** + * Change cannot be overridden, due to the app not being debuggable. + */ + public static final int DISABLED_NOT_DEBUGGABLE = 1; + /** + * Change cannot be overridden, due to the build being non-debuggable and the change being + * non-targetSdk. + */ + public static final int DISABLED_NON_TARGET_SDK = 2; + /** + * Change cannot be overridden, due to the app's targetSdk being above the change's targetSdk. + */ + public static final int DISABLED_TARGET_SDK_TOO_HIGH = 3; + /** + * Package does not exist. + */ + public static final int PACKAGE_DOES_NOT_EXIST = 4; + + @State + public final int state; + public final int appTargetSdk; + public final int changeIdTargetSdk; + + private OverrideAllowedState(Parcel parcel) { + state = parcel.readInt(); + appTargetSdk = parcel.readInt(); + changeIdTargetSdk = parcel.readInt(); + } + + public OverrideAllowedState(@State int state, int appTargetSdk, int changeIdTargetSdk) { + this.state = state; + this.appTargetSdk = appTargetSdk; + this.changeIdTargetSdk = changeIdTargetSdk; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(state); + out.writeInt(appTargetSdk); + out.writeInt(changeIdTargetSdk); + } + + /** + * Enforces the policy for overriding compat changes. + * + * @param changeId the change id that was attempted to be overridden. + * @param packageName the package for which the attempt was made. + * @throws SecurityException if the policy forbids this operation. + */ + public void enforce(long changeId, String packageName) + throws SecurityException { + switch (state) { + case ALLOWED: + return; + case DISABLED_NOT_DEBUGGABLE: + throw new SecurityException( + "Cannot override a change on a non-debuggable app and user build."); + case DISABLED_NON_TARGET_SDK: + throw new SecurityException( + "Cannot override a default enabled/disabled change on a user build."); + case DISABLED_TARGET_SDK_TOO_HIGH: + throw new SecurityException(String.format( + "Cannot override %1$d for %2$s because the app's targetSdk (%3$d) is " + + "above the change's targetSdk threshold (%4$d)", + changeId, packageName, appTargetSdk, changeIdTargetSdk)); + case PACKAGE_DOES_NOT_EXIST: + throw new SecurityException(String.format( + "Cannot override %1$d for %2$s because the package does not exist, and " + + "the change is targetSdk gated.", + changeId, packageName)); + } + } + + public static final @NonNull + Parcelable.Creator<OverrideAllowedState> CREATOR = + new Parcelable.Creator<OverrideAllowedState>() { + public OverrideAllowedState createFromParcel(Parcel parcel) { + OverrideAllowedState info = new OverrideAllowedState(parcel); + return info; + } + + public OverrideAllowedState[] newArray(int size) { + return new OverrideAllowedState[size]; + } + }; +} |
