Skip to content

Commit c1320b3

Browse files
author
Peter Li
committed
Add AAE tests
Fix: 122968161 Test: Manual Change-Id: I312be0511d660926a9a607a27ef34a8a89683dcc
1 parent f77ddb8 commit c1320b3

File tree

7 files changed

+218
-5
lines changed

7 files changed

+218
-5
lines changed

mediacontroller/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ android {
2828

2929
defaultConfig {
3030
applicationId "com.example.android.mediacontroller"
31-
minSdkVersion 17
31+
minSdkVersion 21
3232
targetSdkVersion 28
3333
versionCode 1
3434
versionName "1.0"

mediacontroller/src/main/java/com/example/android/mediacontroller/MediaAppDetails.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ public static ServiceInfo findServiceInfo(String packageName, PackageManager pm)
112112
return null;
113113
}
114114

115+
public static ResolveInfo findPreferenceResolveInfo(String packageName, PackageManager pm) {
116+
if (packageName != null) {
117+
Intent prefsIntent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES);
118+
prefsIntent.setPackage(packageName);
119+
return pm.resolveActivity(prefsIntent, 0);
120+
}
121+
return null;
122+
}
123+
115124
private MediaAppDetails(final Parcel parcel) {
116125
packageName = parcel.readString();
117126
appName = parcel.readString();

mediacontroller/src/main/java/com/example/android/mediacontroller/MediaAppTestDetails.kt

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ import android.support.v4.media.session.MediaControllerCompat
2626
import android.support.v4.media.session.PlaybackStateCompat
2727
import com.example.android.mediacontroller.Test.Companion.androidResources
2828
import kotlin.math.abs
29+
import android.content.Context
30+
import android.content.pm.PackageManager
31+
import android.graphics.drawable.VectorDrawable
32+
import android.util.TypedValue
33+
import java.util.*
2934

3035
/**
3136
* This is where verification tests are managed and configured
@@ -908,4 +913,106 @@ class WaitForTerminalAtTarget(override val test: Test) : TestStep {
908913
}
909914
}
910915
}
911-
}
916+
}
917+
918+
/**
919+
* PASS: An activity with the filter Intent.ACTION_APPLICATION_PREFERENCES is found
920+
* FAIL: otherwise
921+
*/
922+
class CheckForPreferences(override val test: Test,
923+
val appDetails: MediaAppDetails?,
924+
val packageManager: PackageManager) : TestStep {
925+
override val logTag = "${test.name}.WFPB"
926+
override fun execute(
927+
currState: PlaybackStateCompat?,
928+
currMetadata: MediaMetadataCompat?
929+
): TestStepStatus {
930+
val info = MediaAppDetails.findPreferenceResolveInfo(
931+
appDetails?.packageName, packageManager)
932+
933+
if (info != null) {
934+
test.testLogger(logTag, androidResources.getString(R.string.test_preferences_found))
935+
return TestStepStatus.STEP_PASS
936+
}
937+
938+
test.testLogger(logTag, androidResources.getString(R.string.test_preferences_not_found))
939+
return TestStepStatus.STEP_FAIL
940+
}
941+
}
942+
943+
/**
944+
* PASS: custom actions icons are all vector images
945+
* FAIL: otherwise
946+
*/
947+
class CheckCustomActions(override val test: Test, val context: Context, val appDetails: MediaAppDetails?) : TestStep {
948+
override val logTag = "${test.name}.WFPB"
949+
override fun execute(
950+
currState: PlaybackStateCompat?,
951+
currMetadata: MediaMetadataCompat?
952+
): TestStepStatus {
953+
val customActions = test.mediaController.playbackState.customActions
954+
val value = TypedValue()
955+
956+
if (customActions.isEmpty()) {
957+
test.testLogger(logTag, androidResources.getString(R.string.test_empty_custom_actions))
958+
}
959+
960+
var testStatus = TestStepStatus.STEP_PASS
961+
962+
val resources = context.packageManager.getResourcesForApplication(appDetails?.packageName)
963+
for (action in customActions) {
964+
try {
965+
val drawable = resources.getDrawable(action.icon, null)
966+
resources.getValue(action.icon, value, true)
967+
var filename = value.string.toString()
968+
969+
if (drawable !is VectorDrawable) {
970+
test.testLogger(logTag, androidResources.getString(
971+
R.string.test_invalid_icon_type, filename))
972+
testStatus = TestStepStatus.STEP_FAIL
973+
}
974+
} catch (notFound: Resources.NotFoundException) {
975+
test.testLogger(logTag, androidResources.getString(
976+
R.string.test_warn_icon_null, action.icon.toString()))
977+
testStatus = TestStepStatus.STEP_FAIL
978+
}
979+
}
980+
981+
return testStatus
982+
}
983+
}
984+
985+
/**
986+
* PASS: state must be STATE_ERROR and label and intent are found
987+
* CONTINUE: any state other than STATE_ERROR
988+
* FAIL: state is in STATE_ERROR but label and intent are not found
989+
*/
990+
class CheckErrorResolution(override val test: Test) : TestStep {
991+
override val logTag = "${test.name}.WFPB"
992+
override fun execute(
993+
currState: PlaybackStateCompat?,
994+
currMetadata: MediaMetadataCompat?
995+
): TestStepStatus {
996+
if (currState?.state != PlaybackStateCompat.STATE_ERROR) {
997+
test.testLogger(logTag, androidResources.getString(R.string.test_warn_not_state_error))
998+
return TestStepStatus.STEP_CONTINUE
999+
}
1000+
1001+
val label = currState?.extras?.get("android.media.extras.ERROR_RESOLUTION_ACTION_LABEL")
1002+
val intent = currState?.extras?.get("android.media.extras.ERROR_RESOLUTION_ACTION_INTENT")
1003+
1004+
if (label != null && intent != null) {
1005+
return TestStepStatus.STEP_PASS
1006+
}
1007+
1008+
if (label == null) {
1009+
test.testLogger(logTag, androidResources.getString(R.string.test_error_label_not_found))
1010+
}
1011+
if (intent == null) {
1012+
test.testLogger(logTag, androidResources.getString(
1013+
R.string.test_error_intent_not_found))
1014+
}
1015+
1016+
return TestStepStatus.STEP_FAIL
1017+
}
1018+
}

mediacontroller/src/main/java/com/example/android/mediacontroller/MediaAppTestingActivity.kt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,25 @@ class MediaAppTestingActivity : AppCompatActivity() {
520520
getString(R.string.seek_test_desc)
521521
) { query -> runSeekToTest(query, controller, ::logTestUpdate) }
522522

523+
/**
524+
* AAE SPECIFIC TESTS
525+
*/
526+
val errorResolutionDataTest = TestOptionDetails(
527+
getString(R.string.error_resolution_test_title),
528+
getString(R.string.error_resolution_test_desc)
529+
) { _ -> runErrorResolutionDataTest(controller, ::logTestUpdate) }
530+
531+
val customActionIconTypeTest = TestOptionDetails(
532+
getString(R.string.custom_actions_icon_test_title),
533+
getString(R.string.custom_actions_icon_test_desc)
534+
) { _ -> runCustomActionIconTypeTest(
535+
applicationContext, controller, mediaAppDetails, ::logTestUpdate) }
536+
537+
val preferenceTest = TestOptionDetails(
538+
getString(R.string.preference_activity_test_title),
539+
getString(R.string.preference_activity_test_desc)
540+
) { _ -> runPreferenceTest(controller, mediaAppDetails, packageManager, ::logTestUpdate) }
541+
523542
val testOptionAdapter = TestOptionAdapter(arrayOf(
524543
playTest,
525544
playFromSearch,
@@ -530,7 +549,10 @@ class MediaAppTestingActivity : AppCompatActivity() {
530549
skipToNextTest,
531550
skipToPrevTest,
532551
skipToItemTest,
533-
seekToTest
552+
seekToTest,
553+
errorResolutionDataTest,
554+
customActionIconTypeTest,
555+
preferenceTest
534556
))
535557

536558
val testList = test_options_list

mediacontroller/src/main/java/com/example/android/mediacontroller/MediaAppTests.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package com.example.android.mediacontroller
1717

18+
import android.content.Context
19+
import android.content.pm.PackageManager
1820
import android.support.v4.media.session.MediaControllerCompat
1921

2022
/**
@@ -116,4 +118,35 @@ fun runSeekToTest(
116118
.apply {
117119
addStep(ConfigureSeekTo(this, query))
118120
addStep(WaitForTerminalAtTarget(this))
119-
}.runTest()
121+
}.runTest()
122+
123+
fun runErrorResolutionDataTest(
124+
controller: MediaControllerCompat,
125+
logger: (tag: String, message: String) -> Unit?
126+
) = Test(Test.androidResources
127+
.getString(R.string.error_resolution_test_logs_title), controller, logger)
128+
.apply {
129+
addStep(CheckErrorResolution(this))
130+
}.runTest()
131+
132+
fun runCustomActionIconTypeTest(
133+
context: Context,
134+
controller: MediaControllerCompat,
135+
appDetails: MediaAppDetails?,
136+
logger: (tag: String, message: String) -> Unit?
137+
) = Test(Test.androidResources
138+
.getString(R.string.custom_actions_icon_test_logs_title), controller, logger)
139+
.apply {
140+
addStep(CheckCustomActions(this, context, appDetails))
141+
}.runTest()
142+
143+
fun runPreferenceTest(
144+
controller: MediaControllerCompat,
145+
appDetails: MediaAppDetails?,
146+
packageManager: PackageManager,
147+
logger: (tag: String, message: String) -> Unit?
148+
) = Test(Test.androidResources
149+
.getString(R.string.preference_activity_test_logs_title), controller, logger)
150+
.apply {
151+
addStep(CheckForPreferences(this, appDetails, packageManager))
152+
}.runTest()

mediacontroller/src/main/java/com/example/android/mediacontroller/TestUtils.kt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.example.android.mediacontroller
1717

18+
import android.os.Bundle
1819
import android.support.v4.media.MediaMetadataCompat
1920
import android.support.v4.media.session.MediaControllerCompat
2021
import android.support.v4.media.session.MediaSessionCompat
@@ -217,6 +218,28 @@ fun shuffleModeToName(mode: Int?): String {
217218
}
218219
}
219220

221+
fun formatPlaybackStateExtras(extras: Bundle?): String {
222+
if (extras == null) {
223+
return "null"
224+
}
225+
226+
var out = ""
227+
for (key in extras.keySet()) {
228+
out += "${key}: ${extras.get(key)} \n"
229+
}
230+
231+
return out
232+
}
233+
234+
fun formatActions(actions: List<PlaybackStateCompat.CustomAction>): String {
235+
var out = ""
236+
for (action in actions) {
237+
out += "${action.icon} "
238+
}
239+
240+
return out
241+
}
242+
220243
fun formatPlaybackState(state: PlaybackStateCompat?): String {
221244
if (state == null) {
222245
return "!null!"
@@ -240,7 +263,9 @@ fun formatPlaybackState(state: PlaybackStateCompat?): String {
240263
+ "\nLast Position Update Time: " + state.lastPositionUpdateTime
241264
+ "\nPlayback Speed: " + state.playbackSpeed
242265
+ "\nActive Queue Item ID: " + state.activeQueueItemId
243-
+ "\nActions: " + actionsToString(state.actions))
266+
+ "\nActions: " + actionsToString(state.actions)
267+
+ "\nExtras: " + formatPlaybackStateExtras(state.extras)
268+
+ "\nCustomActions: " + formatActions(state.customActions))
244269
}
245270

246271
fun formatPlaybackStateParsable(state: PlaybackStateCompat?): String {

mediacontroller/src/main/res/values/testing_strings.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
<string name="skip_prev_test_desc">This tests the \'skip to previous\' functionality.</string>
6464
<string name="skip_item_test_desc">This tests the \'skip to queue item\' functionality. Enter a Queue ID number in the query field to skip the according queue item.</string>
6565
<string name="seek_test_desc">This tests the \'seek to\' functionality. Enter a timestamp in seconds or a change in position (number of seconds prepended by + to go forward or - to go back) in the query field.</string>
66+
<string name="error_resolution_test_desc">This tests whether PlaybackState has the required extras for error resolution</string>
67+
<string name="custom_actions_icon_test_desc">This tests whether the icon types for custom actions are vector xmls</string>
68+
<string name="preference_activity_test_desc">This tests whether the activity implements a preference activity</string>
6669

6770
<!-- Test Titles -->
6871
<string name="play_test_title">Play Test</string>
@@ -75,6 +78,9 @@
7578
<string name="skip_prev_test_title">Skip To Previous Test</string>
7679
<string name="skip_item_test_title">Skip To Queue Item Test</string>
7780
<string name="seek_test_title">Seek To Test</string>
81+
<string name="error_resolution_test_title">Error Resolution Extras Test</string>
82+
<string name="custom_actions_icon_test_title">Custom Action Icon Type Test</string>
83+
<string name="preference_activity_test_title">Preference Activity Test</string>
7884

7985
<!-- Test Logging Headers -->
8086
<string name="play_test_logs_title">Play</string>
@@ -87,6 +93,9 @@
8793
<string name="skip_prev_test_logs_title">SkipPrev</string>
8894
<string name="skip_item_test_logs_title">SkipItem</string>
8995
<string name="seek_test_logs_title">Seek</string>
96+
<string name="error_resolution_test_logs_title">ErrorResolutionExtras</string>
97+
<string name="custom_actions_icon_test_logs_title">CustomActionIcons</string>
98+
<string name="preference_activity_test_logs_title">PreferenceActivity</string>
9099

91100
<!-- Test States -->
92101
<string name="test_starting">Starting test with state %s and metadata %s</string>
@@ -99,6 +108,8 @@
99108
<string name="test_warn_action_unsupported">Warning: %s is not supported</string>
100109
<string name="test_warn_action_none">Warning: No actions supported</string>
101110
<string name="test_warn_state_diff">Warning: Step did not end with the same state, %s, in which the Test began, %s</string>
111+
<string name="test_warn_not_state_error">Warning: This test requires playback state to be in STATE_ERROR</string>
112+
<string name="test_warn_icon_null">Warning: Custom action icon resource not found %s</string>
102113

103114
<!-- Test Errors -->
104115
<string name="test_error_query_empty">Error: empty query</string>
@@ -116,6 +127,12 @@
116127
<string name="test_metadata_updated">Running: Metadata updated</string>
117128
<string name="test_metadata_changed">Running: Metadata changed</string>
118129
<string name="test_compare_metadata">Comparing original metadata %s to current metadata %s</string>
130+
<string name="test_empty_custom_actions">Application does not have any custom actions</string>
131+
<string name="test_preferences_found">Activity matching preference filter found</string>
132+
<string name="test_preferences_not_found">Activity matching preference filter not found</string>
133+
<string name="test_error_label_not_found">Error resolution label does not exist</string>
134+
<string name="test_error_intent_not_found">Error resolution intent does not exist</string>
135+
<string name="test_invalid_icon_type">Custom action icon must be a vector image %s"</string>
119136

120137
<!-- Test Step Status -->
121138
<string name="test_step_pass_state">Passed: %s</string>

0 commit comments

Comments
 (0)