blob: 932ec643d47854ee0f1b5304c6d2ae04a0624aaa [file] [log] [blame]
/*
* 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.testing;
import android.app.Instrumentation;
import android.compat.Compatibility;
import android.compat.Compatibility.ChangeConfig;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.support.test.InstrumentationRegistry;
import com.android.internal.compat.CompatibilityChangeConfig;
import com.android.internal.compat.IPlatformCompat;
import libcore.junit.util.compat.CoreCompatChangeRule;
import org.junit.runners.model.Statement;
/**
* Allows tests to specify the which change to disable.
*
* <p>To use add the following to the test class. It will only change the behavior of a test method
* if it is annotated with
* {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or
* {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges}.
* </p>
* <pre>
* @Rule
* public TestRule compatChangeRule = new PlatformCompatChangeRule();
* </pre>
*
* <p>Each test method that needs to disable a specific change needs to be annotated
* with {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or
* {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} specifying the change
* id. e.g.:
* </p>
* <pre>
* @Test
* @DisableCompatChanges({42})
* public void testAsIfChange42Disabled() {
* // check behavior
* }
*
* @Test
* @EnableCompatChanges({42})
* public void testAsIfChange42Enabled() {
* // check behavior
*
* </pre>
*/
public class PlatformCompatChangeRule extends CoreCompatChangeRule {
@Override
protected Statement createStatementForConfig(final Statement statement, ChangeConfig config) {
return new CompatChangeStatement(statement, config);
}
private static class CompatChangeStatement extends Statement {
private final Statement mTestStatement;
private final ChangeConfig mConfig;
private CompatChangeStatement(Statement testStatement, ChangeConfig config) {
this.mTestStatement = testStatement;
this.mConfig = config;
}
@Override
public void evaluate() throws Throwable {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
String packageName = instrumentation.getTargetContext().getPackageName();
IPlatformCompat platformCompat = IPlatformCompat.Stub
.asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
if (platformCompat == null) {
throw new IllegalStateException("Could not get IPlatformCompat service!");
}
Compatibility.setOverrides(mConfig);
try {
platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
packageName);
try {
mTestStatement.evaluate();
} finally {
platformCompat.clearOverridesForTest(packageName);
}
} catch (RemoteException e) {
throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
} finally {
Compatibility.clearOverrides();
}
}
}
}