Better activity resolution tests; AFD exceptions.

When calling Intent.resolveActivity(), test the various modes
separately.  Instead of hard-coding ResolverActivity, require that
whatever is returned will be able to update preferred activities.

AFD.createOutputStream() now throws IOException to match the
createInputStream() behavior.  This is a checked exception instead
of a RuntimeException, so we're reducing the severity.

Bug: 10309677, 10667113
Change-Id: If47a5c71bc5ec5a5070aef5979e2fba948ed29bb
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index 0d702f4..5af05eb 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -18,9 +18,25 @@
     package="com.android.cts.content">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application>
-        <uses-library android:name="android.test.runner" />
 
+    <application>
+        <activity android:name="android.app.cts.MockActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.content.action.TEST_ACTION" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="com.android.cts.content.category.TEST_CATEGORY" />
+            </intent-filter>
+        </activity>
+
+        <activity-alias android:name="android.app.cts.MockActivity2"
+                android:targetActivity="android.app.cts.MockActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.content.action.TEST_ACTION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity-alias>
+
+        <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
diff --git a/tests/tests/content/src/android/content/cts/IntentTest.java b/tests/tests/content/src/android/content/cts/IntentTest.java
index a88fdf2..562c915 100644
--- a/tests/tests/content/src/android/content/cts/IntentTest.java
+++ b/tests/tests/content/src/android/content/cts/IntentTest.java
@@ -17,6 +17,7 @@
 package android.content.cts;
 
 import com.android.internal.app.ResolverActivity;
+import com.android.internal.util.Objects;
 import com.android.internal.util.XmlUtils;
 
 
@@ -41,6 +42,7 @@
 import android.provider.Contacts.People;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Xml;
 
 import java.io.IOException;
@@ -57,6 +59,7 @@
     private static final Uri ANOTHER_TEST_URI = People.CONTENT_FILTER_URI;
     private static final String TEST_EXTRA_NAME = "testExtraName";
     private Context mContext;
+    private PackageManager mPm;
     private ComponentName mComponentName;
     private ComponentName mAnotherComponentName;
     private static final String TEST_TYPE = "testType";
@@ -71,6 +74,7 @@
         super.setUp();
         mIntent = new Intent();
         mContext = getContext();
+        mPm = mContext.getPackageManager();
         mComponentName = new ComponentName(mContext, MockActivity.class);
         mAnotherComponentName = new ComponentName(mContext, "tmp");
     }
@@ -713,26 +717,51 @@
         assertEquals(expected, mIntent.getParcelableArrayExtra(TEST_EXTRA_NAME));
     }
 
-    public void testResolveActivity() {
-        final PackageManager pm = mContext.getPackageManager();
+    public void testResolveActivityEmpty() {
+        final Intent emptyIntent = new Intent();
 
-        ComponentName target = mIntent.resolveActivity(pm);
+        // Empty intent shouldn't resolve to anything
+        final ComponentName target = emptyIntent.resolveActivity(mPm);
         assertNull(target);
+    }
 
-        mIntent.setComponent(mComponentName);
-        target = mIntent.resolveActivity(pm);
-        assertEquals(mComponentName, target);
+    public void testResolveActivitySingleMatch() {
+        final Intent intent = new Intent("com.android.cts.content.action.TEST_ACTION");
+        intent.addCategory("com.android.cts.content.category.TEST_CATEGORY");
 
-        mIntent.setComponent(null);
-        mIntent.setData(TEST_URI);
-        target = mIntent.resolveActivity(pm);
-        assertEquals(ResolverActivity.class.getName(), target.getClassName());
-        assertEquals("android", target.getPackageName());
+        // Should only have one activity responding to narrow category
+        final ComponentName target = intent.resolveActivity(mPm);
+        assertEquals("com.android.cts.content", target.getPackageName());
+        assertEquals("android.app.cts.MockActivity", target.getClassName());
+    }
 
-        mIntent.setComponent(null);
-        mIntent.setAction(TEST_TYPE);
-        target = mIntent.resolveActivity(pm);
-        assertNull(target);
+    public void testResolveActivityShortcutMatch() {
+        final Intent intent = new Intent("com.android.cts.content.action.TEST_ACTION");
+        intent.setComponent(
+                new ComponentName("com.android.cts.content", "android.app.cts.MockActivity2"));
+
+        // Multiple activities match, but we asked for explicit component
+        final ComponentName target = intent.resolveActivity(mPm);
+        assertEquals("com.android.cts.content", target.getPackageName());
+        assertEquals("android.app.cts.MockActivity2", target.getClassName());
+    }
+
+    public void testResolveActivityMultipleMatch() {
+        final Intent intent = new Intent("com.android.cts.content.action.TEST_ACTION");
+
+        // Should have multiple activities, resulting in resolver dialog
+        final ComponentName target = intent.resolveActivity(mPm);
+        final String pkgName = target.getPackageName();
+        assertFalse("com.android.cts.content".equals(pkgName));
+
+        // Whoever they are must be able to set preferred activities
+        if (!"android".equals(pkgName)) {
+            if (mPm.checkPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS, pkgName)
+                    != PackageManager.PERMISSION_GRANTED) {
+                fail("Resolved target " + target
+                        + " doesn't have SET_PREFERRED_APPLICATIONS permission");
+            }
+        }
     }
 
     public void testGetCharExtra() {
diff --git a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
index 7891aec..e4a9500 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
@@ -83,8 +83,8 @@
         mOutputStream = null;
         try {
             mOutputStream = mAssetFileDes.createOutputStream();
-            fail("Should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
+            fail("Should throw IOException");
+        } catch (IOException e) {
             // expect
         }
         try {
@@ -120,8 +120,8 @@
         }
         try {
             mOutputStream = mAssetFileDes.createOutputStream();
-            fail("Should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
+            fail("Should throw IOException");
+        } catch (IOException e) {
             // expect
         }
         mAssetFileDes.close();