diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-06-23 02:18:57 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-06-23 02:18:57 +0000 |
commit | 2c13a653310943d23c194c4f2389184c90102628 (patch) | |
tree | 97122709e8c324cf90c35713a7a2c0c2022f9dbb | |
parent | e6ba9a8ea3bb218aab7ee0a0494b052078d8ef9a (diff) | |
parent | a853069ae11bb2cd7b1412cb5826bd265caec7ad (diff) | |
download | cts-android12-mainline-documentsui-release.tar.gz |
Snap for 7483611 from a853069ae11bb2cd7b1412cb5826bd265caec7ad to mainline-documentsui-releaseandroid-mainline-12.0.0_r26android-mainline-12.0.0_r2aml_doc_310851020android12-mainline-documentsui-release
Change-Id: Ic70d3a0358037ccf8333c42818124f81e5fdd8ed
181 files changed, 3044 insertions, 1121 deletions
diff --git a/apps/CameraITS/tests/scene1_1/test_exposure.py b/apps/CameraITS/tests/scene1_1/test_exposure.py index 17cb5d797dc..dc0191801dd 100644 --- a/apps/CameraITS/tests/scene1_1/test_exposure.py +++ b/apps/CameraITS/tests/scene1_1/test_exposure.py @@ -220,11 +220,11 @@ class ExposureTest(its_base_test.ItsBaseTest): (THRESH_EXP_KNEE - e_test) / THRESH_EXP_KNEE) if not 0 <= s_test - s_res < s_test * THRESH_ROUND_DOWN_GAIN: raise AssertionError(f's_write: {s_test}, s_read: {s_res}, ' - f'TOL={THRESH_ROUND_DOWN_GAIN*100:.f%%}') + f'TOL={THRESH_ROUND_DOWN_GAIN*100}%') if not 0 <= e_test - e_res < e_test * thresh_round_down_exp: raise AssertionError(f'e_write: {e_test/1.0E6:.3f}ms, ' f'e_read: {e_res/1.0E6:.3f}ms, ' - f'TOL={thresh_round_down_exp*100:.f%%}') + f'TOL={thresh_round_down_exp*100}%') s_e_product_res = s_res * e_res req_res_ratio = s_e_product / s_e_product_res logging.debug('Capture result s: %d, e: %dns', s_res, e_res) diff --git a/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py b/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py index 6e9ee5d5b9e..e6667637906 100644 --- a/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py +++ b/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py @@ -41,7 +41,7 @@ class CameraLaunchSPerfClassTest(its_base_test.ItsBaseTest): camera_id=self.camera_id) as cam: camera_properties_utils.skip_unless( - cam.is_s_performance_class_primary_camera()) + cam.is_performance_class_primary_camera()) # Load chart for scene. props = cam.get_camera_properties() diff --git a/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py b/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py index 2fe71758a2f..ba4867bd0f7 100644 --- a/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py +++ b/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py @@ -41,7 +41,7 @@ class JpegCaptureSPerfClassTest(its_base_test.ItsBaseTest): camera_id=self.camera_id) as cam: camera_properties_utils.skip_unless( - cam.is_s_performance_class_primary_camera()) + cam.is_performance_class_primary_camera()) # Load chart for scene. props = cam.get_camera_properties() diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py index 1155fc937a8..4cd9e2da89e 100644 --- a/apps/CameraITS/utils/its_session_utils.py +++ b/apps/CameraITS/utils/its_session_utils.py @@ -1075,8 +1075,8 @@ class ItsSession(object): ' support') return data['strValue'] == 'true' - def is_s_performance_class_primary_camera(self): - """Query whether the camera device is a S performance class primary camera. + def is_performance_class_primary_camera(self): + """Query whether the camera device is an R or S performance class primary camera. A primary rear/front facing camera is a camera device with the lowest camera Id for that facing. @@ -1085,13 +1085,13 @@ class ItsSession(object): Boolean """ cmd = {} - cmd['cmdName'] = 'isSPerformanceClassPrimaryCamera' + cmd['cmdName'] = 'isPerformanceClassPrimaryCamera' cmd['cameraId'] = self._camera_id self.sock.send(json.dumps(cmd).encode() + '\n'.encode()) data, _ = self.__read_response_from_socket() - if data['tag'] != 'sPerformanceClassPrimaryCamera': - raise error_util.CameraItsError('Failed to query S performance class ' + if data['tag'] != 'performanceClassPrimaryCamera': + raise error_util.CameraItsError('Failed to query performance class ' 'primary camera') return data['strValue'] == 'true' diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index a4da030f0d1..f51141a06c1 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -94,6 +94,9 @@ removed once tests are refactored to use the proper IPC between theses users. --> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> + <!-- Needed for sensor tests --> + <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> + <application> <meta-data android:name="SuiteName" android:value="CTS_VERIFIER" /> @@ -4560,6 +4563,38 @@ android:value="config_hdmi_source" /> </activity> + <activity android:name=".tv.display.HotplugTestActivity" + android:label="@string/tv_hotplug_test" + android:exported="true" + android:configChanges="orientation|screenSize|density|smallestScreenSize|screenLayout"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + <meta-data android:name="test_category" android:value="@string/test_category_tv"/> + <meta-data android:name="test_required_features" + android:value="android.software.leanback"/> + <meta-data android:name="test_required_configs" + android:value="config_hdmi_source"/> + <meta-data android:name="display_mode" + android:value="multi_display_mode" /> + </activity> + + <activity android:name=".tv.display.ModeSwitchingTestActivity" + android:label="@string/tv_mode_switching_test" + android:exported="true" + android:configChanges="orientation|screenSize|density|smallestScreenSize|screenLayout"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + <meta-data android:name="test_category" android:value="@string/test_category_tv"/> + <meta-data android:name="test_required_features" + android:value="android.software.leanback"/> + <meta-data android:name="display_mode" + android:value="multi_display_mode" /> + </activity> + <activity android:name=".screenpinning.ScreenPinningTestActivity" android:exported="true" android:label="@string/screen_pinning_test"> diff --git a/apps/CtsVerifier/res/layout/policy_transparency_test.xml b/apps/CtsVerifier/res/layout/policy_transparency_test.xml index 131ff3e908d..f2a122612f9 100644 --- a/apps/CtsVerifier/res/layout/policy_transparency_test.xml +++ b/apps/CtsVerifier/res/layout/policy_transparency_test.xml @@ -19,7 +19,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="beforeDescendants" - android:focusableInTouchMode="true"> + android:focusableInTouchMode="true" + android:nextFocusDown="@+id/switch_widget"> <ScrollView android:layout_width="match_parent" android:layout_height="0dp" @@ -51,31 +52,36 @@ android:layout_height="wrap_content" android:paddingStart="8dp" android:paddingEnd="16dp" - android:visibility="gone" /> + android:visibility="gone" + android:nextFocusDown="@+id/edit_text_widget"/> <EditText android:id="@+id/edit_text_widget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="6" android:singleLine="true" android:gravity="center" - android:visibility="gone" /> + android:visibility="gone" + android:nextFocusDown="@+id/update_button"/> <Button android:id="@+id/update_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/policy_transparency_update_button_label" android:paddingStart="8dp" android:paddingEnd="16dp" - android:visibility="gone" /> + android:visibility="gone" + android:nextFocusDown="@+id/spinner_widget"/> <Spinner android:id="@+id/spinner_widget" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="gone" /> + android:visibility="gone" + android:nextFocusDown="@+id/open_settings_button"/> </LinearLayout> <Button android:id="@+id/open_settings_button" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/policy_transparency_open_settings_label" /> + android:text="@string/policy_transparency_open_settings_label" + android:nextFocusUp="@+id/switch_widget"/> <include layout="@layout/pass_fail_buttons"/> </LinearLayout>
\ No newline at end of file diff --git a/apps/CtsVerifier/res/layout/tv_instructions_and_video.xml b/apps/CtsVerifier/res/layout/tv_instructions_and_video.xml new file mode 100644 index 00000000000..d7dfe16fcda --- /dev/null +++ b/apps/CtsVerifier/res/layout/tv_instructions_and_video.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="50px" + android:paddingRight="50px"> + + <FrameLayout + android:id="@+id/instructions" + android:layout_width="match_parent" + android:layout_height="0px" + android:layout_weight="1"> + <LinearLayout + android:id="@+id/test_items" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + </LinearLayout> + </FrameLayout> + + <FrameLayout + android:id="@+id/videoframe" + android:layout_width="match_parent" + android:layout_height="0px" + android:layout_weight="2"> + <SurfaceView + android:id="@+id/surface" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center"> + </SurfaceView> + </FrameLayout> + + <include layout="@layout/pass_fail_buttons"/> + +</LinearLayout> diff --git a/apps/CtsVerifier/res/layout/tv_item.xml b/apps/CtsVerifier/res/layout/tv_item.xml index e2756ec5f98..21334d9ccdc 100644 --- a/apps/CtsVerifier/res/layout/tv_item.xml +++ b/apps/CtsVerifier/res/layout/tv_item.xml @@ -55,7 +55,6 @@ android:layout_height="wrap_content" android:id="@+id/loadingSpinner" android:layout_centerInParent="true" - android:layout_alignParentBottom="true" android:visibility="invisible"/> </RelativeLayout> diff --git a/apps/CtsVerifier/res/raw/bunny_1280x720_24fps_VP9.webm b/apps/CtsVerifier/res/raw/bunny_1280x720_24fps_VP9.webm Binary files differnew file mode 100644 index 00000000000..512e1f084ef --- /dev/null +++ b/apps/CtsVerifier/res/raw/bunny_1280x720_24fps_VP9.webm diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml index 264133aaf17..e3358bdf230 100644 --- a/apps/CtsVerifier/res/values/strings.xml +++ b/apps/CtsVerifier/res/values/strings.xml @@ -4778,6 +4778,7 @@ You should be prompted to select credentials; choose the ones you just installed <!-- Common strings for the TV Display tests --> <string name="tv_start_test">Start Test</string> + <string name="tv_done">Done</string> <!-- Audio Capabilities test --> <string name="tv_audio_capabilities_test">Audio Capabilities Test</string> @@ -4791,6 +4792,33 @@ You should be prompted to select credentials; choose the ones you just installed <string name="tv_audio_capabilities_atmos_supported">Does your Android TV device support Dolby Atmos (either passthrough or decode)? </string> + <!-- Hotplug Test --> + <string name="tv_hotplug_test">Hotplug Test</string> + <string name="tv_hotplug_test_info">This test checks whether DisplayManager responds correctly + to plugging and unplugging the HDMI cable. + </string> + <string name="tv_hotplug_disconnect_display"> + Press the "%1$s" button, disconnect the HDMI cable, wait 2 seconds and then connect the HDMI + cable again. + </string> + + <!-- Mode Switching Test --> + <string name="tv_mode_switching_test">Mode switching test</string> + <string name="tv_mode_switching_test_step_instruction"> + Click "Start Test" and then observe the video below. Testing transition from %1$s to %2$s. + </string> + <string name="tv_mode_switching_test_black_screen_question"> + Did the video playback experience an interruption, for example, a black or solid color + screen? + </string> + <string name="tv_mode_switching_test_is_video_ok"> + Does the video look okay? Click "No" if the video is not playing, there was a snow screen, + audio static, wrong colors, the video is displaced compared to before running the test or + if the video is not playing. Keep in mind that some stutter is expected when the video does + not match the refresh rate. + </string> + <string name="tv_mode_switching_test_mode_switch_step">Mode switch step</string> + <string name="overlay_view_text">Overlay View Dummy Text</string> <string name="custom_rating">Example of input app specific custom rating.</string> diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java index 10775fe7ccb..63d96879dea 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java @@ -148,6 +148,8 @@ public class ItsService extends Service implements SensorEventListener { // Supports at most RAW+YUV+JPEG, one surface each, plus optional background stream private static final int MAX_NUM_OUTPUT_SURFACES = 4; + // Performance class R version number + private static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R; // Performance class S version number private static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1; @@ -735,9 +737,9 @@ public class ItsService extends Service implements SensorEventListener { doCheckStreamCombination(cmdObj); } else if ("isCameraPrivacyModeSupported".equals(cmdObj.getString("cmdName"))) { doCheckCameraPrivacyModeSupport(); - } else if ("isSPerformanceClassPrimaryCamera".equals(cmdObj.getString("cmdName"))) { + } else if ("isPerformanceClassPrimaryCamera".equals(cmdObj.getString("cmdName"))) { String cameraId = cmdObj.getString("cameraId"); - doCheckSPerformanceClassPrimaryCamera(cameraId); + doCheckPerformanceClassPrimaryCamera(cameraId); } else if ("measureCameraLaunchMs".equals(cmdObj.getString("cmdName"))) { String cameraId = cmdObj.getString("cameraId"); doMeasureCameraLaunchMs(cameraId); @@ -1080,8 +1082,9 @@ public class ItsService extends Service implements SensorEventListener { hasPrivacySupport ? "true" : "false"); } - private void doCheckSPerformanceClassPrimaryCamera(String cameraId) throws ItsException { - boolean isSPerfClass = (Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S); + private void doCheckPerformanceClassPrimaryCamera(String cameraId) throws ItsException { + boolean isPerfClass = (Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S + || Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R); if (mItsCameraIdList == null) { mItsCameraIdList = ItsUtils.getItsCompatibleCameraIds(mCameraManager); @@ -1113,8 +1116,8 @@ public class ItsService extends Service implements SensorEventListener { throw new ItsException("Failed to get camera characteristics", e); } - mSocketRunnableObj.sendResponse("sPerformanceClassPrimaryCamera", - (isSPerfClass && isPrimaryCamera) ? "true" : "false"); + mSocketRunnableObj.sendResponse("performanceClassPrimaryCamera", + (isPerfClass && isPrimaryCamera) ? "true" : "false"); } private double invokeCameraPerformanceTest(Class testClass, String testName, diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/UnlockedDeviceRequiredTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/UnlockedDeviceRequiredTest.java index cdaee6620a8..d9f2093a1e0 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/security/UnlockedDeviceRequiredTest.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/UnlockedDeviceRequiredTest.java @@ -26,7 +26,6 @@ import android.app.FragmentTransaction; import android.app.KeyguardManager; import android.content.BroadcastReceiver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; @@ -520,13 +519,9 @@ public class UnlockedDeviceRequiredTest extends PassFailButtons.Activity { * @return {@code true} if the device meets the requirements for the test */ private boolean verifyTestRequirements() { - if (!mKeyguardManager.isDeviceSecure()) { - mTestState = STATE_AWAITING_LOCK_SCREEN_CONFIG; - return false; - } boolean requirementsMet = true; - // If the device was previously verified to not support biometric unlock then do not run - // this verification again. + // Check for biometric support at least once to ensure the user is not prompted to + // configure a biometric unlock if not supported by the device. if (mBiometricsSupported) { int biometricResponse = mBiometricManager.canAuthenticate( BiometricManager.Authenticators.BIOMETRIC_STRONG); @@ -535,14 +530,15 @@ public class UnlockedDeviceRequiredTest extends PassFailButtons.Activity { // boolean to indicate the lack of support to prevent this check on future // invocations. case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE: + case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE: mBiometricsSupported = false; - requirementsMet = true; break; // A success response indicates at least one biometric is registered for device // unlock. case BiometricManager.BIOMETRIC_SUCCESS: - requirementsMet = true; break; + // A response of none enrolled indicates the device has the hardware to support + // biometrics, but a biometric unlock has not yet been configured. case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED: mTestState = STATE_AWAITING_BIOMETRIC_CONFIG; requirementsMet = false; @@ -557,6 +553,10 @@ public class UnlockedDeviceRequiredTest extends PassFailButtons.Activity { break; } } + if (!mKeyguardManager.isDeviceSecure()) { + mTestState = STATE_AWAITING_LOCK_SCREEN_CONFIG; + requirementsMet = false; + } return requirementsMet; } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tunnelmode/MediaCodecFlushActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tunnelmode/MediaCodecFlushActivity.java index d99672d5e99..055f26f7af6 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tunnelmode/MediaCodecFlushActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tunnelmode/MediaCodecFlushActivity.java @@ -1,7 +1,5 @@ package com.android.cts.verifier.tunnelmode; -import android.app.Activity; -import android.content.res.Resources; import android.media.AudioManager; import android.media.cts.MediaCodecTunneledPlayer; import android.net.Uri; @@ -58,7 +56,7 @@ public class MediaCodecFlushActivity extends PassFailButtons.Activity { AudioManager am = (AudioManager) getApplicationContext().getSystemService(AUDIO_SERVICE); mAudioSessionId = am.generateAudioSessionId(); - mPlayer = new MediaCodecTunneledPlayer(mHolder, true, mAudioSessionId); + mPlayer = new MediaCodecTunneledPlayer(this, mHolder, true, mAudioSessionId); // TODO: Do not rely on the video being pre-loaded on the device Uri mediaUri = Uri.fromFile(new File("/data/local/tmp/video.webm")); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.java index 3e8790b3636..658a5fd8b9d 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.java @@ -104,17 +104,18 @@ public class AppLinkTestActivity extends TvAppVerifierActivity implements View.O @Override protected void createTestItems() { - mSupportThirdPartyInputYesItem = createUserItem( + mSupportThirdPartyInputYesItem = createAndAttachUserItem( R.string.tv_input_discover_test_third_party_tif_input_support, R.string.tv_yes, this); setButtonEnabled(mSupportThirdPartyInputYesItem, true); - mSupportThirdPartyInputNoItem = createButtonItem(R.string.tv_no, this); + mSupportThirdPartyInputNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mSupportThirdPartyInputNoItem, true); - mSelectAppLinkItem = createUserItem(R.string.tv_app_link_test_select_app_link, + mSelectAppLinkItem = createAndAttachUserItem(R.string.tv_app_link_test_select_app_link, R.string.tv_launch_tv_app, this); - mVerifyAppLinkIntentItem = createAutoItem( + mVerifyAppLinkIntentItem = createAndAttachAutoItem( R.string.tv_app_link_test_verify_link_clicked); - mVerifyAppLinkCardItem = createUserItem(R.string.tv_input_link_test_verify_link_interface, + mVerifyAppLinkCardItem = createAndAttachUserItem( + R.string.tv_input_link_test_verify_link_interface, android.R.string.yes, this); TextView instructions = (TextView) mVerifyAppLinkCardItem.findViewById(R.id.instructions); Drawable image = getDrawable(R.drawable.app_link_img); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MicrophoneDeviceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MicrophoneDeviceTestActivity.java index eca02c1b100..6c8c7d45efc 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MicrophoneDeviceTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MicrophoneDeviceTestActivity.java @@ -16,14 +16,9 @@ package com.android.cts.verifier.tv; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - import android.annotation.SuppressLint; import android.content.Context; import android.hardware.input.InputManager; -import android.os.Bundle; import android.util.Log; import android.view.InputDevice; import android.view.View; @@ -31,6 +26,10 @@ import android.widget.Toast; import com.android.cts.verifier.R; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + /** * Tests for verifying that all input devices report correct hasMicrophone() states. */ @@ -93,11 +92,11 @@ public class MicrophoneDeviceTestActivity extends TvAppVerifierActivity @Override protected void createTestItems() { - mPreparationYesItem = createUserItem( + mPreparationYesItem = createAndAttachUserItem( R.string.tv_microphone_device_test_prep_question, R.string.tv_yes, this); setButtonEnabled(mPreparationYesItem, true); - mPreparationNoItem = createButtonItem(R.string.tv_no, this); + mPreparationNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mPreparationNoItem, true); } @@ -123,9 +122,10 @@ public class MicrophoneDeviceTestActivity extends TvAppVerifierActivity final CharSequence micQuestion = getString(R.string.tv_microphone_device_test_mic_question, inputDevice.getName()); - final View inputDeviceYesItem = createUserItem(micQuestion, R.string.tv_yes, this); + final View inputDeviceYesItem = + createAndAttachUserItem(micQuestion, R.string.tv_yes, this); setButtonEnabled(inputDeviceYesItem, true); - final View inputDeviceNoItem = createButtonItem(R.string.tv_no, this); + final View inputDeviceNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(inputDeviceNoItem, true); mInputDeviceItems.put( inputDeviceYesItem, Arrays.asList(true, hasMicrophone, inputDeviceNoItem)); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java index a31162f5e88..343fb16afef 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java @@ -137,24 +137,24 @@ public class MultipleTracksTestActivity extends TvAppVerifierActivity @Override protected void createTestItems() { - mSupportThirdPartyInputYesItem = createUserItem( + mSupportThirdPartyInputYesItem = createAndAttachUserItem( R.string.tv_input_discover_test_third_party_tif_input_support, R.string.tv_yes, this); setButtonEnabled(mSupportThirdPartyInputYesItem, true); - mSupportThirdPartyInputNoItem = createButtonItem(R.string.tv_no, this); + mSupportThirdPartyInputNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mSupportThirdPartyInputNoItem, true); - mSelectSubtitleItem = createUserItem( + mSelectSubtitleItem = createAndAttachUserItem( R.string.tv_multiple_tracks_test_select_subtitle, R.string.tv_launch_tv_app, this); - mVerifySetCaptionEnabledItem = createAutoItem( + mVerifySetCaptionEnabledItem = createAndAttachAutoItem( R.string.tv_multiple_tracks_test_verify_set_caption_enabled); - mVerifySelectSubtitleItem = createAutoItem( + mVerifySelectSubtitleItem = createAndAttachAutoItem( R.string.tv_multiple_tracks_test_verify_select_subtitle); - mSelectAudioItem = createUserItem( + mSelectAudioItem = createAndAttachUserItem( R.string.tv_multiple_tracks_test_select_audio, R.string.tv_launch_tv_app, this); mSelectAudioItem.setTag(Integer.valueOf(0)); - mVerifySelectAudioItem = createAutoItem( + mVerifySelectAudioItem = createAndAttachAutoItem( R.string.tv_multiple_tracks_test_verify_select_audio); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java index 2e5711fe297..d17f66f640e 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java @@ -157,26 +157,26 @@ public class ParentalControlTestActivity extends TvAppVerifierActivity @Override protected void createTestItems() { - mSupportThirdPartyInputYesItem = createUserItem( + mSupportThirdPartyInputYesItem = createAndAttachUserItem( R.string.tv_input_discover_test_third_party_tif_input_support, R.string.tv_yes, this); setButtonEnabled(mSupportThirdPartyInputYesItem, true); - mSupportThirdPartyInputNoItem = createButtonItem(R.string.tv_no, this); + mSupportThirdPartyInputNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mSupportThirdPartyInputNoItem, true); - mParentalControlsSwitchYesItem = createUserItem( + mParentalControlsSwitchYesItem = createAndAttachUserItem( R.string.tv_parental_control_test_check_parental_controls_switch, R.string.tv_yes, this); - mParentalControlsSwitchNoItem = createButtonItem(R.string.tv_no, this); - mTurnOnParentalControlItem = createUserItem( + mParentalControlsSwitchNoItem = createAndAttachButtonItem(R.string.tv_no, this); + mTurnOnParentalControlItem = createAndAttachUserItem( R.string.tv_parental_control_test_turn_on_parental_control, R.string.tv_launch_tv_app, this); - mVerifyReceiveBroadcast1Item = createAutoItem( + mVerifyReceiveBroadcast1Item = createAndAttachAutoItem( R.string.tv_parental_control_test_verify_receive_broadcast1); - mBlockTvMaItem = createUserItem(R.string.tv_parental_control_test_block_tv_ma, + mBlockTvMaItem = createAndAttachUserItem(R.string.tv_parental_control_test_block_tv_ma, R.string.tv_launch_tv_app, this); - mVerifyReceiveBroadcast2Item = createAutoItem( + mVerifyReceiveBroadcast2Item = createAndAttachAutoItem( R.string.tv_parental_control_test_verify_receive_broadcast2); - mBlockUnblockItem = createUserItem(R.string.tv_parental_control_test_block_unblock, + mBlockUnblockItem = createAndAttachUserItem(R.string.tv_parental_control_test_block_unblock, R.string.tv_launch_tv_app, this); mTurnOnParentalControlItem.setVisibility(View.GONE); mVerifyReceiveBroadcast1Item.setVisibility(View.GONE); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java index 7b80155c69b..bbdbbba9cf6 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java @@ -1,8 +1,6 @@ package com.android.cts.verifier.tv; -import com.android.cts.verifier.tv.TvAppVerifierActivity; - import java.util.List; import java.util.stream.Collectors; @@ -35,7 +33,9 @@ public class TestSequence { } // Initialize all containing test steps. - steps.stream().forEach(step -> step.createUiElements()); + steps.stream() + .flatMap(step -> step.createUiElements().stream()) + .forEach(view -> context.addItem(view)); // After a step is completed we enable the button of the next step. for (int i = 0; i < steps.size() - 1; i++) { diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java index 6c9b5a10b79..9c117e4f2c6 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java @@ -16,6 +16,7 @@ package com.android.cts.verifier.tv; +import android.app.Activity; import android.view.View; import android.widget.TextView; @@ -24,9 +25,12 @@ import com.android.cts.verifier.R; import com.google.common.truth.FailureStrategy; import com.google.common.truth.StandardSubjectBuilder; +import java.util.ArrayList; +import java.util.List; + /** Encapsulates the logic of a test step, which displays human instructions. */ public abstract class TestStepBase { - protected final TvAppVerifierActivity mContext; + protected final Activity mContext; private boolean mHasPassed; private Runnable mOnDoneListener; @@ -41,7 +45,7 @@ public abstract class TestStepBase { * @param context The test activity which this test step is part of. * @param instructionText The text of the test instruction visible to the user. */ - public TestStepBase(TvAppVerifierActivity context, String instructionText) { + public TestStepBase(Activity context, String instructionText) { this.mContext = context; FailureStrategy failureStrategy = @@ -59,8 +63,12 @@ public abstract class TestStepBase { } /** Creates the View for this test step in the context {@link TvAppVerifierActivity}. */ - public void createUiElements() { - mInstructionView = mContext.createAutoItem(mInstructionText); + public List<View> createUiElements() { + mInstructionView = TvAppVerifierActivity + .createAutoItem(mContext.getLayoutInflater(), mInstructionText, null); + List<View> list = new ArrayList<>(); + list.add(mInstructionView); + return list; } /** Enables interactivity for this test step - for example, it enables buttons. */ diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java index 41db8e75845..09cef36f5ef 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java @@ -199,32 +199,32 @@ public class TimeShiftTestActivity extends TvAppVerifierActivity @Override protected void createTestItems() { - mSupportThirdPartyInputYesItem = createUserItem( + mSupportThirdPartyInputYesItem = createAndAttachUserItem( R.string.tv_input_discover_test_third_party_tif_input_support, R.string.tv_yes, this); setButtonEnabled(mSupportThirdPartyInputYesItem, true); - mSupportThirdPartyInputNoItem = createButtonItem(R.string.tv_no, this); + mSupportThirdPartyInputNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mSupportThirdPartyInputNoItem, true); - mPauseResumeItem = createUserItem( + mPauseResumeItem = createAndAttachUserItem( R.string.tv_time_shift_test_pause_resume, R.string.tv_launch_tv_app, this); - mVerifyResumeAfterPauseItem = createAutoItem( + mVerifyResumeAfterPauseItem = createAndAttachAutoItem( R.string.tv_time_shift_test_verify_resume_after_pause); - mVerifyPositionTrackingItem = createAutoItem( + mVerifyPositionTrackingItem = createAndAttachAutoItem( R.string.tv_time_shift_test_verify_position_tracking); - mSetPlaybackParamsItem = createUserItem( + mSetPlaybackParamsItem = createAndAttachUserItem( R.string.tv_time_shift_test_speed_rate, R.string.tv_launch_tv_app, this); - mVerifyRewindItem = createAutoItem( + mVerifyRewindItem = createAndAttachAutoItem( R.string.tv_time_shift_test_verify_rewind); - mVerifyFastForwardItem = createAutoItem( + mVerifyFastForwardItem = createAndAttachAutoItem( R.string.tv_time_shift_test_verify_fast_forward); - mSeekToItem = createUserItem( + mSeekToItem = createAndAttachUserItem( R.string.tv_time_shift_test_seek, R.string.tv_launch_tv_app, this); - mVerifySeekToPreviousItem = createAutoItem( + mVerifySeekToPreviousItem = createAndAttachAutoItem( R.string.tv_time_shift_test_verify_seek_to_previous); - mVerifySeekToNextItem = createAutoItem( + mVerifySeekToNextItem = createAndAttachAutoItem( R.string.tv_time_shift_test_verify_seek_to_next); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java index 1c9fc0fa7e9..c65a3e0a1de 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java @@ -78,7 +78,8 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { /** * Call this to create a test step where the user must perform some action. */ - public View createUserItem(int instructionTextId, int buttonTextId, View.OnClickListener l) { + public View createAndAttachUserItem(int instructionTextId, int buttonTextId, + View.OnClickListener l) { View item = mInflater.inflate(R.layout.tv_item, mItemList, false); TextView instructions = (TextView) item.findViewById(R.id.instructions); instructions.setText(instructionTextId); @@ -93,12 +94,12 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { /** * Call this to create a test step where the user must perform some action. */ - public View createUserItem(CharSequence instructionCharSequence, + public View createAndAttachUserItem(CharSequence instructionCharSequence, int buttonTextId, View.OnClickListener l) { View item = mInflater.inflate(R.layout.tv_item, mItemList, false); - TextView instructions = (TextView) item.findViewById(R.id.instructions); + TextView instructions = item.findViewById(R.id.instructions); instructions.setText(instructionCharSequence); - Button button = (Button) item.findViewById(R.id.user_action_button); + Button button = item.findViewById(R.id.user_action_button); button.setVisibility(View.VISIBLE); button.setText(buttonTextId); button.setOnClickListener(l); @@ -110,9 +111,9 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { * Call this to create a test step where the test automatically evaluates whether * an expected condition is satisfied. */ - public View createAutoItem(int stringId) { + public View createAndAttachAutoItem(int stringId) { View item = mInflater.inflate(R.layout.tv_item, mItemList, false); - TextView instructions = (TextView) item.findViewById(R.id.instructions); + TextView instructions = item.findViewById(R.id.instructions); instructions.setText(stringId); mItemList.addView(item); return item; @@ -122,10 +123,20 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { * Call this to create a test step where the test automatically evaluates whether * an expected condition is satisfied. */ - public View createAutoItem(CharSequence instructionCharSequence) { - View item = mInflater.inflate(R.layout.tv_item, mItemList, false); - TextView instructions = (TextView) item.findViewById(R.id.instructions); + public static View createAutoItem(LayoutInflater inflater, + CharSequence instructionCharSequence, ViewGroup root) { + View item = inflater.inflate(R.layout.tv_item, root, false); + TextView instructions = item.findViewById(R.id.instructions); instructions.setText(instructionCharSequence); + return item; + } + + /** + * Call this to create a test step where the test automatically evaluates whether + * an expected condition is satisfied, and to attach it to the activity. + */ + public View createAndAttachAutoItem(CharSequence instructionCharSequence) { + View item = createAutoItem(mInflater, instructionCharSequence, mItemList); mItemList.addView(item); return item; } @@ -133,20 +144,37 @@ public abstract class TvAppVerifierActivity extends PassFailButtons.Activity { /** * Call this to create alternative choice for the previous test step. */ - public View createButtonItem(int buttonTextId, View.OnClickListener l) { - View item = mInflater.inflate(R.layout.tv_item, mItemList, false); - Button button = (Button) item.findViewById(R.id.user_action_button); + public static View createButtonItem(LayoutInflater inflater, ViewGroup root, int buttonTextId, + View.OnClickListener l) { + View item = inflater.inflate(R.layout.tv_item, root, false); + Button button = item.findViewById(R.id.user_action_button); button.setVisibility(View.VISIBLE); button.setText(buttonTextId); button.setOnClickListener(l); - ImageView status = (ImageView) item.findViewById(R.id.status); + ImageView status = item.findViewById(R.id.status); status.setVisibility(View.INVISIBLE); - TextView instructions = (TextView) item.findViewById(R.id.instructions); + TextView instructions = item.findViewById(R.id.instructions); instructions.setVisibility(View.GONE); + return item; + } + + /** + * Call this to create alternative choice for the previous test step and to attach it to the + * activity. + */ + public View createAndAttachButtonItem(int buttonTextId, View.OnClickListener l) { + View item = createButtonItem(mInflater, mItemList, buttonTextId, l); mItemList.addView(item); return item; } + /** + * Adds an item to the activity. + */ + public void addItem(View item) { + mItemList.addView(item); + } + static boolean containsButton(View item, View button) { return item == null ? false : item.findViewById(R.id.user_action_button) == button; } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java index f1f79cf90e4..4f68e8b80ab 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java @@ -151,31 +151,32 @@ public class TvInputDiscoveryTestActivity extends TvAppVerifierActivity @Override protected void createTestItems() { - mSupportThirdPartyInputYesItem = createUserItem( + mSupportThirdPartyInputYesItem = createAndAttachUserItem( R.string.tv_input_discover_test_third_party_tif_input_support, R.string.tv_yes, this); setButtonEnabled(mSupportThirdPartyInputYesItem, true); - mSupportThirdPartyInputNoItem = createButtonItem(R.string.tv_no, this); + mSupportThirdPartyInputNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mSupportThirdPartyInputNoItem, true); - mGoToSetupItem = createUserItem(R.string.tv_input_discover_test_go_to_setup, + mGoToSetupItem = createAndAttachUserItem(R.string.tv_input_discover_test_go_to_setup, R.string.tv_launch_tv_app, this); - mVerifySetupItem = createAutoItem(R.string.tv_input_discover_test_verify_setup); - mTuneToChannelItem = createUserItem(R.string.tv_input_discover_test_tune_to_channel, + mVerifySetupItem = createAndAttachAutoItem(R.string.tv_input_discover_test_verify_setup); + mTuneToChannelItem = createAndAttachUserItem( + R.string.tv_input_discover_test_tune_to_channel, R.string.tv_launch_tv_app, this); - mVerifyTuneItem = createAutoItem(R.string.tv_input_discover_test_verify_tune); - mVerifyOverlayViewItem = createAutoItem( + mVerifyTuneItem = createAndAttachAutoItem(R.string.tv_input_discover_test_verify_tune); + mVerifyOverlayViewItem = createAndAttachAutoItem( R.string.tv_input_discover_test_verify_overlay_view); - mVerifyOverlayViewSizeChanged = createAutoItem( + mVerifyOverlayViewSizeChanged = createAndAttachAutoItem( R.string.tv_input_discover_test_verify_size_changed); - mVerifyGlobalSearchItem = createAutoItem( + mVerifyGlobalSearchItem = createAndAttachAutoItem( R.string.tv_input_discover_test_verify_global_search); - mGoToEpgItem = createUserItem(R.string.tv_input_discover_test_go_to_epg, + mGoToEpgItem = createAndAttachUserItem(R.string.tv_input_discover_test_go_to_epg, R.string.tv_launch_epg, this); - mVerifyEpgItem = createUserItem(R.string.tv_input_discover_test_verify_epg, + mVerifyEpgItem = createAndAttachUserItem(R.string.tv_input_discover_test_verify_epg, R.string.tv_yes, this); - mTriggerSetupItem = createUserItem(R.string.tv_input_discover_test_trigger_setup, + mTriggerSetupItem = createAndAttachUserItem(R.string.tv_input_discover_test_trigger_setup, R.string.tv_launch_setup, this); - mVerifyTriggerSetupItem = createUserItem( + mVerifyTriggerSetupItem = createAndAttachUserItem( R.string.tv_input_discover_test_verify_trigger_setup, R.string.tv_yes, this); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java index 91651ce5862..599bef21c8c 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java @@ -99,10 +99,10 @@ public class AudioCapabilitiesTestActivity extends TvAppVerifierActivity @Override protected void createTestItems() { mSupportDolbyAtmosYesItem = - createUserItem( + createAndAttachUserItem( R.string.tv_audio_capabilities_atmos_supported, R.string.tv_yes, this); setButtonEnabled(mSupportDolbyAtmosYesItem, true); - mSupportDolbyAtmosNoItem = createButtonItem(R.string.tv_no, this); + mSupportDolbyAtmosNoItem = createAndAttachButtonItem(R.string.tv_no, this); setButtonEnabled(mSupportDolbyAtmosNoItem, true); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java index 19563809ca7..0a419068140 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java @@ -15,6 +15,7 @@ */ package com.android.cts.verifier.tv.audio; +import android.app.Activity; import android.view.View; import androidx.annotation.StringRes; @@ -22,6 +23,8 @@ import androidx.annotation.StringRes; import com.android.cts.verifier.tv.TestStepBase; import com.android.cts.verifier.tv.TvAppVerifierActivity; +import java.util.List; + /** Test step containing instruction to the user and a button. */ public abstract class TestStep extends TestStepBase { protected View mButtonView; @@ -33,24 +36,27 @@ public abstract class TestStep extends TestStepBase { * * @param context The test activity which this test step is part of. * @param instructionText Text of the test instruction visible to the user. - * @param buttonTextId Id of a string resource containing the text of the button. + * @param buttonStringId Id of a string resource containing the text of the button. */ public TestStep( - TvAppVerifierActivity context, String instructionText, @StringRes int buttonStringId) { + Activity context, String instructionText, @StringRes int buttonStringId) { super(context, instructionText); mButtonStringId = buttonStringId; } /** Creates the View for this test step in the context {@link TvAppVerifierActivity}. */ @Override - public void createUiElements() { - super.createUiElements(); + public List<View> createUiElements() { + List<View> list = super.createUiElements(); mButtonView = - mContext.createButtonItem( + TvAppVerifierActivity.createButtonItem(mContext.getLayoutInflater(), + null, mButtonStringId, (View view) -> { onButtonClickRunTest(); }); + list.add(mButtonView); + return list; } @Override diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/HotplugTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/HotplugTestActivity.java new file mode 100644 index 00000000000..79120b22993 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/HotplugTestActivity.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2021 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 com.android.cts.verifier.tv.display; + +import android.annotation.StringRes; +import android.content.Context; +import android.hardware.display.DisplayManager; +import android.view.Display; +import android.view.View; + +import com.android.cts.verifier.R; +import com.android.cts.verifier.tv.TestSequence; +import com.android.cts.verifier.tv.TestStepBase; +import com.android.cts.verifier.tv.TvAppVerifierActivity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Test when the HDMI cable on HDMI source devices (e.g. set-top boxes and TV sticks) is plugged out + * and in {@link android.hardware.display.DisplayManager.DisplayListener#onDisplayChanged}. The + * test also verifies that the display capabilities when the HDMI cable is unplugged contain only + * one display mode and no HDR capabilities. + */ +public class HotplugTestActivity extends TvAppVerifierActivity { + private static final float REFRESH_RATE_TOLERANCE = 0.01f; + private TestSequence mTestSequence; + + @Override + protected void setInfoResources() { + setInfoResources(R.string.tv_hotplug_test, R.string.tv_hotplug_test_info, -1); + } + + @Override + protected void createTestItems() { + List<TestStepBase> testSteps = new ArrayList<>(); + testSteps.add(new NoDisplayTestStep(this)); + mTestSequence = new TestSequence(this, testSteps); + mTestSequence.init(); + } + + @Override + public String getTestDetails() { + return mTestSequence.getFailureDetails(); + } + + private static class DisplayCapabilities { + public Display.Mode[] modes; + public Display.HdrCapabilities hdrCapabilities; + + DisplayCapabilities(Display display) { + this.modes = display.getSupportedModes(); + this.hdrCapabilities = display.getHdrCapabilities(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DisplayCapabilities)) return false; + DisplayCapabilities that = (DisplayCapabilities) o; + return modesAreEqual(modes, that.modes) + && Objects.equals(hdrCapabilities, that.hdrCapabilities); + } + + private boolean modesAreEqual(Display.Mode[] left, Display.Mode[] right) { + if (left.length != right.length) { + return false; + } + + for (int i = 0; i < left.length; i++) { + if (!modesAreEqual(left[i], right[i])) { + return false; + } + } + + return true; + } + + private boolean modesAreEqual(Display.Mode left, Display.Mode right) { + // Compare all properties except the ID. + return left.getPhysicalHeight() == right.getPhysicalHeight() + && left.getPhysicalWidth() == right.getPhysicalWidth() + && Math.abs(left.getRefreshRate() - right.getRefreshRate()) + < REFRESH_RATE_TOLERANCE + && Arrays.equals( + left.getAlternativeRefreshRates(), right.getAlternativeRefreshRates()); + } + + @Override + public String toString() { + String modesStr = Arrays.stream(modes) + .map(Display.Mode::toString) + .collect(Collectors.joining("\n\t")); + return "DisplayCapabilities{" + + "modes=" + modesStr + + ", hdrCapabilities=" + hdrCapabilities + '}'; + } + } + + private static class NoDisplayTestStep extends AsyncTestStep implements + DisplayManager.DisplayListener { + // All recorded states of the display capabilities. The first element are the initial + // display capabilities; each subsequent element is the state after a received + // onDisplayChanged(). + private List<DisplayCapabilities> mRecordedCapabilities = new ArrayList<>(); + + private int mNumOnDisplayChanged = 0; + private boolean mDisconnectDetected = false; + private boolean mConnectDetected = false; + + private View mDoneButtonView; + private DisplayManager mDisplayManager; + + NoDisplayTestStep(TvAppVerifierActivity context) { + super( + context, + R.string.tv_hotplug_test, + getInstructionText(context), + getButtonStringId()); + } + + private static String getInstructionText(Context context) { + return context.getString( + R.string.tv_hotplug_disconnect_display, + context.getString(getButtonStringId())); + } + + @StringRes + private static int getButtonStringId() { + return R.string.tv_start_test; + } + + @Override + public List<View> createUiElements() { + List<View> list = super.createUiElements(); + mDoneButtonView = TvAppVerifierActivity.createButtonItem( + mContext.getLayoutInflater(), + null, + R.string.tv_done, + (View view) -> recordTestStateAndFinish()); + list.add(mDoneButtonView); + return list; + } + + @Override + public void runTestAsync() { + setButtonEnabled(mDoneButtonView, true); + + mDisplayManager = mContext.getSystemService(DisplayManager.class); + Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); + mRecordedCapabilities.add(new DisplayCapabilities(display)); + mDisplayManager.registerDisplayListener(this, null); + } + + @Override + public void onDisplayAdded(int displayId) { + getAsserter().withMessage("onDisplayAdded() is not expected").fail(); + } + + @Override + public void onDisplayRemoved(int displayId) { + getAsserter().withMessage("onDisplayRemoved() is not expected").fail(); + } + + @Override + public void onDisplayChanged(int displayId) { + getAsserter().that(displayId).isEqualTo(Display.DEFAULT_DISPLAY); + + mNumOnDisplayChanged++; + DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + DisplayCapabilities currCapabilities = new DisplayCapabilities(display); + mRecordedCapabilities.add(currCapabilities); + + // Some TVs may send multiple onDisplayChanged() events, for that reason we + // test that in the sequence of states after each onDisplayChanged() there's + // a state which looks like a disconnected display, followed by a state which looks + // like the initial state. + if (!mDisconnectDetected) { + boolean isDisconnectedDisplay = + display.getHdrCapabilities().getSupportedHdrTypes().length == 0 + && display.getSupportedModes().length == 1; + + if (isDisconnectedDisplay) { + mDisconnectDetected = true; + } + } else if (!mConnectDetected) { + DisplayCapabilities initialCapabilities = mRecordedCapabilities.get(0); + if (currCapabilities.equals(initialCapabilities)) { + mConnectDetected = true; + recordTestStateAndFinish(); + } + } + } + + private void recordTestStateAndFinish() { + setButtonEnabled(mDoneButtonView, false); + mDisplayManager.unregisterDisplayListener(this); + if (!mConnectDetected || !mDisconnectDetected) { + String recordedCapabilitiesStr = mRecordedCapabilities.stream() + .map(DisplayCapabilities::toString) + .collect(Collectors.joining("\n")); + String message = "Number of onDisplayChanged() events = " + mNumOnDisplayChanged + + "\n" + "Disconnect detected = " + mDisconnectDetected + "\n" + + "Recorded states = " + recordedCapabilitiesStr; + getAsserter().withMessage(message).fail(); + } + done(); + } + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/ModeSwitchingTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/ModeSwitchingTestActivity.java new file mode 100644 index 00000000000..23bf053e7ad --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/ModeSwitchingTestActivity.java @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2021 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 com.android.cts.verifier.tv.display; + +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.hardware.display.DisplayManager; +import android.media.AudioManager; +import android.media.cts.MediaCodecTunneledPlayer; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; +import android.view.Display; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; +import com.android.cts.verifier.tv.TestStepBase; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Test activity to verify that + * 1. switching display modes during video playback doesn't cause crashes or major regressions + * in video quality + * 2. switching between modes is seamless if and only if the modes have alternative refresh rates + * (see {@link Display.Mode#getAlternativeRefreshRates}) + */ +public class ModeSwitchingTestActivity extends PassFailButtons.Activity { + private static final String TAG = ModeSwitchingTestActivity.class.getSimpleName(); + private static final float REFRESH_RATE_TOLERANCE = 0.01f; + + private SurfaceHolder mHolder; + private int mAudioSessionId = 0; + private MediaCodecTunneledPlayer mPlayer; + + private ViewGroup mItemList; + private List<TestStepBase> mSteps; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.tv_instructions_and_video); + mItemList = findViewById(R.id.test_items); + + DisplayManager displayManager = getSystemService(DisplayManager.class); + Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + + List<Display.Mode> modeList = findTestModes(display); + + Display.Mode lastMode = display.getMode(); + mSteps = new ArrayList<>(); + for (Display.Mode mode : modeList) { + boolean isSeamlessSwitch = isSeamlessSwitch(lastMode, mode); + mSteps.addAll(createTestStepsForTransition(lastMode, mode, isSeamlessSwitch)); + lastMode = mode; + } + + if (!mSteps.isEmpty()) { + initTestStep(0); + } + + setPassFailButtonClickListeners(); + getPassButton().setEnabled(false); + + SurfaceView surfaceView = findViewById(R.id.surface); + mHolder = surfaceView.getHolder(); + mHolder.addCallback(new SurfaceHolder.Callback() { + public void surfaceCreated(SurfaceHolder holder) { + playVideo(); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + } + + public void surfaceDestroyed(SurfaceHolder holder) { + } + }); + + AudioManager am = (AudioManager) getApplicationContext().getSystemService(AUDIO_SERVICE); + mAudioSessionId = am.generateAudioSessionId(); + + mPlayer = new MediaCodecTunneledPlayer(this, mHolder, true, mAudioSessionId); + + Uri mediaUri = getAsResourceUri(R.raw.bunny_1280x720_24fps_VP9); + mPlayer.setVideoDataSource(mediaUri, null); + mPlayer.setAudioDataSource(mediaUri, null); + } + + private Uri getAsResourceUri(int resId) { + Resources res = getResources(); + return new Uri.Builder() + .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + .authority(res.getResourcePackageName(resId)) + .appendPath(res.getResourceTypeName(resId)) + .appendPath(res.getResourceEntryName(resId)) + .build(); + } + + private List<Display.Mode> findTestModes(Display display) { + Display.Mode activeMode = display.getMode(); + + List<Display.Mode> modeList = new ArrayList<>(); + // Find a mode to test refresh rate switch - the mode with smallest refresh rate and + // the same resolution as the active mode + Arrays.stream(display.getSupportedModes()) + .filter(mode -> !mode.equals(activeMode)) + .filter(mode -> isResolutionEqual(mode, activeMode)) + .min(Comparator.comparingDouble(Display.Mode::getRefreshRate)) + .ifPresent(modeList::add); + + // Find a mode to test seamless mode switch. + if (modeList.size() > 0 && !isSeamlessSwitch(activeMode, modeList.get(0)) + && activeMode.getAlternativeRefreshRates().length > 0) { + Arrays.stream(display.getSupportedModes()) + .filter(mode -> !mode.equals(activeMode)) + .filter(mode -> isSeamlessSwitch(activeMode, mode)) + .findFirst() + .ifPresent(modeList::add); + } + + // Find a mode to test resolution switch - the first 16:9 mode with resolution less + // than the active mode. + Arrays.stream(display.getSupportedModes()) + .filter(mode -> !mode.equals(activeMode)) + .filter(mode -> !isResolutionEqual(mode, activeMode)) + .filter(this::is16to9) + .max(Comparator.comparing(Display.Mode::getPhysicalHeight)) + .ifPresent(modeList::add); + + return modeList; + } + + private void initTestStep(int stepIndex) { + final TestStepBase currStep = mSteps.get(stepIndex); + currStep.createUiElements() + .forEach(view -> mItemList.addView(view)); + + currStep.setOnDoneListener(() -> { + // Delay so the user can see the passing state of the finished + // step, before replacing it with the next one + mItemList.postDelayed(() -> { + int nextStepIndex = stepIndex + 1; + if (!currStep.hasPassed() || nextStepIndex >= mSteps.size()) { + onAllStepsDone(); + return; + } + + mItemList.removeAllViews(); + initTestStep(nextStepIndex); + }, 500); + }); + + currStep.enableInteractivity(); + } + + private void onAllStepsDone() { + // The sequence passes if all containing test steps pass. + boolean allTestStepsPass = mSteps.stream().allMatch(step -> step.hasPassed()); + getPassButton().setEnabled(allTestStepsPass); + } + + private List<TestStepBase> createTestStepsForTransition( + Display.Mode currMode, Display.Mode nextMode, boolean isSeamless) { + List<TestStepBase> steps = new ArrayList<>(); + steps.add(new ModeSwitchStep(this, + currMode, + nextMode + )); + + String blackScreenQuestion = + getResources().getString(R.string.tv_mode_switching_test_black_screen_question); + if (isSeamless) { + steps.add(new YesNoTestStep(this, blackScreenQuestion, + /* passingButton */ R.string.tv_no, /* failingButton */ R.string.tv_yes)); + } else { + steps.add(new YesNoTestStep(this, blackScreenQuestion, + /* passingButton */ R.string.tv_yes, /* failingButton */ R.string.tv_no)); + } + + steps.add(new YesNoTestStep(this, + getResources().getString(R.string.tv_mode_switching_test_is_video_ok), + R.string.tv_yes, R.string.tv_no)); + return steps; + + } + + private boolean isSeamlessSwitch(Display.Mode from, Display.Mode to) { + if (!isResolutionEqual(from, to)) { + return false; + } + + for (float refreshRate : from.getAlternativeRefreshRates()) { + if (Math.abs(refreshRate - to.getRefreshRate()) < REFRESH_RATE_TOLERANCE) { + return true; + } + } + return false; + } + + private boolean isResolutionEqual(Display.Mode left, Display.Mode right) { + return left.getPhysicalHeight() == right.getPhysicalHeight() + && left.getPhysicalWidth() == right.getPhysicalWidth(); + } + + private boolean is16to9(Display.Mode mode) { + return mode.getPhysicalHeight() * 16 == mode.getPhysicalWidth() * 9; + } + + + private void playVideo() { + try { + mPlayer.start(); + mPlayer.prepare(); + mPlayer.setLoopEnabled(true); + mPlayer.startThread(); + } catch (Exception e) { + Log.d(TAG, "Could not play video", e); + } + } + + @Override + public void onPause() { + super.onPause(); + if (mPlayer != null) { + mPlayer.pause(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mPlayer != null) { + mPlayer.reset(); + mPlayer = null; + } + } + + @Override + public String getTestDetails() { + return mSteps.stream() + .filter(step -> !step.hasPassed()) + .map(step -> step.getFailureDetails()) + .collect(Collectors.joining("\n")); + } + + // Test step which shows instruction text to the user and performs a mode switch. This + // test step will always pass successfully. + private static class ModeSwitchStep extends SyncTestStep { + private Display.Mode mNextMode; + + ModeSwitchStep(Activity context, Display.Mode currMode, Display.Mode nextMode) { + super(context, R.string.tv_mode_switching_test_mode_switch_step, + getInstructionText(context, currMode, nextMode), + R.string.tv_start_test); + this.mNextMode = nextMode; + } + + private static String getInstructionText(Context context, Display.Mode currMode, + Display.Mode nextMode) { + return context.getResources().getString( + R.string.tv_mode_switching_test_step_instruction, + formatMode(currMode), + formatMode(nextMode)); + } + + private static String formatMode(Display.Mode mode) { + return String.format("%dx%d %.2fHz", + mode.getPhysicalWidth(), mode.getPhysicalHeight(), mode.getRefreshRate()); + } + + @Override + public void runTest() { + Window window = mContext.getWindow(); + WindowManager.LayoutParams params = window.getAttributes(); + params.preferredDisplayModeId = mNextMode.getModeId(); + window.setAttributes(params); + } + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java index 6ee34f314e8..89dc391f247 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java @@ -16,6 +16,7 @@ package com.android.cts.verifier.tv.display; +import android.app.Activity; import android.view.View; import androidx.annotation.StringRes; @@ -23,6 +24,8 @@ import androidx.annotation.StringRes; import com.android.cts.verifier.tv.TestStepBase; import com.android.cts.verifier.tv.TvAppVerifierActivity; +import java.util.List; + /** Test step containing instruction to the user and a button. */ public abstract class OneButtonTestStep extends TestStepBase { @@ -42,7 +45,7 @@ public abstract class OneButtonTestStep extends TestStepBase { * @param buttonStringId Id of a string resource containing the text of the button. */ public OneButtonTestStep( - TvAppVerifierActivity context, + Activity context, @StringRes int stepNameStringId, String instructionText, @StringRes int buttonStringId) { @@ -52,21 +55,25 @@ public abstract class OneButtonTestStep extends TestStepBase { } @Override - public void createUiElements() { - super.createUiElements(); + public List<View> createUiElements() { + List<View> list = super.createUiElements(); mButtonView = - mContext.createButtonItem( + TvAppVerifierActivity.createButtonItem(mContext.getLayoutInflater(), + null, mButtonStringId, (View view) -> { String stepName = mContext.getString(mStepNameStringId); appendInfoDetails("Running test step %s...", stepName); onButtonClickRunTest(); }); + list.add(mButtonView); + return list; } @Override public void enableInteractivity() { TvAppVerifierActivity.setButtonEnabled(mButtonView, true); + mButtonView.requestFocus(); } @Override diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java index a1736fba688..f60db64b45b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/SyncTestStep.java @@ -16,16 +16,16 @@ package com.android.cts.verifier.tv.display; -import androidx.annotation.StringRes; +import android.app.Activity; -import com.android.cts.verifier.tv.TvAppVerifierActivity; +import androidx.annotation.StringRes; /** * Encapsulates the logic of a synchronously running test step, which displays human instructions * and a button to start the test. For asynchronous steps see {@link AsyncTestStep}. */ public abstract class SyncTestStep extends OneButtonTestStep { - public SyncTestStep(TvAppVerifierActivity context, @StringRes int stepNameStringId, + public SyncTestStep(Activity context, @StringRes int stepNameStringId, String instructionText, @StringRes int buttonStringId) { super(context, stepNameStringId, instructionText, buttonStringId); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java index 4f300d4cf39..886c92c9f05 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java @@ -16,21 +16,24 @@ package com.android.cts.verifier.tv.display; +import android.app.Activity; import android.view.View; -import com.android.cts.verifier.R; import com.android.cts.verifier.tv.TestStepBase; import com.android.cts.verifier.tv.TvAppVerifierActivity; +import java.util.List; + /** * Encapsulates the logic of a test step, which displays human instructions for a manual test and * two buttons - Yes and No, which respectively set the test in passing and failing state. */ -public abstract class YesNoTestStep extends TestStepBase { - private View positiveButton; - private View negativeButton; - private final int positiveButtonText; - private final int negativeButtonText; +public class YesNoTestStep extends TestStepBase { + private View mPositiveButton; + private View mNegativeButton; + private final int mPositiveButtonText; + private final int mNegativeButtonText; + /** * Constructs a test step containing human instructions for a manual test and two buttons - Yes * and No. @@ -38,43 +41,54 @@ public abstract class YesNoTestStep extends TestStepBase { * @param context The test activity which this test step is part of. * @param instructionText The text of the test instruction visible to the user. */ - public YesNoTestStep(TvAppVerifierActivity context, String instructionText, + public YesNoTestStep(Activity context, String instructionText, int positiveButtonText, int negativeButtonText) { super(context, instructionText); - this.positiveButtonText = positiveButtonText; - this.negativeButtonText = negativeButtonText; + this.mPositiveButtonText = positiveButtonText; + this.mNegativeButtonText = negativeButtonText; } @Override - public void createUiElements() { - super.createUiElements(); - positiveButton = - mContext.createButtonItem( - positiveButtonText, + public List<View> createUiElements() { + List<View> list = super.createUiElements(); + mPositiveButton = + TvAppVerifierActivity.createButtonItem( + mContext.getLayoutInflater(), + null, + mPositiveButtonText, + (View view) -> { disableInteractivity(); // do nothing so the test will pass done(); }); - negativeButton = - mContext.createButtonItem( - negativeButtonText, + list.add(mPositiveButton); + + mNegativeButton = + TvAppVerifierActivity.createButtonItem( + mContext.getLayoutInflater(), + null, + mNegativeButtonText, (View view) -> { disableInteractivity(); getAsserter().fail(); done(); }); + list.add(mNegativeButton); + + return list; } @Override public void enableInteractivity() { - TvAppVerifierActivity.setButtonEnabled(positiveButton, true); - TvAppVerifierActivity.setButtonEnabled(negativeButton, true); + TvAppVerifierActivity.setButtonEnabled(mPositiveButton, true); + TvAppVerifierActivity.setButtonEnabled(mNegativeButton, true); + mPositiveButton.requestFocus(); } @Override public void disableInteractivity() { - TvAppVerifierActivity.setButtonEnabled(positiveButton, false); - TvAppVerifierActivity.setButtonEnabled(negativeButton, false); + TvAppVerifierActivity.setButtonEnabled(mPositiveButton, false); + TvAppVerifierActivity.setButtonEnabled(mNegativeButton, false); } } diff --git a/common/device-side/bedstead/eventlib/Android.bp b/common/device-side/bedstead/eventlib/Android.bp index 52545a6e0ec..cef979c5616 100644 --- a/common/device-side/bedstead/eventlib/Android.bp +++ b/common/device-side/bedstead/eventlib/Android.bp @@ -11,7 +11,8 @@ android_library { ], static_libs: [ "Nene", - "androidx.test.ext.junit"], + "Queryable" + ], manifest: "src/main/AndroidManifest.xml", min_sdk_version: "27" } diff --git a/common/device-side/bedstead/eventlib/OWNERS b/common/device-side/bedstead/eventlib/OWNERS deleted file mode 100644 index ce3438fef33..00000000000 --- a/common/device-side/bedstead/eventlib/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -scottjonathan@google.com -alexkershaw@google.com
\ No newline at end of file diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java index 35bdf2adb7b..379d29765f3 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/EventLogsQuery.java @@ -19,6 +19,7 @@ package com.android.eventlib; import android.os.UserHandle; import com.android.bedstead.nene.users.UserReference; +import com.android.queryable.Queryable; import java.util.HashSet; import java.util.Set; @@ -28,7 +29,7 @@ import java.util.function.Function; * Interface to provide additional restrictions on an {@link Event} query. */ public abstract class EventLogsQuery<E extends Event, F extends EventLogsQuery> - extends EventLogs<E> { + extends EventLogs<E> implements Queryable { /** * Default implementation of {@link EventLogsQuery} used when there are no additional query diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/CustomEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/CustomEvent.java index 26c090640cd..ea05843d07b 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/CustomEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/CustomEvent.java @@ -23,10 +23,10 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.queryhelpers.SerializableQuery; -import com.android.eventlib.queryhelpers.SerializableQueryHelper; -import com.android.eventlib.queryhelpers.StringQuery; -import com.android.eventlib.queryhelpers.StringQueryHelper; +import com.android.queryable.queries.SerializableQuery; +import com.android.queryable.queries.SerializableQueryHelper; +import com.android.queryable.queries.StringQuery; +import com.android.queryable.queries.StringQueryHelper; import java.io.Serializable; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityCreatedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityCreatedEvent.java index 0e9660c66f0..2474368c479 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityCreatedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityCreatedEvent.java @@ -25,13 +25,13 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; -import com.android.eventlib.queryhelpers.BundleQueryHelper; -import com.android.eventlib.queryhelpers.PersistableBundleQuery; -import com.android.eventlib.queryhelpers.PersistableBundleQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; +import com.android.queryable.queries.BundleQueryHelper; +import com.android.queryable.queries.PersistableBundleQuery; +import com.android.queryable.queries.PersistableBundleQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link Activity#onCreate(Bundle)} or diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityDestroyedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityDestroyedEvent.java index da40ebf1f1f..88a00de0747 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityDestroyedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityDestroyedEvent.java @@ -23,9 +23,9 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; /** * Event logged when {@link Activity#onDestroy()} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityPausedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityPausedEvent.java index 5f223173ef8..2e706ef1d55 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityPausedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityPausedEvent.java @@ -23,9 +23,9 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; /** * Event logged when {@link Activity#onPause()} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityRestartedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityRestartedEvent.java index c8f6d86ad2b..40a9eb9df73 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityRestartedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityRestartedEvent.java @@ -23,9 +23,9 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; /** * Event logged when {@link Activity#onRestart()} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityResumedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityResumedEvent.java index 5d10f83b3a2..72c3b3b21e2 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityResumedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityResumedEvent.java @@ -23,9 +23,9 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; /** * Event logged when {@link Activity#onResume()}} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStartedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStartedEvent.java index e0ee6576344..e3209808e75 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStartedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStartedEvent.java @@ -23,9 +23,9 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; /** * Event logged when {@link Activity#onStart()} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStoppedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStoppedEvent.java index 736a097532e..fd802c7b403 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStoppedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/activities/ActivityStoppedEvent.java @@ -23,9 +23,9 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; -import com.android.eventlib.queryhelpers.ActivityQuery; -import com.android.eventlib.queryhelpers.ActivityQueryHelper; +import com.android.queryable.info.ActivityInfo; +import com.android.queryable.queries.ActivityQuery; +import com.android.queryable.queries.ActivityQueryHelper; /** * Event logged when {@link Activity#onStop()} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/broadcastreceivers/BroadcastReceivedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/broadcastreceivers/BroadcastReceivedEvent.java index b4a2717bca8..ff849a0ef16 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/broadcastreceivers/BroadcastReceivedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/broadcastreceivers/BroadcastReceivedEvent.java @@ -25,12 +25,12 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.BroadcastReceiverInfo; -import com.android.eventlib.queryhelpers.BroadcastReceiverQuery; -import com.android.eventlib.queryhelpers.BroadcastReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQuery; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.BroadcastReceiverInfo; +import com.android.queryable.queries.BroadcastReceiverQuery; +import com.android.queryable.queries.BroadcastReceiverQueryHelper; +import com.android.queryable.queries.IntentQuery; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link BroadcastReceiver#onReceive(Context, Intent)} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisableRequestedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisableRequestedEvent.java index f1f82df6f5b..397399b9f2c 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisableRequestedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisableRequestedEvent.java @@ -25,11 +25,11 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQuery; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.DeviceAdminReceiverInfo; +import com.android.queryable.queries.DeviceAdminReceiverQuery; +import com.android.queryable.queries.DeviceAdminReceiverQueryHelper; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link DeviceAdminReceiver#onDisableRequested(Context, Intent)} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisabledEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisabledEvent.java index 25bd3d9619b..d3ccc356b09 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisabledEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminDisabledEvent.java @@ -25,11 +25,11 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQuery; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.DeviceAdminReceiverInfo; +import com.android.queryable.queries.DeviceAdminReceiverQuery; +import com.android.queryable.queries.DeviceAdminReceiverQueryHelper; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link DeviceAdminReceiver#onDisabled(Context, Intent)} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminEnabledEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminEnabledEvent.java index b390ed88224..1ea2699015b 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminEnabledEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminEnabledEvent.java @@ -25,11 +25,11 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQuery; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.DeviceAdminReceiverInfo; +import com.android.queryable.queries.DeviceAdminReceiverQuery; +import com.android.queryable.queries.DeviceAdminReceiverQueryHelper; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link DeviceAdminReceiver#onEnabled(Context, Intent)} is called. diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordChangedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordChangedEvent.java index 82998d6b2dd..5e09058135c 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordChangedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordChangedEvent.java @@ -26,13 +26,13 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQuery; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.queryhelpers.UserHandleQuery; -import com.android.eventlib.queryhelpers.UserHandleQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.DeviceAdminReceiverInfo; +import com.android.queryable.queries.DeviceAdminReceiverQuery; +import com.android.queryable.queries.DeviceAdminReceiverQueryHelper; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.queries.UserHandleQuery; +import com.android.queryable.queries.UserHandleQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent)} or diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordFailedEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordFailedEvent.java index b796a258de1..9bc1c84f970 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordFailedEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordFailedEvent.java @@ -26,13 +26,13 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQuery; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.queryhelpers.UserHandleQuery; -import com.android.eventlib.queryhelpers.UserHandleQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.DeviceAdminReceiverInfo; +import com.android.queryable.queries.DeviceAdminReceiverQuery; +import com.android.queryable.queries.DeviceAdminReceiverQueryHelper; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.queries.UserHandleQuery; +import com.android.queryable.queries.UserHandleQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link DeviceAdminReceiver#onPasswordFailed(Context, Intent)} or diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordSucceededEvent.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordSucceededEvent.java index ba22d98d717..f6a0504b54f 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordSucceededEvent.java +++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/events/deviceadminreceivers/DeviceAdminPasswordSucceededEvent.java @@ -26,13 +26,13 @@ import androidx.annotation.CheckResult; import com.android.eventlib.Event; import com.android.eventlib.EventLogger; import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQuery; -import com.android.eventlib.queryhelpers.DeviceAdminReceiverQueryHelper; -import com.android.eventlib.queryhelpers.IntentQueryHelper; -import com.android.eventlib.queryhelpers.UserHandleQuery; -import com.android.eventlib.queryhelpers.UserHandleQueryHelper; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.info.DeviceAdminReceiverInfo; +import com.android.queryable.queries.DeviceAdminReceiverQuery; +import com.android.queryable.queries.DeviceAdminReceiverQueryHelper; +import com.android.queryable.queries.IntentQueryHelper; +import com.android.queryable.queries.UserHandleQuery; +import com.android.queryable.queries.UserHandleQueryHelper; +import com.android.queryable.util.SerializableParcelWrapper; /** * Event logged when {@link DeviceAdminReceiver#onPasswordSucceeded(Context, Intent)} or diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityWrapper.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityWrapper.java index a0de452ea78..a7d43fbd31e 100644 --- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityWrapper.java +++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityWrapper.java @@ -18,6 +18,7 @@ package com.android.bedstead.nene.activities; import android.app.Activity; import android.content.Intent; +import android.os.Bundle; class ActivityWrapper implements NeneActivity { @@ -51,4 +52,9 @@ class ActivityWrapper implements NeneActivity { public void startActivity(Intent intent) { mActivity.startActivity(intent); } + + @Override + public void startActivity(Intent intent, Bundle options) { + mActivity.startActivity(intent, options); + } } diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/NeneActivity.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/NeneActivity.java index 37dd49a4624..372a89a7c7b 100644 --- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/NeneActivity.java +++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/NeneActivity.java @@ -18,6 +18,7 @@ package com.android.bedstead.nene.activities; import android.app.Activity; import android.content.Intent; +import android.os.Bundle; /** * Interface for use by classes which are able to be used in Nene activity test apis. @@ -39,4 +40,7 @@ public interface NeneActivity { /** See {@link Activity#startActivity}. */ void startActivity(Intent intent); + + /** See {@link Activity#startActivity}. */ + void startActivity(Intent intent, Bundle options); } diff --git a/common/device-side/bedstead/queryable/Android.bp b/common/device-side/bedstead/queryable/Android.bp new file mode 100644 index 00000000000..edae7901b57 --- /dev/null +++ b/common/device-side/bedstead/queryable/Android.bp @@ -0,0 +1,34 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_library { + name: "Queryable", + sdk_version: "test_current", + srcs: [ + "src/main/java/**/*.java", + ], + static_libs: ["androidx.test.ext.junit"], + manifest: "src/main/AndroidManifest.xml", + min_sdk_version: "27" +} + +android_test { + name: "BedsteadQueryableTest", + srcs: [ + "src/test/java/**/*.java" + ], + test_suites: [ + "general-tests", + ], + static_libs: [ + "Queryable", + "ActivityContext", + "androidx.test.ext.junit", + "ctstestrunner-axt", + "truth-prebuilt", + "testng", // for assertThrows + ], + manifest: "src/test/AndroidManifest.xml", + min_sdk_version: "27" +} diff --git a/common/device-side/bedstead/queryable/AndroidTest.xml b/common/device-side/bedstead/queryable/AndroidTest.xml new file mode 100644 index 00000000000..32d559defcd --- /dev/null +++ b/common/device-side/bedstead/queryable/AndroidTest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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. + --> +<configuration description="Config for Event Library test cases"> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="BedsteadQueryableTest.apk" /> + <option name="install-arg" value="-t" /> + </target_preparer> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.queryable.test" /> + </test> +</configuration>
\ No newline at end of file diff --git a/common/device-side/bedstead/queryable/TEST_MAPPING b/common/device-side/bedstead/queryable/TEST_MAPPING new file mode 100644 index 00000000000..62bc822cebd --- /dev/null +++ b/common/device-side/bedstead/queryable/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "postsubmit": [ + { + "name": "BedsteadQueryableTest" + } + ] +} diff --git a/common/device-side/bedstead/queryable/src/main/AndroidManifest.xml b/common/device-side/bedstead/queryable/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..836303a12c1 --- /dev/null +++ b/common/device-side/bedstead/queryable/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2021 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.queryable"> + <uses-sdk android:minSdkVersion="27" /> + <application> + </application> +</manifest> diff --git a/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/Queryable.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/Queryable.java new file mode 100644 index 00000000000..09bd40adae8 --- /dev/null +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/Queryable.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2021 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 com.android.queryable; + +public interface Queryable { +} diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/ActivityInfo.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/ActivityInfo.java index 41ccb8a3174..632afabefe6 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/ActivityInfo.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/ActivityInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import android.app.Activity; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/BroadcastReceiverInfo.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/BroadcastReceiverInfo.java index 83095bedb53..30c19e9564f 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/BroadcastReceiverInfo.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/BroadcastReceiverInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import android.content.BroadcastReceiver; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/ClassInfo.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/ClassInfo.java index b0d245a1daf..a964335e191 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/ClassInfo.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/ClassInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import java.io.Serializable; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/DeviceAdminReceiverInfo.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/DeviceAdminReceiverInfo.java index 611e216b28e..46602031cbf 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/info/DeviceAdminReceiverInfo.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/info/DeviceAdminReceiverInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import android.app.admin.DeviceAdminReceiver; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ActivityQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ActivityQuery.java index 91d67eaa6f7..8fe37eb3c60 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ActivityQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ActivityQuery.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.app.Activity; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; /** Query for an {@link Activity}. */ -public interface ActivityQuery<E extends EventLogsQuery> extends ClassQuery<E> { +public interface ActivityQuery<E extends Queryable> extends ClassQuery<E> { } diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ActivityQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ActivityQueryHelper.java index 8389d4c2a75..77a619187c3 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ActivityQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ActivityQueryHelper.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ActivityInfo; +import com.android.queryable.Queryable; +import com.android.queryable.info.ActivityInfo; /** Implementation of {@link ActivityQuery}. */ -public final class ActivityQueryHelper<E extends EventLogsQuery> implements ActivityQuery<E> { +public final class ActivityQueryHelper<E extends Queryable> implements ActivityQuery<E> { private final E mQuery; private final ClassQueryHelper<E> mClassQueryHelper; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BroadcastReceiverQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BroadcastReceiverQuery.java index be8f6599865..45febeb4273 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BroadcastReceiverQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BroadcastReceiverQuery.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.content.BroadcastReceiver; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; /** Query for an {@link BroadcastReceiver}. */ -public interface BroadcastReceiverQuery<E extends EventLogsQuery> extends ClassQuery<E> { +public interface BroadcastReceiverQuery<E extends Queryable> extends ClassQuery<E> { } diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BroadcastReceiverQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BroadcastReceiverQueryHelper.java index 4957cd43d2c..a63f700c485 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BroadcastReceiverQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BroadcastReceiverQueryHelper.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.BroadcastReceiverInfo; +import com.android.queryable.Queryable; +import com.android.queryable.info.BroadcastReceiverInfo; /** Implementation of {@link BroadcastReceiverQuery}. */ -public final class BroadcastReceiverQueryHelper<E extends EventLogsQuery> +public final class BroadcastReceiverQueryHelper<E extends Queryable> implements BroadcastReceiverQuery<E> { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleKeyQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleKeyQuery.java index 035285cf6b2..0ec1156078c 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleKeyQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleKeyQuery.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.Bundle; import androidx.annotation.CheckResult; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a single key in a {@link Bundle}. */ -public interface BundleKeyQuery<E extends EventLogsQuery> extends Serializable { +public interface BundleKeyQuery<E extends Queryable> extends Serializable { /** Require that the key exists. */ E exists(); diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleKeyQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleKeyQueryHelper.java index f5851a49782..f102e7d3eae 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleKeyQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleKeyQueryHelper.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.Bundle; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link BundleKeyQuery}. */ -public final class BundleKeyQueryHelper<E extends EventLogsQuery> implements BundleKeyQuery<E>, +public final class BundleKeyQueryHelper<E extends Queryable> implements BundleKeyQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleQuery.java index cf9fd77cae9..123f9e8f35f 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleQuery.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.Bundle; import androidx.annotation.CheckResult; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link Bundle}. */ -public interface BundleQuery<E extends EventLogsQuery> extends Serializable { +public interface BundleQuery<E extends Queryable> extends Serializable { /** Query a given key on the {@link Bundle}. */ @CheckResult diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleQueryHelper.java index dc603879da3..ae4b85e7786 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/BundleQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/BundleQueryHelper.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.Bundle; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.util.SerializableParcelWrapper; +import com.android.queryable.Queryable; import java.io.Serializable; import java.util.HashMap; import java.util.Map; /** Implementation of {@link BundleQuery}. */ -public final class BundleQueryHelper<E extends EventLogsQuery> implements BundleQuery<E>, +public final class BundleQueryHelper<E extends Queryable> implements BundleQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ClassQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ClassQuery.java index 997ff683b72..8fd7b1db8b6 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ClassQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ClassQuery.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import androidx.annotation.CheckResult; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link Class}. */ -public interface ClassQuery<E extends EventLogsQuery> extends Serializable { +public interface ClassQuery<E extends Queryable> extends Serializable { /** Require that the class is the same as {@code clazz}. */ E isSameClassAs(Class<?> clazz); diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ClassQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ClassQueryHelper.java index 0c17d182764..3eca12dffbd 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/ClassQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/ClassQueryHelper.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.ClassInfo; +import com.android.queryable.Queryable; +import com.android.queryable.info.ClassInfo; import java.io.Serializable; /** Implementation of {@link ClassQuery}. */ -public final class ClassQueryHelper<E extends EventLogsQuery> +public final class ClassQueryHelper<E extends Queryable> implements ClassQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/DeviceAdminReceiverQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/DeviceAdminReceiverQuery.java index 3baea1e9596..40a2ffec568 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/DeviceAdminReceiverQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/DeviceAdminReceiverQuery.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.app.admin.DeviceAdminReceiver; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; /** Query for a {@link DeviceAdminReceiver}. */ -public interface DeviceAdminReceiverQuery<E extends EventLogsQuery> +public interface DeviceAdminReceiverQuery<E extends Queryable> extends BroadcastReceiverQuery<E> { } diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/DeviceAdminReceiverQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/DeviceAdminReceiverQueryHelper.java index 6ed0750db4c..68cec2f4ee2 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/DeviceAdminReceiverQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/DeviceAdminReceiverQueryHelper.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.info.DeviceAdminReceiverInfo; +import com.android.queryable.Queryable; +import com.android.queryable.info.DeviceAdminReceiverInfo; /** Implementation of {@link DeviceAdminReceiverQuery}. */ -public final class DeviceAdminReceiverQueryHelper<E extends EventLogsQuery> +public final class DeviceAdminReceiverQueryHelper<E extends Queryable> implements DeviceAdminReceiverQuery<E> { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntegerQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntegerQuery.java index 92b2469579a..5cb442f640a 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntegerQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntegerQuery.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link Integer}. */ -public interface IntegerQuery<E extends EventLogsQuery> extends Serializable { +public interface IntegerQuery<E extends Queryable> extends Serializable { /** Require the {@link Integer} is equal to {@code i}. */ E isEqualTo(int i); diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntegerQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntegerQueryHelper.java index 16619544b64..c6519d486de 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntegerQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntegerQueryHelper.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link IntegerQuery}. */ -public final class IntegerQueryHelper<E extends EventLogsQuery> implements IntegerQuery<E>, +public final class IntegerQueryHelper<E extends Queryable> implements IntegerQuery<E>, Serializable { private Integer mEqualToValue = null; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntentQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntentQuery.java index 45d1e9a5f80..3c83f247adb 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntentQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntentQuery.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.content.Intent; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link Intent}. */ -public interface IntentQuery<E extends EventLogsQuery> extends Serializable { +public interface IntentQuery<E extends Queryable> extends Serializable { /** Query the {@link Intent#getAction}. */ StringQuery<E> action(); diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntentQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntentQueryHelper.java index 459c29e8999..d7774e71037 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/IntentQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/IntentQueryHelper.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.content.Intent; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.util.SerializableParcelWrapper; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link IntentQuery}. */ -public final class IntentQueryHelper<E extends EventLogsQuery> implements IntentQuery<E>, +public final class IntentQueryHelper<E extends Queryable> implements IntentQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleKeyQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleKeyQuery.java index dd3112aebfe..9e75564838e 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleKeyQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleKeyQuery.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.PersistableBundle; import androidx.annotation.CheckResult; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a single key in a {@link PersistableBundle}. */ -public interface PersistableBundleKeyQuery<E extends EventLogsQuery> extends Serializable { +public interface PersistableBundleKeyQuery<E extends Queryable> extends Serializable { /** Require that the key exists. */ E exists(); /** Require that the key does not exist. */ diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleKeyQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleKeyQueryHelper.java index aca4e94930a..ddc9370446a 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleKeyQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleKeyQueryHelper.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.PersistableBundle; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link PersistableBundleKeyQuery}. */ -public final class PersistableBundleKeyQueryHelper<E extends EventLogsQuery> +public final class PersistableBundleKeyQueryHelper<E extends Queryable> implements PersistableBundleKeyQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleQuery.java index 4df56a2c572..67930a7d602 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleQuery.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.PersistableBundle; import androidx.annotation.CheckResult; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link PersistableBundle}. */ -public interface PersistableBundleQuery<E extends EventLogsQuery> extends Serializable { +public interface PersistableBundleQuery<E extends Queryable> extends Serializable { /** Query a given key on the {@link PersistableBundle}. */ @CheckResult diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleQueryHelper.java index 407e2ca3705..287f05ad6a4 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/PersistableBundleQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/PersistableBundleQueryHelper.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.PersistableBundle; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.util.SerializableParcelWrapper; +import com.android.queryable.Queryable; import java.io.Serializable; import java.util.HashMap; import java.util.Map; /** Implementation of {@link PersistableBundleQuery}. */ -public final class PersistableBundleQueryHelper<E extends EventLogsQuery> +public final class PersistableBundleQueryHelper<E extends Queryable> implements PersistableBundleQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/SerializableQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/SerializableQuery.java index c57bc1169c6..a511e429908 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/SerializableQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/SerializableQuery.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link Serializable}. */ -public interface SerializableQuery<E extends EventLogsQuery> extends Serializable { +public interface SerializableQuery<E extends Queryable> extends Serializable { /** Require that the {@link Serializable} is equal to {@code serializable}. */ E isEqualTo(Serializable serializable); } diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/SerializableQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/SerializableQueryHelper.java index 9d24c4945ad..655c55b16b0 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/SerializableQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/SerializableQueryHelper.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link SerializableQuery}. */ -public final class SerializableQueryHelper<E extends EventLogsQuery> +public final class SerializableQueryHelper<E extends Queryable> implements SerializableQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/StringQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/StringQuery.java index 3721c7cc07e..0dfb4b5d307 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/StringQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/StringQuery.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link String}. */ -public interface StringQuery<E extends EventLogsQuery> extends Serializable { +public interface StringQuery<E extends Queryable> extends Serializable { /** Require the {@link String} is equal to {@code string}. */ E isEqualTo(String string); } diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/StringQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/StringQueryHelper.java index b84ff1a0ad9..45b731c0b18 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/StringQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/StringQueryHelper.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link StringQuery}. */ -public final class StringQueryHelper<E extends EventLogsQuery> +public final class StringQueryHelper<E extends Queryable> implements StringQuery<E>, Serializable{ private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/UserHandleQuery.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/UserHandleQuery.java index c0d5d28e44e..7d7fb3235c3 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/UserHandleQuery.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/UserHandleQuery.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.UserHandle; import androidx.annotation.CheckResult; -import com.android.eventlib.EventLogsQuery; +import com.android.queryable.Queryable; import java.io.Serializable; /** Query for a {@link UserHandle}. */ -public interface UserHandleQuery<E extends EventLogsQuery> extends Serializable { +public interface UserHandleQuery<E extends Queryable> extends Serializable { /** Require the {@link UserHandle} is equal to {@code userHandle}. */ E isEqualTo(UserHandle userHandle); diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/UserHandleQueryHelper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/UserHandleQueryHelper.java index 3b5254c9aa4..a4b0a09aad9 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/queryhelpers/UserHandleQueryHelper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/queries/UserHandleQueryHelper.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import android.os.UserHandle; -import com.android.eventlib.EventLogsQuery; -import com.android.eventlib.util.SerializableParcelWrapper; +import com.android.queryable.util.SerializableParcelWrapper; +import com.android.queryable.Queryable; import java.io.Serializable; /** Implementation of {@link UserHandleQuery}. */ -public final class UserHandleQueryHelper<E extends EventLogsQuery> +public final class UserHandleQueryHelper<E extends Queryable> implements UserHandleQuery<E>, Serializable { private final E mQuery; diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/util/SerializableParcelWrapper.java b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/util/SerializableParcelWrapper.java index e0fa4b2d886..0d08c37d442 100644 --- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/util/SerializableParcelWrapper.java +++ b/common/device-side/bedstead/queryable/src/main/java/com/android/queryable/util/SerializableParcelWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.util; +package com.android.queryable.util; import android.os.Parcel; import android.os.Parcelable; diff --git a/common/device-side/bedstead/queryable/src/test/AndroidManifest.xml b/common/device-side/bedstead/queryable/src/test/AndroidManifest.xml new file mode 100644 index 00000000000..986faae755e --- /dev/null +++ b/common/device-side/bedstead/queryable/src/test/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2021 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.queryable.test"> + <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27"/> + <application + android:label="Queryable Tests" + android:testOnly="true"> + <uses-library android:name="android.test.runner" /> + </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.queryable.test" + android:label="Queryable Tests" /> +</manifest> diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/ActivityInfoTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/ActivityInfoTest.java index 17b8e1db1dd..dc3142ee97b 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/ActivityInfoTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/ActivityInfoTest.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import static com.google.common.truth.Truth.assertThat; import android.app.Activity; import com.android.activitycontext.ActivityContext; +import com.android.queryable.info.ActivityInfo; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/BroadcastReceiverInfoTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/BroadcastReceiverInfoTest.java index 2121c86f078..d8b906dda4a 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/BroadcastReceiverInfoTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/BroadcastReceiverInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import static com.google.common.truth.Truth.assertThat; @@ -22,6 +22,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import com.android.queryable.info.BroadcastReceiverInfo; + import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/ClassInfoTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/ClassInfoTest.java index 615cda1df7f..db4cf818ac5 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/ClassInfoTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/ClassInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import static com.google.common.truth.Truth.assertThat; diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/DeviceAdminReceiverInfoTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/DeviceAdminReceiverInfoTest.java index 52505edc420..6e0214beb35 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/info/DeviceAdminReceiverInfoTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/info/DeviceAdminReceiverInfoTest.java @@ -14,12 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.info; +package com.android.queryable.info; import static com.google.common.truth.Truth.assertThat; import android.app.admin.DeviceAdminReceiver; +import com.android.queryable.info.DeviceAdminReceiverInfo; + import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/ActivityQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/ActivityQueryHelperTest.java index ce1423899c4..25c77d520cf 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/ActivityQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/ActivityQueryHelperTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.app.Activity; -import com.android.eventlib.events.CustomEvent; -import com.android.eventlib.info.ActivityInfo; +import com.android.queryable.Queryable; +import com.android.queryable.info.ActivityInfo; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,8 +30,7 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class ActivityQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private static final Class<? extends Activity> CLASS_1 = Activity.class; private static final ActivityInfo CLASS_1_ACTIVITY_INFO = new ActivityInfo(CLASS_1); @@ -42,7 +41,7 @@ public class ActivityQueryHelperTest { @Test public void matches_noRestrictions_returnsTrue() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); assertThat(activityQueryHelper.matches(CLASS_1_ACTIVITY_INFO)).isTrue(); @@ -50,7 +49,7 @@ public class ActivityQueryHelperTest { @Test public void matches_isSameClassAs_doesMatch_returnsTrue() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); activityQueryHelper.isSameClassAs(CLASS_1); @@ -60,7 +59,7 @@ public class ActivityQueryHelperTest { @Test public void matches_isSameClassAs_doesNotMatch_returnsFalse() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); activityQueryHelper.isSameClassAs(CLASS_1); @@ -70,7 +69,7 @@ public class ActivityQueryHelperTest { @Test public void matches_className_doesMatch_returnsTrue() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); activityQueryHelper.className().isEqualTo(CLASS_1_CLASS_NAME); @@ -80,7 +79,7 @@ public class ActivityQueryHelperTest { @Test public void matches_className_doesNotMatch_returnsFalse() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); activityQueryHelper.className().isEqualTo(CLASS_1_CLASS_NAME); @@ -90,7 +89,7 @@ public class ActivityQueryHelperTest { @Test public void matches_simpleName_doesMatch_returnsTrue() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); activityQueryHelper.simpleName().isEqualTo(CLASS_1_SIMPLE_NAME); @@ -100,7 +99,7 @@ public class ActivityQueryHelperTest { @Test public void matches_simpleName_doesNotMatch_returnsFalse() { - ActivityQueryHelper<CustomEvent.CustomEventQuery> activityQueryHelper = + ActivityQueryHelper<Queryable> activityQueryHelper = new ActivityQueryHelper<>(mQuery); activityQueryHelper.simpleName().isEqualTo(CLASS_1_SIMPLE_NAME); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/BundleKeyQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/BundleKeyQueryHelperTest.java index 9283aba4b7f..9557bcb364f 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/BundleKeyQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/BundleKeyQueryHelperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.os.Bundle; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,8 +36,7 @@ public class BundleKeyQueryHelperTest { private static final String STRING_VALUE = "String"; private static final String DIFFERENT_STRING_VALUE = "String2"; - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private final Bundle mBundle = new Bundle(); private final Bundle mBundle2 = new Bundle(); private final Serializable mSerializable = "SerializableString"; @@ -45,7 +44,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_noRestrictions_returnsTrue() { - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); assertThat(bundleKeyQueryHelper.matches(mBundle, KEY)).isTrue(); @@ -54,7 +53,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_stringValueRestriction_meetsRestriction_returnsTrue() { mBundle.putString(KEY, STRING_VALUE); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.stringValue().isEqualTo(STRING_VALUE); @@ -65,7 +64,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_stringValueRestriction_doesNotMeetRestriction_returnsFalse() { mBundle.putString(KEY, STRING_VALUE); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.stringValue().isEqualTo(DIFFERENT_STRING_VALUE); @@ -77,7 +76,7 @@ public class BundleKeyQueryHelperTest { public void matches_bundleValueRestriction_meetsRestriction_returnsTrue() { mBundle.putBundle(KEY, mBundle2); mBundle2.putString(KEY2, STRING_VALUE); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.bundleValue().key(KEY2).exists(); @@ -89,7 +88,7 @@ public class BundleKeyQueryHelperTest { public void matches_bundleValueRestriction_doesNotMeetRestriction_returnsFalse() { mBundle.putBundle(KEY, mBundle2); mBundle2.remove(KEY2); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.bundleValue().key(KEY2).exists(); @@ -100,7 +99,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_serializableValueRestriction_meetsRestriction_returnsTrue() { mBundle.putSerializable(KEY, mSerializable); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.serializableValue().isEqualTo(mSerializable); @@ -111,7 +110,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_serializableValueRestriction_doesNotMeetRestriction_returnsFalse() { mBundle.putSerializable(KEY, mSerializable); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.serializableValue().isEqualTo(mDifferentSerializable); @@ -122,7 +121,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_existsRestriction_meetsRestriction_returnsTrue() { mBundle.putString(KEY, STRING_VALUE); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.exists(); @@ -133,7 +132,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_existsRestriction_doesNotMeetRestriction_returnsFalse() { mBundle.remove(KEY); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.exists(); @@ -144,7 +143,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_doesNotExistRestriction_meetsRestriction_returnsTrue() { mBundle.remove(KEY); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.doesNotExist(); @@ -155,7 +154,7 @@ public class BundleKeyQueryHelperTest { @Test public void matches_doesNotExistRestriction_doesNotMeetRestriction_returnsFalse() { mBundle.putString(KEY, STRING_VALUE); - BundleKeyQueryHelper<CustomEvent.CustomEventQuery> bundleKeyQueryHelper = + BundleKeyQueryHelper<Queryable> bundleKeyQueryHelper = new BundleKeyQueryHelper<>(mQuery); bundleKeyQueryHelper.doesNotExist(); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/BundleQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/BundleQueryHelperTest.java index 12d9b95b39d..bd150bbb5f6 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/BundleQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/BundleQueryHelperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.os.Bundle; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,13 +33,12 @@ public class BundleQueryHelperTest { private static final String KEY2 = "Key2"; private static final String STRING_VALUE = "value"; - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private final Bundle mBundle = new Bundle(); @Test public void matches_noRestrictions_returnsTrue() { - BundleQueryHelper<CustomEvent.CustomEventQuery> bundleQueryHelper = + BundleQueryHelper<Queryable> bundleQueryHelper = new BundleQueryHelper<>(mQuery); assertThat(bundleQueryHelper.matches(mBundle)).isTrue(); @@ -48,7 +47,7 @@ public class BundleQueryHelperTest { @Test public void matches_restrictionOnOneKey_restrictionIsMet_returnsTrue() { mBundle.putString(KEY, STRING_VALUE); - BundleQueryHelper<CustomEvent.CustomEventQuery> bundleQueryHelper = + BundleQueryHelper<Queryable> bundleQueryHelper = new BundleQueryHelper<>(mQuery); bundleQueryHelper.key(KEY).exists(); @@ -59,7 +58,7 @@ public class BundleQueryHelperTest { @Test public void matches_restrictionOnOneKey_restrictionIsNotMet_returnsFalse() { mBundle.putString(KEY, STRING_VALUE); - BundleQueryHelper<CustomEvent.CustomEventQuery> bundleQueryHelper = + BundleQueryHelper<Queryable> bundleQueryHelper = new BundleQueryHelper<>(mQuery); bundleQueryHelper.key(KEY).doesNotExist(); @@ -71,7 +70,7 @@ public class BundleQueryHelperTest { public void matches_restrictionOnMultipleKeys_oneRestrictionIsNotMet_returnsFalse() { mBundle.putString(KEY, STRING_VALUE); mBundle.remove(KEY2); - BundleQueryHelper<CustomEvent.CustomEventQuery> bundleQueryHelper = + BundleQueryHelper<Queryable> bundleQueryHelper = new BundleQueryHelper<>(mQuery); bundleQueryHelper.key(KEY).exists(); @@ -83,7 +82,7 @@ public class BundleQueryHelperTest { @Test public void matches_restrictionOnNonExistingKey_returnsFalse() { mBundle.remove(KEY); - BundleQueryHelper<CustomEvent.CustomEventQuery> bundleQueryHelper = + BundleQueryHelper<Queryable> bundleQueryHelper = new BundleQueryHelper<>(mQuery); bundleQueryHelper.key(KEY).stringValue().isEqualTo(STRING_VALUE); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/ClassQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/ClassQueryHelperTest.java index 175204e0bfa..21bc0962871 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/ClassQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/ClassQueryHelperTest.java @@ -14,14 +14,16 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.app.Activity; import com.android.eventlib.events.CustomEvent; -import com.android.eventlib.info.ClassInfo; +import com.android.queryable.Queryable; +import com.android.queryable.info.ClassInfo; +import com.android.queryable.queries.ClassQueryHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,8 +31,7 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class ClassQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private static final Class<?> CLASS_1 = Activity.class; private static final ClassInfo CLASS_1_CLASS_INFO = new ClassInfo(CLASS_1); @@ -40,7 +41,7 @@ public class ClassQueryHelperTest { @Test public void matches_noRestrictions_returnsTrue() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); assertThat(classQueryHelper.matches(CLASS_1_CLASS_INFO)).isTrue(); @@ -48,7 +49,7 @@ public class ClassQueryHelperTest { @Test public void matches_isSameClassAs_doesMatch_returnsTrue() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); classQueryHelper.isSameClassAs(CLASS_1); @@ -58,7 +59,7 @@ public class ClassQueryHelperTest { @Test public void matches_isSameClassAs_doesNotMatch_returnsFalse() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); classQueryHelper.isSameClassAs(CLASS_1); @@ -68,7 +69,7 @@ public class ClassQueryHelperTest { @Test public void matches_className_doesMatch_returnsTrue() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); classQueryHelper.className().isEqualTo(CLASS_1_CLASS_NAME); @@ -78,7 +79,7 @@ public class ClassQueryHelperTest { @Test public void matches_className_doesNotMatch_returnsFalse() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); classQueryHelper.className().isEqualTo(CLASS_1_CLASS_NAME); @@ -88,7 +89,7 @@ public class ClassQueryHelperTest { @Test public void matches_simpleName_doesMatch_returnsTrue() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); classQueryHelper.simpleName().isEqualTo(CLASS_1_SIMPLE_NAME); @@ -98,7 +99,7 @@ public class ClassQueryHelperTest { @Test public void matches_simpleName_doesNotMatch_returnsFalse() { - ClassQueryHelper<CustomEvent.CustomEventQuery> classQueryHelper = + ClassQueryHelper<Queryable> classQueryHelper = new ClassQueryHelper<>(mQuery); classQueryHelper.simpleName().isEqualTo(CLASS_1_SIMPLE_NAME); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/IntegerQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/IntegerQueryHelperTest.java index 528e9a5686f..f2b7e3da549 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/IntegerQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/IntegerQueryHelperTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,15 +27,14 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class IntegerQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private static final int INTEGER_VALUE = 100; private static final int GREATER_VALUE = 200; private static final int LESS_VALUE = 50; @Test public void matches_noRestrictions_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); assertThat(integerQueryHelper.matches(INTEGER_VALUE)).isTrue(); @@ -43,7 +42,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isEqualTo_meetsRestriction_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isEqualTo(INTEGER_VALUE); @@ -53,7 +52,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isEqualTo_doesNotMeetRestriction_returnsFalse() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isEqualTo(INTEGER_VALUE); @@ -63,7 +62,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isGreaterThan_meetsRestriction_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isGreaterThan(INTEGER_VALUE); @@ -73,7 +72,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isGreaterThan_doesNotMeetRestriction_returnsFalse() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isGreaterThan(INTEGER_VALUE); @@ -83,7 +82,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isGreaterThanOrEqualTo_greaterThan_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isGreaterThanOrEqualTo(INTEGER_VALUE); @@ -93,7 +92,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isGreaterThanOrEqualTo_equalTo_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isGreaterThanOrEqualTo(INTEGER_VALUE); @@ -103,7 +102,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isGreaterThanOrEqualTo_doesNotMeetRestriction_returnsFalse() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isGreaterThanOrEqualTo(INTEGER_VALUE); @@ -113,7 +112,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isLessThan_meetsRestriction_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isLessThan(INTEGER_VALUE); @@ -123,7 +122,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isLessThan_doesNotMeetRestriction_returnsFalse() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isLessThan(INTEGER_VALUE); @@ -133,7 +132,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isLessThanOrEqualTo_lessThan_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isLessThanOrEqualTo(INTEGER_VALUE); @@ -143,7 +142,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isLessThanOrEqualTo_equalTo_returnsTrue() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isLessThanOrEqualTo(INTEGER_VALUE); @@ -153,7 +152,7 @@ public class IntegerQueryHelperTest { @Test public void matches_isLessThanOrEqualTo_doesNotMeetRestriction_returnsFalse() { - IntegerQueryHelper<CustomEvent.CustomEventQuery> integerQueryHelper = + IntegerQueryHelper<Queryable> integerQueryHelper = new IntegerQueryHelper<>(mQuery); integerQueryHelper.isLessThanOrEqualTo(INTEGER_VALUE); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/IntentQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/IntentQueryHelperTest.java index e815479174b..45da9f4358a 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/IntentQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/IntentQueryHelperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.content.Intent; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,15 +29,14 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class IntentQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private static final String STRING_VALUE = "String"; private static final String DIFFERENT_STRING_VALUE = "String2"; @Test public void matches_noRestrictions_returnsTrue() { Intent intent = new Intent(); - IntentQueryHelper<CustomEvent.CustomEventQuery> intentQueryHelper = + IntentQueryHelper<Queryable> intentQueryHelper = new IntentQueryHelper<>(mQuery); assertThat(intentQueryHelper.matches(intent)).isTrue(); @@ -47,7 +46,7 @@ public class IntentQueryHelperTest { public void matches_action_meetsRestriction_returnsTrue() { Intent intent = new Intent(); intent.setAction(STRING_VALUE); - IntentQueryHelper<CustomEvent.CustomEventQuery> intentQueryHelper = + IntentQueryHelper<Queryable> intentQueryHelper = new IntentQueryHelper<>(mQuery); intentQueryHelper.action().isEqualTo(STRING_VALUE); @@ -59,7 +58,7 @@ public class IntentQueryHelperTest { public void matches_action_doesNotMeetRestriction_returnsFalse() { Intent intent = new Intent(); intent.setAction(STRING_VALUE); - IntentQueryHelper<CustomEvent.CustomEventQuery> intentQueryHelper = + IntentQueryHelper<Queryable> intentQueryHelper = new IntentQueryHelper<>(mQuery); intentQueryHelper.action().isEqualTo(DIFFERENT_STRING_VALUE); @@ -71,7 +70,7 @@ public class IntentQueryHelperTest { public void matches_extras_meetsRestriction_returnsTrue() { Intent intent = new Intent(); intent.putExtra(/* key= */ STRING_VALUE, /* value= */ STRING_VALUE); - IntentQueryHelper<CustomEvent.CustomEventQuery> intentQueryHelper = + IntentQueryHelper<Queryable> intentQueryHelper = new IntentQueryHelper<>(mQuery); intentQueryHelper.extras().key(STRING_VALUE).stringValue().isEqualTo(STRING_VALUE); @@ -83,7 +82,7 @@ public class IntentQueryHelperTest { public void matches_extras_doesNotMeetRestriction_returnsFalse() { Intent intent = new Intent(); intent.putExtra(/* key= */ STRING_VALUE, /* value= */ STRING_VALUE); - IntentQueryHelper<CustomEvent.CustomEventQuery> intentQueryHelper = + IntentQueryHelper<Queryable> intentQueryHelper = new IntentQueryHelper<>(mQuery); intentQueryHelper.extras().key(STRING_VALUE).stringValue() diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/PersistableBundleKeyQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/PersistableBundleKeyQueryHelperTest.java index a5875122003..e461700fdb4 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/PersistableBundleKeyQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/PersistableBundleKeyQueryHelperTest.java @@ -14,21 +14,18 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; -import android.os.Bundle; import android.os.PersistableBundle; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import java.io.Serializable; - @RunWith(JUnit4.class) public class PersistableBundleKeyQueryHelperTest { @@ -37,14 +34,13 @@ public class PersistableBundleKeyQueryHelperTest { private static final String STRING_VALUE = "String"; private static final String DIFFERENT_STRING_VALUE = "String2"; - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private final PersistableBundle mPersistableBundle = new PersistableBundle(); private final PersistableBundle mPersistableBundle2 = new PersistableBundle(); @Test public void matches_noRestrictions_returnsTrue() { - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); assertThat(persistableBundleKeyQueryHelper.matches(mPersistableBundle, KEY)).isTrue(); @@ -53,7 +49,7 @@ public class PersistableBundleKeyQueryHelperTest { @Test public void matches_stringValueRestriction_meetsRestriction_returnsTrue() { mPersistableBundle.putString(KEY, STRING_VALUE); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.stringValue().isEqualTo(STRING_VALUE); @@ -64,7 +60,7 @@ public class PersistableBundleKeyQueryHelperTest { @Test public void matches_stringValueRestriction_doesNotMeetRestriction_returnsFalse() { mPersistableBundle.putString(KEY, STRING_VALUE); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.stringValue().isEqualTo(DIFFERENT_STRING_VALUE); @@ -76,7 +72,7 @@ public class PersistableBundleKeyQueryHelperTest { public void matches_persistableBundleValueRestriction_meetsRestriction_returnsTrue() { mPersistableBundle.putPersistableBundle(KEY, mPersistableBundle2); mPersistableBundle2.putString(KEY2, STRING_VALUE); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.persistableBundleValue().key(KEY2).exists(); @@ -88,7 +84,7 @@ public class PersistableBundleKeyQueryHelperTest { public void matches_persistableBundleValueRestriction_doesNotMeetRestriction_returnsFalse() { mPersistableBundle.putPersistableBundle(KEY, mPersistableBundle2); mPersistableBundle2.remove(KEY2); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.persistableBundleValue().key(KEY2).exists(); @@ -99,7 +95,7 @@ public class PersistableBundleKeyQueryHelperTest { @Test public void matches_existsRestriction_meetsRestriction_returnsTrue() { mPersistableBundle.putString(KEY, STRING_VALUE); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.exists(); @@ -110,7 +106,7 @@ public class PersistableBundleKeyQueryHelperTest { @Test public void matches_existsRestriction_doesNotMeetRestriction_returnsFalse() { mPersistableBundle.remove(KEY); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.exists(); @@ -121,7 +117,7 @@ public class PersistableBundleKeyQueryHelperTest { @Test public void matches_doesNotExistRestriction_meetsRestriction_returnsTrue() { mPersistableBundle.remove(KEY); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.doesNotExist(); @@ -132,7 +128,7 @@ public class PersistableBundleKeyQueryHelperTest { @Test public void matches_doesNotExistRestriction_doesNotMeetRestriction_returnsFalse() { mPersistableBundle.putString(KEY, STRING_VALUE); - PersistableBundleKeyQueryHelper<CustomEvent.CustomEventQuery> + PersistableBundleKeyQueryHelper<Queryable> persistableBundleKeyQueryHelper = new PersistableBundleKeyQueryHelper<>(mQuery); persistableBundleKeyQueryHelper.doesNotExist(); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/PersistableBundleQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/PersistableBundleQueryHelperTest.java index 39f11eca69e..6379beef891 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/PersistableBundleQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/PersistableBundleQueryHelperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.os.PersistableBundle; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,13 +32,12 @@ public class PersistableBundleQueryHelperTest { private static final String KEY2 = "Key2"; private static final String STRING_VALUE = "value"; - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private final PersistableBundle mPersistableBundle = new PersistableBundle(); @Test public void matches_noRestrictions_returnsTrue() { - PersistableBundleQueryHelper<CustomEvent.CustomEventQuery> persistableBundleQueryHelper = + PersistableBundleQueryHelper<Queryable> persistableBundleQueryHelper = new PersistableBundleQueryHelper<>(mQuery); assertThat(persistableBundleQueryHelper.matches(mPersistableBundle)).isTrue(); @@ -47,7 +46,7 @@ public class PersistableBundleQueryHelperTest { @Test public void matches_restrictionOnOneKey_restrictionIsMet_returnsTrue() { mPersistableBundle.putString(KEY, STRING_VALUE); - PersistableBundleQueryHelper<CustomEvent.CustomEventQuery> persistableBundleQueryHelper = + PersistableBundleQueryHelper<Queryable> persistableBundleQueryHelper = new PersistableBundleQueryHelper<>(mQuery); persistableBundleQueryHelper.key(KEY).exists(); @@ -58,7 +57,7 @@ public class PersistableBundleQueryHelperTest { @Test public void matches_restrictionOnOneKey_restrictionIsNotMet_returnsFalse() { mPersistableBundle.putString(KEY, STRING_VALUE); - PersistableBundleQueryHelper<CustomEvent.CustomEventQuery> persistableBundleQueryHelper = + PersistableBundleQueryHelper<Queryable> persistableBundleQueryHelper = new PersistableBundleQueryHelper<>(mQuery); persistableBundleQueryHelper.key(KEY).doesNotExist(); @@ -70,7 +69,7 @@ public class PersistableBundleQueryHelperTest { public void matches_restrictionOnMultipleKeys_oneRestrictionIsNotMet_returnsFalse() { mPersistableBundle.putString(KEY, STRING_VALUE); mPersistableBundle.remove(KEY2); - PersistableBundleQueryHelper<CustomEvent.CustomEventQuery> persistableBundleQueryHelper = + PersistableBundleQueryHelper<Queryable> persistableBundleQueryHelper = new PersistableBundleQueryHelper<>(mQuery); persistableBundleQueryHelper.key(KEY).exists(); @@ -82,7 +81,7 @@ public class PersistableBundleQueryHelperTest { @Test public void matches_restrictionOnNonExistingKey_returnsFalse() { mPersistableBundle.remove(KEY); - PersistableBundleQueryHelper<CustomEvent.CustomEventQuery> persistableBundleQueryHelper = + PersistableBundleQueryHelper<Queryable> persistableBundleQueryHelper = new PersistableBundleQueryHelper<>(mQuery); persistableBundleQueryHelper.key(KEY).stringValue().isEqualTo(STRING_VALUE); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/SerializableQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/SerializableQueryHelperTest.java index a1f23b1f01c..2ddc136b7fd 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/SerializableQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/SerializableQueryHelperTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,14 +29,13 @@ import java.io.Serializable; @RunWith(JUnit4.class) public class SerializableQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private final Serializable mSerializable = "SerializableString"; private final Serializable mDifferentSerializable = "SerializableString2"; @Test public void matches_noRestrictions_returnsTrue() { - SerializableQueryHelper<CustomEvent.CustomEventQuery> serializableQueryHelper = + SerializableQueryHelper<Queryable> serializableQueryHelper = new SerializableQueryHelper<>(mQuery); assertThat(serializableQueryHelper.matches(mSerializable)).isTrue(); @@ -44,7 +43,7 @@ public class SerializableQueryHelperTest { @Test public void matches_isEqualTo_meetsRestriction_returnsTrue() { - SerializableQueryHelper<CustomEvent.CustomEventQuery> serializableQueryHelper = + SerializableQueryHelper<Queryable> serializableQueryHelper = new SerializableQueryHelper<>(mQuery); serializableQueryHelper.isEqualTo(mSerializable); @@ -54,7 +53,7 @@ public class SerializableQueryHelperTest { @Test public void matches_isEqualTo_doesNotMeetRestriction_returnsFalse() { - SerializableQueryHelper<CustomEvent.CustomEventQuery> serializableQueryHelper = + SerializableQueryHelper<Queryable> serializableQueryHelper = new SerializableQueryHelper<>(mQuery); serializableQueryHelper.isEqualTo(mDifferentSerializable); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/StringQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/StringQueryHelperTest.java index 2cb6b16afee..9797b8c246e 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/StringQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/StringQueryHelperTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,14 +27,13 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class StringQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private static final String STRING_VALUE = "String"; private static final String DIFFERENT_STRING_VALUE = "String2"; @Test public void matches_noRestrictions_returnsTrue() { - StringQueryHelper<CustomEvent.CustomEventQuery> stringQueryHelper = + StringQueryHelper<Queryable> stringQueryHelper = new StringQueryHelper<>(mQuery); assertThat(stringQueryHelper.matches(STRING_VALUE)).isTrue(); @@ -42,7 +41,7 @@ public class StringQueryHelperTest { @Test public void matches_isEqualTo_meetsRestriction_returnsTrue() { - StringQueryHelper<CustomEvent.CustomEventQuery> stringQueryHelper = + StringQueryHelper<Queryable> stringQueryHelper = new StringQueryHelper<>(mQuery); stringQueryHelper.isEqualTo(STRING_VALUE); @@ -52,7 +51,7 @@ public class StringQueryHelperTest { @Test public void matches_isEqualTo_doesNotMeetRestriction_returnsFalse() { - StringQueryHelper<CustomEvent.CustomEventQuery> stringQueryHelper = + StringQueryHelper<Queryable> stringQueryHelper = new StringQueryHelper<>(mQuery); stringQueryHelper.isEqualTo(DIFFERENT_STRING_VALUE); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/UserHandleQueryHelperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/UserHandleQueryHelperTest.java index 9b125864fc5..941e5faa582 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/queryhelpers/UserHandleQueryHelperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/queries/UserHandleQueryHelperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.eventlib.queryhelpers; +package com.android.queryable.queries; import static com.google.common.truth.Truth.assertThat; import android.os.UserHandle; -import com.android.eventlib.events.CustomEvent; +import com.android.queryable.Queryable; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,15 +29,14 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class UserHandleQueryHelperTest { - private final CustomEvent.CustomEventQuery mQuery = - CustomEvent.queryPackage("testPackage"); // package is not used + private final Queryable mQuery = null; private static final int USER_HANDLE_ID = 1; private static final UserHandle USER_HANDLE = UserHandle.of(USER_HANDLE_ID); private static final UserHandle DIFFERENT_USER_HANDLE = UserHandle.of(2); @Test public void matches_noRestrictions_returnsTrue() { - UserHandleQueryHelper<CustomEvent.CustomEventQuery> userHandleQueryHelper = + UserHandleQueryHelper<Queryable> userHandleQueryHelper = new UserHandleQueryHelper<>(mQuery); assertThat(userHandleQueryHelper.matches(USER_HANDLE)).isTrue(); @@ -45,7 +44,7 @@ public class UserHandleQueryHelperTest { @Test public void matches_isEqualTo_meetsRestriction_returnsTrue() { - UserHandleQueryHelper<CustomEvent.CustomEventQuery> userHandleQueryHelper = + UserHandleQueryHelper<Queryable> userHandleQueryHelper = new UserHandleQueryHelper<>(mQuery); userHandleQueryHelper.isEqualTo(USER_HANDLE); @@ -55,7 +54,7 @@ public class UserHandleQueryHelperTest { @Test public void matches_isEqualTo_doesNotMeetRestriction_returnsFalse() { - UserHandleQueryHelper<CustomEvent.CustomEventQuery> userHandleQueryHelper = + UserHandleQueryHelper<Queryable> userHandleQueryHelper = new UserHandleQueryHelper<>(mQuery); userHandleQueryHelper.isEqualTo(USER_HANDLE); @@ -65,7 +64,7 @@ public class UserHandleQueryHelperTest { @Test public void matches_id_meetsRestriction_returnsTrue() { - UserHandleQueryHelper<CustomEvent.CustomEventQuery> userHandleQueryHelper = + UserHandleQueryHelper<Queryable> userHandleQueryHelper = new UserHandleQueryHelper<>(mQuery); userHandleQueryHelper.id().isEqualTo(USER_HANDLE_ID); @@ -75,7 +74,7 @@ public class UserHandleQueryHelperTest { @Test public void matches_id_doesNotMeetRestriction_returnsFalse() { - UserHandleQueryHelper<CustomEvent.CustomEventQuery> userHandleQueryHelper = + UserHandleQueryHelper<Queryable> userHandleQueryHelper = new UserHandleQueryHelper<>(mQuery); userHandleQueryHelper.id().isEqualTo(USER_HANDLE_ID); diff --git a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/util/SerializableParcelWrapperTest.java b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/util/SerializableParcelWrapperTest.java index fa73206ab78..8ee103f9612 100644 --- a/common/device-side/bedstead/eventlib/src/test/java/com/android/eventlib/util/SerializableParcelWrapperTest.java +++ b/common/device-side/bedstead/queryable/src/test/java/com/android/queryable/util/SerializableParcelWrapperTest.java @@ -14,13 +14,15 @@ * limitations under the License. */ -package com.android.eventlib.util; +package com.android.queryable.util; import static com.google.common.truth.Truth.assertThat; import android.os.Bundle; import android.os.Parcelable; +import com.android.queryable.util.SerializableParcelWrapper; + import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/common/device-side/bedstead/testapp/src/main/library/java/com/android/bedstead/testapp/TestAppActivityReference.java b/common/device-side/bedstead/testapp/src/main/library/java/com/android/bedstead/testapp/TestAppActivityReference.java index 01e3c84ab17..87d1fc383b9 100644 --- a/common/device-side/bedstead/testapp/src/main/library/java/com/android/bedstead/testapp/TestAppActivityReference.java +++ b/common/device-side/bedstead/testapp/src/main/library/java/com/android/bedstead/testapp/TestAppActivityReference.java @@ -20,6 +20,7 @@ import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import android.content.Intent; +import android.os.Bundle; import com.android.bedstead.nene.TestApis; import com.android.bedstead.nene.activities.ActivityReference; @@ -69,4 +70,21 @@ public abstract class TestAppActivityReference { return sTestApis.activities().wrap( TestAppActivity.class, new TestAppActivityImpl(mInstance, mComponent)); } + + /** + * Starts the activity. + */ + public com.android.bedstead.nene.activities.Activity<TestAppActivity> start(Bundle options) { + Intent intent = new Intent(); + intent.setComponent(mComponent.componentName()); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); + sTestApis.context().instrumentedContext().startActivity(intent, options); + + ActivityCreatedEvent + .queryPackage(mComponent.packageName().packageName()) + .whereActivity().className().isEqualTo(mComponent.className()).waitForEvent(); + + return sTestApis.activities().wrap( + TestAppActivity.class, new TestAppActivityImpl(mInstance, mComponent)); + } } diff --git a/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchHostTestBase.java b/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchHostTestBase.java index 7dd10d9fad6..203fa8255b0 100644 --- a/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchHostTestBase.java +++ b/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchHostTestBase.java @@ -29,6 +29,8 @@ public abstract class AppSearchHostTestBase extends BaseHostJUnit4Test { protected static final String TARGET_APK_A = "CtsAppSearchHostTestHelperA.apk"; protected static final String TARGET_PKG_A = "android.appsearch.app.a"; protected static final String TEST_CLASS_A = TARGET_PKG_A + ".AppSearchDeviceTest"; + protected static final String TEST_STORAGE_AUGMENTER_CLASS_A = + TARGET_PKG_A + ".AppSearchStorageAugmenterDeviceTest"; protected static final String TARGET_APK_B = "CtsAppSearchHostTestHelperB.apk"; protected static final String TARGET_PKG_B = "android.appsearch.app.b"; protected static final String TEST_CLASS_B = TARGET_PKG_B + ".AppSearchDeviceTest"; @@ -58,6 +60,13 @@ public abstract class AppSearchHostTestBase extends BaseHostJUnit4Test { runDeviceTests(deviceTestRunOptions)).isTrue(); } + protected void runStorageAugmenterDeviceTestAsUserInPkgA(@Nonnull String testMethod, int userId) + throws Exception { + assertWithMessage(testMethod + " failed").that( + runDeviceTests(getDevice(), TARGET_PKG_A, TEST_STORAGE_AUGMENTER_CLASS_A, + testMethod, userId, DEFAULT_INSTRUMENTATION_TIMEOUT_MS)).isTrue(); + } + protected void runDeviceTestAsUserInPkgB(@Nonnull String testMethod, int userId) throws Exception { assertWithMessage(testMethod + " failed").that( diff --git a/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchMultiUserTest.java b/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchMultiUserTest.java index 7627d90b458..1764cab4de8 100644 --- a/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchMultiUserTest.java +++ b/hostsidetests/appsearch/src/android/appsearch/cts/AppSearchMultiUserTest.java @@ -111,4 +111,21 @@ public class AppSearchMultiUserTest extends AppSearchHostTestBase { getDevice().startUser(mSecondaryUserId, /*waitFlag=*/true); runDeviceTestAsUserInPkgB("testGlobalGetDocuments_nonexist", mSecondaryUserId); } + + @Test + public void testReadStorageInfoFromFile() throws Exception { + runDeviceTestAsUserInPkgA("testPutDocuments", mSecondaryUserId); + + getDevice().stopUser(mSecondaryUserId, /*waitFlag=*/true, /*forceFlag=*/true); + getDevice().startUser(mSecondaryUserId, /*waitFlag=*/true); + // Write user's storage info into file while initializing AppSearchImpl. + runStorageAugmenterDeviceTestAsUserInPkgA("connectToAppSearch", mSecondaryUserId); + + // Disconnect user from AppSearch. While AppSearchImpl doesn't exist for the user, user's + // storage info would be read from file. + getDevice().stopUser(mSecondaryUserId, /*waitFlag=*/true, /*forceFlag=*/true); + getDevice().startUser(mSecondaryUserId, /*waitFlag=*/true); + + runStorageAugmenterDeviceTestAsUserInPkgA("testReadStorageInfo", mSecondaryUserId); + } } diff --git a/hostsidetests/appsearch/test-apps/AppSearchHostTestHelperA/src/android/appsearch/app/a/AppSearchStorageAugmenterDeviceTest.java b/hostsidetests/appsearch/test-apps/AppSearchHostTestHelperA/src/android/appsearch/app/a/AppSearchStorageAugmenterDeviceTest.java new file mode 100644 index 00000000000..3e91498f944 --- /dev/null +++ b/hostsidetests/appsearch/test-apps/AppSearchHostTestHelperA/src/android/appsearch/app/a/AppSearchStorageAugmenterDeviceTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2021 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.appsearch.app.a; + +import static android.os.storage.StorageManager.UUID_DEFAULT; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.appsearch.AppSearchManager; +import android.app.usage.StorageStats; +import android.app.usage.StorageStatsManager; +import android.content.Context; +import android.os.UserHandle; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.server.appsearch.testing.AppSearchSessionShimImpl; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class AppSearchStorageAugmenterDeviceTest { + + @Test + public void connectToAppSearch() throws Exception { + AppSearchSessionShimImpl.createSearchSession( + new AppSearchManager.SearchContext.Builder("dbName").build()).get(); + } + + @Test + public void testReadStorageInfo() throws Exception { + Context context = ApplicationProvider.getApplicationContext(); + StorageStatsManager storageStatsManager = + context.getSystemService(StorageStatsManager.class); + String packageName = context.getPackageName(); + UserHandle user = context.getUser(); + int uid = android.os.Process.myUid(); + + // Query the storage info through AppSearchStorageStatsAugmenter. + StorageStats statsForPkg = + storageStatsManager.queryStatsForPackage(UUID_DEFAULT, packageName, user); + StorageStats statsForUid = storageStatsManager.queryStatsForUid(UUID_DEFAULT, uid); + + assertThat(statsForPkg.getDataBytes()).isGreaterThan(0); + assertThat(statsForUid.getDataBytes()).isGreaterThan(0); + } +} diff --git a/hostsidetests/devicepolicy/app/DelegateApp/src/com/android/cts/delegate/SecurityLoggingDelegateTest.java b/hostsidetests/devicepolicy/app/DelegateApp/src/com/android/cts/delegate/SecurityLoggingDelegateTest.java index cfff6b088f4..092a3149f19 100644 --- a/hostsidetests/devicepolicy/app/DelegateApp/src/com/android/cts/delegate/SecurityLoggingDelegateTest.java +++ b/hostsidetests/devicepolicy/app/DelegateApp/src/com/android/cts/delegate/SecurityLoggingDelegateTest.java @@ -84,6 +84,8 @@ public class SecurityLoggingDelegateTest extends BaseTestCase { */ @Test public void testGenerateLogs() throws Exception { + // If any logs are available, fetch them so that force-security-logs causes a broadcast. + mDpm.retrieveSecurityLogs(null); try { final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); keyGen.initialize(new KeyGenParameterSpec.Builder( diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java index 16cee1e592d..95a0e282ca1 100644 --- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java +++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java @@ -155,114 +155,6 @@ public class LockTaskTest extends BaseDeviceAdminTest { mContext.unregisterReceiver(mReceiver); } - // When LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK is set, un-allowed apps cannot - // be launched in the same task. - public void testStartActivity_withinTask_blockInTask() throws Exception { - mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME }); - mDevicePolicyManager.setLockTaskFeatures( - ADMIN_COMPONENT, LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK); - startLockTask(UTILITY_ACTIVITY); - waitForResume(); - - mIsReceiverActivityRunning = false; - Intent launchIntent = createReceiverActivityIntent(false /*newTask*/, false /*shouldWait*/); - Intent lockTaskUtility = getLockTaskUtility(UTILITY_ACTIVITY); - lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent); - mContext.startActivity(lockTaskUtility); - - synchronized (mReceiverActivityRunningLock) { - mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS); - assertFalse(mIsReceiverActivityRunning); - } - - Log.d(TAG, "Waiting for the system dialog"); - mUiDevice.waitForIdle(); - assertTrue(mUiDevice.wait( - Until.hasObject(By.textContains(RECEIVER_ACTIVITY_PACKAGE_NAME)), - ACTIVITY_RESUMED_TIMEOUT_MILLIS)); - Log.d(TAG, "dialog found"); - - // Dismiss the system dialog - mUiDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER); - mUiDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER); - assertFalse(mUiDevice.wait( - Until.hasObject(By.textContains(RECEIVER_ACTIVITY_PACKAGE_NAME)), - ACTIVITY_RESUMED_TIMEOUT_MILLIS)); - - mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, 0); - } - - // When LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK is set, the system dialog will also be - // shown when an un-allowed app is being launched in a new task. - public void testStartActivity_newTask_blockInTask() throws Exception { - mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME }); - mDevicePolicyManager.setLockTaskFeatures( - ADMIN_COMPONENT, LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK); - startLockTask(UTILITY_ACTIVITY); - waitForResume(); - - mIsReceiverActivityRunning = false; - Intent launchIntent = createReceiverActivityIntent(true /*newTask*/, false /*shouldWait*/); - Intent lockTaskUtility = getLockTaskUtility(UTILITY_ACTIVITY); - lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent); - mContext.startActivity(lockTaskUtility); - - synchronized (mReceiverActivityRunningLock) { - mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS); - assertFalse(mIsReceiverActivityRunning); - } - - Log.d(TAG, "Waiting for the system dialog"); - mUiDevice.waitForIdle(); - assertTrue(mUiDevice.wait( - Until.hasObject(By.textContains(RECEIVER_ACTIVITY_PACKAGE_NAME)), - ACTIVITY_RESUMED_TIMEOUT_MILLIS)); - Log.d(TAG, "dialog found"); - - // Dismiss the system dialog - mUiDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER); - mUiDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER); - assertFalse(mUiDevice.wait( - Until.hasObject(By.textContains(RECEIVER_ACTIVITY_PACKAGE_NAME)), - ACTIVITY_RESUMED_TIMEOUT_MILLIS)); - - mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, 0); - } - - // This launches an allowed activity that is not part of the current task. - // This should be permitted as a part of lock task. - public void testStartActivity_outsideTaskAllowed() throws Exception { - mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME, - RECEIVER_ACTIVITY_PACKAGE_NAME}); - startLockTask(UTILITY_ACTIVITY); - waitForResume(); - - mIsReceiverActivityRunning = false; - Intent launchIntent = createReceiverActivityIntent(true /*newTask*/, false /*shouldWait*/); - mContext.startActivity(launchIntent); - synchronized (mReceiverActivityRunningLock) { - mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS); - assertTrue(mIsReceiverActivityRunning); - } - stopAndFinish(UTILITY_ACTIVITY); - } - - // This launches a not-allowed activity that is not part of the current task. - // This should be blocked. - public void testStartActivity_outsideTaskNotAllowed() throws Exception { - mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME }); - startLockTask(UTILITY_ACTIVITY); - waitForResume(); - - Intent launchIntent = createReceiverActivityIntent(true /*newTask*/, false /*shouldWait*/); - mContext.startActivity(launchIntent); - synchronized (mActivityResumedLock) { - mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS); - assertFalse(mIsReceiverActivityRunning); - } - stopAndFinish(UTILITY_ACTIVITY); - } - // Test the lockTaskMode flag for an activity declaring if_whitelisted. // Allow the activity and verify that lock task mode is started. public void testManifestArgument_allowed() throws Exception { @@ -323,30 +215,6 @@ public class LockTaskTest extends BaseDeviceAdminTest { assertFalse(mIsActivityResumed); } - // Start lock task with ActivityOptions - public void testActivityOptions_allowed() throws Exception { - mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME }); - startLockTaskWithOptions(UTILITY_ACTIVITY); - waitForResume(); - - // Verify that activity open and activity manager is in lock task. - assertLockTaskModeActive(); - assertTrue(mIsActivityRunning); - assertTrue(mIsActivityResumed); - - stopAndFinish(UTILITY_ACTIVITY); - } - - // Starting a not-allowed activity with ActivityOptions is not allowed - public void testActivityOptions_notAllowed() throws Exception { - try { - startLockTaskWithOptions(UTILITY_ACTIVITY); - fail(); - } catch (SecurityException e) { - // pass - } - } - /** * Checks that lock task mode is active and fails the test if it isn't. */ @@ -413,24 +281,6 @@ public class LockTaskTest extends BaseDeviceAdminTest { } /** - * Calls startLockTask on the LockTaskUtilityActivity - */ - private void startLockTask(String className) throws InterruptedException { - Intent intent = getLockTaskUtility(className); - intent.putExtra(LockTaskUtilityActivity.START_LOCK_TASK, true); - startAndWait(intent); - } - - /** - * Starts LockTaskUtilityActivity with {@link ActivityOptions#setLockTaskEnabled(boolean)} - */ - private void startLockTaskWithOptions(String className) throws InterruptedException { - Intent intent = getLockTaskUtility(className); - Bundle options = ActivityOptions.makeBasic().setLockTaskEnabled(true).toBundle(); - startAndWait(intent, options); - } - - /** * Calls stopLockTask on the LockTaskUtilityActivity */ private void stopLockTask(String className) throws InterruptedException { @@ -481,14 +331,4 @@ public class LockTaskTest extends BaseDeviceAdminTest { intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); return intent; } - - /** Create an intent to launch {@link #RECEIVER_ACTIVITY_NAME}. */ - private Intent createReceiverActivityIntent(boolean newTask, boolean shouldWait) { - final Intent intent = new Intent(); - intent.setComponent( - new ComponentName(RECEIVER_ACTIVITY_PACKAGE_NAME, RECEIVER_ACTIVITY_NAME)); - intent.setAction(shouldWait ? ACTION_CREATE_AND_WAIT : ACTION_JUST_CREATE); - intent.setFlags(newTask ? Intent.FLAG_ACTIVITY_NEW_TASK : 0); - return intent; - } } diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminFeaturesCheckerRule.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminFeaturesCheckerRule.java index 084392db2a1..b1b42b0e1fb 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminFeaturesCheckerRule.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAdminFeaturesCheckerRule.java @@ -67,15 +67,6 @@ public final class DeviceAdminFeaturesCheckerRule implements TestRule { String testName = description.getDisplayName(); - TemporaryIgnoreOnHeadlessSystemUserMode temporarilyIgnoredAnnotation = description - .getAnnotation(TemporaryIgnoreOnHeadlessSystemUserMode.class); - if (temporarilyIgnoredAnnotation != null - && BaseDevicePolicyTest.isHeadlessSystemUserMode(testDevice)) { - throw new AssumptionViolatedException( - "TEMPORARILY skipping " + testName + " on headless system user mode " - + "(reason: " + temporarilyIgnoredAnnotation.reason() + ")"); - } - IgnoreOnHeadlessSystemUserMode ignoredAnnotation = description .getAnnotation(IgnoreOnHeadlessSystemUserMode.class); if (ignoredAnnotation != null @@ -209,17 +200,6 @@ public final class DeviceAdminFeaturesCheckerRule implements TestRule { } /** - * TODO(b/132260693): STOPSHIP - temporary annotation used on tests that haven't been fixed to - * run on headless system user yet - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD}) - public static @interface TemporaryIgnoreOnHeadlessSystemUserMode { - String bugId(); - String reason(); - } - - /** * Annotation used on tests that cannot run on devices that use headless system user mode. */ @Retention(RetentionPolicy.RUNTIME) diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java index 4d392ca949a..1398e0ad9a5 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java @@ -28,7 +28,6 @@ import android.platform.test.annotations.LargeTest; import android.platform.test.annotations.RequiresDevice; import android.stats.devicepolicy.EventId; -import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporaryIgnoreOnHeadlessSystemUserMode; import com.android.cts.devicepolicy.annotations.LockSettingsTest; import com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier; import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper; @@ -439,7 +438,6 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest { } @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "187862351", reason = "also failing on phones") public void testGrantOfSensorsRelatedPermissions() throws Exception { installAppPermissionAppAsUser(); executeDeviceTestMethod(".PermissionsTest", "testSensorsRelatedPermissionsCannotBeGranted"); @@ -452,7 +450,6 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest { } @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "187862351", reason = "also failing on phones") public void testSensorsRelatedPermissionsNotGrantedViaPolicy() throws Exception { installAppPermissionAppAsUser(); executeDeviceTestMethod(".PermissionsTest", @@ -460,7 +457,6 @@ public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest { } @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "187862351", reason = "also failing on phones") public void testStateOfSensorsRelatedPermissionsCannotBeRead() throws Exception { installAppPermissionAppAsUser(); executeDeviceTestMethod(".PermissionsTest", diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java index 979d6cf4310..028b12a8ff5 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java @@ -31,7 +31,6 @@ import android.stats.devicepolicy.EventId; import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.RequiresAdditionalFeatures; -import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporaryIgnoreOnHeadlessSystemUserMode; import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper; import com.android.tradefed.log.LogUtil.CLog; @@ -573,8 +572,6 @@ public class DeviceOwnerTest extends BaseDeviceOwnerTest { .build()); } - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "132360087", - reason = "need more investigation / decide how to support it") @Test public void testBluetoothRestriction() throws Exception { executeDeviceOwnerTest("BluetoothRestrictionTest"); @@ -785,7 +782,6 @@ public class DeviceOwnerTest extends BaseDeviceOwnerTest { .build()); } - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "185486201", reason = "need to change DPMS") @Test public void testDefaultSmsApplication() throws Exception { assumeHasTelephonyFeature(); diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java index 1cdd0fe02ab..84d364ac8f0 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java @@ -25,7 +25,6 @@ import android.platform.test.annotations.LargeTest; import android.stats.devicepolicy.EventId; import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.IgnoreOnHeadlessSystemUserMode; -import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporaryIgnoreOnHeadlessSystemUserMode; import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.log.LogUtil.CLog; @@ -552,46 +551,6 @@ public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest { } @Override - @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test makes" - + " sense as keys generated by DO wouldn't match keys checked by PO") - public void testKeyManagement() throws Exception { - super.testKeyManagement(); - } - - @Override - @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test makes" - + " sense as keys generated by DO wouldn't match keys checked by PO") - public void testGenerateKeyPairLogged() throws Exception { - super.testGenerateKeyPairLogged(); - } - - @Override - @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test makes" - + " sense as keys generated by DO wouldn't match keys checked by PO") - public void testDelegatedCertInstallerDirectly() throws Exception { - super.testDelegatedCertInstallerDirectly(); - } - - @Override - @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test makes" - + " sense as keys generated by DO wouldn't match keys checked by PO") - public void testSetKeyGrant() throws Exception { - super.testSetKeyGrant(); - } - - @Override - @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test makes" - + " sense as keys generated by DO wouldn't match keys checked by PO") - public void testSetKeyPairCertificateLogged() throws Exception { - super.testSetKeyPairCertificateLogged(); - } - - @Override public void testApplicationHidden() throws Exception { if (isHeadlessSystemUserMode()) { // Must run on user 0 because the test has a broadcast receiver that listen to packages diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java index eae5c48d982..99f16658dcc 100644 --- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java +++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.fail; import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.RequiresAdditionalFeatures; import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.RequiresProfileOwnerSupport; -import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporaryIgnoreOnHeadlessSystemUserMode; import org.junit.Test; @@ -57,22 +56,16 @@ public class ProfileOwnerTest extends BaseDevicePolicyTest { } @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "183020176", - reason = "decide if it's needed or fix it") public void testManagement() throws Exception { executeProfileOwnerTest("ManagementTest"); } @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "183020176", - reason = "decide if it's needed or fix it") public void testAdminActionBookkeeping() throws Exception { executeProfileOwnerTest("AdminActionBookkeepingTest"); } @Test - @TemporaryIgnoreOnHeadlessSystemUserMode(bugId = "183020176", - reason = "decide if it's needed or fix it") public void testAppUsageObserver() throws Exception { executeProfileOwnerTest("AppUsageObserverTest"); } diff --git a/hostsidetests/edi/src/android/edi/cts/ClasspathDeviceInfo.java b/hostsidetests/edi/src/android/edi/cts/ClasspathDeviceInfo.java index c24919ac103..2785ab2b398 100644 --- a/hostsidetests/edi/src/android/edi/cts/ClasspathDeviceInfo.java +++ b/hostsidetests/edi/src/android/edi/cts/ClasspathDeviceInfo.java @@ -27,6 +27,7 @@ import android.compat.testing.Classpaths.ClasspathType; import com.android.compatibility.common.util.DeviceInfo; import com.android.compatibility.common.util.HostInfoStore; import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.log.LogUtil.CLog; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -96,6 +97,10 @@ public class ClasspathDeviceInfo extends DeviceInfo { String libraryVersion = words[2]; for (int i = 3; i < words.length; i++) { String path = words[i]; + if (!mDevice.doesFileExist(path)) { + CLog.w("Shared library is not present on device " + path); + continue; + } store.startGroup(); store.startGroup("shared_library"); @@ -112,26 +117,8 @@ public class ClasspathDeviceInfo extends DeviceInfo { } private void collectClassInfo(HostInfoStore store, String path) throws Exception { - ImmutableSet<ClassDef> classes; - try { - classes = Classpaths.getClassDefsFromJar(mDevice, path); - } catch (IllegalStateException e) { - // Check if this is a known issue where a jar is not present on device. - if (e.getMessage().contains("could not pull remote file " + path)) { - // TODO(b/189924891): stop ignoring libhwinfo.jar - if (path.equals("/product/framework/libhwinfo.jar")) { - return; - } - // TODO(b/191046702): stop ignoring uimservicelibrary.jar - if (path.equals("/system/framework/uimservicelibrary.jar")) { - return; - } - } - throw e; - } - store.startArray("classes"); - for (ClassDef classDef : classes) { + for (ClassDef classDef : Classpaths.getClassDefsFromJar(mDevice, path)) { store.startGroup(); store.addResult("name", classDef.getType()); store.endGroup(); diff --git a/hostsidetests/install/OWNERS b/hostsidetests/install/OWNERS index 71cfd5aec8c..3b63f6b8609 100644 --- a/hostsidetests/install/OWNERS +++ b/hostsidetests/install/OWNERS @@ -1,3 +1,3 @@ # Bug component: 36137 -include ../Stagedinstall/OWNERS -chenghsiuchang@google.com
\ No newline at end of file +include ../stagedinstall/OWNERS +chenghsiuchang@google.com diff --git a/libs/install/src/com/android/cts/install/lib/Install.java b/libs/install/src/com/android/cts/install/lib/Install.java index ac9966fcb44..6d817ed765e 100644 --- a/libs/install/src/com/android/cts/install/lib/Install.java +++ b/libs/install/src/com/android/cts/install/lib/Install.java @@ -201,6 +201,9 @@ public class Install { if (mIsStaged || isApex) { SystemUtil.runShellCommandForNoOutput("pm bypass-staged-installer-check true"); } + if (isApex) { + SystemUtil.runShellCommandForNoOutput("pm bypass-allowed-apex-update-check true"); + } try { PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(mSessionMode); @@ -223,6 +226,9 @@ public class Install { if (mIsStaged || isApex) { SystemUtil.runShellCommandForNoOutput("pm bypass-staged-installer-check false"); } + if (isApex) { + SystemUtil.runShellCommandForNoOutput("pm bypass-allowed-apex-update-check false"); + } } } diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java index 40923607a31..b82cc48d63a 100644 --- a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java +++ b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java @@ -143,6 +143,11 @@ public class ExactAlarmsTest { + sContext.getOpPackageName(), output -> output.contains("Enabled")); } + private static void disableChange() { + SystemUtil.runShellCommand("am compat disable --no-kill REQUIRE_EXACT_ALARM_PERMISSION " + + sContext.getOpPackageName(), output -> output.contains("Disabled")); + } + @After public void resetChanges() { // This is needed because compat persists the overrides beyond package uninstall @@ -228,6 +233,13 @@ public class ExactAlarmsTest { assertTrue(mAlarmManager.canScheduleExactAlarms()); } + @Test + public void canScheduleExactAlarmWhenChangeDisabled() throws IOException { + disableChange(); + revokeAppOp(); + assertTrue(mAlarmManager.canScheduleExactAlarms()); + } + @Test(expected = SecurityException.class) public void setAlarmClockWithoutPermission() throws IOException { revokeAppOp(); diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java index 816385bd043..85715be6bbf 100644 --- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java +++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java @@ -193,6 +193,10 @@ public class JobThrottlingTest { // TODO(b/159176758): make sure that initial power supply is on. BatteryUtils.runDumpsysBatterySetPluggedIn(true); } + + // Kill as many things in the background as possible so we avoid LMK interfering with the + // test. + mUiDevice.executeShellCommand("am kill-all"); } @Test diff --git a/tests/app/src/android/app/cts/UiModeManagerTest.java b/tests/app/src/android/app/cts/UiModeManagerTest.java index eaa16d993e0..979df70121e 100644 --- a/tests/app/src/android/app/cts/UiModeManagerTest.java +++ b/tests/app/src/android/app/cts/UiModeManagerTest.java @@ -28,6 +28,7 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.ParcelFileDescriptor; import android.os.UserHandle; +import android.platform.test.annotations.SystemUserOnly; import android.test.AndroidTestCase; import android.util.ArraySet; import android.util.Log; @@ -48,6 +49,9 @@ import java.time.LocalTime; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; + +@SystemUserOnly(reason = "UiAutomation doesn't support untrusted UID's. " + + "see UiAutomationConnection#throwIfCalledByNotTrustedUidLocked") public class UiModeManagerTest extends AndroidTestCase { private static final String TAG = "UiModeManagerTest"; private static final long MAX_WAIT_TIME_SECS = 2; diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchBatchResultCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchBatchResultCtsTest.java index aab709865bb..d82b44d5d36 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchBatchResultCtsTest.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchBatchResultCtsTest.java @@ -18,7 +18,7 @@ package android.app.appsearch.cts.app; import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.app.appsearch.AppSearchBatchResult; import android.app.appsearch.AppSearchResult; @@ -58,8 +58,8 @@ public class AppSearchBatchResultCtsTest { assertThat(result1.isSuccess()).isFalse(); assertThat(result2.isSuccess()).isFalse(); - expectThrows(IllegalStateException.class, result1::checkSuccess); - expectThrows(IllegalStateException.class, result2::checkSuccess); + assertThrows(IllegalStateException.class, result1::checkSuccess); + assertThrows(IllegalStateException.class, result2::checkSuccess); } @Test @@ -77,7 +77,7 @@ public class AppSearchBatchResultCtsTest { .build(); assertThat(result1.isSuccess()).isFalse(); - expectThrows(IllegalStateException.class, result1::checkSuccess); + assertThrows(IllegalStateException.class, result1::checkSuccess); assertThat(result2.isSuccess()).isTrue(); result2.checkSuccess(); } diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaCtsTest.java index bc7f271f86b..7b3ad3f6374 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaCtsTest.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaCtsTest.java @@ -18,7 +18,7 @@ package android.app.appsearch.cts.app; import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.app.appsearch.AppSearchSchema; import android.app.appsearch.AppSearchSchema.PropertyConfig; @@ -35,7 +35,7 @@ public class AppSearchSchemaCtsTest { @Test public void testInvalidEnums() { StringPropertyConfig.Builder builder = new StringPropertyConfig.Builder("test"); - expectThrows(IllegalArgumentException.class, () -> builder.setCardinality(99)); + assertThrows(IllegalArgumentException.class, () -> builder.setCardinality(99)); } @Test @@ -58,7 +58,7 @@ public class AppSearchSchemaCtsTest { .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN) .build()); IllegalSchemaException e = - expectThrows( + assertThrows( IllegalSchemaException.class, () -> builder.addProperty( @@ -278,10 +278,10 @@ public class AppSearchSchemaCtsTest { // Setting an indexing type other NONE with the default tokenizer type (NONE) should fail. builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS); - expectThrows(IllegalStateException.class, () -> builder.build()); + assertThrows(IllegalStateException.class, () -> builder.build()); builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES); - expectThrows(IllegalStateException.class, () -> builder.build()); + assertThrows(IllegalStateException.class, () -> builder.build()); // Explicitly setting the default should work fine. builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE); @@ -290,10 +290,10 @@ public class AppSearchSchemaCtsTest { // Explicitly setting the default tokenizer type should result in the same behavior. builder.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_NONE) .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS); - expectThrows(IllegalStateException.class, () -> builder.build()); + assertThrows(IllegalStateException.class, () -> builder.build()); builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES); - expectThrows(IllegalStateException.class, () -> builder.build()); + assertThrows(IllegalStateException.class, () -> builder.build()); builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE); assertThat(builder.build()).isNotNull(); @@ -306,10 +306,10 @@ public class AppSearchSchemaCtsTest { final StringPropertyConfig.Builder builder = new StringPropertyConfig.Builder("property") .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN); - expectThrows(IllegalStateException.class, () -> builder.build()); + assertThrows(IllegalStateException.class, () -> builder.build()); builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE); - expectThrows(IllegalStateException.class, () -> builder.build()); + assertThrows(IllegalStateException.class, () -> builder.build()); // Setting indexing type to be something other than NONE with tokenizer type PLAIN should // be just fine. diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaMigrationCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaMigrationCtsTestBase.java index 830cc25c014..c425456316b 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaMigrationCtsTestBase.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSchemaMigrationCtsTestBase.java @@ -24,7 +24,7 @@ import static com.android.server.appsearch.testing.AppSearchTestUtils.doGet; import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.annotation.NonNull; import android.app.appsearch.AppSearchBatchResult; @@ -72,7 +72,6 @@ import java.util.concurrent.ExecutionException; * FALSE FALSE FALSE TRUE Impossible case, migrators are inactivity * FALSE FALSE FALSE FALSE fail throw error */ -// TODO(b/178060626) add a platform version of this test public abstract class AppSearchSchemaMigrationCtsTestBase { private static final String DB_NAME = ""; @@ -359,7 +358,7 @@ public abstract class AppSearchSchemaMigrationCtsTestBase { AppSearchSchema $B_C_Schema = new AppSearchSchema.Builder("testSchema").build(); ExecutionException exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb.setSchema( @@ -380,7 +379,7 @@ public abstract class AppSearchSchemaMigrationCtsTestBase { AppSearchSchema $B_$C_Schema = new AppSearchSchema.Builder("testSchema").build(); ExecutionException exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb.setSchema( @@ -772,7 +771,7 @@ public abstract class AppSearchSchemaMigrationCtsTestBase { // SetSchema with forceOverride=false ExecutionException exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb.setSchema( @@ -900,7 +899,7 @@ public abstract class AppSearchSchemaMigrationCtsTestBase { // SetSchema with forceOverride=false ExecutionException exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb.setSchema( @@ -969,7 +968,7 @@ public abstract class AppSearchSchemaMigrationCtsTestBase { // SetSchema with forceOverride=false // Source type exist, destination type doesn't exist. ExecutionException exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb.setSchema( @@ -989,7 +988,7 @@ public abstract class AppSearchSchemaMigrationCtsTestBase { // SetSchema with forceOverride=true // Source type exist, destination type doesn't exist. exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb.setSchema( diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java index cfda19f11de..d30d661752f 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java @@ -26,7 +26,7 @@ import static com.android.server.appsearch.testing.AppSearchTestUtils.retrieveAl import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.annotation.NonNull; import android.app.appsearch.AppSearchBatchResult; @@ -135,7 +135,7 @@ public abstract class AppSearchSessionCtsTestBase { new AppSearchSchema.Builder(AppSearchEmail.SCHEMA_TYPE).build(); Throwable throwable = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb1.setSchema( @@ -151,7 +151,7 @@ public abstract class AppSearchSessionCtsTestBase { assertThat(exception).hasMessageThat().contains("Incompatible types: {builtin:Email}"); throwable = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb1.setSchema(new SetSchemaRequest.Builder().build()).get()) .getCause(); @@ -546,7 +546,7 @@ public abstract class AppSearchSessionCtsTestBase { // Try to remove the email schema. This should fail as it's an incompatible change. Throwable failResult1 = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb1.setSchema(new SetSchemaRequest.Builder().build()).get()) .getCause(); @@ -628,7 +628,7 @@ public abstract class AppSearchSessionCtsTestBase { // Try to remove the email schema in database1. This should fail as it's an incompatible // change. Throwable failResult1 = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb1.setSchema(new SetSchemaRequest.Builder().build()).get()) .getCause(); @@ -2070,6 +2070,93 @@ public abstract class AppSearchSessionCtsTestBase { } @Test + public void testSetSnippetCount() throws Exception { + // Schema registration + AppSearchSchema genericSchema = + new AppSearchSchema.Builder("Generic") + .addProperty( + new StringPropertyConfig.Builder("subject") + .setCardinality(PropertyConfig.CARDINALITY_REPEATED) + .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN) + .setIndexingType( + StringPropertyConfig.INDEXING_TYPE_PREFIXES) + .build()) + .build(); + mDb1.setSchema(new SetSchemaRequest.Builder().addSchemas(genericSchema).build()).get(); + + // Index documents + checkIsBatchResultSuccess( + mDb1.put( + new PutDocumentsRequest.Builder() + .addGenericDocuments( + new GenericDocument.Builder<>("namespace", "id1", "Generic") + .setPropertyString( + "subject", + "I like cats", + "I like dogs", + "I like birds", + "I like fish") + .setScore(10) + .build(), + new GenericDocument.Builder<>("namespace", "id2", "Generic") + .setPropertyString( + "subject", + "I like red", + "I like green", + "I like blue", + "I like yellow") + .setScore(20) + .build(), + new GenericDocument.Builder<>("namespace", "id3", "Generic") + .setPropertyString( + "subject", + "I like cupcakes", + "I like donuts", + "I like eclairs", + "I like froyo") + .setScore(5) + .build()) + .build())); + + // Query for the document + SearchResultsShim searchResults = + mDb1.search( + "like", + new SearchSpec.Builder() + .addFilterSchemas("Generic") + .setSnippetCount(2) + .setSnippetCountPerProperty(3) + .setMaxSnippetSize(11) + .setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE) + .setTermMatch(SearchSpec.TERM_MATCH_PREFIX) + .build()); + + // Check result 1 + List<SearchResult> results = searchResults.getNextPage().get(); + assertThat(results).hasSize(3); + + assertThat(results.get(0).getGenericDocument().getId()).isEqualTo("id2"); + List<SearchResult.MatchInfo> matchInfos = results.get(0).getMatchInfos(); + assertThat(matchInfos).hasSize(3); + assertThat(matchInfos.get(0).getSnippet()).isEqualTo("I like red"); + assertThat(matchInfos.get(1).getSnippet()).isEqualTo("I like"); + assertThat(matchInfos.get(2).getSnippet()).isEqualTo("I like blue"); + + // Check result 2 + assertThat(results.get(1).getGenericDocument().getId()).isEqualTo("id1"); + matchInfos = results.get(1).getMatchInfos(); + assertThat(matchInfos).hasSize(3); + assertThat(matchInfos.get(0).getSnippet()).isEqualTo("I like cats"); + assertThat(matchInfos.get(1).getSnippet()).isEqualTo("I like dogs"); + assertThat(matchInfos.get(2).getSnippet()).isEqualTo("I like"); + + // Check result 2 + assertThat(results.get(2).getGenericDocument().getId()).isEqualTo("id3"); + matchInfos = results.get(2).getMatchInfos(); + assertThat(matchInfos).isEmpty(); + } + + @Test public void testCJKSnippet() throws Exception { // Schema registration AppSearchSchema genericSchema = @@ -2929,7 +3016,7 @@ public abstract class AppSearchSessionCtsTestBase { // Try to query the closed database // We are using the same-thread db here to make sure it has been closed. IllegalStateException e = - expectThrows( + assertThrows( IllegalStateException.class, () -> sameThreadDb.search( @@ -3036,7 +3123,7 @@ public abstract class AppSearchSessionCtsTestBase { // Use an incorrect namespace; it fails ExecutionException e = - expectThrows( + assertThrows( ExecutionException.class, () -> mDb1.reportUsage( diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java index 649448a165e..063d8c1c508 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java @@ -18,7 +18,7 @@ package android.app.appsearch.cts.app; import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.app.appsearch.GenericDocument; @@ -343,7 +343,7 @@ public class GenericDocumentCtsTest { new GenericDocument.Builder<>("namespace", "id1", "schemaType1"); String nullString = null; - expectThrows( + assertThrows( IllegalArgumentException.class, () -> builder.setPropertyString("testKey", "string1", nullString)); } @@ -689,19 +689,19 @@ public class GenericDocumentCtsTest { // Some paths are invalid because they are malformed. These throw an exception --- the // querier shouldn't provide such paths. - expectThrows( + assertThrows( IllegalArgumentException.class, () -> doc.getPropertyStringArray("propDocs.[0]propInts")); - expectThrows( + assertThrows( IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[0")); - expectThrows( + assertThrows( IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[0.]")); - expectThrows( + assertThrows( IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[banana]")); - expectThrows( + assertThrows( IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[-1]")); - expectThrows( + assertThrows( IllegalArgumentException.class, () -> doc.getPropertyStringArray("propDocs[0]cat")); } diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java index f9271b8ef42..7dbe8d9733f 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java @@ -21,7 +21,7 @@ import static com.android.server.appsearch.testing.AppSearchTestUtils.convertSea import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.annotation.NonNull; import android.app.appsearch.AppSearchResult; @@ -744,7 +744,7 @@ public abstract class GlobalSearchSessionCtsTestBase { SearchResult firstResult = page.get(0); ExecutionException exception = - expectThrows( + assertThrows( ExecutionException.class, () -> mGlobalAppSearchManager diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/SetSchemaRequestCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/SetSchemaRequestCtsTest.java index bf5a44ad283..1d59881192a 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/SetSchemaRequestCtsTest.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/SetSchemaRequestCtsTest.java @@ -19,7 +19,7 @@ package android.app.appsearch.cts.app; import static com.google.common.truth.Truth.assertThat; -import static org.testng.Assert.expectThrows; +import static org.junit.Assert.assertThrows; import android.annotation.NonNull; import android.app.appsearch.AppSearchSchema; @@ -189,7 +189,7 @@ public class SetSchemaRequestCtsTest { @Test public void testInvalidSchemaReferences_fromDisplayedBySystem() { IllegalArgumentException expected = - expectThrows( + assertThrows( IllegalArgumentException.class, () -> new SetSchemaRequest.Builder() @@ -201,7 +201,7 @@ public class SetSchemaRequestCtsTest { @Test public void testInvalidSchemaReferences_fromPackageVisibility() { IllegalArgumentException expected = - expectThrows( + assertThrows( IllegalArgumentException.class, () -> new SetSchemaRequest.Builder() @@ -328,7 +328,7 @@ public class SetSchemaRequestCtsTest { @Test public void testSetVersion() { IllegalArgumentException exception = - expectThrows( + assertThrows( IllegalArgumentException.class, () -> new SetSchemaRequest.Builder() diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java index f083968cfa3..d6d5cfc0941 100644 --- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java @@ -25,7 +25,6 @@ import android.hardware.Camera; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraCharacteristics.Key; import android.hardware.camera2.CameraDevice; -import android.hardware.camera2.CameraExtensionCharacteristics; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CaptureRequest; @@ -107,8 +106,9 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { private static final long PREVIEW_RUN_MS = 500; private static final long FRAME_DURATION_30FPS_NSEC = (long) 1e9 / 30; - private static final long MIN_BACK_SENSOR_PERFORMANCE_CLASS_RESOLUTION = 12000000; - private static final long MIN_FRONT_SENSOR_PERFORMANCE_CLASS_RESOLUTION = 6000000; + private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000; + private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000; + private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000; /* * HW Levels short hand @@ -2551,19 +2551,20 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { } /** - * Check camera characteristics for S Performance class requirements as specified + * Check camera characteristics for R and S Performance class requirements as specified * in CDD camera section 7.5 */ @Test @CddTest(requirement="7.5") - public void testCameraSPerfClassCharacteristics() throws Exception { + public void testCameraPerfClassCharacteristics() throws Exception { if (mAdoptShellPerm) { // Skip test for system camera. Performance class is only applicable for public camera // ids. return; } + boolean isRPerfClass = CameraTestUtils.isRPerfClass(); boolean isSPerfClass = CameraTestUtils.isSPerfClass(); - if (!isSPerfClass) { + if (!isRPerfClass && !isSPerfClass) { return; } @@ -2595,36 +2596,9 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { if (isPrimaryRear) { hasPrimaryRear = true; mCollector.expectTrue("Primary rear camera resolution should be at least " + - MIN_BACK_SENSOR_PERFORMANCE_CLASS_RESOLUTION + " pixels, is "+ + MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+ sensorResolution, - sensorResolution >= MIN_BACK_SENSOR_PERFORMANCE_CLASS_RESOLUTION); - - // 720P @ 240fps - boolean supportHighSpeed = staticInfo.isCapabilitySupported(CONSTRAINED_HIGH_SPEED); - mCollector.expectTrue("Primary rear camera should support high speed recording", - supportHighSpeed); - if (supportHighSpeed) { - boolean supportHD240 = false; - Size[] availableHighSpeedSizes = config.getHighSpeedVideoSizes(); - for (Size size : availableHighSpeedSizes) { - if (!size.equals(HD)) { - continue; - } - Range<Integer>[] availableFpsRanges = - config.getHighSpeedVideoFpsRangesFor(size); - for (Range<Integer> fpsRange : availableFpsRanges) { - if (fpsRange.getUpper() == 240) { - supportHD240 = true; - break; - } - } - if (supportHD240) { - break; - } - } - mCollector.expectTrue("Primary rear camera should support HD @ 240fps", - supportHD240); - } + sensorResolution >= MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION); // 4K @ 30fps boolean supportUHD = videoSizes.contains(UHD); @@ -2639,10 +2613,17 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { } } else { hasPrimaryFront = true; - mCollector.expectTrue("Primary front camera resolution should be at least " + - MIN_FRONT_SENSOR_PERFORMANCE_CLASS_RESOLUTION + " pixels, is "+ - sensorResolution, - sensorResolution >= MIN_FRONT_SENSOR_PERFORMANCE_CLASS_RESOLUTION); + if (isSPerfClass) { + mCollector.expectTrue("Primary front camera resolution should be at least " + + MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+ + sensorResolution, + sensorResolution >= MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION); + } else { + mCollector.expectTrue("Primary front camera resolution should be at least " + + MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION + " pixels, is "+ + sensorResolution, + sensorResolution >= MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION); + } // 1080P @ 30fps boolean supportFULLHD = videoSizes.contains(FULLHD); mCollector.expectTrue("Primary front camera should support 1080P video recording", @@ -2657,37 +2638,34 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { String facingString = hasPrimaryRear ? "rear" : "front"; // H-1-3 - mCollector.expectTrue("Primary " + facingString + " camera should be at least FULL, " + - "but is " + toStringHardwareLevel(staticInfo.getHardwareLevelChecked()), - staticInfo.isHardwareLevelAtLeastFull()); - - // H-1-4 - if (isPrimaryRear) { - mCollector.expectTrue("Primary rear camera should support RAW capability", - staticInfo.isCapabilitySupported(RAW)); + if (isSPerfClass || (isRPerfClass && isPrimaryRear)) { + mCollector.expectTrue("Primary " + facingString + + " camera should be at least FULL, but is " + + toStringHardwareLevel(staticInfo.getHardwareLevelChecked()), + staticInfo.isHardwareLevelAtLeastFull()); + } else { + mCollector.expectTrue("Primary " + facingString + + " camera should be at least LIMITED, but is " + + toStringHardwareLevel(staticInfo.getHardwareLevelChecked()), + staticInfo.isHardwareLevelAtLeastLimited()); } - // H-1-5 + // H-1-4 Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE); mCollector.expectTrue( "Primary " + facingString + " camera should support real-time timestamp source", timestampSource != null && timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME)); - // H-1-9 - CameraExtensionCharacteristics extensionChars = - mCameraManager.getCameraExtensionCharacteristics(cameraId); - List<Integer> supportedExtensions = extensionChars.getSupportedExtensions(); - mCollector.expectTrue( - "Primary " + facingString + " camera must support the HDR camera2 extension", - supportedExtensions.contains(CameraExtensionCharacteristics.EXTENSION_HDR)); - mCollector.expectTrue( - "Primary " + facingString + " camera must support the NIGHT camera2 extension", - supportedExtensions.contains(CameraExtensionCharacteristics.EXTENSION_NIGHT)); + // H-1-8 + if (isSPerfClass && isPrimaryRear) { + mCollector.expectTrue("Primary rear camera should support RAW capability", + staticInfo.isCapabilitySupported(RAW)); + } } - mCollector.expectTrue("There must be a primary rear camera for S performance class.", + mCollector.expectTrue("There must be a primary rear camera for performance class.", hasPrimaryRear); - mCollector.expectTrue("There must be a primary front camera for S performance class.", + mCollector.expectTrue("There must be a primary front camera for performance class.", hasPrimaryFront); } diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java index 922142fad44..14cb94e8b77 100644 --- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java @@ -1727,41 +1727,53 @@ public class RobustnessTest extends Camera2AndroidTestCase { Size targetSize = CameraTestUtils.getMaxSize(configs.getOutputSizes(format)); // Create outputConfiguration with this size and format SimpleImageReaderListener imageListener = new SimpleImageReaderListener(); + SurfaceTexture textureTarget = null; + ImageReader readerTarget = null; if (format == ImageFormat.PRIVATE) { - SurfaceTexture target = new SurfaceTexture(1); - target.setDefaultBufferSize(targetSize.getWidth(), targetSize.getHeight()); - outputConfig = new OutputConfiguration(new Surface(target)); + textureTarget = new SurfaceTexture(1); + textureTarget.setDefaultBufferSize(targetSize.getWidth(), targetSize.getHeight()); + outputConfig = new OutputConfiguration(new Surface(textureTarget)); } else { - ImageReader target = ImageReader.newInstance(targetSize.getWidth(), + readerTarget = ImageReader.newInstance(targetSize.getWidth(), targetSize.getHeight(), format, MIN_RESULT_COUNT); - target.setOnImageAvailableListener(imageListener, mHandler); - outputConfig = new OutputConfiguration(target.getSurface()); - } - int invalidSensorPixelMode = - maxResolution ? CameraMetadata.SENSOR_PIXEL_MODE_DEFAULT : - CameraMetadata.SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION; - - outputConfig.addSensorPixelModeUsed(invalidSensorPixelMode); - CameraCaptureSession.StateCallback sessionListener = - mock(CameraCaptureSession.StateCallback.class); - List<OutputConfiguration> outputs = new ArrayList<>(); - outputs.add(outputConfig); - CameraCaptureSession session = - CameraTestUtils.configureCameraSessionWithConfig(mCamera, outputs, - sessionListener, mHandler); + readerTarget.setOnImageAvailableListener(imageListener, mHandler); + outputConfig = new OutputConfiguration(readerTarget.getSurface()); + } + try { + int invalidSensorPixelMode = + maxResolution ? CameraMetadata.SENSOR_PIXEL_MODE_DEFAULT : + CameraMetadata.SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION; + + outputConfig.addSensorPixelModeUsed(invalidSensorPixelMode); + CameraCaptureSession.StateCallback sessionListener = + mock(CameraCaptureSession.StateCallback.class); + List<OutputConfiguration> outputs = new ArrayList<>(); + outputs.add(outputConfig); + CameraCaptureSession session = + CameraTestUtils.configureCameraSessionWithConfig(mCamera, outputs, + sessionListener, mHandler); - verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()). - onConfigureFailed(any(CameraCaptureSession.class)); - verify(sessionListener, never()).onConfigured(any(CameraCaptureSession.class)); - - // Remove the invalid sensor pixel mode, session configuration should succeed - sessionListener = mock(CameraCaptureSession.StateCallback.class); - outputConfig.removeSensorPixelModeUsed(invalidSensorPixelMode); - CameraTestUtils.configureCameraSessionWithConfig(mCamera, outputs, - sessionListener, mHandler); - verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()). - onConfigured(any(CameraCaptureSession.class)); - verify(sessionListener, never()).onConfigureFailed(any(CameraCaptureSession.class)); + verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()). + onConfigureFailed(any(CameraCaptureSession.class)); + verify(sessionListener, never()).onConfigured(any(CameraCaptureSession.class)); + + // Remove the invalid sensor pixel mode, session configuration should succeed + sessionListener = mock(CameraCaptureSession.StateCallback.class); + outputConfig.removeSensorPixelModeUsed(invalidSensorPixelMode); + CameraTestUtils.configureCameraSessionWithConfig(mCamera, outputs, + sessionListener, mHandler); + verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()). + onConfigured(any(CameraCaptureSession.class)); + verify(sessionListener, never()).onConfigureFailed(any(CameraCaptureSession.class)); + } finally { + if (textureTarget != null) { + textureTarget.release(); + } + + if (readerTarget != null) { + readerTarget.close(); + } + } } } diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java index f495c6772fc..1daa3f6f01e 100644 --- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java +++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java @@ -3508,9 +3508,17 @@ public class CameraTestUtils extends Assert { return zoomRatios; } + private static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R; private static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1; /** + * Check whether this mobile device is R performance class as defined in CDD + */ + public static boolean isRPerfClass() { + return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R; + } + + /** * Check whether this mobile device is S performance class as defined in CDD */ public static boolean isSPerfClass() { diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java index 5744a0429be..a9ba8eea358 100644 --- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java +++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java @@ -546,7 +546,7 @@ public class LoginActivityTest assertRightActivity(session, sessionId, activity); - final int additionalEvents = 5; + final int additionalEvents = 4; final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session, additionalEvents); diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java index 495e633f759..026f6fb7b5f 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java @@ -17,6 +17,7 @@ package android.devicepolicy.cts; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; +import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME; import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD; @@ -31,8 +32,11 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assume.assumeFalse; import static org.testng.Assert.assertThrows; +import android.app.ActivityOptions; import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; import android.content.Intent; +import android.os.Bundle; import com.android.bedstead.harrier.BedsteadJUnit4; import com.android.bedstead.harrier.DeviceState; @@ -43,7 +47,7 @@ import com.android.bedstead.harrier.annotations.enterprise.PositivePolicyTest; import com.android.bedstead.harrier.policies.LockTask; import com.android.bedstead.nene.TestApis; import com.android.bedstead.nene.activities.Activity; -import com.android.bedstead.nene.activities.NeneActivity; +import com.android.bedstead.nene.packages.ComponentReference; import com.android.bedstead.testapp.TestApp; import com.android.bedstead.testapp.TestAppActivity; import com.android.bedstead.testapp.TestAppActivityReference; @@ -91,6 +95,11 @@ public class LockTaskTest { private static final TestAppProvider sTestAppProvider = new TestAppProvider(); private static final TestApp sTestApp = sTestAppProvider.any(); + private static final TestApp sSecondTestApp = sTestAppProvider.any(); + + private static final ComponentReference BLOCKED_ACTIVITY_COMPONENT = + sTestApis.packages().component(new ComponentName( + "android", "com.android.internal.app.BlockedAppActivity")); @Test @Postsubmit(reason = "New test") @@ -499,15 +508,14 @@ public class LockTaskTest { @Test @PositivePolicyTest(policy = LockTask.class) public void setLockTaskPackages_removingCurrentlyLockedTask_otherLockedTasksRemainLocked() { - TestApp secondTestApp = sTestAppProvider.any(); String[] originalLockTaskPackages = sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( - new String[]{sTestApp.packageName(), secondTestApp.packageName()}); + new String[]{sTestApp.packageName(), sSecondTestApp.packageName()}); try (TestAppInstanceReference testApp = sTestApp.install(sTestApis.users().instrumented()); TestAppInstanceReference testApp2 = - secondTestApp.install(sTestApis.users().instrumented())) { + sSecondTestApp.install(sTestApis.users().instrumented())) { Activity<TestAppActivity> activity = testApp.activities().any().start(); activity.startLockTask(); Activity<TestAppActivity> activity2 = testApp2.activities().any().start(); @@ -519,7 +527,7 @@ public class LockTaskTest { // TODO(b/189327037): Replace with more direct integration between TestApp and EventLib EventLogs<ActivityDestroyedEvent> events = - ActivityDestroyedEvent.queryPackage(secondTestApp.packageName()) + ActivityDestroyedEvent.queryPackage(sSecondTestApp.packageName()) .whereActivity().className().isEqualTo( activity2.activity().component().className()); assertThat(events.poll()).isNotNull(); @@ -538,15 +546,14 @@ public class LockTaskTest { @Test @PositivePolicyTest(policy = LockTask.class) public void startActivity_withinSameTask_startsActivity() { - TestApp secondTestApp = sTestAppProvider.any(); String[] originalLockTaskPackages = sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); - sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( - new String[]{sTestApp.packageName()}); try (TestAppInstanceReference testApp = sTestApp.install(sTestApis.users().instrumented()); TestAppInstanceReference testApp2 = - secondTestApp.install(sTestApis.users().instrumented())) { + sSecondTestApp.install(sTestApis.users().instrumented())) { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{sTestApp.packageName()}); Activity<TestAppActivity> firstActivity = testApp.activities().any().start(); TestAppActivityReference secondActivity = testApp2.activities().any(); Intent secondActivityIntent = new Intent(); @@ -557,7 +564,7 @@ public class LockTaskTest { firstActivity.startActivity(secondActivityIntent); EventLogs<ActivityStartedEvent> events = - ActivityStartedEvent.queryPackage(secondTestApp.packageName()) + ActivityStartedEvent.queryPackage(sSecondTestApp.packageName()) .whereActivity().className().isEqualTo(secondActivity.component().className()); assertThat(events.poll()).isNotNull(); assertThat(sTestApis.activities().foregroundActivity()).isEqualTo(secondActivity.component()); @@ -565,4 +572,189 @@ public class LockTaskTest { sDeviceState.dpc().devicePolicyManager().setLockTaskPackages(originalLockTaskPackages); } } + + @Test + @PositivePolicyTest(policy = LockTask.class) + public void startActivity_withinSameTask_blockStartInTask_doesNotStart() { + String[] originalLockTaskPackages = + sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); + int originalLockTaskFeatures = + sDeviceState.dpc().devicePolicyManager().getLockTaskFeatures(); + try (TestAppInstanceReference testApp = + sTestApp.install(sTestApis.users().instrumented()); + TestAppInstanceReference testApp2 = + sSecondTestApp.install(sTestApis.users().instrumented())) { + try { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{sTestApp.packageName()}); + sDeviceState.dpc().devicePolicyManager().setLockTaskFeatures( + LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK); + Activity<TestAppActivity> firstActivity = testApp.activities().any().start(); + firstActivity.startLockTask(); + TestAppActivityReference secondActivity = testApp2.activities().any(); + Intent secondActivityIntent = new Intent(); + secondActivityIntent.setComponent(secondActivity.component().componentName()); + + firstActivity.activity().startActivity(secondActivityIntent); + + assertThat(sTestApis.activities().foregroundActivity()) + .isEqualTo(BLOCKED_ACTIVITY_COMPONENT); + } finally { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + originalLockTaskPackages); + sDeviceState.dpc().devicePolicyManager().setLockTaskFeatures( + originalLockTaskFeatures); + } + } + } + + @Test + @PositivePolicyTest(policy = LockTask.class) + public void startActivity_inNewTask_blockStartInTask_doesNotStart() { + String[] originalLockTaskPackages = + sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); + int originalLockTaskFeatures = + sDeviceState.dpc().devicePolicyManager().getLockTaskFeatures(); + try (TestAppInstanceReference testApp = + sTestApp.install(sTestApis.users().instrumented()); + TestAppInstanceReference testApp2 = + sSecondTestApp.install(sTestApis.users().instrumented())) { + try { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{sTestApp.packageName()}); + sDeviceState.dpc().devicePolicyManager().setLockTaskFeatures( + LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK); + Activity<TestAppActivity> firstActivity = testApp.activities().any().start(); + firstActivity.startLockTask(); + TestAppActivityReference secondActivity = testApp2.activities().any(); + Intent secondActivityIntent = new Intent(); + secondActivityIntent.setComponent(secondActivity.component().componentName()); + secondActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + firstActivity.activity().startActivity(secondActivityIntent); + + assertThat(sTestApis.activities().foregroundActivity()) + .isEqualTo(BLOCKED_ACTIVITY_COMPONENT); + } finally { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + originalLockTaskPackages); + sDeviceState.dpc().devicePolicyManager().setLockTaskFeatures( + originalLockTaskFeatures); + } + } + } + + @Test + @PositivePolicyTest(policy = LockTask.class) + public void startActivity_fromPermittedPackage_newTask_starts() { + String[] originalLockTaskPackages = + sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); + + try (TestAppInstanceReference testApp = + sTestApp.install(sTestApis.users().instrumented()); + TestAppInstanceReference testApp2 = + sSecondTestApp.install(sTestApis.users().instrumented())) { + try { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{sTestApp.packageName(), sSecondTestApp.packageName()}); + Activity<TestAppActivity> firstActivity = testApp.activities().any().start(); + firstActivity.startLockTask(); + TestAppActivityReference secondActivity = testApp2.activities().any(); + Intent secondActivityIntent = new Intent(); + secondActivityIntent.setComponent(secondActivity.component().componentName()); + secondActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + firstActivity.startActivity(secondActivityIntent); + + assertThat(sTestApis.activities().foregroundActivity()) + .isEqualTo(secondActivity.component()); + } finally { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + originalLockTaskPackages); + } + } + } + + @Test + @PositivePolicyTest(policy = LockTask.class) + public void startActivity_fromNonPermittedPackage_newTask_doesNotStart() { + String[] originalLockTaskPackages = + sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); + + try (TestAppInstanceReference testApp = + sTestApp.install(sTestApis.users().instrumented()); + TestAppInstanceReference testApp2 = + sSecondTestApp.install(sTestApis.users().instrumented())) { + try { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{sTestApp.packageName()}); + Activity<TestAppActivity> firstActivity = testApp.activities().any().start(); + firstActivity.startLockTask(); + TestAppActivityReference secondActivity = testApp2.activities().any(); + Intent secondActivityIntent = new Intent(); + secondActivityIntent.setComponent(secondActivity.component().componentName()); + secondActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + firstActivity.activity().startActivity(secondActivityIntent); + + assertThat(sTestApis.activities().foregroundActivity()) + .isEqualTo(firstActivity.activity().component()); + } finally { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + originalLockTaskPackages); + } + } + } + + @Test + @PositivePolicyTest(policy = LockTask.class) + public void startActivity_lockTaskEnabledOption_startsInLockTaskMode() { + String[] originalLockTaskPackages = + sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); + + try (TestAppInstanceReference testApp = + sTestApp.install(sTestApis.users().instrumented())) { + try { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{sTestApp.packageName()}); + Bundle options = ActivityOptions.makeBasic().setLockTaskEnabled(true).toBundle(); + Activity<TestAppActivity> activity = testApp.activities().any().start(options); + + try { + assertThat(sTestApis.activities().foregroundActivity()).isEqualTo( + activity.activity().component()); + assertThat(sTestApis.activities().getLockTaskModeState()).isEqualTo( + LOCK_TASK_MODE_LOCKED); + } finally { + activity.stopLockTask(); + } + } finally { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + originalLockTaskPackages); + } + } + } + + @Test + @PositivePolicyTest(policy = LockTask.class) + public void startActivity_lockTaskEnabledOption_notAllowedPackage_throwsException() { + String[] originalLockTaskPackages = + sDeviceState.dpc().devicePolicyManager().getLockTaskPackages(); + + try (TestAppInstanceReference testApp = + sTestApp.install(sTestApis.users().instrumented())) { + try { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + new String[]{}); + Bundle options = ActivityOptions.makeBasic().setLockTaskEnabled(true).toBundle(); + + assertThrows(SecurityException.class, () -> { + testApp.activities().any().start(options); + }); + } finally { + sDeviceState.dpc().devicePolicyManager().setLockTaskPackages( + originalLockTaskPackages); + } + } + } } diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java index 2ae96288536..fd652f3ce12 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java @@ -299,8 +299,7 @@ public final class CompatChangeTests extends MultiDisplayTestBase { // Note that we're using getBounds() in portrait, rather than getAppBounds() like other // tests, because we're comparing to the display size and therefore need to consider insets. runMinAspectRatioTest(NON_RESIZEABLE_PORTRAIT_ACTIVITY, - /* expectedInPortrait= */ SIZE_COMPAT_DISPLAY_ASPECT_RATIO, - /* expectedInLandscape= */ FIXED_ORIENTATION_MIN_ASPECT_RATIO, + /* expected= */ SIZE_COMPAT_DISPLAY_ASPECT_RATIO, /* useAppBoundsInPortrait= */false); } @@ -314,8 +313,7 @@ public final class CompatChangeTests extends MultiDisplayTestBase { // Note that we're using getBounds() in portrait, rather than getAppBounds() like other // tests, because we're comparing to the display size and therefore need to consider insets. runMinAspectRatioTest(NON_RESIZEABLE_PORTRAIT_ACTIVITY, - /* expectedInPortrait= */ SIZE_COMPAT_DISPLAY_ASPECT_RATIO, - /* expectedInLandscape= */ FIXED_ORIENTATION_MIN_ASPECT_RATIO, + /* expected= */ SIZE_COMPAT_DISPLAY_ASPECT_RATIO, /* useAppBoundsInPortrait= */false); } @@ -520,7 +518,7 @@ public final class CompatChangeTests extends MultiDisplayTestBase { * @param expected the expected aspect ratio in both portrait and landscape displays. */ private void runMinAspectRatioTest(ComponentName activity, float expected) { - runMinAspectRatioTest(activity, expected, expected, /* useAppBoundsInPortrait= */ true); + runMinAspectRatioTest(activity, expected, /* useAppBoundsInPortrait= */ true); } /** @@ -528,13 +526,13 @@ public final class CompatChangeTests extends MultiDisplayTestBase { * aspect ratio. The second time, the display is resized to a landscape aspect ratio. * * @param activity the activity under test. - * @param expectedInPortrait the expected aspect ratio in portrait display. - * @param expectedInLandscape the expected aspect ratio in portrait display. + * @param expected the expected aspect ratio in both a portrait and a landscape + * display. * @param useAppBoundsInPortrait whether to use {@code activity#getAppBounds} rather than * {@code activity.getBounds} in portrait display. */ - private void runMinAspectRatioTest(ComponentName activity, float expectedInPortrait, - float expectedInLandscape, boolean useAppBoundsInPortrait) { + private void runMinAspectRatioTest(ComponentName activity, float expected, + boolean useAppBoundsInPortrait) { // Change the aspect ratio of the display to something that is smaller than all the aspect // ratios used throughout those tests but still portrait. This ensures we're using // enforcing aspect ratio behaviour within orientation. @@ -543,7 +541,7 @@ public final class CompatChangeTests extends MultiDisplayTestBase { mDisplayMetricsSession.changeAspectRatio(SIZE_COMPAT_DISPLAY_ASPECT_RATIO, ORIENTATION_PORTRAIT); launchActivity(activity); - assertEquals(expectedInPortrait, + assertEquals(expected, getActivityAspectRatio(activity, /* useAppBounds= */ useAppBoundsInPortrait), FLOAT_EQUALITY_DELTA); @@ -552,10 +550,8 @@ public final class CompatChangeTests extends MultiDisplayTestBase { mDisplayMetricsSession.changeAspectRatio(SIZE_COMPAT_DISPLAY_ASPECT_RATIO, ORIENTATION_LANDSCAPE); launchActivity(activity); - // A different aspect ratio logic is applied in fixed orientation letterboxing, so we need - // to use getBounds() rather than getAppBounds() here. - assertEquals(expectedInLandscape, - getActivityAspectRatio(activity, /* useAppBounds= */ false), + assertEquals(expected, + getActivityAspectRatio(activity, /* useAppBounds= */ true), FLOAT_EQUALITY_DELTA); } diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayHashManagerTest.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayHashManagerTest.java index 4427b18eb6a..ed0f7d5d2b3 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayHashManagerTest.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayHashManagerTest.java @@ -21,6 +21,7 @@ import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ER import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS; +import static android.widget.LinearLayout.VERTICAL; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -44,19 +45,22 @@ import android.view.displayhash.DisplayHash; import android.view.displayhash.DisplayHashManager; import android.view.displayhash.DisplayHashResultCallback; import android.view.displayhash.VerifiedDisplayHash; +import android.widget.LinearLayout; import android.widget.RelativeLayout; import androidx.annotation.NonNull; -import androidx.test.core.app.ActivityScenario; import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; import com.android.compatibility.common.util.SystemUtil; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -64,6 +68,7 @@ import java.util.concurrent.TimeUnit; @Presubmit public class DisplayHashManagerTest { + private static final int MAX_RETRIES = 3; private final Point mTestViewSize = new Point(200, 300); private Instrumentation mInstrumentation; @@ -73,24 +78,27 @@ public class DisplayHashManagerTest { private View mTestView; private DisplayHashManager mDisplayHashManager; - private String mFirstHashAlgorithm; + private String mPhashAlgorithm; private Executor mExecutor; private SyncDisplayHashResultCallback mSyncDisplayHashResultCallback; + @Rule + public ActivityTestRule<TestActivity> mActivityRule = + new ActivityTestRule<>(TestActivity.class); + @Before public void setUp() throws Exception { mInstrumentation = InstrumentationRegistry.getInstrumentation(); Context context = mInstrumentation.getContext(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.setClass(context, TestActivity.class); - ActivityScenario<TestActivity> scenario = ActivityScenario.launch(intent); + mActivity = mActivityRule.getActivity(); - scenario.onActivity(activity -> { - mActivity = activity; - mMainView = new RelativeLayout(activity); - activity.setContentView(mMainView); + mActivity.runOnUiThread(() -> { + mMainView = new RelativeLayout(mActivity); + mActivity.setContentView(mMainView); }); mInstrumentation.waitForIdleSync(); mDisplayHashManager = context.getSystemService(DisplayHashManager.class); @@ -98,7 +106,14 @@ public class DisplayHashManagerTest { Set<String> algorithms = mDisplayHashManager.getSupportedHashAlgorithms(); assertNotNull(algorithms); assertNotEquals(0, algorithms.size()); - mFirstHashAlgorithm = algorithms.iterator().next(); + for (String algorithm : algorithms) { + if ("pHash".equalsIgnoreCase(algorithm)) { + mPhashAlgorithm = algorithm; + break; + } + } + assertNotNull(mPhashAlgorithm); + mExecutor = context.getMainExecutor(); mSyncDisplayHashResultCallback = new SyncDisplayHashResultCallback(); SystemUtil.runWithShellPermissionIdentity( @@ -123,13 +138,29 @@ public class DisplayHashManagerTest { }); mInstrumentation.waitForIdleSync(); - DisplayHash displayHash = generateDisplayHash(null); + int retryCount = 0; + // A solid color image has expected hash of all 0s + byte[] expectedImageHash = new byte[8]; + VerifiedDisplayHash verifiedDisplayHash = null; + + // Sometimes the app can still be launching when generating a display hash. This could + // result in a different image hash. Give the test a few tries to let the activity settle. + while (retryCount < MAX_RETRIES && (verifiedDisplayHash == null || + !Arrays.equals(expectedImageHash, verifiedDisplayHash.getImageHash()))) { + DisplayHash displayHash = generateDisplayHash(null); + + verifiedDisplayHash = mDisplayHashManager.verifyDisplayHash(displayHash); + assertNotNull(verifiedDisplayHash); + retryCount++; + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } - VerifiedDisplayHash verifiedDisplayHash = mDisplayHashManager.verifyDisplayHash( - displayHash); - assertNotNull(verifiedDisplayHash); assertEquals(mTestViewSize.x, verifiedDisplayHash.getBoundsInWindow().width()); assertEquals(mTestViewSize.y, verifiedDisplayHash.getBoundsInWindow().height()); + assertArrayEquals(expectedImageHash, verifiedDisplayHash.getImageHash()); } @Test @@ -165,7 +196,7 @@ public class DisplayHashManagerTest { mMainView.invalidate(); }); mInstrumentation.waitForIdleSync(); - mTestView.generateDisplayHash(mFirstHashAlgorithm, new Rect(), mExecutor, + mTestView.generateDisplayHash(mPhashAlgorithm, new Rect(), mExecutor, mSyncDisplayHashResultCallback); int errorCode = mSyncDisplayHashResultCallback.getError(); @@ -210,7 +241,7 @@ public class DisplayHashManagerTest { Rect bounds = new Rect(mTestViewSize.x + 1, mTestViewSize.y + 1, mTestViewSize.x + 100, mTestViewSize.y + 100); - mTestView.generateDisplayHash(mFirstHashAlgorithm, new Rect(bounds), + mTestView.generateDisplayHash(mPhashAlgorithm, new Rect(bounds), mExecutor, mSyncDisplayHashResultCallback); int errorCode = mSyncDisplayHashResultCallback.getError(); assertEquals(DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN, errorCode); @@ -229,7 +260,7 @@ public class DisplayHashManagerTest { }); mInstrumentation.waitForIdleSync(); - mTestView.generateDisplayHash(mFirstHashAlgorithm, null, mExecutor, + mTestView.generateDisplayHash(mPhashAlgorithm, null, mExecutor, mSyncDisplayHashResultCallback); int errorCode = mSyncDisplayHashResultCallback.getError(); @@ -266,7 +297,7 @@ public class DisplayHashManagerTest { mInstrumentation.waitForIdleSync(); mSyncDisplayHashResultCallback.reset(); - mTestView.generateDisplayHash(mFirstHashAlgorithm, null, mExecutor, + mTestView.generateDisplayHash(mPhashAlgorithm, null, mExecutor, mSyncDisplayHashResultCallback); int errorCode = mSyncDisplayHashResultCallback.getError(); @@ -366,24 +397,81 @@ public class DisplayHashManagerTest { }); mInstrumentation.waitForIdleSync(); - mTestView.generateDisplayHash(mFirstHashAlgorithm, null, mExecutor, + mTestView.generateDisplayHash(mPhashAlgorithm, null, mExecutor, mSyncDisplayHashResultCallback); mSyncDisplayHashResultCallback.getDisplayHash(); mSyncDisplayHashResultCallback.reset(); // Generate a second display hash right away. - mTestView.generateDisplayHash(mFirstHashAlgorithm, null, mExecutor, + mTestView.generateDisplayHash(mPhashAlgorithm, null, mExecutor, mSyncDisplayHashResultCallback); int errorCode = mSyncDisplayHashResultCallback.getError(); assertEquals(DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS, errorCode); } + @Test + public void testGenerateAndVerifyDisplayHash_MultiColor() { + mInstrumentation.runOnMainSync(() -> { + final RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(mTestViewSize.x, + mTestViewSize.y); + LinearLayout linearLayout = new LinearLayout(mActivity); + linearLayout.setOrientation(VERTICAL); + LinearLayout.LayoutParams blueParams = new LinearLayout.LayoutParams(mTestViewSize.x, + mTestViewSize.y / 2); + View blueView = new View(mActivity); + blueView.setBackgroundColor(Color.BLUE); + LinearLayout.LayoutParams redParams = new LinearLayout.LayoutParams(mTestViewSize.x, + mTestViewSize.y / 2); + View redView = new View(mActivity); + redView.setBackgroundColor(Color.RED); + + linearLayout.addView(blueView, blueParams); + linearLayout.addView(redView, redParams); + mTestView = linearLayout; + + mMainView.addView(mTestView, p); + mMainView.invalidate(); + }); + mInstrumentation.waitForIdleSync(); + + int retryCount = 0; + byte[] expectedImageHash = new byte[]{-1, -1, 127, -1, -1, -1, 127, 127}; + VerifiedDisplayHash verifiedDisplayHash = null; + + // Sometimes the app can still be launching when generating a display hash. This could + // result in a different image hash. Give the test a few tries to let the activity settle. + while (retryCount < MAX_RETRIES && (verifiedDisplayHash == null || + !Arrays.equals(expectedImageHash, verifiedDisplayHash.getImageHash()))) { + DisplayHash displayHash = generateDisplayHash(null); + + verifiedDisplayHash = mDisplayHashManager.verifyDisplayHash(displayHash); + assertNotNull(verifiedDisplayHash); + retryCount++; + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + + assertEquals(mTestViewSize.x, verifiedDisplayHash.getBoundsInWindow().width()); + assertEquals(mTestViewSize.y, verifiedDisplayHash.getBoundsInWindow().height()); + assertArrayEquals(expectedImageHash, verifiedDisplayHash.getImageHash()); + } + private DisplayHash generateDisplayHash(Rect bounds) { - mTestView.generateDisplayHash(mFirstHashAlgorithm, bounds, mExecutor, - mSyncDisplayHashResultCallback); + DisplayHash displayHash = null; + int retryCount = 0; + while (displayHash == null && retryCount < MAX_RETRIES) { + mTestView.generateDisplayHash(mPhashAlgorithm, bounds, mExecutor, + mSyncDisplayHashResultCallback); + displayHash = mSyncDisplayHashResultCallback.getDisplayHash(); + retryCount++; + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } - DisplayHash displayHash = mSyncDisplayHashResultCallback.getDisplayHash(); assertNotNull(displayHash); - return displayHash; } diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java index 867d101e328..e84f0a63a33 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java @@ -53,6 +53,7 @@ import android.graphics.Insets; import android.os.CancellationSignal; import android.platform.test.annotations.Presubmit; import android.server.wm.WindowInsetsAnimationTestBase.TestActivity; +import android.util.Log; import android.view.View; import android.view.WindowInsets; import android.view.WindowInsetsAnimation; @@ -172,7 +173,7 @@ public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase @After public void tearDown() throws Throwable { runOnUiThread(() -> {}); // Fence to make sure we dispatched everything. - mCallbacks.forEach(VerifyingCallback::assertNoRunningAnimations); + mCallbacks.forEach(VerifyingCallback::assertNoPendingAnimations); // Unregistering VerifyingCallback as tearing down the MockIme also triggers UI events, // which can trigger assertion failures in VerifyingCallback otherwise. @@ -727,6 +728,7 @@ public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase private final Callback mInner; private final Set<WindowInsetsAnimation> mPreparedAnimations = new HashSet<>(); private final Set<WindowInsetsAnimation> mRunningAnimations = new HashSet<>(); + private final Set<WindowInsetsAnimation> mEndedAnimations = new HashSet<>(); public VerifyingCallback(Callback callback) { super(callback.getDispatchMode()); @@ -735,6 +737,7 @@ public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase @Override public void onPrepare(@NonNull WindowInsetsAnimation animation) { + mErrorCollector.checkThat("onPrepare: animation", animation, notNullValue()); mErrorCollector.checkThat("onPrepare", mPreparedAnimations, not(hasItem(animation))); mPreparedAnimations.add(animation); mInner.onPrepare(animation); @@ -744,6 +747,9 @@ public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase @Override public WindowInsetsAnimation.Bounds onStart(@NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) { + mErrorCollector.checkThat("onStart: animation", animation, notNullValue()); + mErrorCollector.checkThat("onStart: bounds", bounds, notNullValue()); + mErrorCollector.checkThat("onStart: mPreparedAnimations", mPreparedAnimations, hasItem(animation)); mErrorCollector.checkThat("onStart: mRunningAnimations", @@ -757,6 +763,10 @@ public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase @Override public WindowInsets onProgress(@NonNull WindowInsets insets, @NonNull List<WindowInsetsAnimation> runningAnimations) { + mErrorCollector.checkThat("onProgress: insets", insets, notNullValue()); + mErrorCollector.checkThat("onProgress: runningAnimations", + runningAnimations, notNullValue()); + mErrorCollector.checkThat("onProgress", new HashSet<>(runningAnimations), is(equalTo(mRunningAnimations))); return mInner.onProgress(insets, runningAnimations); @@ -764,34 +774,57 @@ public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase @Override public void onEnd(@NonNull WindowInsetsAnimation animation) { - mErrorCollector.checkThat("onEnd: mRunningAnimations", - mRunningAnimations, hasItem(animation)); + mErrorCollector.checkThat("onEnd: animation", animation, notNullValue()); + + mErrorCollector.checkThat("onEnd for this animation was already dispatched", + mEndedAnimations, not(hasItem(animation))); + mErrorCollector.checkThat("onEnd: animation must be either running or prepared", + mRunningAnimations.contains(animation) || mEndedAnimations.contains(animation), + is(true)); mRunningAnimations.remove(animation); mPreparedAnimations.remove(animation); + mEndedAnimations.add(animation); mInner.onEnd(animation); } - public void assertNoRunningAnimations() { - mErrorCollector.checkThat(mRunningAnimations, hasSize(0)); + public void assertNoPendingAnimations() { + mErrorCollector.checkThat("Animations with onStart but missing onEnd:", + mRunningAnimations, equalTo(Set.of())); + mErrorCollector.checkThat("Animations with onPrepare but missing onStart:", + mPreparedAnimations, equalTo(Set.of())); } } public static final class LimitedErrorCollector extends ErrorCollector { - private static final int LIMIT = 1; - private static final boolean REPORT_SUPPRESSED_ERRORS = false; + private static final int THROW_LIMIT = 1; + private static final int LOG_LIMIT = 10; + private static final boolean REPORT_SUPPRESSED_ERRORS_AS_THROWABLE = false; private int mCount = 0; + private List<Throwable> mSuppressedErrors = new ArrayList<>(); @Override public void addError(Throwable error) { - if (mCount++ < LIMIT) { + if (mCount < THROW_LIMIT) { super.addError(error); + } else if (mCount < LOG_LIMIT) { + mSuppressedErrors.add(error); } + mCount++; } @Override protected void verify() throws Throwable { - if (mCount > LIMIT && REPORT_SUPPRESSED_ERRORS) { - super.addError(new AssertionError((mCount - LIMIT) + " errors suppressed.")); + if (mCount > THROW_LIMIT) { + if (REPORT_SUPPRESSED_ERRORS_AS_THROWABLE) { + super.addError( + new AssertionError((mCount - THROW_LIMIT) + " errors suppressed.")); + } else { + Log.i("LimitedErrorCollector", (mCount - THROW_LIMIT) + " errors suppressed; " + + "additional errors:"); + for (Throwable t : mSuppressedErrors) { + Log.e("LimitedErrorCollector", "", t); + } + } } super.verify(); } diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java index f7c00ce54f9..162c428a856 100644 --- a/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java +++ b/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java @@ -177,7 +177,7 @@ public class NavigationBarColorTest extends EndToEndImeTestBase { case DIMMING_DIALOG_ABOVE_IME: { final AlertDialog alertDialog = getOnMainSync(() -> { final TextView textView = new TextView(activity); - textView.setText("Dummy"); + textView.setText("Sample Text"); textView.requestFocus(); final AlertDialog dialog = new AlertDialog.Builder(activity) .setView(textView) diff --git a/tests/musicrecognition/src/android/musicrecognition/cts/MusicRecognitionManagerTest.java b/tests/musicrecognition/src/android/musicrecognition/cts/MusicRecognitionManagerTest.java index 0502df3b54c..d6fa70cdd27 100644 --- a/tests/musicrecognition/src/android/musicrecognition/cts/MusicRecognitionManagerTest.java +++ b/tests/musicrecognition/src/android/musicrecognition/cts/MusicRecognitionManagerTest.java @@ -23,7 +23,6 @@ import static com.android.compatibility.common.util.ShellUtils.runShellCommand; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -37,7 +36,6 @@ import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import android.app.AppOpsManager; -import android.app.AppOpsManager.OnOpStartedListener; import android.content.Context; import android.media.AudioAttributes; @@ -226,25 +224,15 @@ public class MusicRecognitionManagerTest { appOpsManager.startWatchingActive(new String[] { AppOpsManager.OPSTR_RECORD_AUDIO }, context.getMainExecutor(), listener); - // Started listener used just for verifying attribution tag. - final AppOpsManager.OnOpStartedListener startedListener = mock( - AppOpsManager.OnOpStartedListener.class); - - appOpsManager.startWatchingStarted(new int[] { AppOpsManager.OP_RECORD_AUDIO }, - startedListener); - // Invoke API RecognitionRequest request = invokeMusicRecognitionApi(); // The app op should start - verify(listener, timeout(VERIFY_APPOP_CHANGE_TIMEOUT_MS) - .only()).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), - eq(uid), eq(packageName), eq(true)); - String expectedAttributionTag = "CtsMusicRecognitionAttributionTag"; - verify(startedListener, timeout(VERIFY_APPOP_CHANGE_TIMEOUT_MS) - .only()).onOpStarted(eq(AppOpsManager.OP_RECORD_AUDIO), - eq(uid), eq(packageName), eq(expectedAttributionTag), anyInt(), anyInt()); + verify(listener, timeout(VERIFY_APPOP_CHANGE_TIMEOUT_MS)) + .onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), + eq(uid), eq(packageName), eq(expectedAttributionTag), eq(true), + anyInt(), anyInt()); // Wait for streaming to finish. reset(listener); @@ -255,9 +243,10 @@ public class MusicRecognitionManagerTest { } // The app op should finish - verify(listener, timeout(VERIFY_APPOP_CHANGE_TIMEOUT_MS) - .only()).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), - eq(uid), eq(packageName), eq(false)); + verify(listener, timeout(VERIFY_APPOP_CHANGE_TIMEOUT_MS)) + .onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), + eq(uid), eq(packageName), eq(expectedAttributionTag), eq(false), + anyInt(), anyInt()); // Start with a clean slate diff --git a/tests/tests/app.usage/AndroidManifest.xml b/tests/tests/app.usage/AndroidManifest.xml index 71ec3d38d4f..141a9afc513 100644 --- a/tests/tests/app.usage/AndroidManifest.xml +++ b/tests/tests/app.usage/AndroidManifest.xml @@ -51,6 +51,10 @@ <activity android:name=".FragmentTestActivity" /> <activity android:name=".TaskRootActivity" /> <service android:name=".TestService" /> + <service android:name=".TestJob" + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" + /> </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" diff --git a/tests/tests/app.usage/src/android/app/usage/cts/TestJob.java b/tests/tests/app.usage/src/android/app/usage/cts/TestJob.java new file mode 100644 index 00000000000..decc9d8e61e --- /dev/null +++ b/tests/tests/app.usage/src/android/app/usage/cts/TestJob.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 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.app.usage.cts; + +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; +import android.content.Context; + +import java.util.function.BooleanSupplier; + +public final class TestJob extends JobService { + + public static final int TEST_JOB_ID = 1; + public static final String NOTIFICATION_CHANNEL_ID = TestJob.class.getSimpleName(); + private static boolean sJobStarted; + public static BooleanSupplier hasJobStarted = new BooleanSupplier() { + @Override + public boolean getAsBoolean() { + return sJobStarted; + } + }; + + @Override + public boolean onStartJob(JobParameters params) { + sJobStarted = true; + return false; + } + + @Override + public boolean onStopJob(JobParameters params) { + return false; + } + + public static void schedule(Context context) { + sJobStarted = false; + JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); + ComponentName componentName = new ComponentName(context, TestJob.class); + + JobInfo jobInfo = new JobInfo.Builder(TEST_JOB_ID, componentName).build(); + jobScheduler.schedule(jobInfo); + } +} diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java index 5f12ea7c882..51321b1c2af 100644 --- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java +++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java @@ -115,6 +115,8 @@ public class UsageStatsTest { private static final String DELETE_SHELL_COMMAND = "settings delete global "; + private static final String JOBSCHEDULER_RUN_SHELL_COMMAND = "cmd jobscheduler run"; + private static final String TEST_APP_PKG = "android.app.usage.cts.test1"; private static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity"; private static final String TEST_APP_CLASS_LOCUS @@ -248,7 +250,7 @@ public class UsageStatsTest { @AppModeFull(reason = "No usage events access in instant apps") @Test - public void testLastAnyTimeComponentUsed_launchActivity() throws Exception { + public void testLastTimeAnyComponentUsed_launchActivityShouldBeDetected() throws Exception { mUiDevice.wakeUp(); dismissKeyguard(); // also want to start out with the keyguard dismissed. @@ -256,33 +258,62 @@ public class UsageStatsTest { launchSubActivity(Activities.ActivityOne.class); final long endTime = System.currentTimeMillis(); + verifyLastTimeAnyComponentUsedWithinRange(startTime, endTime, mTargetPackage); + } + + @AppModeFull(reason = "No usage events access in instant apps") + @Test + public void testLastTimeAnyComponentUsed_bindServiceShouldBeDetected() throws Exception { + mUiDevice.wakeUp(); + dismissKeyguard(); // also want to start out with the keyguard dismissed. + + final long startTime = System.currentTimeMillis(); + bindToTestService(); + final long endTime = System.currentTimeMillis(); + + verifyLastTimeAnyComponentUsedWithinRange(startTime, endTime, TEST_APP_PKG); + } + + private void verifyLastTimeAnyComponentUsedWithinRange( + long startTime, long endTime, String targetPackage) { final Map<String, UsageStats> map = mUsageStatsManager.queryAndAggregateUsageStats( startTime, endTime); - final UsageStats stats = map.get(mTargetPackage); + final UsageStats stats = map.get(targetPackage); assertNotNull(stats); - final long lastTimeComponentUsed = stats.getLastTimeAnyComponentUsed(); - assertLessThan(startTime, lastTimeComponentUsed); - assertLessThan(lastTimeComponentUsed, endTime); + final long lastTimeAnyComponentUsed = stats.getLastTimeAnyComponentUsed(); + assertLessThan(startTime, lastTimeAnyComponentUsed); + assertLessThan(lastTimeAnyComponentUsed, endTime); + + final long lastDayAnyComponentUsedGlobal = + mUsageStatsManager.getLastTimeAnyComponentUsed(targetPackage) / DAY; + assertLessThanOrEqual(startTime / DAY, lastDayAnyComponentUsedGlobal); + assertLessThanOrEqual(lastDayAnyComponentUsedGlobal, endTime / DAY); } @AppModeFull(reason = "No usage events access in instant apps") @Test - public void testLastTimeAnyComponentUsedGlobal_launchActivity() throws Exception { + public void testLastTimeAnyComponentUsed_JobServiceShouldBeIngnored() throws Exception { mUiDevice.wakeUp(); - dismissKeyguard(); + dismissKeyguard(); // also want to start out with the keyguard dismissed. - final long startDay = System.currentTimeMillis() / TimeUnit.DAYS.toMillis(1) - * TimeUnit.DAYS.toMillis(1); - launchSubActivity(Activities.ActivityOne.class); - final long endDay = System.currentTimeMillis() / TimeUnit.DAYS.toMillis(1) - * TimeUnit.DAYS.toMillis(1); + final long startTime = System.currentTimeMillis(); + runJobImmediately(); + waitUntil(TestJob.hasJobStarted, /* expected */ true); - final long lastTimeAnyComponentUsed = - mUsageStatsManager.getLastTimeAnyComponentUsed(mTargetPackage); - assertLessThanOrEqual(startDay, lastTimeAnyComponentUsed); - assertLessThanOrEqual(lastTimeAnyComponentUsed, endDay); - } + final Map<String, UsageStats> map = mUsageStatsManager.queryAndAggregateUsageStats( + startTime, System.currentTimeMillis()); + final UsageStats stats = map.get(mTargetPackage); + if (stats != null) { + final long lastTimeAnyComponentUsed = stats.getLastTimeAnyComponentUsed(); + // Check that the usage is NOT detected. + assertLessThanOrEqual(lastTimeAnyComponentUsed, startTime); + } + final long lastDayAnyComponentUsedGlobal = + mUsageStatsManager.getLastTimeAnyComponentUsed(mTargetPackage) / DAY; + // Check that the usage is NOT detected. + assertLessThanOrEqual(lastDayAnyComponentUsedGlobal, startTime / DAY); + } @AppModeFull(reason = "No usage events access in instant apps") @Test @@ -1769,6 +1800,13 @@ public class UsageStatsTest { } } + private void runJobImmediately() throws Exception { + TestJob.schedule(mContext); + executeShellCmd(JOBSCHEDULER_RUN_SHELL_COMMAND + + " " + mContext.getPackageName() + + " " + TestJob.TEST_JOB_ID); + } + private boolean isAppInactiveAsPermissionlessApp(String pkg) throws Exception { final ITestReceiver testService = bindToTestService(); return testService.isAppInactive(pkg); diff --git a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java index 78776ba54d8..98f1377a14a 100644 --- a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java +++ b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java @@ -84,6 +84,7 @@ import android.os.Process; import android.os.RemoteCallback; import android.os.UserHandle; import android.util.SparseArray; +import android.view.accessibility.AccessibilityManager; import java.util.ArrayList; import java.util.Arrays; @@ -239,6 +240,9 @@ public class TestActivity extends Activity { .getString(Intent.EXTRA_INSTALLER_PACKAGE_NAME); sendSetInstallerPackageName(remoteCallback, targetPackageName, installerPackageName); + } else if (Constants.ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES.equals( + action)) { + sendGetInstalledAccessibilityServicePackages(remoteCallback); } else { sendError(remoteCallback, new Exception("unknown action " + action)); } @@ -247,6 +251,16 @@ public class TestActivity extends Activity { } } + private void sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback) { + final String[] packages = getSystemService( + AccessibilityManager.class).getInstalledAccessibilityServiceList().stream().map( + p -> p.getComponentName().getPackageName()).distinct().toArray(String[]::new); + final Bundle result = new Bundle(); + result.putStringArray(EXTRA_RETURN_RESULT, packages); + remoteCallback.sendResult(result); + finish(); + } + private void onCommandReady(Intent intent) { final RemoteCallback callback = intent.getParcelableExtra(EXTRA_REMOTE_READY_CALLBACK); if (callback != null) { diff --git a/tests/tests/appenumeration/app/target/AndroidManifest-filters.xml b/tests/tests/appenumeration/app/target/AndroidManifest-filters.xml index 59ec446a11c..eeb31703085 100644 --- a/tests/tests/appenumeration/app/target/AndroidManifest-filters.xml +++ b/tests/tests/appenumeration/app/target/AndroidManifest-filters.xml @@ -74,5 +74,16 @@ <action android:name="android.appenumeration.action.BROADCAST_UNEXPORTED"/> </intent-filter> </receiver> + <service android:name="android.appenumeration.testapp.StubAccessibilityService" + android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" + android:exported="true"> + <intent-filter> + <action android:name="android.accessibilityservice.AccessibilityService"/> + <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC"/> + </intent-filter> + + <meta-data android:name="android.accessibilityservice" + android:resource="@xml/stub_accessibility_service"/> + </service> </application> </manifest> diff --git a/tests/tests/appenumeration/app/target/res/values/strings.xml b/tests/tests/appenumeration/app/target/res/values/strings.xml new file mode 100644 index 00000000000..23e27131c43 --- /dev/null +++ b/tests/tests/appenumeration/app/target/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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. +--> + +<resources> + + <!-- String description for the test accessibility service --> + <string name="stub_accessibility_service">stubAccessibililityService</string> + +</resources> diff --git a/tests/tests/appenumeration/app/target/res/xml/stub_accessibility_service.xml b/tests/tests/appenumeration/app/target/res/xml/stub_accessibility_service.xml new file mode 100644 index 00000000000..e202f36f0f6 --- /dev/null +++ b/tests/tests/appenumeration/app/target/res/xml/stub_accessibility_service.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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. +--> + +<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" + android:description="@string/stub_accessibility_service" + android:accessibilityEventTypes="typeAllMask" + android:accessibilityFeedbackType="feedbackGeneric" + android:notificationTimeout="0" /> diff --git a/tests/tests/appenumeration/app/target/src/android/appenumeration/testapp/StubAccessibilityService.java b/tests/tests/appenumeration/app/target/src/android/appenumeration/testapp/StubAccessibilityService.java new file mode 100644 index 00000000000..aa34f54a169 --- /dev/null +++ b/tests/tests/appenumeration/app/target/src/android/appenumeration/testapp/StubAccessibilityService.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 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.appenumeration.testapp; + +import android.accessibilityservice.AccessibilityService; +import android.view.accessibility.AccessibilityEvent; + +/** + * A stub accessibility service to verify the package visibility of {@link + * android.view.accessibility.AccessibilityManager}. + */ +public class StubAccessibilityService extends AccessibilityService { + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + } + + @Override + public void onInterrupt() { + } +} diff --git a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java index 740470e7262..c93016b3edf 100644 --- a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java +++ b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java @@ -205,7 +205,8 @@ public class Constants { PKG_BASE + "cts.action.GET_PREFERRED_ACTIVITIES"; public static final String ACTION_SET_INSTALLER_PACKAGE_NAME = PKG_BASE + "cts.action.SET_INSTALLER_PACKAGE_NAME"; - + public static final String ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES = + PKG_BASE + "cts.action.GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES"; public static final String EXTRA_REMOTE_CALLBACK = "remoteCallback"; public static final String EXTRA_REMOTE_READY_CALLBACK = "remoteReadyCallback"; public static final String EXTRA_ERROR = "error"; diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java index 4a26aaf82f9..123808e80cf 100644 --- a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java +++ b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.SET_PREFERRED_APPLICATIONS; import static android.appenumeration.cts.Constants.ACTION_AWAIT_LAUNCHER_APPS_CALLBACK; import static android.appenumeration.cts.Constants.ACTION_BIND_SERVICE; import static android.appenumeration.cts.Constants.ACTION_CHECK_SIGNATURES; +import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES; import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS; import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_PACKAGES; import static android.appenumeration.cts.Constants.ACTION_GET_NAMES_FOR_UIDS; @@ -649,6 +650,21 @@ public class AppEnumerationTests { assertVisible(QUERIES_WILDCARD_SHARE, TARGET_SHARE); } + @Test + public void queriesNothing_cannotSeeA11yService() throws Exception { + if (!sGlobalFeatureEnabled) return; + final String[] result = getInstalledAccessibilityServices(QUERIES_NOTHING); + assertThat(result, not(hasItemInArray(TARGET_FILTERS))); + } + + @Test + public void queriesNothingHasPermission_canSeeA11yService() throws Exception { + if (!sGlobalFeatureEnabled) return; + final String[] result = getInstalledAccessibilityServices(QUERIES_NOTHING_PERM); + assertThat(QUERIES_NOTHING_PERM + " should be able to see " + TARGET_FILTERS, + result, hasItemInArray(TARGET_FILTERS)); + } + private void assertVisible(String sourcePackageName, String targetPackageName) throws Exception { if (!sGlobalFeatureEnabled) return; @@ -1183,6 +1199,13 @@ public class AppEnumerationTests { } } + private String[] getInstalledAccessibilityServices (String sourcePackageName) + throws Exception { + final Bundle response = sendCommandBlocking(sourcePackageName, null /*targetPackageName*/, + null /*queryIntent*/, ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES); + return response.getStringArray(Intent.EXTRA_RETURN_RESULT); + } + private PackageInfo getPackageInfo(String sourcePackageName, String targetPackageName) throws Exception { Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName, diff --git a/tests/tests/appop/src/android/app/appops/cts/DiscreteAppopsTest.kt b/tests/tests/appop/src/android/app/appops/cts/DiscreteAppopsTest.kt index bc7763a5a3b..fec50eb328f 100644 --- a/tests/tests/appop/src/android/app/appops/cts/DiscreteAppopsTest.kt +++ b/tests/tests/appop/src/android/app/appops/cts/DiscreteAppopsTest.kt @@ -55,6 +55,7 @@ private const val PACKAGE_NAME = "android.app.appops.cts.appfordiscretetest" private const val TIMEOUT_MILLIS = 45000L private const val DEFAULT_TIME_QUANT_MILLIS = 60000L private const val SHORT_TIME_QUANT_MILLIS = 2000L +private const val CALLBACK_PROPAGATION_DELAY = 5000L private const val SAFETY_MARGIN_MILLIS = 5000L private const val TEN_MINUTES_MILLIS = 600000L private const val ONE_MINUTE_MILLIS = 60000L @@ -892,15 +893,28 @@ class DiscreteAppopsTest { DeviceConfig.setProperty(NAMESPACE_PRIVACY, PROPERTY_FLAGS, 8.toString(), false) } - waitUntilSafelyInTimeQuant(DEFAULT_TIME_QUANT_MILLIS, SAFETY_MARGIN_MILLIS) - runWithShellPermissionIdentity { - appOpsManager.noteProxyOp(OPSTR_FINE_LOCATION, PACKAGE_NAME, uid, null, null) - appOpsManager.noteOp(OPSTR_FINE_LOCATION, uid, PACKAGE_NAME, null, null) + var allOps: HistoricalOps? = null + + for (i in 1..3) { + waitUntilSafelyInTimeQuant(DEFAULT_TIME_QUANT_MILLIS, SAFETY_MARGIN_MILLIS) + runWithShellPermissionIdentity { + appOpsManager.noteProxyOp(OPSTR_FINE_LOCATION, PACKAGE_NAME, uid, null, null) + appOpsManager.noteOp(OPSTR_FINE_LOCATION, uid, PACKAGE_NAME, null, null) + } + allOps = getHistoricalOps(HISTORY_FLAG_DISCRETE) + if (allOps!!.getUidOpsAt(0).getPackageOpsAt(0).getOpAt(0).getDiscreteAccessAt(0) + .getLastAccessTime(OP_FLAG_SELF) == -1L) { + break + } + runWithShellPermissionIdentity { + appOpsManager.clearHistory() + } + // maybe device_config callback didn't propagate yet, give it some more time + Thread.sleep(CALLBACK_PROPAGATION_DELAY) } val timeStamp = System.currentTimeMillis() / DEFAULT_TIME_QUANT_MILLIS * DEFAULT_TIME_QUANT_MILLIS - var allOps = getHistoricalOps(HISTORY_FLAG_DISCRETE) assertThat(allOps).isNotNull() assertThat(allOps!!.uidCount).isEqualTo(1) @@ -933,13 +947,22 @@ class DiscreteAppopsTest { runWithShellPermissionIdentity { DeviceConfig.setProperty(NAMESPACE_PRIVACY, PROPERTY_OPS_LIST, "1", false) } - waitUntilSafelyInTimeQuant(DEFAULT_TIME_QUANT_MILLIS, SAFETY_MARGIN_MILLIS) - noteOp(OPSTR_FINE_LOCATION, uid, PACKAGE_NAME, null, null) - noteOp(OPSTR_CAMERA, uid, PACKAGE_NAME, null, null) + var allOps: HistoricalOps? = null + for (i in 1..3) { + waitUntilSafelyInTimeQuant(DEFAULT_TIME_QUANT_MILLIS, SAFETY_MARGIN_MILLIS) + noteOp(OPSTR_FINE_LOCATION, uid, PACKAGE_NAME, null, null) + noteOp(OPSTR_CAMERA, uid, PACKAGE_NAME, null, null) + allOps = getHistoricalOps(HISTORY_FLAG_DISCRETE) + if (allOps!!.getUidOpsAt(0).getPackageOpsAt(0).opCount == 1) break + runWithShellPermissionIdentity { + appOpsManager.clearHistory() + } + // maybe device_config callback didn't propagate yet, give it some more time + Thread.sleep(CALLBACK_PROPAGATION_DELAY) + } val timeStamp = System.currentTimeMillis() / DEFAULT_TIME_QUANT_MILLIS * DEFAULT_TIME_QUANT_MILLIS - var allOps = getHistoricalOps(HISTORY_FLAG_DISCRETE) assertThat(allOps).isNotNull() assertThat(allOps!!.uidCount).isEqualTo(1) diff --git a/tests/tests/car/src/android/car/cts/CarOccupantZoneManagerTest.java b/tests/tests/car/src/android/car/cts/CarOccupantZoneManagerTest.java index 7c7cc1b06b0..0c6651df46a 100644 --- a/tests/tests/car/src/android/car/cts/CarOccupantZoneManagerTest.java +++ b/tests/tests/car/src/android/car/cts/CarOccupantZoneManagerTest.java @@ -16,6 +16,8 @@ package android.car.cts; +import static android.view.Display.DEFAULT_DISPLAY; + import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -25,6 +27,7 @@ import android.car.Car; import android.car.CarOccupantZoneManager; import android.car.CarOccupantZoneManager.OccupantZoneConfigChangeListener; import android.car.CarOccupantZoneManager.OccupantZoneInfo; +import android.hardware.display.DisplayManager; import android.os.Process; import android.os.UserHandle; import android.platform.test.annotations.AppModeFull; @@ -70,6 +73,15 @@ public class CarOccupantZoneManagerTest extends CarApiTestBase { } @Test + public void testGetDisplayType_mainDisplay() { + DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + Display defaultDisplay = displayManager.getDisplay(DEFAULT_DISPLAY); + + assertThat(mCarOccupantZoneManager.getDisplayType(defaultDisplay)).isEqualTo( + CarOccupantZoneManager.DISPLAY_TYPE_MAIN); + } + + @Test public void testDriverUserIdMustBeCurrentUser() { int myUid = Process.myUid(); assertWithMessage("Driver user id must correspond to current user id (Process.myUid: %s)", @@ -96,7 +108,7 @@ public class CarOccupantZoneManagerTest extends CarApiTestBase { @Test public void testDriverDisplayIdIsDefaultDisplay() { - assertThat(getDriverDisplay().getDisplayId()).isEqualTo(Display.DEFAULT_DISPLAY); + assertThat(getDriverDisplay().getDisplayId()).isEqualTo(DEFAULT_DISPLAY); } @Test @@ -123,7 +135,7 @@ public class CarOccupantZoneManagerTest extends CarApiTestBase { } private OccupantZoneConfigChangeListener createOccupantZoneConfigChangeListener() { - return new OccupantZoneConfigChangeListener () { + return new OccupantZoneConfigChangeListener() { public void onOccupantZoneConfigChanged(int changeFlags) { Log.i(TAG, "Got a confing change, flags: " + changeFlags); } diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java index eab27ce451a..75f07703abd 100644 --- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java +++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java @@ -92,6 +92,20 @@ public class CarPackageManagerTest extends CarApiTestBase { } @Test + public void testIsServiceDistractionOptimized() { + assertThat(mCarPm.isServiceDistractionOptimized("com.android.car", + "anything.anything")).isTrue(); + if (Build.TYPE.equalsIgnoreCase("user")) { + // Should be false as not from trusted source. + assertThat(mCarPm.isServiceDistractionOptimized("android.car.cts", + "anything.anything")).isFalse(); + } else { + assertThat(mCarPm.isServiceDistractionOptimized("android.car.cts", + "anything.anything")).isTrue(); + } + } + + @Test public void testNonDistractionOptimizedActivityNotAllowed() { // Not distraction optimized, but from system app assertThat(mCarPm.isActivityDistractionOptimized("com.android.car", diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java index 07997045aaf..29e295a2df6 100644 --- a/tests/tests/content/src/android/content/cts/ContextTest.java +++ b/tests/tests/content/src/android/content/cts/ContextTest.java @@ -79,9 +79,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; @AppModeFull // TODO(Instant) Figure out which APIs should work. public class ContextTest extends AndroidTestCase { @@ -237,6 +235,33 @@ public class ContextTest extends AndroidTestCase { assertEquals("baz", params.getNextAttributionSource().getAttributionTag()); } + public void testAttributionSourceSetNext() throws Exception { + final AttributionSource next = new AttributionSource.Builder(2) + .setPackageName("nextBar") + .setAttributionTag("nextBaz") + .build(); + final ContextParams params = new ContextParams.Builder() + .setAttributionTag("foo") + .setNextAttributionSource(new AttributionSource.Builder(1) + .setPackageName("bar") + .setAttributionTag("baz") + .setNext(next) + .build()) + .build(); + + // Setting a 'next' should not affect prev. + assertEquals("foo", params.getAttributionTag()); + assertEquals(1, params.getNextAttributionSource().getUid()); + assertEquals("bar", params.getNextAttributionSource().getPackageName()); + assertEquals("baz", params.getNextAttributionSource().getAttributionTag()); + + final AttributionSource check = + params.getNextAttributionSource().getNext(); + assertEquals(2, check.getUid()); + assertEquals("nextBar", check.getPackageName()); + assertEquals("nextBaz", check.getAttributionTag()); + } + public void testContextParams_Inherit() throws Exception { final ContextParams orig = new ContextParams.Builder() .setAttributionTag("foo").build(); diff --git a/tests/tests/media/libaudiojni/Android.bp b/tests/tests/media/libaudiojni/Android.bp index 0fc6126b382..ded7b83a99a 100644 --- a/tests/tests/media/libaudiojni/Android.bp +++ b/tests/tests/media/libaudiojni/Android.bp @@ -45,5 +45,7 @@ cc_test_library { "-Wno-deprecated-declarations", ], gtest: false, - sdk_version: "current", + // this test suite will run on sdk 29 as part of MTS, make sure it's compatible + // (revisit if/when we add features to this library that require newer sdk. + sdk_version: "29", } diff --git a/tests/tests/media/libimagereaderjni/Android.bp b/tests/tests/media/libimagereaderjni/Android.bp index d97c51186b1..bb845948fff 100644 --- a/tests/tests/media/libimagereaderjni/Android.bp +++ b/tests/tests/media/libimagereaderjni/Android.bp @@ -33,6 +33,8 @@ cc_test_library { "-Wall", ], gtest: false, - sdk_version: "current", + // this test suite will run on sdk 29 as part of MTS, make sure it's compatible + // (revisit if/when we add features to this library that require newer sdk. + sdk_version: "29", stl: "libc++_static", } diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java index 1c8dcc52671..70cb2729903 100644 --- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java +++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java @@ -24,10 +24,12 @@ import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecList; import android.media.MediaExtractor; import android.media.MediaFormat; +import android.os.Build; import android.platform.test.annotations.AppModeFull; import android.util.Log; import android.view.Surface; +import com.android.compatibility.common.util.ApiLevelUtil; import com.android.compatibility.common.util.MediaUtils; import android.opengl.GLES20; @@ -51,6 +53,8 @@ public class AdaptivePlaybackTest extends MediaPlayerTestBase { private boolean verify = false; private static final int MIN_FRAMES_BEFORE_DRC = 2; + private static boolean sIsAtLeastS = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S); + public Iterable<Codec> H264(CodecFactory factory) { return factory.createCodecList( MediaFormat.MIMETYPE_VIDEO_AVC, @@ -1058,9 +1062,12 @@ public class AdaptivePlaybackTest extends MediaPlayerTestBase { // Previous dequeue was output format change; format change must // correspond to a new sequence, so it must happen right before // the first frame of one of the sequences. - assertTrue("cannot find formatchange " + info.presentationTimeUs + + // this part of test is new for Android12 + if (sIsAtLeastS) { + assertTrue("Codec " + getName() + " cannot find formatchange " + info.presentationTimeUs + " in " + mFirstQueueTimestamps, mFirstQueueTimestamps.remove(info.presentationTimeUs)); + } mOutputFormatChanged = false; } diff --git a/tests/tests/media/src/android/media/cts/CodecState.java b/tests/tests/media/src/android/media/cts/CodecState.java index 1bb0aa50696..199c0329003 100644 --- a/tests/tests/media/src/android/media/cts/CodecState.java +++ b/tests/tests/media/src/android/media/cts/CodecState.java @@ -49,7 +49,9 @@ public class CodecState { private LinkedList<Integer> mAvailableOutputBufferIndices; private LinkedList<MediaCodec.BufferInfo> mAvailableOutputBufferInfos; private volatile long mPresentationTimeUs; - private long mSampleBaseTimeUs; + private long mFirstSampleTimeUs; + private long mPlaybackStartTimeUs; + private long mLastPresentTimeUs; private MediaCodec mCodec; private MediaTimeProvider mMediaTimeProvider; private MediaExtractor mExtractor; @@ -60,6 +62,9 @@ public class CodecState { /** A list of reported rendered video frames' timestamps. */ private ArrayList<Long> mRenderedVideoFrameTimestampList; + /** If true the video/audio will start from the beginning when it reaches the end. */ + private boolean mLoopEnabled = false; + /** * Manages audio and video playback using MediaCodec and AudioTrack. */ @@ -80,7 +85,9 @@ public class CodecState { mLimitQueueDepth = limitQueueDepth; mTunneled = tunneled; mAudioSessionId = audioSessionId; - mSampleBaseTimeUs = -1; + mFirstSampleTimeUs = -1; + mPlaybackStartTimeUs = 0; + mLastPresentTimeUs = 0; mCodec = codec; @@ -221,6 +228,10 @@ public class CodecState { return sampleTime; } + public void setLoopEnabled(boolean enabled) { + mLoopEnabled = enabled; + } + /** * Extracts some data from the configured MediaExtractor and feeds it to the configured * MediaCodec. @@ -260,30 +271,38 @@ public class CodecState { } if (mTunneled && !mIsAudio) { - if (mSampleBaseTimeUs == -1) { - mSampleBaseTimeUs = sampleTime; + if (mFirstSampleTimeUs == -1) { + mFirstSampleTimeUs = sampleTime; } - sampleTime -= mSampleBaseTimeUs; + sampleTime -= mFirstSampleTimeUs; } + mLastPresentTimeUs = mPlaybackStartTimeUs + sampleTime; + if ((sampleFlags & MediaExtractor.SAMPLE_FLAG_ENCRYPTED) != 0) { MediaCodec.CryptoInfo info = new MediaCodec.CryptoInfo(); mExtractor.getSampleCryptoInfo(info); mCodec.queueSecureInputBuffer( - inputBufferIndex, 0 /* offset */, info, sampleTime, 0 /* flags */); + inputBufferIndex, 0 /* offset */, info, mLastPresentTimeUs, 0 /* flags */); } else { mCodec.queueInputBuffer( - inputBufferIndex, 0 /* offset */, sampleSize, sampleTime, 0 /* flags */); + inputBufferIndex, 0 /* offset */, sampleSize, mLastPresentTimeUs, 0 /* flags */); } mExtractor.advance(); - return sampleTime; + return mLastPresentTimeUs; } else if (trackIndex < 0) { Log.d(TAG, "saw input EOS on track " + mTrackIndex); - mSawInputEOS = true; + if (mLoopEnabled) { + Log.d(TAG, "looping from the beginning"); + mExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); + mPlaybackStartTimeUs = mLastPresentTimeUs; + return null; + } + mSawInputEOS = true; mCodec.queueInputBuffer( inputBufferIndex, 0 /* offset */, 0 /* sampleSize */, 0 /* sampleTime */, MediaCodec.BUFFER_FLAG_END_OF_STREAM); @@ -344,7 +363,7 @@ public class CodecState { mSawOutputEOS = true; // Do not stop audio track here. Video presentation may not finish - // yet, stopping the auido track now would result in getAudioTimeUs + // yet, stopping the audio track now would result in getAudioTimeUs // returning 0 and prevent video samples from being presented. // We stop the audio track before the playback thread exits. return false; diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java index 1db1c598173..b2a888dcbb3 100644 --- a/tests/tests/media/src/android/media/cts/DecoderTest.java +++ b/tests/tests/media/src/android/media/cts/DecoderTest.java @@ -3623,7 +3623,7 @@ public class DecoderTest extends MediaPlayerTestBase { AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); mMediaCodecPlayer = new MediaCodecTunneledPlayer( - getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); + mContext, getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); Uri mediaUri = Uri.fromFile(new File(mInpPrefix, videoName)); mMediaCodecPlayer.setAudioDataSource(mediaUri, null); @@ -3692,7 +3692,7 @@ public class DecoderTest extends MediaPlayerTestBase { AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); mMediaCodecPlayer = new MediaCodecTunneledPlayer( - getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); + mContext, getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); Uri mediaUri = Uri.fromFile(new File(mInpPrefix, videoName)); mMediaCodecPlayer.setAudioDataSource(mediaUri, null); @@ -3748,7 +3748,7 @@ public class DecoderTest extends MediaPlayerTestBase { AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); mMediaCodecPlayer = new MediaCodecTunneledPlayer( - getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); + mContext, getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); Uri mediaUri = Uri.fromFile(new File(mInpPrefix, videoName)); mMediaCodecPlayer.setAudioDataSource(mediaUri, null); @@ -3826,7 +3826,7 @@ public class DecoderTest extends MediaPlayerTestBase { // Setup tunnel mode test media player AudioManager am = mContext.getSystemService(AudioManager.class); mMediaCodecPlayer = new MediaCodecTunneledPlayer( - getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); + mContext, getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); Uri mediaUri = Uri.fromFile(new File(mInpPrefix, videoName)); mMediaCodecPlayer.setAudioDataSource(mediaUri, null); @@ -3922,7 +3922,7 @@ public class DecoderTest extends MediaPlayerTestBase { AudioManager am = mContext.getSystemService(AudioManager.class); mMediaCodecPlayer = new MediaCodecTunneledPlayer( - getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); + mContext, getActivity().getSurfaceHolder(), true, am.generateAudioSessionId()); Uri mediaUri = Uri.fromFile(new File(mInpPrefix, videoName)); mMediaCodecPlayer.setAudioDataSource(mediaUri, null); diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTunneledPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecTunneledPlayer.java index bc3ae6e5c61..677e64474c0 100644 --- a/tests/tests/media/src/android/media/cts/MediaCodecTunneledPlayer.java +++ b/tests/tests/media/src/android/media/cts/MediaCodecTunneledPlayer.java @@ -15,6 +15,7 @@ */ package android.media.cts; +import android.content.Context; import android.media.AudioTimestamp; import android.media.MediaCodec; import android.media.MediaCodecInfo; @@ -64,11 +65,13 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider { private Uri mVideoUri; private boolean mTunneled; private int mAudioSessionId; + private Context mContext; /* * Media player class to playback video using tunneled MediaCodec. */ - public MediaCodecTunneledPlayer(SurfaceHolder holder, boolean tunneled, int AudioSessionId) { + public MediaCodecTunneledPlayer(Context context, SurfaceHolder holder, boolean tunneled, int AudioSessionId) { + mContext = context; mSurfaceHolder = holder; mTunneled = tunneled; mAudioTrackState = null; @@ -203,8 +206,8 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider { } } - mAudioExtractor.setDataSource(mAudioUri.toString(), mAudioHeaders); - mVideoExtractor.setDataSource(mVideoUri.toString(), mVideoHeaders); + mAudioExtractor.setDataSource(mContext, mAudioUri, mAudioHeaders); + mVideoExtractor.setDataSource(mContext, mVideoUri, mVideoHeaders); if (null == mVideoCodecStates) { mVideoCodecStates = new HashMap<Integer, CodecState>(); @@ -406,6 +409,25 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider { } } + /** + * Enables or disables looping. Should be called after {@link #prepare()}. + */ + public void setLoopEnabled(boolean enabled) { + synchronized (mState) { + if (mVideoCodecStates != null) { + for (CodecState state : mVideoCodecStates.values()) { + state.setLoopEnabled(enabled); + } + } + + if (mAudioCodecStates != null) { + for (CodecState state : mAudioCodecStates.values()) { + state.setLoopEnabled(enabled); + } + } + } + } + public void reset() { synchronized (mState) { if (mState == STATE_PLAYING) { @@ -444,7 +466,7 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider { try { mThread.join(); } catch (InterruptedException ex) { - Log.d(TAG, "mThread.join " + ex); + Log.d(TAG, "mThread.join ", ex); } } @@ -470,7 +492,7 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider { state.doSomeWork(); } } catch (IllegalStateException e) { - throw new Error("Video CodecState.doSomeWork" + e); + throw new Error("Video CodecState.doSomeWork", e); } try { @@ -478,7 +500,7 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider { state.doSomeWork(); } } catch (IllegalStateException e) { - throw new Error("Audio CodecState.doSomeWork" + e); + throw new Error("Audio CodecState.doSomeWork", e); } } diff --git a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java index e07862bacc7..dca76eeee05 100644 --- a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java +++ b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java @@ -24,6 +24,7 @@ import android.media.MediaFormat; import android.media.MediaPlayer; import android.media.cts.TestUtils.Monitor; import android.net.Uri; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.platform.test.annotations.AppModeFull; import android.platform.test.annotations.Presubmit; @@ -34,6 +35,7 @@ import android.webkit.cts.CtsTestServer; import androidx.test.filters.SmallTest; +import com.android.compatibility.common.util.ApiLevelUtil; import com.android.compatibility.common.util.MediaUtils; import org.apache.http.Header; @@ -76,6 +78,8 @@ public class NativeDecoderTest extends MediaPlayerTestBase { private static final int CONFIG_MODE_NONE = 0; private static final int CONFIG_MODE_QUEUE = 1; + private static boolean sIsAtLeastS = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S); + static final String mInpPrefix = WorkDir.getMediaDirString(); short[] mMasterBuffer; @@ -613,35 +617,42 @@ public class NativeDecoderTest extends MediaPlayerTestBase { int fd, long startOffset, long length); @Presubmit + @NonMediaMainlineTest public void testMuxerAvc() throws Exception { // IMPORTANT: this file must not have B-frames testMuxer("video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4", false); } + @NonMediaMainlineTest public void testMuxerH263() throws Exception { // IMPORTANT: this file must not have B-frames testMuxer("video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_11025hz.3gp", false); } + @NonMediaMainlineTest public void testMuxerHevc() throws Exception { // IMPORTANT: this file must not have B-frames testMuxer("video_640x360_mp4_hevc_450kbps_no_b.mp4", false); } + @NonMediaMainlineTest public void testMuxerVp8() throws Exception { testMuxer("bbb_s1_640x360_webm_vp8_2mbps_30fps_vorbis_5ch_320kbps_48000hz.webm", true); } + @NonMediaMainlineTest public void testMuxerVp9() throws Exception { testMuxer("video_1280x720_webm_vp9_csd_309kbps_25fps_vorbis_stereo_128kbps_48000hz.webm", true); } + @NonMediaMainlineTest public void testMuxerVp9NoCsd() throws Exception { testMuxer("bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm", true); } + @NonMediaMainlineTest public void testMuxerVp9Hdr() throws Exception { testMuxer("video_256x144_webm_vp9_hdr_83kbps_24fps.webm", true); } @@ -652,6 +663,7 @@ public class NativeDecoderTest extends MediaPlayerTestBase { testMuxer("video_176x144_mp4_mpeg2_105kbps_25fps_aac_stereo_128kbps_44100hz.mp4", false); } + @NonMediaMainlineTest public void testMuxerMpeg4() throws Exception { // IMPORTANT: this file must not have B-frames testMuxer("video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4", false); @@ -768,6 +780,21 @@ public class NativeDecoderTest extends MediaPlayerTestBase { } } + // before S, mpeg4 writers jammed a fixed SAR value into the output; + // this was fixed in S + if (!sIsAtLeastS) { + if (f1.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT) + && f2.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT)) { + f2.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, + f1.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT)); + } + if (f1.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH) + && f2.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)) { + f2.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, + f1.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)); + } + } + // look for f2 (the new) being a superset (>=) of f1 (the original) // ensure that all of our fields in f1 appear in f2 with the same // value. We allow f2 to contain extra fields. diff --git a/tests/tests/os/src/android/os/cts/AppHibernationIntegrationTest.kt b/tests/tests/os/src/android/os/cts/AppHibernationIntegrationTest.kt index a7e893da586..e2718df7d80 100644 --- a/tests/tests/os/src/android/os/cts/AppHibernationIntegrationTest.kt +++ b/tests/tests/os/src/android/os/cts/AppHibernationIntegrationTest.kt @@ -21,8 +21,8 @@ import android.content.Context import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager -import android.os.Build import android.net.Uri +import android.os.Build import android.platform.test.annotations.AppModeFull import android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION import android.provider.Settings @@ -114,9 +114,8 @@ class AppHibernationIntegrationTest { packageManager.getApplicationInfo(APK_PACKAGE_NAME_S_APP, 0 /* flags */) val stopped = ((ai.flags and ApplicationInfo.FLAG_STOPPED) != 0) assertTrue(stopped) - runShellCommandOrThrow("cmd statusbar expand-notifications") - waitFindObject(By.textContains("unused app")) - .click() + openUnusedAppsNotification() + waitFindObject(By.text(APK_PACKAGE_NAME_S_APP)) } } diff --git a/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt b/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt index faae778e5f2..da554097481 100644 --- a/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt +++ b/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt @@ -21,26 +21,46 @@ import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_TOP_SLEEPING import android.app.Instrumentation import android.app.UiAutomation import android.content.Context +import android.content.pm.PackageManager import android.os.ParcelFileDescriptor import android.os.Process import android.provider.DeviceConfig +import android.support.test.uiautomator.By import android.support.test.uiautomator.BySelector +import android.support.test.uiautomator.UiDevice import android.support.test.uiautomator.UiObject2 +import android.support.test.uiautomator.UiScrollable +import android.support.test.uiautomator.UiSelector +import android.support.test.uiautomator.Until import androidx.test.InstrumentationRegistry +import com.android.compatibility.common.util.ExceptionUtils.wrappingExceptions import com.android.compatibility.common.util.LogcatInspector import com.android.compatibility.common.util.SystemUtil.eventually import com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity import com.android.compatibility.common.util.ThrowingSupplier import com.android.compatibility.common.util.UiAutomatorUtils +import com.android.compatibility.common.util.UiDumpUtils import com.android.compatibility.common.util.click import com.android.compatibility.common.util.depthFirstSearch import com.android.compatibility.common.util.textAsString import org.hamcrest.Matcher import org.hamcrest.Matchers +import org.junit.Assert import org.junit.Assert.assertThat import java.io.InputStream +const val SYSUI_PKG_NAME = "com.android.systemui" +const val NOTIF_LIST_ID = "com.android.systemui:id/notification_stack_scroller" +const val CLEAR_ALL_BUTTON_ID = "dismiss_text" +// Time to find a notification. Unlikely, but in cases with a lot of notifications, it may take +// time to find the notification we're looking for +const val NOTIF_FIND_TIMEOUT = 20000L +const val VIEW_WAIT_TIMEOUT = 1000L + +const val CMD_EXPAND_NOTIFICATIONS = "cmd statusbar expand-notifications" +const val CMD_COLLAPSE = "cmd statusbar collapse" + const val APK_PATH_S_APP = "/data/local/tmp/cts/os/CtsAutoRevokeSApp.apk" const val APK_PACKAGE_NAME_S_APP = "android.os.cts.autorevokesapp" const val APK_PATH_R_APP = "/data/local/tmp/cts/os/CtsAutoRevokeRApp.apk" @@ -148,6 +168,82 @@ fun goHome() { runShellCommandOrThrow("input keyevent KEYCODE_HOME") } +/** + * Open the "unused apps" notification which is sent after the hibernation job. + */ +fun openUnusedAppsNotification() { + val notifSelector = By.textContains("unused app") + if (hasFeatureWatch()) { + val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation + expandNotificationsWatch(UiAutomatorUtils.getUiDevice()) + waitFindObject(uiAutomation, notifSelector).click() + // In wear os, notification has one additional button to open it + waitFindObject(uiAutomation, By.text("Open")).click() + } else { + runShellCommandOrThrow(CMD_EXPAND_NOTIFICATIONS) + waitFindNotification(notifSelector, NOTIF_FIND_TIMEOUT).click() + } +} + +fun hasFeatureWatch(): Boolean { + return InstrumentationRegistry.getTargetContext().packageManager.hasSystemFeature( + PackageManager.FEATURE_WATCH) +} + +private fun expandNotificationsWatch(uiDevice: UiDevice) { + with(uiDevice) { + wakeUp() + // Swipe up from bottom to reveal notifications + val x = displayWidth / 2 + swipe(x, displayHeight, x, 0, 1) + } +} + +/** + * Reset to the top of the notifications list. + */ +private fun resetNotifications(notificationList: UiScrollable) { + runShellCommandOrThrow(CMD_COLLAPSE) + notificationList.waitUntilGone(VIEW_WAIT_TIMEOUT) + runShellCommandOrThrow(CMD_EXPAND_NOTIFICATIONS) +} + +private fun waitFindNotification(selector: BySelector, timeoutMs: Long): + UiObject2 { + var view: UiObject2? = null + val start = System.currentTimeMillis() + val uiDevice = UiAutomatorUtils.getUiDevice() + + var isAtEnd = false + var wasScrolledUpAlready = false + while (view == null && start + timeoutMs > System.currentTimeMillis()) { + view = uiDevice.wait(Until.findObject(selector), VIEW_WAIT_TIMEOUT) + if (view == null) { + val notificationList = UiScrollable(UiSelector().resourceId(NOTIF_LIST_ID)) + wrappingExceptions({ cause: Throwable? -> UiDumpUtils.wrapWithUiDump(cause) }) { + Assert.assertTrue("Notification list view not found", + notificationList.waitForExists(VIEW_WAIT_TIMEOUT)) + } + if (isAtEnd) { + if (wasScrolledUpAlready) { + break + } + resetNotifications(notificationList) + isAtEnd = false + wasScrolledUpAlready = true + } else { + notificationList.scrollForward() + isAtEnd = uiDevice.hasObject(By.res(SYSUI_PKG_NAME, CLEAR_ALL_BUTTON_ID)) + } + } + } + wrappingExceptions({ cause: Throwable? -> UiDumpUtils.wrapWithUiDump(cause) }) { + Assert.assertNotNull("View not found after waiting for " + timeoutMs + "ms: " + selector, + view) + } + return view!! +} + fun waitFindObject(uiAutomation: UiAutomation, selector: BySelector): UiObject2 { try { return UiAutomatorUtils.waitFindObject(selector) diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt index e17883cfbae..d5cc564449f 100644 --- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt +++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt @@ -31,7 +31,6 @@ import android.os.Build import android.platform.test.annotations.AppModeFull import android.support.test.uiautomator.By import android.support.test.uiautomator.BySelector -import android.support.test.uiautomator.UiDevice import android.support.test.uiautomator.UiObject2 import android.support.test.uiautomator.UiObjectNotFoundException import android.view.accessibility.AccessibilityNodeInfo @@ -84,7 +83,6 @@ class AutoRevokeTest { private val context: Context = InstrumentationRegistry.getTargetContext() private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() - private val uiDevice: UiDevice = UiDevice.getInstance(instrumentation) private val mPermissionControllerResources: Resources = context.createPackageContext( context.packageManager.permissionControllerPackageName, 0).resources @@ -392,19 +390,6 @@ class AutoRevokeTest { assertPermission(PERMISSION_GRANTED) } - private fun openUnusedAppsNotification() { - if (hasFeatureWatch()) { - expandNotificationsWatch() - } else { - runShellCommandOrThrow("cmd statusbar expand-notifications") - } - waitFindObject(By.textContains("unused app")).click() - if (hasFeatureWatch()) { - // In wear os, notification has one additional button to open it - waitFindObject(By.text("Open")).click() - } - } - private fun goBack() { runShellCommandOrThrow("input keyevent KEYCODE_BACK") } @@ -500,19 +485,6 @@ class AutoRevokeTest { waitForIdle() } - private fun hasFeatureWatch(): Boolean { - return context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) - } - - private fun expandNotificationsWatch() { - with(uiDevice) { - wakeUp() - // Swipe up from bottom to reveal notifications - val x = displayWidth / 2 - swipe(x, displayHeight, x, 0, 1) - } - } - private fun assertAllowlistState(state: Boolean) { assertThat( waitFindObject(By.textStartsWith("Auto-revoke allowlisted: ")).text, diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml index 41b34e96e91..ff9bbcf29a4 100644 --- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml +++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml @@ -410,6 +410,76 @@ android:label="@string/car_permission_label_car_test_service" android:description="@string/car_permission_desc_car_test_service"/> + <permission android:name="android.car.permission.ACCESS_PRIVATE_DISPLAY_ID" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_access_private_display_id" + android:description="@string/car_permission_desc_access_private_display_id"/> + + <permission android:name="android.car.permission.MONITOR_CAR_EVS_STATUS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_monitor_evs_status" + android:description="@string/car_permission_desc_monitor_evs_status"/> + + <permission android:name="android.car.permission.CONTROL_CAR_POWER_POLICY" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_control_car_power_policy" + android:description="@string/car_permission_desc_control_car_power_policy"/> + + <permission android:name="android.car.permission.COLLECT_CAR_WATCHDOG_METRICS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_collect_car_watchdog_metrics" + android:description="@string/car_permission_desc_collect_car_watchdog_metrics"/> + + <permission android:name="android.car.permission.USE_CAR_TELEMETRY_SERVICE" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_use_telemetry_service" + android:description="@string/car_permission_desc_use_telemetry_service"/> + + <permission android:name="android.car.permission.CONTROL_CAR_EVS_ACTIVITY" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_control_evs_activity" + android:description="@string/car_permission_desc_control_evs_activity"/> + + <permission android:name="android.car.permission.REQUEST_CAR_EVS_ACTIVITY" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_request_evs_activity" + android:description="@string/car_permission_desc_request_evs_activity"/> + + <permission android:name="android.car.permission.USE_CAR_EVS_CAMERA" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_use_evs_camera" + android:description="@string/car_permission_desc_use_evs_camera"/> + + <permission android:name="android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_encryption_binding_seed" + android:description="@string/car_permission_desc_encryption_binding_seed"/> + + <permission android:name="android.car.permission.READ_CAR_POWER_POLICY" + android:protectionLevel="normal" + android:label="@string/car_permission_label_read_car_power_policy" + android:description="@string/car_permission_desc_read_car_power_policy"/> + + <permission android:name="android.car.permission.CAR_EPOCH_TIME" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_car_epoch_time" + android:description="@string/car_permission_desc_car_epoch_time"/> + + <permission android:name="android.car.permission.CONTROL_CAR_WATCHDOG_CONFIG" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_control_car_watchdog_config" + android:description="@string/car_permission_desc_control_car_watchdog_config"/> + + <permission android:name="android.car.permission.TEMPLATE_RENDERER" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_template_renderer" + android:description="@string/car_permission_desc_template_renderer"/> + + <permission android:name="android.car.permission.CAR_MONITOR_INPUT" + android:protectionLevel="signature" + android:label="@string/car_permission_label_monitor_input" + android:description="@string/car_permission_desc_monitor_input"/> + <uses-permission android:name="android.permission.CALL_PHONE"/> <uses-permission android:name="android.permission.DEVICE_POWER"/> <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS"/> diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt index ee0f2025b08..67da23047f4 100644 --- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt +++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt @@ -443,20 +443,6 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { click(By.text(permissionLabel)) - // Watch does not show an alert dialog when the user turns on permission, only when they - // turns it off. - if (isWatch) { - try { - if (waitFindObjectOrNull(By.text(permissionLabel), 1000) != null) { - continue - } - } catch (e: StaleObjectException) { - // It sometimes causes StaleObjectException when screen changes due to click - // It should be ignored, because it depends on timing - Log.w("CtsPermission3TestCases", "Caught StaleObjectException") - } - } - val wasGranted = if (isAutomotive) { // Automotive doesn't support one time permissions, and thus // won't show an "Ask every time" message @@ -557,7 +543,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { } private fun isMediaStorageButton(permission: String, targetSdk: Int): Boolean = - if (isTv) { + if (isTv || isWatch) { false } else { when (permission) { @@ -571,7 +557,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { } private fun isAllStorageButton(permission: String, targetSdk: Int): Boolean = - if (isTv) { + if (isTv || isWatch) { false } else { when (permission) { diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp index 32cd60e72a0..f383b242892 100644 --- a/tests/tests/provider/Android.bp +++ b/tests/tests/provider/Android.bp @@ -40,7 +40,8 @@ android_test { srcs: [ "src/**/*.java", - "app/GalleryTestApp/src/**/*.java"], + "app/GalleryTestApp/src/**/*.java", + "app/MultiAuthorityApp/src/**/*.java"], // uncomment when b/140885436 is fixed // sdk_version: "test_current", @@ -48,7 +49,10 @@ android_test { platform_apis: true, - data: [":CtsProviderGalleryTestApp"], + data: [ + ":CtsProviderGalleryTestApp", + ":CtsProviderMultiAuthorityApp" + ], } filegroup { diff --git a/tests/tests/provider/AndroidTest.xml b/tests/tests/provider/AndroidTest.xml index 6b763cd6d5a..a2cc5442c9d 100644 --- a/tests/tests/provider/AndroidTest.xml +++ b/tests/tests/provider/AndroidTest.xml @@ -27,6 +27,7 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsProviderTestCases.apk" /> <option name="test-file-name" value="CtsProviderGalleryTestApp.apk" /> + <option name="test-file-name" value="CtsProviderMultiAuthorityApp.apk" /> </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> diff --git a/tests/tests/provider/app/MultiAuthorityApp/Android.bp b/tests/tests/provider/app/MultiAuthorityApp/Android.bp new file mode 100644 index 00000000000..823fec4c7fb --- /dev/null +++ b/tests/tests/provider/app/MultiAuthorityApp/Android.bp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test_helper_app { + name: "CtsProviderMultiAuthorityApp", + + sdk_version: "current", + + srcs: ["**/*.java"], + + dex_preopt: { + enabled: false, + }, + optimize: { + enabled: false, + }, + min_sdk_version : "29", +} diff --git a/tests/tests/provider/app/MultiAuthorityApp/AndroidManifest.xml b/tests/tests/provider/app/MultiAuthorityApp/AndroidManifest.xml new file mode 100644 index 00000000000..b6ed4030af5 --- /dev/null +++ b/tests/tests/provider/app/MultiAuthorityApp/AndroidManifest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.provider.apps.cts.multiauthority"> + + <application> + <provider android:name=".MultiAuthorityProvider" + android:exported="true" + android:authorities="android.provider.apps.cts.multi1;android.provider.apps.cts.multi2" /> + </application> + +</manifest> diff --git a/tests/tests/provider/app/MultiAuthorityApp/src/android/provider/apps/cts/multiauthority/MultiAuthorityProvider.java b/tests/tests/provider/app/MultiAuthorityApp/src/android/provider/apps/cts/multiauthority/MultiAuthorityProvider.java new file mode 100644 index 00000000000..956df7c3832 --- /dev/null +++ b/tests/tests/provider/app/MultiAuthorityApp/src/android/provider/apps/cts/multiauthority/MultiAuthorityProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 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.provider.apps.cts.multiauthority; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class MultiAuthorityProvider extends ContentProvider { + @Override + public boolean onCreate() { + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + throw new UnsupportedOperationException(); + } + + @Override + public String getType(Uri uri) { + throw new UnsupportedOperationException(); + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + throw new UnsupportedOperationException(); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } +} diff --git a/tests/tests/provider/src/android/provider/cts/MultiAuthorityTest.java b/tests/tests/provider/src/android/provider/cts/MultiAuthorityTest.java new file mode 100644 index 00000000000..be6ff87b0bf --- /dev/null +++ b/tests/tests/provider/src/android/provider/cts/MultiAuthorityTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2021 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.provider.cts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import com.android.compatibility.common.util.SystemUtil; + +import android.app.ActivityManager; +import android.app.Instrumentation; +import android.content.ContentProviderClient; +import android.content.ContentResolver; +import android.content.Context; +import android.provider.SearchIndexableResource; + +import androidx.test.filters.SmallTest; +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class MultiAuthorityTest { + + private static final String PROVIDER1 = "android.provider.apps.cts.multi1"; + private static final String PROVIDER2 = "android.provider.apps.cts.multi2"; + private static final String PROVIDER_NONEXISTENT = "android.provider.apps.cts.multi3"; + + private Context mContext; + private ActivityManager mAm; + private ContentResolver mContentResolver; + + @Before + public void setUp() { + mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + mContentResolver = mContext.getContentResolver(); + mAm = mContext.getSystemService(ActivityManager.class); + } + + @After + public void shutDown() { + killProviderProcess(); + } + + private void killProviderProcess() { + SystemUtil.runWithShellPermissionIdentity(() -> { + mAm.forceStopPackage("android.provider.apps.cts.multiauthority"); + }); + } + + @Test + public void testAuthority1() { + ContentProviderClient cpc = mContentResolver.acquireContentProviderClient(PROVIDER1); + assertNotNull("Couldn't acquire provider", cpc); + cpc.release(); + } + + @Test + public void testAuthorityBoth() { + ContentProviderClient cpc = mContentResolver.acquireContentProviderClient(PROVIDER2); + assertNotNull("Couldn't acquire provider 2", cpc); + cpc.release(); + cpc = mContentResolver.acquireContentProviderClient(PROVIDER1); + assertNotNull("Couldn't acquire provider 1", cpc); + cpc.release(); + } + + @Test + public void testAuthorityNonExistent() { + ContentProviderClient cpc = + mContentResolver.acquireContentProviderClient(PROVIDER_NONEXISTENT); + assertNull("Could acquire non-existent provider 3!", cpc); + } +} diff --git a/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java index 97cc62a758a..49471aaeb5f 100644 --- a/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java +++ b/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java @@ -29,6 +29,7 @@ import android.database.Cursor; import android.net.Uri; import android.provider.BaseColumns; import android.provider.Telephony; +import android.telephony.TelephonyManager; import android.util.Log; /** @@ -136,7 +137,8 @@ public class SmsBackupRestoreTest extends TestCaseThatRunsIfTelephonyIsEnabled { * @throws Exception */ public void testSmsBackupRestore() throws Exception { - if (!mHasFeature) { + TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); + if (!mHasFeature || !telephonyManager.isSmsCapable()) { Log.i(TAG, "skipping testSmsBackupRestore"); return; } diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_MediaTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_MediaTest.java index f5eaa5e3da4..a196c5a2333 100644 --- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_MediaTest.java +++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Audio_MediaTest.java @@ -186,7 +186,7 @@ public class MediaStore_Audio_MediaTest { } } - @Test + @Test(timeout = 60000) public void testCanonicalize() throws Exception { // Remove all audio left over from other tests ProviderTestUtils.executeShellCommand("content delete" diff --git a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/RemovableSims.java b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/RemovableSims.java index 27a3389a1ed..d012eb631aa 100644 --- a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/RemovableSims.java +++ b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/RemovableSims.java @@ -91,7 +91,8 @@ class RemovableSims { } public List<SubscriptionInfo> getSubscriptionInfoForRemovableSims() { - if (mRemovableSubscriptionInfos == null) { + if (mRemovableSubscriptionInfos == null || + mRemovableSubscriptionInfos.size() < mRemovableSimSlotCount) { initialize(); } return mRemovableSubscriptionInfos; diff --git a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_SimRecordsTest.java b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_SimRecordsTest.java index 37ea8f685ce..9e0abfbb5ab 100644 --- a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_SimRecordsTest.java +++ b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookContract_SimRecordsTest.java @@ -48,6 +48,7 @@ import com.android.compatibility.common.util.SystemUtil; import com.google.common.collect.ImmutableList; +import org.junit.Assume; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; @@ -156,6 +157,10 @@ public class SimPhonebookContract_SimRecordsTest { @Test public void queryFdn_noFdnRecords_returnsEmptyCursor() { + try (Cursor cursor = + query(ElementaryFiles.getItemUri(mDefaultSubscriptionId, EF_FDN), null)) { + Assume.assumeTrue("SIM does not support FDN", cursor.moveToFirst()); + } try (Cursor cursor = query(SimRecords.getContentUri(mDefaultSubscriptionId, EF_FDN), null)) { assertThat(cursor).hasCount(0); diff --git a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookRequirementsRule.java b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookRequirementsRule.java index a7773b50428..1a115ccfbf2 100644 --- a/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookRequirementsRule.java +++ b/tests/tests/simphonebookprovider/src/android/provider/cts/simphonebook/SimPhonebookRequirementsRule.java @@ -26,9 +26,12 @@ import android.telephony.TelephonyManager; import androidx.test.core.app.ApplicationProvider; +import com.android.compatibility.common.util.PollingCheck; + import org.junit.rules.ExternalResource; class SimPhonebookRequirementsRule extends ExternalResource { + private static final String TAG = "SimPhonebookRequirementsRule"; private final int mMinimumSimCount; @@ -50,10 +53,19 @@ class SimPhonebookRequirementsRule extends ExternalResource { // DSDS or DSDA (e.g. crosshatch and blueline). assumeThat("not enough SIMs", telephonyManager.getSupportedModemCount(), greaterThanOrEqualTo(mMinimumSimCount)); - RemovableSims removableSims = new RemovableSims(context); - assumeThat(removableSims.getRemovableSimSlotCount(), + RemovableSims removableSims = new RemovableSims(context); + assumeThat("Device does not have enough SIMs.", + removableSims.getRemovableSimSlotCount(), greaterThanOrEqualTo(mMinimumSimCount)); + try { + // Poll for a bit in case it takes a while for the SIMs to be initialized. + PollingCheck.waitFor(30_000, + () -> removableSims + .getSubscriptionInfoForRemovableSims().size() >= mMinimumSimCount); + } catch (AssertionError e) { + // Swallowed here because the assert that follows validates the same thing. + } assertWithMessage("A SIM must be installed in each SIM slot") .that(removableSims.getSubscriptionInfoForRemovableSims().size()) .isAtLeast(mMinimumSimCount); diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml index ad9f709a7f0..96a07b36904 100644 --- a/tests/tests/telecom/AndroidManifest.xml +++ b/tests/tests/telecom/AndroidManifest.xml @@ -42,6 +42,7 @@ <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> + <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" /> <application> <uses-library android:name="android.test.runner"/> diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java index d63f8ef845f..0b74a9e69d5 100644 --- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java +++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java @@ -283,6 +283,12 @@ public class TestUtils { public static final String ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION_STRING = "ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION "; + /** + * See {@link TelecomManager#ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION} + */ + public static final String ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION_STRING = + "ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION "; + private static final String COMMAND_SET_CALL_DIAGNOSTIC_SERVICE = "telecom set-call-diagnostic-service "; diff --git a/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java b/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java index 9be176b2bc7..8e2d759168c 100644 --- a/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java +++ b/tests/tests/telecom2/src/android/telecom/cts/TelecomManagerNoPermissionsTest.java @@ -19,6 +19,7 @@ package android.telecom.cts; import android.content.Context; import android.telecom.TelecomManager; import android.test.InstrumentationTestCase; +import android.util.Log; /** * Verifies correct operation of TelecomManager APIs when the correct permissions have not been @@ -89,4 +90,37 @@ public class TelecomManagerNoPermissionsTest extends InstrumentationTestCase { TestUtils.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION_STRING); } } + + public void testGetPhoneAccountCompatPermissions() throws Exception { + if (!TestUtils.shouldTestTelecom(mContext)) { + return; + } + + try { + TestUtils.enableCompatCommand(getInstrumentation(), + TestUtils.ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION_STRING); + + try { + mTelecomManager.getPhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1); + fail("TelecomManager#getPhoneAccount should require READ_PHONE_NUMBERS or " + + "READ_PRIVILEGED_PHONE_STATE when " + + "ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION is enabled"); + } catch (SecurityException e) { + //expected + } + + TestUtils.disableCompatCommand(getInstrumentation(), + TestUtils.ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION_STRING); + try { + mTelecomManager.getPhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1); + } catch (SecurityException e) { + fail("TelecomManager#getPhoneAccount shouldn't require READ_PHONE_NUMBERS or " + + "READ_PRIVILEGED_PHONE_STATE when " + + "ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION is disabled"); + } + } finally { + TestUtils.resetCompatCommand(getInstrumentation(), + TestUtils.ENABLE_GET_PHONE_ACCOUNT_PERMISSION_PROTECTION_STRING); + } + } } diff --git a/tests/tests/vcn/src/android/net/vcn/cts/TestNetworkWrapper.java b/tests/tests/vcn/src/android/net/vcn/cts/TestNetworkWrapper.java index 6d0a95743e4..52b6245a186 100644 --- a/tests/tests/vcn/src/android/net/vcn/cts/TestNetworkWrapper.java +++ b/tests/tests/vcn/src/android/net/vcn/cts/TestNetworkWrapper.java @@ -18,9 +18,6 @@ package android.net.vcn.cts; import static android.net.cts.util.CtsNetUtils.TestNetworkCallback; -import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity; -import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; - import android.annotation.NonNull; import android.content.Context; import android.net.ConnectivityManager; @@ -106,9 +103,7 @@ public class TestNetworkWrapper implements AutoCloseable { throws Exception { mConnectivityManager = context.getSystemService(ConnectivityManager.class); mVcnManager = context.getSystemService(VcnManager.class); - mTestNetworkManager = - callWithShellPermissionIdentity( - () -> context.getSystemService(TestNetworkManager.class)); + mTestNetworkManager = context.getSystemService(TestNetworkManager.class); try { final LinkAddress linkAddress = @@ -116,49 +111,31 @@ public class TestNetworkWrapper implements AutoCloseable { localAddress, localAddress instanceof Inet4Address ? IP4_PREFIX_LEN : IP6_PREFIX_LEN); final TestNetworkInterface tni = - callWithShellPermissionIdentity( - () -> { - return mTestNetworkManager.createTunInterface( - Arrays.asList(linkAddress)); - }); + mTestNetworkManager.createTunInterface(Arrays.asList(linkAddress)); tunFd = tni.getFileDescriptor(); final String iface = tni.getInterfaceName(); - vcnNetworkCallback = - callWithShellPermissionIdentity( - () -> { - final NetworkRequest nr = - new NetworkRequest.Builder(TEST_NETWORK_REQUEST) - .setNetworkSpecifier(iface) - .build(); - final VcnTestNetworkCallback cb = new VcnTestNetworkCallback(); - mConnectivityManager.requestNetwork(nr, cb); - return cb; - }); + final NetworkRequest nr = + new NetworkRequest.Builder(TEST_NETWORK_REQUEST) + .setNetworkSpecifier(iface) + .build(); + vcnNetworkCallback = new VcnTestNetworkCallback(); + mConnectivityManager.requestNetwork(nr, vcnNetworkCallback); final NetworkCapabilities nc = createNetworkCapabilitiesForIface(iface, isMetered, subIds); final LinkProperties lp = createLinkPropertiesForIface(iface, mtu); + final VcnNetworkPolicyResult policy = mVcnManager.applyVcnNetworkPolicy(nc, lp); + if (policy.isTeardownRequested()) { + throw new IllegalStateException("Restart requested in bringup"); + } + mTestNetworkAgent = - callWithShellPermissionIdentity( - () -> { - final VcnNetworkPolicyResult policy = - mVcnManager.applyVcnNetworkPolicy(nc, lp); - if (policy.isTeardownRequested()) { - throw new IllegalStateException("Restart requested in bringup"); - } - - final TestNetworkAgent agent = - new TestNetworkAgent( - context, - Looper.getMainLooper(), - policy.getNetworkCapabilities(), - lp); - agent.register(); - agent.markConnected(); - return agent; - }); + new TestNetworkAgent( + context, Looper.getMainLooper(), policy.getNetworkCapabilities(), lp); + mTestNetworkAgent.register(); + mTestNetworkAgent.markConnected(); tunNetwork = vcnNetworkCallback.waitForAvailable(); mCloseGuard.open(TAG); @@ -232,42 +209,40 @@ public class TestNetworkWrapper implements AutoCloseable { @Override public void close() { mCloseGuard.close(); - runWithShellPermissionIdentity( - () -> { - if (vcnNetworkCallback != null) { - try { - mConnectivityManager.unregisterNetworkCallback(vcnNetworkCallback); - } catch (Exception e) { - Log.e(TAG, "Failed to unregister Network CB", e); - } - } - if (mTestNetworkAgent != null) { - synchronized (mTestNetworkAgent) { - try { - mTestNetworkAgent.teardown(); - } catch (Exception e) { - Log.e(TAG, "Failed to unregister TestNetworkAgent", e); - } - } - } + if (vcnNetworkCallback != null) { + try { + mConnectivityManager.unregisterNetworkCallback(vcnNetworkCallback); + } catch (Exception e) { + Log.e(TAG, "Failed to unregister Network CB", e); + } + } - if (tunNetwork != null) { - try { - mTestNetworkManager.teardownTestNetwork(tunNetwork); - } catch (Exception e) { - Log.e(TAG, "Failed to tear down Test Network", e); - } - } + if (mTestNetworkAgent != null) { + synchronized (mTestNetworkAgent) { + try { + mTestNetworkAgent.teardown(); + } catch (Exception e) { + Log.e(TAG, "Failed to unregister TestNetworkAgent", e); + } + } + } - if (tunFd != null) { - try { - tunFd.close(); - } catch (Exception e) { - Log.e(TAG, "Failed to close Test Network FD", e); - } - } - }); + if (tunNetwork != null) { + try { + mTestNetworkManager.teardownTestNetwork(tunNetwork); + } catch (Exception e) { + Log.e(TAG, "Failed to tear down Test Network", e); + } + } + + if (tunFd != null) { + try { + tunFd.close(); + } catch (Exception e) { + Log.e(TAG, "Failed to close Test Network FD", e); + } + } } @Override @@ -321,11 +296,9 @@ public class TestNetworkWrapper implements AutoCloseable { @Override public void onNetworkUnwanted() { - // Not guaranteed to be called from the same thread, so synchronize on this. The shell - // is needed for teardown because unregistering the VcnPolicyListener requires - // permission MANAGE_TEST_NETWORKS. + // Not guaranteed to be called from the same thread, so synchronize on this. synchronized (this) { - runWithShellPermissionIdentity(() -> teardown()); + teardown(); } } @@ -353,24 +326,19 @@ public class TestNetworkWrapper implements AutoCloseable { private class TestVcnNetworkPolicyChangeListener implements VcnNetworkPolicyChangeListener { @Override public void onPolicyChanged() { - runWithShellPermissionIdentity( - () -> { - synchronized (TestNetworkAgent.this) { - final VcnNetworkPolicyResult policy = - mVcnManager.applyVcnNetworkPolicy( - mTestNetworkAgent.getNetworkCapabilities(), - mTestNetworkAgent.getLinkProperties()); - if (policy.isTeardownRequested()) { - Log.w( - POLICY_LISTENER_TAG, - "network teardown requested on policy change"); - teardown(); - return; - } - - updateNetworkCapabilities(policy.getNetworkCapabilities()); - } - }); + synchronized (TestNetworkAgent.this) { + final VcnNetworkPolicyResult policy = + mVcnManager.applyVcnNetworkPolicy( + mTestNetworkAgent.getNetworkCapabilities(), + mTestNetworkAgent.getLinkProperties()); + if (policy.isTeardownRequested()) { + Log.w(POLICY_LISTENER_TAG, "network teardown requested on policy change"); + teardown(); + return; + } + + updateNetworkCapabilities(policy.getNetworkCapabilities()); + } } } } diff --git a/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java b/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java index 9bf818ddab3..7fec0011b09 100644 --- a/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java +++ b/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java @@ -23,6 +23,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import static org.junit.Assert.assertEquals; @@ -96,12 +98,19 @@ public class VcnManagerTest extends VcnTestBase { @Before public void setUp() throws Exception { assumeTrue(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY)); + + getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(); } @After public void tearDown() throws Exception { - if (mTestNetworkWrapper != null) { - mTestNetworkWrapper.close(); + try { + if (mTestNetworkWrapper != null) { + mTestNetworkWrapper.close(); + mTestNetworkWrapper = null; + } + } finally { + getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); } } @@ -172,6 +181,9 @@ public class VcnManagerTest extends VcnTestBase { @Test(expected = SecurityException.class) public void testAddVcnNetworkPolicyChangeListener_noNetworkFactoryPermission() throws Exception { + // Drop shell permission identity to test unpermissioned behavior. + getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); + final TestVcnNetworkPolicyChangeListener listener = new TestVcnNetworkPolicyChangeListener(); @@ -192,6 +204,9 @@ public class VcnManagerTest extends VcnTestBase { @Test(expected = SecurityException.class) public void testApplyVcnNetworkPolicy_noNetworkFactoryPermission() throws Exception { + // Drop shell permission identity to test unpermissioned behavior. + getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); + final NetworkCapabilities nc = new NetworkCapabilities.Builder().build(); final LinkProperties lp = new LinkProperties(); @@ -334,7 +349,7 @@ public class VcnManagerTest extends VcnTestBase { true /* expectNotVcnManaged */, false /* expectNotMetered */); - CarrierPrivilegeUtils.withCarrierPrivileges(mContext, subId, () -> { + CarrierPrivilegeUtils.withCarrierPrivilegesForShell(mContext, subId, () -> { SubscriptionGroupUtils.withEphemeralSubscriptionGroup(mContext, subId, (subGrp) -> { mVcnManager.setVcnConfig(subGrp, buildVcnConfig()); diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml index 02f38cdfa1d..5b84e13d571 100644 --- a/tests/tests/view/AndroidManifest.xml +++ b/tests/tests/view/AndroidManifest.xml @@ -17,6 +17,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.view.cts" + xmlns:tools="http://schemas.android.com/tools" android:targetSandboxVersion="2"> <uses-permission android:name="android.permission.CAMERA"/> @@ -447,6 +448,13 @@ </intent-filter> </activity> + <!-- Overrides the activity declaration in AndroidX test library to remove the starting + animation. --> + <activity + android:name="androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity" + tools:replace="android:theme" + android:theme="@style/WhiteBackgroundTheme" /> + <service android:name="android.view.textclassifier.cts.CtsTextClassifierService" android:exported="true" android:permission="android.permission.BIND_TEXTCLASSIFIER_SERVICE"> diff --git a/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java index 7a3ba981bd3..b8223a78a35 100644 --- a/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java +++ b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java @@ -16,6 +16,7 @@ package android.view.cts; +import static android.server.wm.ActivityManagerTestBase.createFullscreenActivityScenarioRule; import static android.view.cts.util.ASurfaceControlTestUtils.applyAndDeleteSurfaceTransaction; import static android.view.cts.util.ASurfaceControlTestUtils.createSurfaceTransaction; import static android.view.cts.util.ASurfaceControlTestUtils.nSurfaceControl_acquire; @@ -66,7 +67,7 @@ import android.view.cts.surfacevalidator.ASurfaceControlTestActivity.PixelChecke import android.view.cts.surfacevalidator.PixelColor; import android.view.cts.util.ASurfaceControlTestUtils; -import androidx.test.rule.ActivityTestRule; +import androidx.test.ext.junit.rules.ActivityScenarioRule; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; @@ -94,8 +95,8 @@ public class ASurfaceControlTest { private static final int DEFAULT_LAYOUT_HEIGHT = 100; @Rule - public ActivityTestRule<ASurfaceControlTestActivity> mActivityRule = - new ActivityTestRule<>(ASurfaceControlTestActivity.class); + public ActivityScenarioRule<ASurfaceControlTestActivity> mActivityRule = + createFullscreenActivityScenarioRule(ASurfaceControlTestActivity.class); @Rule public TestName mName = new TestName(); @@ -104,7 +105,7 @@ public class ASurfaceControlTest { @Before public void setup() { - mActivity = mActivityRule.getActivity(); + mActivityRule.getScenario().onActivity(activity -> mActivity = activity); } /////////////////////////////////////////////////////////////////////////// diff --git a/tests/translation/src/android/translation/cts/unittests/TranslationCapabilityTest.java b/tests/translation/src/android/translation/cts/unittests/TranslationCapabilityTest.java index 14c9bcfe555..f24d36e8cad 100644 --- a/tests/translation/src/android/translation/cts/unittests/TranslationCapabilityTest.java +++ b/tests/translation/src/android/translation/cts/unittests/TranslationCapabilityTest.java @@ -34,20 +34,20 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class TranslationCapabilityTest { - private final TranslationSpec sourceSpec = + private final TranslationSpec mSourceSpec = new TranslationSpec(ULocale.ENGLISH, TranslationSpec.DATA_FORMAT_TEXT); - private final TranslationSpec targetSpec = + private final TranslationSpec mTargetSpec = new TranslationSpec(ULocale.FRENCH, TranslationSpec.DATA_FORMAT_TEXT); @Test public void testCapability_nullSpecs() { assertThrows(NullPointerException.class, () -> new TranslationCapability(TranslationCapability.STATE_AVAILABLE_TO_DOWNLOAD, - null, targetSpec, /* uiTranslationEnabled= */ true, + null, mTargetSpec, /* uiTranslationEnabled= */ true, /* supportedTranslationFlags= */ 0)); assertThrows(NullPointerException.class, () -> new TranslationCapability(TranslationCapability.STATE_AVAILABLE_TO_DOWNLOAD, - sourceSpec, null,/* uiTranslationEnabled= */ true, + mSourceSpec, null,/* uiTranslationEnabled= */ true, /* supportedTranslationFlags= */ 0)); } @@ -55,7 +55,7 @@ public class TranslationCapabilityTest { public void testCapability_validCapability() { final TranslationCapability capability = new TranslationCapability(TranslationCapability.STATE_AVAILABLE_TO_DOWNLOAD, - sourceSpec, targetSpec,/* uiTranslationEnabled= */ true, + mSourceSpec, mTargetSpec,/* uiTranslationEnabled= */ true, TranslationContext.FLAG_TRANSLITERATION); assertThat(capability.getState()) @@ -77,7 +77,7 @@ public class TranslationCapabilityTest { public void testParceledCapability() { final TranslationCapability capability = new TranslationCapability(TranslationCapability.STATE_AVAILABLE_TO_DOWNLOAD, - sourceSpec, targetSpec,/* uiTranslationEnabled= */ true, + mSourceSpec, mTargetSpec,/* uiTranslationEnabled= */ true, TranslationContext.FLAG_TRANSLITERATION); assertThat(capability.getState()) @@ -115,4 +115,25 @@ public class TranslationCapabilityTest { assertThat(parceledCapability.getTargetSpec().getDataFormat()) .isEqualTo(TranslationSpec.DATA_FORMAT_TEXT); } + + @Test + public void testCapability_allModelStates() { + new TranslationCapability(TranslationCapability.STATE_AVAILABLE_TO_DOWNLOAD, + mSourceSpec, mTargetSpec, /* uiTranslationEnabled= */ true, + /* supportedTranslationFlags= */ 0); + new TranslationCapability(TranslationCapability.STATE_DOWNLOADING, + mSourceSpec, mTargetSpec,/* uiTranslationEnabled= */ true, + /* supportedTranslationFlags= */ 0); + new TranslationCapability(TranslationCapability.STATE_ON_DEVICE, + mSourceSpec, mTargetSpec, /* uiTranslationEnabled= */ true, + /* supportedTranslationFlags= */ 0); + new TranslationCapability(TranslationCapability.STATE_NOT_AVAILABLE, + mSourceSpec, mTargetSpec,/* uiTranslationEnabled= */ true, + /* supportedTranslationFlags= */ 0); + + // TODO: Remove magic constant and expose to test api later + new TranslationCapability(/* STATE_REMOVED_AND_AVAILABLE= */ 1000, + mSourceSpec, mTargetSpec, /* uiTranslationEnabled= */ true, + /* supportedTranslationFlags= */ 0); + } } |