Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2018 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 package android.contentcaptureservice.cts;
     17 
     18 import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
     19 import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
     20 import static android.contentcaptureservice.cts.Helper.resetService;
     21 import static android.contentcaptureservice.cts.Helper.sContext;
     22 import static android.contentcaptureservice.cts.Helper.setService;
     23 import static android.contentcaptureservice.cts.Helper.toSet;
     24 import static android.provider.Settings.Secure.CONTENT_CAPTURE_ENABLED;
     25 
     26 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
     27 
     28 import android.content.ComponentName;
     29 import android.content.ContentCaptureOptions;
     30 import android.contentcaptureservice.cts.CtsContentCaptureService.ServiceWatcher;
     31 import android.provider.DeviceConfig;
     32 import android.util.Log;
     33 import android.util.Pair;
     34 import android.view.contentcapture.ContentCaptureManager;
     35 
     36 import androidx.annotation.NonNull;
     37 import androidx.annotation.Nullable;
     38 import androidx.test.ext.junit.runners.AndroidJUnit4;
     39 
     40 import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
     41 import com.android.compatibility.common.util.DeviceConfigStateManager;
     42 import com.android.compatibility.common.util.RequiredServiceRule;
     43 import com.android.compatibility.common.util.SafeCleanerRule;
     44 import com.android.compatibility.common.util.SettingsStateChangerRule;
     45 import com.android.compatibility.common.util.SettingsUtils;
     46 
     47 import org.junit.AfterClass;
     48 import org.junit.Before;
     49 import org.junit.BeforeClass;
     50 import org.junit.Rule;
     51 import org.junit.rules.RuleChain;
     52 import org.junit.rules.TestRule;
     53 import org.junit.runner.RunWith;
     54 import org.junit.runners.model.Statement;
     55 
     56 import java.util.Set;
     57 
     58 /**
     59  * Base class for all (or most :-) integration tests in this CTS suite.
     60  */
     61 @RunWith(AndroidJUnit4.class)
     62 public abstract class AbstractContentCaptureIntegrationTest {
     63 
     64     private static final String TAG = AbstractContentCaptureIntegrationTest.class.getSimpleName();
     65 
     66     protected static final DeviceConfigStateManager sKillSwitchManager =
     67             new DeviceConfigStateManager(sContext, DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
     68             ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED);
     69 
     70     protected final String mTag = getClass().getSimpleName();
     71 
     72     private final RequiredServiceRule mRequiredServiceRule =
     73             new RequiredServiceRule(CONTENT_CAPTURE_MANAGER_SERVICE);
     74 
     75     private final DeviceConfigStateChangerRule mVerboseLoggingRule =
     76             new DeviceConfigStateChangerRule(
     77             sContext, DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
     78             ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL,
     79             Integer.toString(ContentCaptureManager.LOGGING_LEVEL_VERBOSE));
     80 
     81     private final ContentCaptureLoggingTestRule mLoggingRule = new ContentCaptureLoggingTestRule();
     82 
     83     /**
     84      * Watcher set on {@link #enableService()} and used to wait until it's gone after the test
     85      * finishes.
     86      */
     87     private ServiceWatcher mServiceWatcher;
     88 
     89     protected final SafeCleanerRule mSafeCleanerRule = new SafeCleanerRule()
     90             .setDumper(mLoggingRule)
     91             .add(() -> {
     92                 return CtsContentCaptureService.getExceptions();
     93             });
     94 
     95     private final TestRule mServiceDisablerRule = (base, description) -> {
     96         return new Statement() {
     97             @Override
     98             public void evaluate() throws Throwable {
     99                 try {
    100                     base.evaluate();
    101                 } finally {
    102                     Log.v(mTag, "@mServiceDisablerRule: safelyDisableService()");
    103                     safelyDisableService();
    104                 }
    105             }
    106         };
    107     };
    108 
    109     private void safelyDisableService() {
    110         try {
    111             resetService();
    112 
    113             if (mServiceWatcher != null) {
    114                 mServiceWatcher.waitOnDestroy();
    115             }
    116         } catch (Throwable t) {
    117             Log.e(TAG, "error disablign service", t);
    118         }
    119     }
    120 
    121     private final DeviceConfigStateChangerRule mKillSwitchKillerRule =
    122             new DeviceConfigStateChangerRule(sKillSwitchManager, "true");
    123 
    124     private final SettingsStateChangerRule mFeatureEnablerRule = new SettingsStateChangerRule(
    125             sContext, CONTENT_CAPTURE_ENABLED, "1");
    126 
    127     @Rule
    128     public final RuleChain mLookAllTheseRules = RuleChain
    129             // mRequiredServiceRule should be first so the test can be skipped right away
    130             .outerRule(mRequiredServiceRule)
    131 
    132             // service must be disable at the last step, otherwise it's contents are not dump in
    133             // case of error
    134             .around(mServiceDisablerRule)
    135 
    136             // log everything
    137             .around(mVerboseLoggingRule)
    138 
    139             // enable it as soon as possible, as it have to wait for the listener
    140             .around(mKillSwitchKillerRule)
    141             .around(mFeatureEnablerRule)
    142 
    143             // mLoggingRule wraps the test but doesn't interfere with it
    144             .around(mLoggingRule)
    145 
    146             // mSafeCleanerRule will catch errors
    147             .around(mSafeCleanerRule)
    148 
    149             // Finally, let subclasses set their own rule
    150             .around(getMainTestRule());
    151 
    152     /**
    153      * Hack to make sure ContentCapture is available for the CTS test package.
    154      *
    155      * <p>It must be set here because when the application starts it queries the server, at which
    156      * point our service is not set yet.
    157      */
    158     // TODO: remove this hack if we ever split the CTS module in multiple APKs
    159     @BeforeClass
    160     public static void whitelistSelf() {
    161         final ContentCaptureOptions options = ContentCaptureOptions.forWhitelistingItself();
    162         Log.v(TAG, "@BeforeClass: whitelistSelf(): options=" + options);
    163         sContext.getApplicationContext().setContentCaptureOptions(options);
    164     }
    165 
    166     @AfterClass
    167     public static void unWhitelistSelf() {
    168         Log.v(TAG, "@afterClass: unWhitelistSelf()");
    169         sContext.getApplicationContext().setContentCaptureOptions(null);
    170     }
    171 
    172     @BeforeClass
    173     public static void disableDefaultService() {
    174         Log.v(TAG, "@BeforeClass: disableDefaultService()");
    175         Helper.setDefaultServiceEnabled(false);
    176     }
    177 
    178     @AfterClass
    179     public static void enableDefaultService() {
    180         Log.v(TAG, "@AfterClass: enableDefaultService()");
    181         Helper.setDefaultServiceEnabled(true);
    182     }
    183 
    184     @Before
    185     public void prepareDevice() throws Exception {
    186         Log.v(mTag, "@Before: prepareDevice()");
    187 
    188         // Unlock screen.
    189         runShellCommand("input keyevent KEYCODE_WAKEUP");
    190 
    191         // Dismiss keyguard, in case it's set as "Swipe to unlock".
    192         runShellCommand("wm dismiss-keyguard");
    193 
    194         // Collapse notifications.
    195         runShellCommand("cmd statusbar collapse");
    196     }
    197 
    198     @Before
    199     public void clearState() {
    200         Log.v(mTag, "@Before: clearState()");
    201         CtsContentCaptureService.resetStaticState();
    202     }
    203 
    204     @Nullable
    205     public static void setFeatureEnabledBySettings(@Nullable boolean enabled) {
    206         SettingsUtils.syncSet(sContext, CONTENT_CAPTURE_ENABLED, enabled ? "1" : "0");
    207     }
    208 
    209     /**
    210      * Sets {@link CtsContentCaptureService} as the service for the current user and waits until
    211      * its created, then whitelist the CTS test package.
    212      */
    213     public CtsContentCaptureService enableService() throws InterruptedException {
    214         return enableService(toSet(MY_PACKAGE), /* whitelistedComponents= */ null);
    215     }
    216 
    217     public CtsContentCaptureService enableService(@Nullable Set<String> whitelistedPackages,
    218             @Nullable Set<ComponentName> whitelistedComponents) throws InterruptedException {
    219         return enableService(new Pair<>(whitelistedPackages, whitelistedComponents));
    220     }
    221 
    222     public CtsContentCaptureService enableService(
    223             @Nullable Pair<Set<String>, Set<ComponentName>> whitelist) throws InterruptedException {
    224         if (mServiceWatcher != null) {
    225             throw new IllegalStateException("There Can Be Only One!");
    226         }
    227         mServiceWatcher = CtsContentCaptureService.setServiceWatcher();
    228         setService(CtsContentCaptureService.SERVICE_NAME);
    229 
    230         mServiceWatcher.whitelist(whitelist);
    231 
    232         return mServiceWatcher.waitOnCreate();
    233     }
    234 
    235     /**
    236      * Gets the test-specific {@link Rule}.
    237      */
    238     @NonNull
    239     protected abstract TestRule getMainTestRule();
    240 }
    241