diff options
20 files changed, 1621 insertions, 20 deletions
diff --git a/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py index f8a97e41aa0..065f8549b8c 100644 --- a/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py +++ b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py @@ -118,7 +118,7 @@ def main(): dist_max = math.sqrt(pow(w, 2)+pow(h, 2))/2 for spb_ct in SPB_CT_LIST: # list sample block center location - num_sample = (1-spb_ct*2)/spb_r/2 + 1 + num_sample = int(numpy.asscalar((1-spb_ct*2)/spb_r/2 + 1)) ct_cord_x = numpy.concatenate( (numpy.arange(spb_ct, 1-spb_ct+spb_r, spb_r*2), spb_ct*numpy.ones((num_sample-1)), diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index a7a8cc1f37f..cc62cef8786 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -125,6 +125,8 @@ <meta-data android:name="test_category" android:value="@string/test_category_device_admin" /> <meta-data android:name="test_required_features" android:value="android.software.device_admin" /> + <meta-data android:name="test_excluded_features" + android:value="android.hardware.type.watch" /> </activity> <activity android:name=".admin.ScreenLockTestActivity" diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java index 1ca394ac649..b9988f8f15a 100644 --- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java +++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/OptionHelper.java @@ -108,7 +108,7 @@ public final class OptionHelper { // match -option=value or --option=value "((-[-\\w]+([ =]" // allow -option "...", -option x y z, and -option x:y:z - + "(" + quoteMatching + "|([\\w\\s:.]|"+ nonSpacedHypen + ")+))?" + + "(" + quoteMatching + "|([\\w\\/\\s:.]|"+ nonSpacedHypen + ")+))?" + "))|" // allow anything in direct quotes + quoteMatching diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java index d8cafa09b0b..3645458d54e 100644 --- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java +++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/util/OptionHelperTest.java @@ -33,6 +33,7 @@ public class OptionHelperTest extends TestCase { private static final String TEST_CLASS = "test-class"; private static final String TEST_CLASS_SHORTNAME = "c"; private static final String TEST_FILTER = "test-filter"; + private static final String TEST_LOGPATH = "test-logpath"; private static final String TEST_NAME = "test-name"; private static final String TEST_SUITE = "test-suite"; private static final String TEST_SUITE_SHORTNAME = "s"; @@ -55,11 +56,16 @@ public class OptionHelperTest extends TestCase { importance = Importance.ALWAYS) private List<String> mFilters = new ArrayList<>(); + @Option(name = TEST_LOGPATH, + importance = Importance.ALWAYS) + private String mLogPath = null; + public void testGetOptionNames() throws Exception { Set<String> optionNames = OptionHelper.getOptionNames(this); - List<String> expectedNames = Arrays.asList(TEST_CLASS, TEST_NAME, TEST_SUITE); + List<String> expectedNames = Arrays.asList(TEST_CLASS, TEST_NAME, TEST_SUITE, + TEST_LOGPATH); assertEquals("Missing option names", true, optionNames.containsAll(expectedNames)); - assertEquals("Expected four elements", 4, optionNames.size()); + assertEquals("Expected five elements", 5, optionNames.size()); } public void testGetOptionShortNames() throws Exception { @@ -77,7 +83,8 @@ public class OptionHelperTest extends TestCase { List<String> validSubset = Arrays.asList("--" + TEST_CLASS, "fooclass", "-" + TEST_SUITE_SHORTNAME, "foosuite"); List<String> allValidNames = Arrays.asList("--" + TEST_CLASS, "fooclass", - "-" + TEST_SUITE_SHORTNAME, "foosuite:foo-key:fooval", "--" + TEST_NAME, "footest"); + "-" + TEST_SUITE_SHORTNAME, "foosuite:foo-key:fooval", "--" + TEST_NAME, "footest", + "--" + TEST_LOGPATH, "path/to/log-directory/"); List<String> validQuoteSubset = Arrays.asList("-" + TEST_CLASS_SHORTNAME, fakeTestClass, "--" + TEST_NAME + "=" + fakeTestMethod, "--" + TEST_FILTER, fakeTestClass + " " @@ -94,7 +101,8 @@ public class OptionHelperTest extends TestCase { + " -s foosuite", this)); assertEquals("Expected two long names and one short name", allValidNames, OptionHelper.getValidCliArgs("test --" + TEST_CLASS + " fooclass -b fake" - + " -s foosuite:foo-key:fooval " + "--" + TEST_NAME + " footest", this)); + + " -s foosuite:foo-key:fooval --" + TEST_NAME + " footest --" + TEST_LOGPATH + + " path/to/log-directory/", this)); assertEquals("Expected matching arrays", validQuoteSubset, OptionHelper.getValidCliArgs(inputString, this)); } diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java index 6e08f7d5eeb..dc92526ffe0 100644 --- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java +++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java @@ -28,6 +28,7 @@ import android.os.storage.StorageManager; import android.provider.AlarmClock; import android.provider.MediaStore; import android.provider.Settings; +import android.speech.RecognizerIntent; import android.telecom.TelecomManager; import android.test.AndroidTestCase; @@ -50,6 +51,23 @@ public class AvailableIntentsTest extends AndroidTestCase { } /** + * Assert target intent is not resolved by a filter with priority greater than 0. + * @param intent - the Intent will be handled. + */ + private void assertDefaultHandlerValidPriority(final Intent intent) { + PackageManager packageManager = mContext.getPackageManager(); + List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0); + assertNotNull(resolveInfoList); + // one or more activity can handle this intent. + assertTrue(resolveInfoList.size() > 0); + // no activities override defaults with a high priority. Only system activities can override + // the priority. + for (ResolveInfo resolveInfo : resolveInfoList) { + assertTrue(resolveInfo.priority <= 0); + } + } + + /** * Test ACTION_VIEW when url is http://web_address, * it will open a browser window to the URL specified. */ @@ -292,4 +310,16 @@ public class AvailableIntentsTest extends AndroidTestCase { public void testManageStorage() { assertCanBeHandled(new Intent(StorageManager.ACTION_MANAGE_STORAGE)); } + + public void testVoiceCommand() { + Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND); + assertCanBeHandled(intent); + assertDefaultHandlerValidPriority(intent); + } + + public void testVoiceSearchHandsFree() { + Intent intent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); + assertCanBeHandled(intent); + assertDefaultHandlerValidPriority(intent); + } } diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java index c42dad51b80..2e1ff6bc81c 100644 --- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java +++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java @@ -1339,7 +1339,20 @@ public class EncodeVirtualDisplayWithCompositionTest extends AndroidTestCase { for (Size sz : standardSizes) { MediaFormat format = MediaFormat.createVideoFormat( MIME_TYPE, sz.getWidth(), sz.getHeight()); - format.setInteger(MediaFormat.KEY_FRAME_RATE, 15); // require at least 15fps + format.setInteger(MediaFormat.KEY_COLOR_FORMAT, + MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); + int bitRate = BITRATE_DEFAULT; + if (sz.getWidth() == 1920 && sz.getHeight() == 1080) { + bitRate = BITRATE_1080p; + } else if (sz.getWidth() == 1280 && sz.getHeight() == 720) { + bitRate = BITRATE_720p; + } else if (sz.getWidth() == 800 && sz.getHeight() == 480) { + bitRate = BITRATE_800x480; + } + format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); + format.setInteger(MediaFormat.KEY_FRAME_RATE, 30); + format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL); + Log.i(TAG,"format = " + format.toString()); if (mcl.findEncoderForFormat(format) != null) { return sz; } diff --git a/tests/tests/net/assets/HSR1ProfileWithCACert.base64 b/tests/tests/net/assets/HSR1ProfileWithCACert.base64 new file mode 100644 index 00000000000..995963d2b4c --- /dev/null +++ b/tests/tests/net/assets/HSR1ProfileWithCACert.base64 @@ -0,0 +1,85 @@ +Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu +dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh +cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 +IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n +SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo +YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn +UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi +V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ +M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM +MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth +VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt +RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD +QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD +QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD +QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx +bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 +MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv +Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 +ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo +YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 +VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo +YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi +RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj +bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i +MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy +UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX +eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD +QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD +OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 +dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 +S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV +K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G +dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur +TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn +SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 +WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 +VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM +MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ +Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi +V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ +a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX +eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD +QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q +VTJSbWx1WjJWeWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV +KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG +bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB +OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB +Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 +VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs +UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn +SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 +WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk +V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU +bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ +QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 +LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD +UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR +VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U +bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU +azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V +VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw +TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY +TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T +dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV +RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo +U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK +ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz +M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh +CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX +TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH +U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF +YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk +MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV +akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ +MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD +amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY +ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew +OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX +MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF +MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw +aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG +S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS +a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts +RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= diff --git a/tests/tests/net/assets/PerProviderSubscription.xml b/tests/tests/net/assets/PerProviderSubscription.xml new file mode 100644 index 00000000000..7f2d95de95e --- /dev/null +++ b/tests/tests/net/assets/PerProviderSubscription.xml @@ -0,0 +1,399 @@ +<MgmtTree xmlns="syncml:dmddf1.2"> + <VerDTD>1.2</VerDTD> + <Node> + <NodeName>PerProviderSubscription</NodeName> + <RTProperties> + <Type> + <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName> + </Type> + </RTProperties> + <Node> + <NodeName>UpdateIdentifier</NodeName> + <Value>12</Value> + </Node> + <Node> + <NodeName>i001</NodeName> + <Node> + <NodeName>HomeSP</NodeName> + <Node> + <NodeName>FriendlyName</NodeName> + <Value>Century House</Value> + </Node> + <Node> + <NodeName>FQDN</NodeName> + <Value>mi6.co.uk</Value> + </Node> + <Node> + <NodeName>RoamingConsortiumOI</NodeName> + <Value>112233,445566</Value> + </Node> + <Node> + <NodeName>IconURL</NodeName> + <Value>icon.test.com</Value> + </Node> + <Node> + <NodeName>NetworkID</NodeName> + <Node> + <NodeName>n001</NodeName> + <Node> + <NodeName>SSID</NodeName> + <Value>TestSSID</Value> + </Node> + <Node> + <NodeName>HESSID</NodeName> + <Value>12345678</Value> + </Node> + </Node> + <Node> + <NodeName>n002</NodeName> + <Node> + <NodeName>SSID</NodeName> + <Value>NullHESSID</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>HomeOIList</NodeName> + <Node> + <NodeName>h001</NodeName> + <Node> + <NodeName>HomeOI</NodeName> + <Value>11223344</Value> + </Node> + <Node> + <NodeName>HomeOIRequired</NodeName> + <Value>true</Value> + </Node> + </Node> + <Node> + <NodeName>h002</NodeName> + <Node> + <NodeName>HomeOI</NodeName> + <Value>55667788</Value> + </Node> + <Node> + <NodeName>HomeOIRequired</NodeName> + <Value>false</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>OtherHomePartners</NodeName> + <Node> + <NodeName>o001</NodeName> + <Node> + <NodeName>FQDN</NodeName> + <Value>other.fqdn.com</Value> + </Node> + </Node> + </Node> + </Node> + <Node> + <NodeName>Credential</NodeName> + <Node> + <NodeName>CreationDate</NodeName> + <Value>2016-01-01T10:00:00Z</Value> + </Node> + <Node> + <NodeName>ExpirationDate</NodeName> + <Value>2016-02-01T10:00:00Z</Value> + </Node> + <Node> + <NodeName>Realm</NodeName> + <Value>shaken.stirred.com</Value> + </Node> + <Node> + <NodeName>CheckAAAServerCertStatus</NodeName> + <Value>true</Value> + </Node> + <Node> + <NodeName>UsernamePassword</NodeName> + <Node> + <NodeName>Username</NodeName> + <Value>james</Value> + </Node> + <Node> + <NodeName>Password</NodeName> + <Value>Ym9uZDAwNw==</Value> + </Node> + <Node> + <NodeName>MachineManaged</NodeName> + <Value>true</Value> + </Node> + <Node> + <NodeName>SoftTokenApp</NodeName> + <Value>TestApp</Value> + </Node> + <Node> + <NodeName>AbleToShare</NodeName> + <Value>true</Value> + </Node> + <Node> + <NodeName>EAPMethod</NodeName> + <Node> + <NodeName>EAPType</NodeName> + <Value>21</Value> + </Node> + <Node> + <NodeName>InnerMethod</NodeName> + <Value>MS-CHAP-V2</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>DigitalCertificate</NodeName> + <Node> + <NodeName>CertificateType</NodeName> + <Value>x509v3</Value> + </Node> + <Node> + <NodeName>CertSHA256Fingerprint</NodeName> + <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> + </Node> + </Node> + <Node> + <NodeName>SIM</NodeName> + <Node> + <NodeName>IMSI</NodeName> + <Value>imsi</Value> + </Node> + <Node> + <NodeName>EAPType</NodeName> + <Value>24</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>Policy</NodeName> + <Node> + <NodeName>PreferredRoamingPartnerList</NodeName> + <Node> + <NodeName>p001</NodeName> + <Node> + <NodeName>FQDN_Match</NodeName> + <Value>test1.fqdn.com,exactMatch</Value> + </Node> + <Node> + <NodeName>Priority</NodeName> + <Value>127</Value> + </Node> + <Node> + <NodeName>Country</NodeName> + <Value>us,fr</Value> + </Node> + </Node> + <Node> + <NodeName>p002</NodeName> + <Node> + <NodeName>FQDN_Match</NodeName> + <Value>test2.fqdn.com,includeSubdomains</Value> + </Node> + <Node> + <NodeName>Priority</NodeName> + <Value>200</Value> + </Node> + <Node> + <NodeName>Country</NodeName> + <Value>*</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>MinBackhaulThreshold</NodeName> + <Node> + <NodeName>m001</NodeName> + <Node> + <NodeName>NetworkType</NodeName> + <Value>home</Value> + </Node> + <Node> + <NodeName>DLBandwidth</NodeName> + <Value>23412</Value> + </Node> + <Node> + <NodeName>ULBandwidth</NodeName> + <Value>9823</Value> + </Node> + </Node> + <Node> + <NodeName>m002</NodeName> + <Node> + <NodeName>NetworkType</NodeName> + <Value>roaming</Value> + </Node> + <Node> + <NodeName>DLBandwidth</NodeName> + <Value>9271</Value> + </Node> + <Node> + <NodeName>ULBandwidth</NodeName> + <Value>2315</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>PolicyUpdate</NodeName> + <Node> + <NodeName>UpdateInterval</NodeName> + <Value>120</Value> + </Node> + <Node> + <NodeName>UpdateMethod</NodeName> + <Value>OMA-DM-ClientInitiated</Value> + </Node> + <Node> + <NodeName>Restriction</NodeName> + <Value>HomeSP</Value> + </Node> + <Node> + <NodeName>URI</NodeName> + <Value>policy.update.com</Value> + </Node> + <Node> + <NodeName>UsernamePassword</NodeName> + <Node> + <NodeName>Username</NodeName> + <Value>updateUser</Value> + </Node> + <Node> + <NodeName>Password</NodeName> + <Value>updatePass</Value> + </Node> + </Node> + <Node> + <NodeName>TrustRoot</NodeName> + <Node> + <NodeName>CertURL</NodeName> + <Value>update.cert.com</Value> + </Node> + <Node> + <NodeName>CertSHA256Fingerprint</NodeName> + <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>SPExclusionList</NodeName> + <Node> + <NodeName>s001</NodeName> + <Node> + <NodeName>SSID</NodeName> + <Value>excludeSSID</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>RequiredProtoPortTuple</NodeName> + <Node> + <NodeName>r001</NodeName> + <Node> + <NodeName>IPProtocol</NodeName> + <Value>12</Value> + </Node> + <Node> + <NodeName>PortNumber</NodeName> + <Value>34,92,234</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>MaximumBSSLoadValue</NodeName> + <Value>23</Value> + </Node> + </Node> + <Node> + <NodeName>CredentialPriority</NodeName> + <Value>99</Value> + </Node> + <Node> + <NodeName>AAAServerTrustRoot</NodeName> + <Node> + <NodeName>a001</NodeName> + <Node> + <NodeName>CertURL</NodeName> + <Value>server1.trust.root.com</Value> + </Node> + <Node> + <NodeName>CertSHA256Fingerprint</NodeName> + <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>SubscriptionUpdate</NodeName> + <Node> + <NodeName>UpdateInterval</NodeName> + <Value>120</Value> + </Node> + <Node> + <NodeName>UpdateMethod</NodeName> + <Value>SSP-ClientInitiated</Value> + </Node> + <Node> + <NodeName>Restriction</NodeName> + <Value>RoamingPartner</Value> + </Node> + <Node> + <NodeName>URI</NodeName> + <Value>subscription.update.com</Value> + </Node> + <Node> + <NodeName>UsernamePassword</NodeName> + <Node> + <NodeName>Username</NodeName> + <Value>subscriptionUser</Value> + </Node> + <Node> + <NodeName>Password</NodeName> + <Value>subscriptionPass</Value> + </Node> + </Node> + <Node> + <NodeName>TrustRoot</NodeName> + <Node> + <NodeName>CertURL</NodeName> + <Value>subscription.update.cert.com</Value> + </Node> + <Node> + <NodeName>CertSHA256Fingerprint</NodeName> + <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> + </Node> + </Node> + </Node> + <Node> + <NodeName>SubscriptionParameter</NodeName> + <Node> + <NodeName>CreationDate</NodeName> + <Value>2016-02-01T10:00:00Z</Value> + </Node> + <Node> + <NodeName>ExpirationDate</NodeName> + <Value>2016-03-01T10:00:00Z</Value> + </Node> + <Node> + <NodeName>TypeOfSubscription</NodeName> + <Value>Gold</Value> + </Node> + <Node> + <NodeName>UsageLimits</NodeName> + <Node> + <NodeName>DataLimit</NodeName> + <Value>921890</Value> + </Node> + <Node> + <NodeName>StartDate</NodeName> + <Value>2016-12-01T10:00:00Z</Value> + </Node> + <Node> + <NodeName>TimeLimit</NodeName> + <Value>120</Value> + </Node> + <Node> + <NodeName>UsageTimePeriod</NodeName> + <Value>99910</Value> + </Node> + </Node> + </Node> + </Node> + </Node> +</MgmtTree> diff --git a/tests/tests/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/tests/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java new file mode 100644 index 00000000000..bea4500855b --- /dev/null +++ b/tests/tests/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2017 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.net.wifi.aware.cts; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.net.wifi.aware.AttachCallback; +import android.net.wifi.aware.Characteristics; +import android.net.wifi.aware.IdentityChangedListener; +import android.net.wifi.aware.WifiAwareManager; +import android.net.wifi.aware.WifiAwareSession; +import android.test.AndroidTestCase; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single + * device to validate Wi-Fi Aware. + */ +public class SingleDeviceTest extends AndroidTestCase { + private static final String TAG = "WifiAwareCtsTests"; + + // wait for Wi-Fi Aware to become available + static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; + + private final Object mLock = new Object(); + + private WifiAwareManager mWifiAwareManager; + private WifiManager mWifiManager; + private WifiManager.WifiLock mWifiLock; + + // used to store any WifiAwareSession allocated during tests - will clean-up after tests + private List<WifiAwareSession> mSessions = new ArrayList<>(); + + private class WifiAwareBroadcastReceiver extends BroadcastReceiver { + private CountDownLatch mBlocker = new CountDownLatch(1); + + @Override + public void onReceive(Context context, Intent intent) { + if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) { + mBlocker.countDown(); + } + } + + boolean waitForStateChange() throws InterruptedException { + return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + } + }; + + private class AttachCallbackTest extends AttachCallback { + static final int ATTACHED = 0; + static final int ATTACH_FAILED = 1; + static final int ERROR = 2; // no callback: timeout, interruption + + private CountDownLatch mBlocker = new CountDownLatch(1); + private int mCallbackCalled = ERROR; // garbage init + private WifiAwareSession mSession = null; + + @Override + public void onAttached(WifiAwareSession session) { + mCallbackCalled = ATTACHED; + mSession = session; + synchronized (mLock) { + mSessions.add(session); + } + mBlocker.countDown(); + } + + @Override + public void onAttachFailed() { + mCallbackCalled = ATTACH_FAILED; + mBlocker.countDown(); + } + + /** + * Waits for any of the callbacks to be called - or an error (timeout, interruption). + * Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values. + */ + int waitForAnyCallback() { + try { + boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + if (noTimeout) { + return mCallbackCalled; + } else { + return ERROR; + } + } catch (InterruptedException e) { + return ERROR; + } + } + + /** + * Access the session created by a callback. Only useful to be called after calling + * waitForAnyCallback() and getting the ATTACHED code back. + */ + WifiAwareSession getSession() { + return mSession; + } + } + + private class IdentityChangedListenerTest extends IdentityChangedListener { + private CountDownLatch mBlocker = new CountDownLatch(1); + private byte[] mMac = null; + + @Override + public void onIdentityChanged(byte[] mac) { + mMac = mac; + mBlocker.countDown(); + } + + /** + * Waits for the listener callback to be called - or an error (timeout, interruption). + * Returns true on callback called, false on error (timeout, interruption). + */ + boolean waitForListener() { + try { + return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return false; + } + } + + /** + * Returns the MAC address of the discovery interface supplied to the triggered callback. + */ + byte[] getMac() { + return mMac; + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + mWifiAwareManager = (WifiAwareManager) getContext().getSystemService( + Context.WIFI_AWARE_SERVICE); + assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager); + + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull("Wi-Fi Manager", mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) { + mWifiManager.setWifiEnabled(true); + } + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); + WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver(); + mContext.registerReceiver(receiver, intentFilter); + if (!mWifiAwareManager.isAvailable()) { + assertTrue("Timeout waiting for Wi-Fi Aware to change status", + receiver.waitForStateChange()); + assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); + } + } + + @Override + protected void tearDown() throws Exception { + if (!TestUtils.shouldTestWifiAware(getContext())) { + super.tearDown(); + return; + } + + synchronized (mLock) { + for (WifiAwareSession session : mSessions) { + // no damage from destroying twice (i.e. ok if test cleaned up after itself already) + session.destroy(); + } + mSessions.clear(); + } + + super.tearDown(); + } + + /** + * Validate: + * - Characteristics are available + * - Characteristics values are legitimate. Not in the CDD. However, the tested values are + * based on the Wi-Fi Aware protocol. + */ + public void testCharacteristics() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + Characteristics characteristics = mWifiAwareManager.getCharacteristics(); + assertNotNull("Wi-Fi Aware characteristics are null", characteristics); + assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255); + assertEquals("Service Specific Information Length", + characteristics.getMaxServiceSpecificInfoLength(), 255); + assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255); + } + + /** + * Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns + * correct status. + */ + public void testAvailabilityStatusChange() throws Exception { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); + + // 1. Disable Wi-Fi + WifiAwareBroadcastReceiver receiver1 = new WifiAwareBroadcastReceiver(); + mContext.registerReceiver(receiver1, intentFilter); + mWifiManager.setWifiEnabled(false); + + assertTrue("Timeout waiting for Wi-Fi Aware to change status", + receiver1.waitForStateChange()); + assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable()); + + // 2. Enable Wi-Fi + WifiAwareBroadcastReceiver receiver2 = new WifiAwareBroadcastReceiver(); + mContext.registerReceiver(receiver2, intentFilter); + mWifiManager.setWifiEnabled(true); + + assertTrue("Timeout waiting for Wi-Fi Aware to change status", + receiver2.waitForStateChange()); + assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); + } + + /** + * Validate that can attach to Wi-Fi Aware. + */ + public void testAttachNoIdentity() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + AttachCallbackTest attachCb = new AttachCallbackTest(); + mWifiAwareManager.attach(attachCb, null); + int cbCalled = attachCb.waitForAnyCallback(); + assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); + + WifiAwareSession session = attachCb.getSession(); + assertNotNull("Wi-Fi Aware session", session); + + session.destroy(); + } + + /** + * Validate that can attach to Wi-Fi Aware and get identity information. Use the identity + * information to validate that MAC address changes on every attach. + * + * Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used + * then the attach/destroy will not correspond to enable/disable and will not result in a new + * MAC address being generated. + */ + public void testAttachDiscoveryAddressChanges() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + final int numIterations = 10; + Set<TestUtils.MacWrapper> macs = new HashSet<>(); + + for (int i = 0; i < numIterations; ++i) { + AttachCallbackTest attachCb = new AttachCallbackTest(); + IdentityChangedListenerTest identityL = new IdentityChangedListenerTest(); + mWifiAwareManager.attach(attachCb, identityL, null); + assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED, + attachCb.waitForAnyCallback()); + assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener()); + + WifiAwareSession session = attachCb.getSession(); + assertNotNull("Wi-Fi Aware session: iteration " + i, session); + + byte[] mac = identityL.getMac(); + assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac); + + session.destroy(); + + macs.add(new TestUtils.MacWrapper(mac)); + } + + assertEquals("", numIterations, macs.size()); + } +} diff --git a/tests/tests/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/tests/net/src/android/net/wifi/aware/cts/TestUtils.java new file mode 100644 index 00000000000..a12c8bb0d23 --- /dev/null +++ b/tests/tests/net/src/android/net/wifi/aware/cts/TestUtils.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017 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.net.wifi.aware.cts; + +import android.content.Context; +import android.content.pm.PackageManager; + +import java.util.Arrays; + +/** + * Test utilities for Wi-Fi Aware CTS test suite. + */ +class TestUtils { + static final String TAG = "WifiAwareCtsTests"; + + /** + * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware + * should be tested if the feature is supported on the current device. + */ + static boolean shouldTestWifiAware(Context context) { + final PackageManager pm = context.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); + } + + /** + * Wraps a byte[] (MAC address representation). Intended to provide hash and equality operators + * so that the MAC address can be used in containers. + */ + static class MacWrapper { + private byte[] mMac; + + MacWrapper(byte[] mac) { + mMac = mac; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof MacWrapper)) { + return false; + } + + MacWrapper lhs = (MacWrapper) o; + return Arrays.equals(mMac, lhs.mMac); + } + + @Override + public int hashCode() { + return Arrays.hashCode(mMac); + } + } +} diff --git a/tests/tests/net/src/android/net/wifi/cts/ConfigParserTest.java b/tests/tests/net/src/android/net/wifi/cts/ConfigParserTest.java new file mode 100644 index 00000000000..52ed2a6d736 --- /dev/null +++ b/tests/tests/net/src/android/net/wifi/cts/ConfigParserTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2017 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.net.wifi.cts; + +import android.net.wifi.hotspot2.ConfigParser; +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; +import android.test.AndroidTestCase; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Arrays; + +/** + * CTS tests for Hotspot 2.0 Release 1 installation file parsing API. + */ +public class ConfigParserTest extends AndroidTestCase { + /** + * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a + * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}. + */ + private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT = + "assets/HSR1ProfileWithCACert.base64"; + + /** + * Read the content of the given resource file into a String. + * + * @param filename String name of the file + * @return String + * @throws IOException + */ + private String loadResourceFile(String filename) throws IOException { + InputStream in = getClass().getClassLoader().getResourceAsStream(filename); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + + return builder.toString(); + } + + /** + * Generate a {@link PasspointConfiguration} that matches the configuration specified in the + * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}. + * + * @return {@link PasspointConfiguration} + */ + private PasspointConfiguration generateConfigurationFromProfile() { + PasspointConfiguration config = new PasspointConfiguration(); + + // HomeSP configuration. + HomeSp homeSp = new HomeSp(); + homeSp.setFriendlyName("Century House"); + homeSp.setFqdn("mi6.co.uk"); + homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); + config.setHomeSp(homeSp); + + // Credential configuration. + Credential credential = new Credential(); + credential.setRealm("shaken.stirred.com"); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setUsername("james"); + userCredential.setPassword("Ym9uZDAwNw=="); + userCredential.setEapType(21); + userCredential.setNonEapInnerMethod("MS-CHAP-V2"); + credential.setUserCredential(userCredential); + Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); + certCredential.setCertType("x509v3"); + byte[] certSha256Fingerprint = new byte[32]; + Arrays.fill(certSha256Fingerprint, (byte)0x1f); + certCredential.setCertSha256Fingerprint(certSha256Fingerprint); + credential.setCertCredential(certCredential); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi("imsi"); + simCredential.setEapType(24); + credential.setSimCredential(simCredential); + credential.setCaCertificate(FakeKeys.CA_CERT0); + config.setCredential(credential); + return config; + } + + /** + * Verify a valid installation file is parsed successfully with the matching contents. + * + * @throws Exception + */ + public void testParseConfigFile() throws Exception { + String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT); + PasspointConfiguration expectedConfig = generateConfigurationFromProfile(); + PasspointConfiguration actualConfig = + ConfigParser.parsePasspointConfig( + "application/x-wifi-config", configStr.getBytes()); + assertTrue(actualConfig.equals(expectedConfig)); + } +}
\ No newline at end of file diff --git a/tests/tests/net/src/android/net/wifi/cts/FakeKeys.java b/tests/tests/net/src/android/net/wifi/cts/FakeKeys.java new file mode 100644 index 00000000000..f422c2f0fa3 --- /dev/null +++ b/tests/tests/net/src/android/net/wifi/cts/FakeKeys.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2016 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.net.wifi.cts; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; + +/** + * A class containing test certificates and private keys. + */ +public class FakeKeys { + private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" + + "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + + "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" + + "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + + "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" + + "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" + + "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" + + "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" + + "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" + + "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" + + "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" + + "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" + + "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" + + "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" + + "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" + + "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" + + "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" + + "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING); + + private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" + + "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + + "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" + + "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + + "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" + + "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" + + "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" + + "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" + + "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" + + "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" + + "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" + + "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" + + "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" + + "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" + + "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" + + "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" + + "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" + + "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING); + + private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" + + "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" + + "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" + + "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" + + "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" + + "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" + + "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" + + "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" + + "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" + + "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" + + "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" + + "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" + + "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" + + "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" + + "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" + + "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" + + "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" + + "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" + + "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" + + "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" + + "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" + + "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" + + "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" + + "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" + + "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" + + "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" + + "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" + + "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR); + + private static final byte[] FAKE_RSA_KEY_1 = new byte[] { + (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, + (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, + (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, + (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, + (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, + (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, + (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, + (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, + (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, + (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, + (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, + (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, + (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, + (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, + (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, + (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, + (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, + (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, + (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, + (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, + (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, + (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, + (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, + (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, + (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, + (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, + (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, + (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, + (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, + (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, + (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, + (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, + (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, + (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, + (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, + (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, + (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, + (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, + (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, + (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, + (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, + (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, + (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, + (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, + (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, + (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, + (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, + (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, + (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, + (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, + (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, + (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, + (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, + (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, + (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, + (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, + (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, + (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, + (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, + (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, + (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, + (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, + (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, + (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, + (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, + (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, + (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, + (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, + (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, + (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, + (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, + (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, + (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, + (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, + (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, + (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, + (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, + (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, + (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, + (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, + (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, + (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, + (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, + (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, + (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, + (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, + (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, + (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, + (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, + (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, + (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, + (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, + (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, + (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, + (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, + (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, + (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, + (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, + (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, + (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, + (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, + (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, + (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, + (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 + }; + public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); + + private static X509Certificate loadCertificate(String blob) { + try { + final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8)); + + return (X509Certificate) certFactory.generateCertificate(stream); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { + try { + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + return null; + } + } +} diff --git a/tests/tests/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/tests/net/src/android/net/wifi/cts/PpsMoParserTest.java new file mode 100644 index 00000000000..5eccc0d0bbe --- /dev/null +++ b/tests/tests/net/src/android/net/wifi/cts/PpsMoParserTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2017 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.net.wifi.cts; + +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.omadm.PpsMoParser; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; +import android.net.wifi.hotspot2.pps.Policy; +import android.net.wifi.hotspot2.pps.UpdateParameter; +import android.test.AndroidTestCase; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * CTS tests for PPS MO (PerProviderSubscription Management Object) XML string parsing API. + */ +public class PpsMoParserTest extends AndroidTestCase { + private static final String PPS_MO_XML_FILE = "assets/PerProviderSubscription.xml"; + + /** + * Read the content of the given resource file into a String. + * + * @param filename String name of the file + * @return String + * @throws IOException + */ + private String loadResourceFile(String filename) throws IOException { + InputStream in = getClass().getClassLoader().getResourceAsStream(filename); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + return builder.toString(); + } + + /** + * Generate a {@link PasspointConfiguration} that matches the configuration specified in the + * XML file {@link #PPS_MO_XML_FILE}. + * + * @return {@link PasspointConfiguration} + */ + private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + byte[] certFingerprint = new byte[32]; + Arrays.fill(certFingerprint, (byte) 0x1f); + + PasspointConfiguration config = new PasspointConfiguration(); + config.setUpdateIdentifier(12); + config.setCredentialPriority(99); + + // AAA Server trust root. + Map<String, byte[]> trustRootCertList = new HashMap<>(); + trustRootCertList.put("server1.trust.root.com", certFingerprint); + config.setTrustRootCertList(trustRootCertList); + + // Subscription update. + UpdateParameter subscriptionUpdate = new UpdateParameter(); + subscriptionUpdate.setUpdateIntervalInMinutes(120); + subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); + subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); + subscriptionUpdate.setServerUri("subscription.update.com"); + subscriptionUpdate.setUsername("subscriptionUser"); + subscriptionUpdate.setBase64EncodedPassword("subscriptionPass"); + subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com"); + subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); + config.setSubscriptionUpdate(subscriptionUpdate); + + // Subscription parameters. + config.setSubscriptionCreationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); + config.setSubscriptionExpirationTimeInMs(format.parse("2016-03-01T10:00:00Z").getTime()); + config.setSubscriptionType("Gold"); + config.setUsageLimitDataLimit(921890); + config.setUsageLimitStartTimeInMs(format.parse("2016-12-01T10:00:00Z").getTime()); + config.setUsageLimitTimeLimitInMinutes(120); + config.setUsageLimitUsageTimePeriodInMinutes(99910); + + // HomeSP configuration. + HomeSp homeSp = new HomeSp(); + homeSp.setFriendlyName("Century House"); + homeSp.setFqdn("mi6.co.uk"); + homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); + homeSp.setIconUrl("icon.test.com"); + Map<String, Long> homeNetworkIds = new HashMap<>(); + homeNetworkIds.put("TestSSID", 0x12345678L); + homeNetworkIds.put("NullHESSID", null); + homeSp.setHomeNetworkIds(homeNetworkIds); + homeSp.setMatchAllOis(new long[] {0x11223344}); + homeSp.setMatchAnyOis(new long[] {0x55667788}); + homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); + config.setHomeSp(homeSp); + + // Credential configuration. + Credential credential = new Credential(); + credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime()); + credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); + credential.setRealm("shaken.stirred.com"); + credential.setCheckAaaServerCertStatus(true); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setUsername("james"); + userCredential.setPassword("Ym9uZDAwNw=="); + userCredential.setMachineManaged(true); + userCredential.setSoftTokenApp("TestApp"); + userCredential.setAbleToShare(true); + userCredential.setEapType(21); + userCredential.setNonEapInnerMethod("MS-CHAP-V2"); + credential.setUserCredential(userCredential); + Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); + certCredential.setCertType("x509v3"); + certCredential.setCertSha256Fingerprint(certFingerprint); + credential.setCertCredential(certCredential); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi("imsi"); + simCredential.setEapType(24); + credential.setSimCredential(simCredential); + config.setCredential(credential); + + // Policy configuration. + Policy policy = new Policy(); + List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); + Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); + partner1.setFqdn("test1.fqdn.com"); + partner1.setFqdnExactMatch(true); + partner1.setPriority(127); + partner1.setCountries("us,fr"); + Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); + partner2.setFqdn("test2.fqdn.com"); + partner2.setFqdnExactMatch(false); + partner2.setPriority(200); + partner2.setCountries("*"); + preferredRoamingPartnerList.add(partner1); + preferredRoamingPartnerList.add(partner2); + policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); + policy.setMinHomeDownlinkBandwidth(23412); + policy.setMinHomeUplinkBandwidth(9823); + policy.setMinRoamingDownlinkBandwidth(9271); + policy.setMinRoamingUplinkBandwidth(2315); + policy.setExcludedSsidList(new String[] {"excludeSSID"}); + Map<Integer, String> requiredProtoPortMap = new HashMap<>(); + requiredProtoPortMap.put(12, "34,92,234"); + policy.setRequiredProtoPortMap(requiredProtoPortMap); + policy.setMaximumBssLoadValue(23); + UpdateParameter policyUpdate = new UpdateParameter(); + policyUpdate.setUpdateIntervalInMinutes(120); + policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); + policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); + policyUpdate.setServerUri("policy.update.com"); + policyUpdate.setUsername("updateUser"); + policyUpdate.setBase64EncodedPassword("updatePass"); + policyUpdate.setTrustRootCertUrl("update.cert.com"); + policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); + policy.setPolicyUpdate(policyUpdate); + config.setPolicy(policy); + return config; + } + + /** + * Parse and verify all supported fields under PPS MO tree. + * + * @throws Exception + */ + public void testParsePPSMOTree() throws Exception { + String ppsMoTree = loadResourceFile(PPS_MO_XML_FILE); + PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree(); + PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree); + assertTrue(actualConfig.equals(expectedConfig)); + } +} diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java index 4185189f505..d3dc8faadd1 100644 --- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -29,6 +29,9 @@ import android.net.wifi.WifiConfiguration.Status; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.TxPacketCountListener; import android.net.wifi.WifiManager.WifiLock; +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; import android.os.SystemClock; import android.provider.Settings; import android.test.AndroidTestCase; @@ -38,6 +41,8 @@ import com.android.compatibility.common.util.WifiConfigCreator; import java.net.HttpURLConnection; import java.net.URL; +import java.security.MessageDigest; +import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -543,4 +548,130 @@ public class WifiManagerTest extends AndroidTestCase { } assertTrue(i < 15); } + + /** + * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint + * configuration with an user credential. + * + * @throws Exception + */ + public void testAddPasspointConfigWithUserCredential() throws Exception { + testAddPasspointConfig(generatePasspointConfig(generateUserCredential())); + } + + /** + * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint + * configuration with a certificate credential. + * + * @throws Exception + */ + public void testAddPasspointConfigWithCertCredential() throws Exception { + testAddPasspointConfig(generatePasspointConfig(generateCertCredential())); + } + + /** + * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint + * configuration with a SIm credential. + * + * @throws Exception + */ + public void testAddPasspointConfigWithSimCredential() throws Exception { + testAddPasspointConfig(generatePasspointConfig(generateSimCredential())); + } + + /** + * Helper function for generating a {@link PasspointConfiguration} for testing. + * + * @return {@link PasspointConfiguration} + */ + private PasspointConfiguration generatePasspointConfig(Credential credential) { + PasspointConfiguration config = new PasspointConfiguration(); + config.setCredential(credential); + + // Setup HomeSp. + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("Test.com"); + homeSp.setFriendlyName("Test Provider"); + config.setHomeSp(homeSp); + + return config; + } + + /** + * Helper function for generating an user credential for testing. + * + * @return {@link Credential} + */ + private Credential generateUserCredential() { + Credential credential = new Credential(); + credential.setRealm("test.net"); + Credential.UserCredential userCred = new Credential.UserCredential(); + userCred.setEapType(21 /* EAP_TTLS */); + userCred.setUsername("username"); + userCred.setPassword("password"); + userCred.setNonEapInnerMethod("PAP"); + credential.setUserCredential(userCred); + credential.setCaCertificate(FakeKeys.CA_CERT0); + return credential; + } + + /** + * Helper function for generating a certificate credential for testing. + * + * @return {@link Credential} + */ + private Credential generateCertCredential() throws Exception { + Credential credential = new Credential(); + credential.setRealm("test.net"); + Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); + certCredential.setCertType("x509v3"); + certCredential.setCertSha256Fingerprint( + MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); + credential.setCertCredential(certCredential); + credential.setCaCertificate(FakeKeys.CA_CERT0); + credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); + credential.setClientPrivateKey(FakeKeys.RSA_KEY1); + return credential; + } + + /** + * Helper function for generating a SIM credential for testing. + * + * @return {@link Credential} + */ + private Credential generateSimCredential() throws Exception { + Credential credential = new Credential(); + credential.setRealm("test.net"); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi("1234*"); + simCredential.setEapType(18 /* EAP_SIM */); + credential.setSimCredential(simCredential); + return credential; + } + + /** + * Helper function verifying Passpoint configuration management APIs (add, remove, get) for + * a given configuration. + * + * @param config The configuration to test with + */ + private void testAddPasspointConfig(PasspointConfiguration config) throws Exception { + assertTrue(mWifiManager.addOrUpdatePasspointConfiguration(config)); + + // Certificates and keys will be set to null after it is installed to the KeyStore by + // WifiManager. Reset them in the expected config so that it can be used to compare + // against the retrieved config. + config.getCredential().setCaCertificate(null); + config.getCredential().setClientCertificateChain(null); + config.getCredential().setClientPrivateKey(null); + + // Retrieve the configuration and verify it. + List<PasspointConfiguration> configList = mWifiManager.getPasspointConfigurations(); + assertEquals(1, configList.size()); + assertEquals(config, configList.get(0)); + + // Remove the configuration and verify no installed configuration. + assertTrue(mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn())); + assertTrue(mWifiManager.getPasspointConfigurations().isEmpty()); + } } diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java index 4257067d7a5..329031a79a3 100644 --- a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java +++ b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java @@ -180,6 +180,7 @@ public class CtsConnectionService extends ConnectionService { Log.i(LOG_TAG, "Service has been unbound"); sServiceUnBoundLatch.countDown(); sIsBound = false; + sConnectionService = null; return super.onUnbind(intent); } diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java index ee2f842601b..4185318642d 100644 --- a/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java +++ b/tests/tests/telecom/src/android/telecom/cts/CtsSelfManagedConnectionService.java @@ -94,12 +94,14 @@ public class CtsSelfManagedConnectionService extends ConnectionService { } @Override - public void onCreateIncomingConnectionFailed(ConnectionRequest request) { + public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerHandle, + ConnectionRequest request) { mLocks[CREATE_INCOMING_CONNECTION_FAILED_LOCK].countDown(); } @Override - public void onCreateOutgoingConnectionFailed(ConnectionRequest request) { + public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerHandle, + ConnectionRequest request) { mLocks[CREATE_OUTGOING_CONNECTION_FAILED_LOCK].countDown(); } diff --git a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java index 084c4209543..5ace9fff557 100644 --- a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java +++ b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.function.Predicate; import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS; +import static android.telecom.cts.TestUtils.waitOnAllHandlers; /** * CTS tests for the self-managed {@link android.telecom.ConnectionService} APIs. @@ -37,7 +38,6 @@ import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS; public class SelfManagedConnectionServiceTest extends BaseTelecomTestWithMockServices { private Uri TEST_ADDRESS_1 = Uri.fromParts("sip", "call1@test.com", null); private Uri TEST_ADDRESS_2 = Uri.fromParts("sip", "call2@test.com", null); - private Uri TEST_ADDRESS_3 = Uri.fromParts("sip", "call3@test.com", null); @Override protected void setUp() throws Exception { @@ -197,7 +197,6 @@ public class SelfManagedConnectionServiceTest extends BaseTelecomTestWithMockSer // Expect there to be no managed calls at the moment. assertFalse(mTelecomManager.isInManagedCall()); - assertMockInCallServiceUnbound(); setDisconnectedAndVerify(connection); } @@ -226,7 +225,6 @@ public class SelfManagedConnectionServiceTest extends BaseTelecomTestWithMockSer // Expect there to be no managed calls at the moment. assertFalse(mTelecomManager.isInManagedCall()); - assertMockInCallServiceUnbound(); setDisconnectedAndVerify(connection); } @@ -346,6 +344,8 @@ public class SelfManagedConnectionServiceTest extends BaseTelecomTestWithMockSer connections.forEach((selfManagedConnection) -> selfManagedConnection.disconnectAndDestroy()); + + waitOnAllHandlers(getInstrumentation()); } public void testEmergencyCallOngoing() throws Exception { diff --git a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java index 9f79628bb34..7f2b27bba89 100644 --- a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java +++ b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java @@ -444,6 +444,16 @@ public class VideoCallTest extends BaseTelecomTestWithMockServices { Connection.VideoProvider.SESSION_EVENT_RX_RESUME); } }); + + assertCallSessionEventReceived(inCallService.getVideoCallCallback(call), + VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR, + new Work() { + @Override + public void doWork() { + connection.sendMockCallSessionEvent( + Connection.VideoProvider.SESSION_EVENT_CAMERA_PERMISSION_ERROR); + } + }); } /** diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java index 62f04c9c905..88475d1a240 100644 --- a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java +++ b/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java @@ -154,7 +154,7 @@ public class SmsUsageMonitorShortCodeTest extends InstrumentationTestCase { new ShortCodeTest("ch", "123", CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("ch", "234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), new ShortCodeTest("ch", "3456", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), - new ShortCodeTest("ch", "98765", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), + new ShortCodeTest("ch", "98765", CATEGORY_FREE_SHORT_CODE), new ShortCodeTest("ch", "543", CATEGORY_PREMIUM_SHORT_CODE), new ShortCodeTest("ch", "83111", CATEGORY_PREMIUM_SHORT_CODE), new ShortCodeTest("ch", "234567", CATEGORY_NOT_SHORT_CODE), diff --git a/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java index 9769175d1dd..94b2d14f67f 100644 --- a/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java +++ b/tests/tests/tv/src/android/media/tv/cts/BundledTvInputServiceTest.java @@ -157,13 +157,11 @@ public class BundledTvInputServiceTest if (!Utils.hasTvInputFramework(getActivity())) { return; } - // On average, the device is expected to have ~ 5 pass-through inputs (HDMI1-4 and - // Component) and tuning should be completed within 3 seconds, which gives 15 seconds - // for an input. Set 5 minutes of timeout for this test case and try 20 iterations. - final int ITERATIONS = 20; - for (int i = 0; i < mPassthroughInputList.size() * ITERATIONS; ++i) { - final TvInputInfo info = - mPassthroughInputList.get(i % mPassthroughInputList.size()); + // Tuning should be completed within 3 seconds on average, therefore, we set 100 iterations + // here to fit the test case running time in 5 minutes limitation of CTS test cases. + final int ITERATIONS = 100; + for (int i = 0; i < ITERATIONS; ++i) { + final TvInputInfo info = mPassthroughInputList.get(i % mPassthroughInputList.size()); mCallback.mVideoUnavailableReasonMap.remove(info.getId()); runTestOnUiThread(new Runnable() { @Override |