blob: 932ec643d47854ee0f1b5304c6d2ae04a0624aaa [file] [log] [blame]
Andrei Onea02d81c02019-11-18 14:21:44 +00001/*
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
17package android.compat.testing;
18
19import android.app.Instrumentation;
20import android.compat.Compatibility;
21import android.compat.Compatibility.ChangeConfig;
22import android.content.Context;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25import android.support.test.InstrumentationRegistry;
26
27import com.android.internal.compat.CompatibilityChangeConfig;
28import com.android.internal.compat.IPlatformCompat;
29
30import libcore.junit.util.compat.CoreCompatChangeRule;
31
32import org.junit.runners.model.Statement;
33
34/**
35 * Allows tests to specify the which change to disable.
36 *
37 * <p>To use add the following to the test class. It will only change the behavior of a test method
38 * if it is annotated with
39 * {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or
40 * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges}.
41 * </p>
42 * <pre>
43 * @Rule
44 * public TestRule compatChangeRule = new PlatformCompatChangeRule();
45 * </pre>
46 *
47 * <p>Each test method that needs to disable a specific change needs to be annotated
48 * with {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or
49 * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} specifying the change
50 * id. e.g.:
51 * </p>
52 * <pre>
53 * @Test
54 * @DisableCompatChanges({42})
55 * public void testAsIfChange42Disabled() {
56 * // check behavior
57 * }
58 *
59 * @Test
60 * @EnableCompatChanges({42})
61 * public void testAsIfChange42Enabled() {
62 * // check behavior
63 *
64 * </pre>
65 */
66public class PlatformCompatChangeRule extends CoreCompatChangeRule {
67
68 @Override
69 protected Statement createStatementForConfig(final Statement statement, ChangeConfig config) {
70 return new CompatChangeStatement(statement, config);
71 }
72
73
74 private static class CompatChangeStatement extends Statement {
75 private final Statement mTestStatement;
76 private final ChangeConfig mConfig;
77
78 private CompatChangeStatement(Statement testStatement, ChangeConfig config) {
79 this.mTestStatement = testStatement;
80 this.mConfig = config;
81 }
82
83 @Override
84 public void evaluate() throws Throwable {
85 Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
86 String packageName = instrumentation.getTargetContext().getPackageName();
87 IPlatformCompat platformCompat = IPlatformCompat.Stub
88 .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
89 if (platformCompat == null) {
90 throw new IllegalStateException("Could not get IPlatformCompat service!");
91 }
92 Compatibility.setOverrides(mConfig);
93 try {
94 platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
95 packageName);
96 try {
97 mTestStatement.evaluate();
98 } finally {
99 platformCompat.clearOverridesForTest(packageName);
100 }
101 } catch (RemoteException e) {
102 throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
103 } finally {
104 Compatibility.clearOverrides();
105 }
106 }
107 }
108}