• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.translation.cts;
18 
19 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
20 
21 import android.app.Instrumentation;
22 import android.app.UiAutomation;
23 import android.content.ContentCaptureOptions;
24 import android.content.Context;
25 import android.graphics.Bitmap;
26 import android.os.UserHandle;
27 import android.util.Log;
28 
29 import androidx.test.InstrumentationRegistry;
30 import androidx.test.uiautomator.By;
31 import androidx.test.uiautomator.UiDevice;
32 import androidx.test.uiautomator.UiObject2;
33 import androidx.test.uiautomator.Until;
34 
35 import com.android.compatibility.common.util.BitmapUtils;
36 
37 import java.io.File;
38 import java.io.IOException;
39 
40 /**
41  * Helper for common funcionalities.
42  */
43 public final class Helper {
44 
45     private static final String TAG = "Helper";
46 
47     public static final String ACTIVITY_PACKAGE = "android.translation.cts";
48 
49     public static final String ACTION_REGISTER_UI_TRANSLATION_CALLBACK =
50             "android.translation.cts.action.REGISTER_UI_TRANSLATION_CALLBACK";
51     public static final String ACTION_UNREGISTER_UI_TRANSLATION_CALLBACK =
52             "android.translation.cts.action.UNREGISTER_UI_TRANSLATION_CALLBACK";
53     public static final String ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_START =
54             "android.translation.cts.action.ASSERT_UI_TRANSLATION_CALLBACK_ON_START";
55     public static final String ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_FINISH =
56             "android.translation.cts.action.ASSERT_UI_TRANSLATION_CALLBACK_ON_FINISH";
57     public static final String ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_RESUME =
58             "android.translation.cts.action.ASSERT_UI_TRANSLATION_CALLBACK_ON_RESUME";
59     public static final String ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_PAUSE =
60             "android.translation.cts.action.ASSERT_UI_TRANSLATION_CALLBACK_ON_PAUSE";
61 
62     public static final String EXTRA_FINISH_COMMAND = "finish_command";
63     public static final String EXTRA_SOURCE_LOCALE = "source_locale";
64     public static final String EXTRA_TARGET_LOCALE = "target_locale";
65     public static final String EXTRA_PACKAGE_NAME = "package_name";
66     public static final String EXTRA_CALL_COUNT = "call_count";
67 
68     public static final String CUSTOM_TRANSLATION_ID_MY_TAG = "myTag";
69     public static final String LOCAL_TEST_FILES_DIR = "/sdcard/CtsTranslationTestCases";
70     public static final int TEMP_SERVICE_DURATION_MS = 30_000;
71 
72     private static final String LOG_TAG = "log.tag.UiTranslation";
73 
74     /**
75      * Sets the translation service temporarily.
76      *
77      * @param service name of temporary translation service.
78      */
setTemporaryTranslationService(String service)79     public static void setTemporaryTranslationService(String service) {
80         Log.d(TAG, "Setting translation service to " + service);
81         final int userId = UserHandle.myUserId();
82         runShellCommand("cmd translation set temporary-service %d %s %d", userId, service,
83                 TEMP_SERVICE_DURATION_MS);
84     }
85 
86     /**
87      * Resets the translation service.
88      */
resetTemporaryTranslationService()89     public static void resetTemporaryTranslationService() {
90         final int userId = UserHandle.myUserId();
91         Log.d(TAG, "Resetting back user " + userId + " to default translation service");
92         runShellCommand("cmd translation set temporary-service %d", userId);
93     }
94 
95     /**
96      * Sets the content capture service temporarily.
97      *
98      * @param service name of temporary translation service.
99      */
setTemporaryContentCaptureService(String service)100     public static void setTemporaryContentCaptureService(String service) {
101         Log.d(TAG, "Setting content capture service to " + service);
102         final int userId = UserHandle.myUserId();
103         runShellCommand("cmd content_capture set temporary-service %d %s %d", userId, service,
104                 TEMP_SERVICE_DURATION_MS);
105     }
106 
107     /**
108      * Resets the content capture service.
109      */
resetTemporaryContentCaptureService()110     public static void resetTemporaryContentCaptureService() {
111         final int userId = UserHandle.myUserId();
112         Log.d(TAG, "Resetting back user " + userId + " to default service");
113         runShellCommand("cmd content_capture set temporary-service %d", userId);
114     }
115 
116     /**
117      * Enable or disable the default content capture service.
118      *
119      * @param enabled {@code true} to enable default content capture service.
120      */
setDefaultContentCaptureServiceEnabled(boolean enabled)121     public static void setDefaultContentCaptureServiceEnabled(boolean enabled) {
122         final int userId = UserHandle.myUserId();
123         Log.d(TAG, "setDefaultServiceEnabled(user=" + userId + ", enabled= " + enabled + ")");
124         runShellCommand("cmd content_capture set default-service-enabled %d %s", userId,
125                 Boolean.toString(enabled));
126     }
127 
128     /**
129      * Add the cts itself into content capture allow list.
130      *
131      * @param context Context of the app.
132      */
allowSelfForContentCapture(Context context)133     public static void allowSelfForContentCapture(Context context) {
134         final ContentCaptureOptions options = ContentCaptureOptions.forWhitelistingItself();
135         Log.v(TAG, "allowSelfForContentCapture(): options=" + options);
136         context.getApplicationContext().setContentCaptureOptions(options);
137     }
138 
139     /**
140      * Reset the cts itself from content capture allow list.
141      *
142      * @param context Context of the app.
143      */
unAllowSelfForContentCapture(Context context)144     public static void unAllowSelfForContentCapture(Context context) {
145         Log.v(TAG, "unAllowSelfForContentCapture()");
146         context.getApplicationContext().setContentCaptureOptions(null);
147     }
148 
149     /**
150      * Return a ui object for resource id.
151      *
152      * @param resourcePackage  package of the object
153      * @param resourceId the resource id of the object
154      */
findObjectByResId(String resourcePackage, String resourceId)155     public static UiObject2 findObjectByResId(String resourcePackage, String resourceId) {
156         final UiDevice uiDevice =
157                 UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
158         final UiObject2 foundObj = uiDevice.wait(
159                         Until.findObject(By.res(resourcePackage, resourceId)), 5_000L);
160         return foundObj;
161     }
162 
163     /**
164      * Enable DEBUG log and returns the original log level value.
165      */
enableDebugLog()166     public static String enableDebugLog() {
167         String originalValue = System.getProperty(LOG_TAG, "");
168         System.setProperty(LOG_TAG, "DEBUG");
169         Log.d(TAG, "enableDebugLog(), original value = " + originalValue);
170         return originalValue;
171     }
172 
173     /**
174      * Disable debug log.
175      *
176      * @param level the log level. The value can be DEBUG, INFO, VERBOSE or empty if not set.
177      */
disableDebugLog(String level)178     public static void disableDebugLog(String level) {
179         Log.d(TAG, "disableDebugLog(), set level  " + level);
180         System.setProperty(LOG_TAG, level);
181     }
182 
183     // TODO: Move to a library that can be shared for smart os components.
184     /**
185      * Takes a screenshot and save it in the file system for analysis.
186      */
takeScreenshotAndSave(Context context, String testName, String targetFolder)187     public static void takeScreenshotAndSave(Context context, String testName,
188             String targetFolder) {
189         File file = null;
190         try {
191             file = createTestFile(testName,"sreenshot.png", targetFolder);
192             if (file != null) {
193                 Log.i(TAG, "Taking screenshot on " + file);
194                 final Bitmap screenshot = takeScreenshot();
195                 saveBitmapToFile(screenshot, file);
196             }
197         } catch (Exception e) {
198             Log.e(TAG, "Error taking screenshot and saving on " + file, e);
199         }
200     }
201 
saveBitmapToFile(Bitmap bitmap, File file)202     public static File saveBitmapToFile(Bitmap bitmap, File file) {
203         Log.i(TAG, "Saving bitmap at " + file);
204         BitmapUtils.saveBitmap(bitmap, file.getParent(), file.getName());
205         return file;
206     }
207 
takeScreenshot()208     private static Bitmap takeScreenshot() {
209         final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
210         UiAutomation automan = instrumentation.getUiAutomation();
211         final Bitmap bitmap = automan.takeScreenshot();
212         return bitmap;
213     }
214 
createTestFile(String testName, String name, String targetFolder)215     public static File createTestFile(String testName, String name, String targetFolder)
216             throws IOException {
217         final File dir = getLocalDirectory(targetFolder);
218         if (dir == null) return null;
219         final String prefix = testName.replaceAll("\\.|\\(|\\/", "_").replaceAll("\\)", "");
220         final String filename = prefix + "-" + name;
221 
222         return createFile(dir, filename);
223     }
224 
getLocalDirectory(String targetFolder)225     private static File getLocalDirectory(String targetFolder) {
226         final File dir = new File(targetFolder);
227         dir.mkdirs();
228         if (!dir.exists()) {
229             Log.e(TAG, "Could not create directory " + dir);
230             return null;
231         }
232         return dir;
233     }
234 
createFile(File dir, String filename)235     private static File createFile(File dir, String filename) throws IOException {
236         final File file = new File(dir, filename);
237         if (file.exists()) {
238             Log.v(TAG, "Deleting file " + file);
239             file.delete();
240         }
241         if (!file.createNewFile()) {
242             Log.e(TAG, "Could not create file " + file);
243             return null;
244         }
245         return file;
246     }
247 }
248