/* * Copyright (C) 2018 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.contentcaptureservice.cts; import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE; import static android.contentcaptureservice.cts.Helper.MY_PACKAGE; import static android.contentcaptureservice.cts.Helper.resetService; import static android.contentcaptureservice.cts.Helper.sContext; import static android.contentcaptureservice.cts.Helper.sUserSettings; import static android.contentcaptureservice.cts.Helper.setService; import static android.contentcaptureservice.cts.Helper.toSet; import static android.provider.Settings.Secure.CONTENT_CAPTURE_ENABLED; import static com.android.compatibility.common.util.ShellUtils.runShellCommand; import android.content.ComponentName; import android.content.ContentCaptureOptions; import android.contentcaptureservice.cts.CtsContentCaptureService.ServiceWatcher; import android.provider.DeviceConfig; import android.util.Log; import android.util.Pair; import android.view.contentcapture.ContentCaptureManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.compatibility.common.util.DeviceConfigStateChangerRule; import com.android.compatibility.common.util.DeviceConfigStateManager; import com.android.compatibility.common.util.RequiredServiceRule; import com.android.compatibility.common.util.SafeCleanerRule; import com.android.compatibility.common.util.SettingsStateChangerRule; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.junit.runners.model.Statement; import java.util.Set; /** * Base class for all (or most :-) integration tests in this CTS suite. */ @RunWith(AndroidJUnit4.class) public abstract class AbstractContentCaptureIntegrationTest { private static final String TAG = AbstractContentCaptureIntegrationTest.class.getSimpleName(); protected static final DeviceConfigStateManager sKillSwitchManager = new DeviceConfigStateManager(sContext, DeviceConfig.NAMESPACE_CONTENT_CAPTURE, ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED); protected final String mTag = getClass().getSimpleName(); private final RequiredServiceRule mRequiredServiceRule = new RequiredServiceRule(CONTENT_CAPTURE_MANAGER_SERVICE); private final DeviceConfigStateChangerRule mVerboseLoggingRule = new DeviceConfigStateChangerRule( sContext, DeviceConfig.NAMESPACE_CONTENT_CAPTURE, ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL, Integer.toString(ContentCaptureManager.LOGGING_LEVEL_VERBOSE)); private final ContentCaptureLoggingTestRule mLoggingRule = new ContentCaptureLoggingTestRule(); /** * Watcher set on {@link #enableService()} and used to wait until it's gone after the test * finishes. */ private ServiceWatcher mServiceWatcher; protected final SafeCleanerRule mSafeCleanerRule = new SafeCleanerRule() .setDumper(mLoggingRule) .add(() -> { return CtsContentCaptureService.getExceptions(); }); private final TestRule mServiceDisablerRule = (base, description) -> { return new Statement() { @Override public void evaluate() throws Throwable { try { base.evaluate(); } finally { Log.v(mTag, "@mServiceDisablerRule: safelyDisableService()"); safelyDisableService(); } } }; }; private void safelyDisableService() { try { resetService(); if (mServiceWatcher != null) { mServiceWatcher.waitOnDestroy(); } } catch (Throwable t) { Log.e(TAG, "error disabling service", t); } } private final DeviceConfigStateChangerRule mKillSwitchKillerRule = new DeviceConfigStateChangerRule(sKillSwitchManager, "true"); private final SettingsStateChangerRule mFeatureEnablerRule = new SettingsStateChangerRule( sContext, CONTENT_CAPTURE_ENABLED, "1"); @Rule public final RuleChain mLookAllTheseRules = RuleChain // mRequiredServiceRule should be first so the test can be skipped right away .outerRule(mRequiredServiceRule) // service must be disable at the last step, otherwise it's contents are not dump in // case of error .around(mServiceDisablerRule) // log everything .around(mVerboseLoggingRule) // enable it as soon as possible, as it have to wait for the listener .around(mKillSwitchKillerRule) .around(mFeatureEnablerRule) // mLoggingRule wraps the test but doesn't interfere with it .around(mLoggingRule) // mSafeCleanerRule will catch errors .around(mSafeCleanerRule) // Finally, let subclasses set their own rule .around(getMainTestRule()); /** * Hack to make sure ContentCapture is available for the CTS test package. * *
It must be set here because when the application starts it queries the server, at which
* point our service is not set yet.
*/
// TODO: remove this hack if we ever split the CTS module in multiple APKs
@BeforeClass
public static void whitelistSelf() {
final ContentCaptureOptions options = ContentCaptureOptions.forWhitelistingItself();
Log.v(TAG, "@BeforeClass: whitelistSelf(): options=" + options);
sContext.getApplicationContext().setContentCaptureOptions(options);
}
@AfterClass
public static void unWhitelistSelf() {
Log.v(TAG, "@afterClass: unWhitelistSelf()");
sContext.getApplicationContext().setContentCaptureOptions(null);
}
@BeforeClass
public static void disableDefaultService() {
Log.v(TAG, "@BeforeClass: disableDefaultService()");
Helper.setDefaultServiceEnabled(false);
}
@AfterClass
public static void enableDefaultService() {
Log.v(TAG, "@AfterClass: enableDefaultService()");
Helper.setDefaultServiceEnabled(true);
}
@Before
public void prepareDevice() throws Exception {
Log.v(mTag, "@Before: prepareDevice()");
// Unlock screen.
runShellCommand("input keyevent KEYCODE_WAKEUP");
// Dismiss keyguard, in case it's set as "Swipe to unlock".
runShellCommand("wm dismiss-keyguard");
// Collapse notifications.
runShellCommand("cmd statusbar collapse");
}
@Before
public void clearState() {
Log.v(mTag, "@Before: clearState()");
CtsContentCaptureService.resetStaticState();
}
@After
public void clearServiceWatcher() {
Log.v(mTag, "@After: clearServiceWatcher()");
CtsContentCaptureService.clearServiceWatcher();
}
@Nullable
public static void setFeatureEnabledBySettings(@Nullable boolean enabled) {
sUserSettings.syncSet(CONTENT_CAPTURE_ENABLED, enabled ? "1" : "0");
}
/**
* Sets {@link CtsContentCaptureService} as the service for the current user and waits until
* its created, then allowlist the CTS test package.
*/
public CtsContentCaptureService enableService() throws InterruptedException {
return enableService(toSet(MY_PACKAGE), /* whitelistedComponents= */ null);
}
public CtsContentCaptureService enableService(@Nullable Set