1 /*
2  * Copyright (C) 2017 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 
17 package android.autofillservice.cts;
18 
19 import static android.autofillservice.cts.Helper.getContext;
20 import static android.autofillservice.cts.Helper.getLoggingLevel;
21 import static android.autofillservice.cts.Helper.hasAutofillFeature;
22 import static android.autofillservice.cts.Helper.setLoggingLevel;
23 import static android.autofillservice.cts.InstrumentedAutoFillService.SERVICE_NAME;
24 import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
25 
26 import android.autofillservice.cts.InstrumentedAutoFillService.Replier;
27 import android.autofillservice.cts.common.SettingsStateKeeperRule;
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.provider.Settings;
31 import android.support.test.InstrumentationRegistry;
32 import android.support.test.runner.AndroidJUnit4;
33 import android.util.Log;
34 import android.widget.RemoteViews;
35 
36 import com.android.compatibility.common.util.RequiredFeatureRule;
37 
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.BeforeClass;
41 import org.junit.ClassRule;
42 import org.junit.Rule;
43 import org.junit.rules.TestWatcher;
44 import org.junit.runner.Description;
45 import org.junit.runner.RunWith;
46 
47 /**
48  * Base class for all other tests.
49  */
50 @RunWith(AndroidJUnit4.class)
51 // NOTE: @ClassRule requires it to be public
52 public abstract class AutoFillServiceTestCase {
53     private static final String TAG = "AutoFillServiceTestCase";
54 
55     static final UiBot sDefaultUiBot = new UiBot();
56 
57     protected static final Replier sReplier = InstrumentedAutoFillService.getReplier();
58 
59     private static final Context sContext = InstrumentationRegistry.getTargetContext();
60 
61     @ClassRule
62     public static final SettingsStateKeeperRule mServiceSettingsKeeper =
63             new SettingsStateKeeperRule(sContext, Settings.Secure.AUTOFILL_SERVICE);
64 
65     @Rule
66     public final TestWatcher watcher = new TestWatcher() {
67         @Override
68         protected void starting(Description description) {
69             JUnitHelper.setCurrentTestName(description.getDisplayName());
70         }
71 
72         @Override
73         protected void finished(Description description) {
74             JUnitHelper.setCurrentTestName(null);
75         }
76     };
77 
78     @Rule
79     public final RetryRule mRetryRule = new RetryRule(2);
80 
81     @Rule
82     public final AutofillLoggingTestRule mLoggingRule = new AutofillLoggingTestRule(TAG);
83 
84     @Rule
85     public final RequiredFeatureRule mRequiredFeatureRule =
86             new RequiredFeatureRule(PackageManager.FEATURE_AUTOFILL);
87 
88     @Rule
89     public final SafeCleanerRule mSafeCleanerRule = new SafeCleanerRule()
90             .setDumper(mLoggingRule)
91             .run(() -> sReplier.assertNoUnhandledFillRequests())
92             .run(() -> sReplier.assertNoUnhandledSaveRequests())
93             .add(() -> { return sReplier.getExceptions(); });
94 
95     protected final Context mContext = sContext;
96     protected final String mPackageName;
97     protected final UiBot mUiBot;
98 
99     /**
100      * Stores the previous logging level so it's restored after the test.
101      */
102     private String mLoggingLevel;
103 
AutoFillServiceTestCase()104     protected AutoFillServiceTestCase() {
105         this(sDefaultUiBot);
106     }
107 
AutoFillServiceTestCase(UiBot uiBot)108     protected AutoFillServiceTestCase(UiBot uiBot) {
109         mPackageName = mContext.getPackageName();
110         mUiBot = uiBot;
111         mUiBot.reset();
112     }
113 
114     @BeforeClass
prepareScreen()115     public static void prepareScreen() throws Exception {
116         if (!hasAutofillFeature()) return;
117 
118         // Unlock screen.
119         runShellCommand("input keyevent KEYCODE_WAKEUP");
120 
121         // Collapse notifications.
122         runShellCommand("cmd statusbar collapse");
123 
124         // Set orientation as portrait, otherwise some tests might fail due to elements not fitting
125         // in, IME orientation, etc...
126         sDefaultUiBot.setScreenOrientation(UiBot.PORTRAIT);
127     }
128 
129     @Before
cleanupStaticState()130     public void cleanupStaticState() {
131         Helper.preTestCleanup();
132         sReplier.reset();
133     }
134 
135     @Before
setVerboseLogging()136     public void setVerboseLogging() {
137         try {
138             mLoggingLevel = getLoggingLevel();
139         } catch (Exception e) {
140             Log.w(TAG, "Could not get previous logging level: " + e);
141             mLoggingLevel = "debug";
142         }
143         try {
144             setLoggingLevel("verbose");
145         } catch (Exception e) {
146             Log.w(TAG, "Could not change logging level to verbose: " + e);
147         }
148     }
149 
150     /**
151      * Cleans up activities that might have been left over.
152      */
153     @Before
154     @After
finishActivities()155     public void finishActivities() {
156         WelcomeActivity.finishIt(mUiBot);
157     }
158 
159     @After
resetVerboseLogging()160     public void resetVerboseLogging() {
161         try {
162             setLoggingLevel(mLoggingLevel);
163         } catch (Exception e) {
164             Log.w(TAG, "Could not restore logging level to " + mLoggingLevel + ": " + e);
165         }
166     }
167 
168     @After
ignoreFurtherRequests()169     public void ignoreFurtherRequests() {
170         InstrumentedAutoFillService.setIgnoreUnexpectedRequests(true);
171     }
172 
173     /**
174      * Enables the {@link InstrumentedAutoFillService} for autofill for the current user.
175      */
enableService()176     protected void enableService() {
177         Helper.enableAutofillService(getContext(), SERVICE_NAME);
178         InstrumentedAutoFillService.setIgnoreUnexpectedRequests(false);
179     }
180 
181     /**
182      * Disables the {@link InstrumentedAutoFillService} for autofill for the current user.
183      */
disableService()184     protected void disableService() {
185         if (!hasAutofillFeature()) return;
186 
187         Helper.disableAutofillService(getContext(), SERVICE_NAME);
188         InstrumentedAutoFillService.setIgnoreUnexpectedRequests(true);
189     }
190 
191     /**
192      * Asserts that the {@link InstrumentedAutoFillService} is enabled for the default user.
193      */
assertServiceEnabled()194     protected void assertServiceEnabled() {
195         Helper.assertAutofillServiceStatus(SERVICE_NAME, true);
196     }
197 
198     /**
199      * Asserts that the {@link InstrumentedAutoFillService} is disabled for the default user.
200      */
assertServiceDisabled()201     protected void assertServiceDisabled() {
202         Helper.assertAutofillServiceStatus(SERVICE_NAME, false);
203     }
204 
createPresentation(String message)205     protected RemoteViews createPresentation(String message) {
206         final RemoteViews presentation = new RemoteViews(getContext()
207                 .getPackageName(), R.layout.list_item);
208         presentation.setTextViewText(R.id.text1, message);
209         return presentation;
210     }
211 }
212