• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.content.cts;
18 
19 import static android.content.IntentFilter.MATCH_ADJUSTMENT_NORMAL;
20 import static android.content.IntentFilter.MATCH_CATEGORY_HOST;
21 import static android.content.IntentFilter.MATCH_CATEGORY_PATH;
22 import static android.content.IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART;
23 import static android.content.IntentFilter.MATCH_CATEGORY_TYPE;
24 import static android.content.IntentFilter.NO_MATCH_DATA;
25 import static android.content.UriRelativeFilter.PATH;
26 import static android.content.UriRelativeFilter.QUERY;
27 import static android.content.UriRelativeFilter.FRAGMENT;
28 import static android.content.UriRelativeFilterGroup.ACTION_ALLOW;
29 import static android.content.UriRelativeFilterGroup.ACTION_BLOCK;
30 import static android.os.PatternMatcher.PATTERN_ADVANCED_GLOB;
31 import static android.os.PatternMatcher.PATTERN_LITERAL;
32 import static android.os.PatternMatcher.PATTERN_PREFIX;
33 import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
34 import static android.os.PatternMatcher.PATTERN_SUFFIX;
35 
36 import static org.junit.Assert.assertEquals;
37 import static org.junit.Assert.assertFalse;
38 import static org.junit.Assert.assertNotNull;
39 import static org.junit.Assert.assertNull;
40 import static org.junit.Assert.assertTrue;
41 import static org.junit.Assert.fail;
42 
43 import android.content.ComponentName;
44 import android.content.ContentResolver;
45 import android.content.Context;
46 import android.content.Intent;
47 import android.content.IntentFilter;
48 import android.content.IntentFilter.AuthorityEntry;
49 import android.content.IntentFilter.MalformedMimeTypeException;
50 import android.content.UriRelativeFilter;
51 import android.content.UriRelativeFilterGroup;
52 import android.content.pm.ActivityInfo;
53 import android.content.pm.Flags;
54 import android.content.pm.PackageManager;
55 import android.content.pm.PackageManager.NameNotFoundException;
56 import android.net.Uri;
57 import android.os.Parcel;
58 import android.os.PatternMatcher;
59 import android.platform.test.annotations.AppModeSdkSandbox;
60 import android.platform.test.annotations.DisabledOnRavenwood;
61 import android.platform.test.annotations.PlatinumTest;
62 import android.platform.test.annotations.RequiresFlagsEnabled;
63 import android.platform.test.flag.junit.CheckFlagsRule;
64 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
65 import android.platform.test.ravenwood.RavenwoodRule;
66 import android.test.mock.MockContext;
67 import android.util.Printer;
68 import android.util.StringBuilderPrinter;
69 import android.util.Xml;
70 
71 import androidx.test.InstrumentationRegistry;
72 import androidx.test.runner.AndroidJUnit4;
73 
74 import org.junit.Before;
75 import org.junit.Rule;
76 import org.junit.Test;
77 import org.junit.runner.RunWith;
78 import org.xmlpull.v1.XmlPullParser;
79 import org.xmlpull.v1.XmlPullParserException;
80 import org.xmlpull.v1.XmlSerializer;
81 
82 import java.io.ByteArrayInputStream;
83 import java.io.ByteArrayOutputStream;
84 import java.io.IOException;
85 import java.io.InputStream;
86 import java.util.Arrays;
87 import java.util.Collection;
88 import java.util.HashSet;
89 import java.util.Iterator;
90 import java.util.Set;
91 import java.util.function.Predicate;
92 
93 @RunWith(AndroidJUnit4.class)
94 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
95 @PlatinumTest(focusArea = "pm")
96 public class IntentFilterTest {
97     @Rule
98     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
99 
100     private Context mContext;
101     private IntentFilter mIntentFilter;
102     private static final String ACTION = "testAction";
103     private static final String CATEGORY = "testCategory";
104     private static final String DATA_DYNAMIC_TYPE = "type/dynamic";
105     private static final String DATA_STATIC_TYPE = "vnd.android.cursor.dir/person";
106     private static final String DATA_SCHEME = "testDataSchemes.";
107     private static final String MIME_GROUP = "mime_group";
108     private static final String SSP = "testSsp";
109     private static final String HOST = "testHost";
110     private static final int PORT = 80;
111     private static final String DATA_PATH = "testDataPath";
112     private static final Uri URI = Uri.parse("content://com.example/people");
113 
114     @Before
setUp()115     public void setUp() throws Exception {
116         if (RavenwoodRule.isOnRavenwood()) {
117             // TODO: replace with mockito when better supported
118             mContext = new MockContext() {
119                 @Override
120                 public String getPackageName() {
121                     return "android.content.cts";
122                 }
123             };
124         } else {
125             mContext = InstrumentationRegistry.getTargetContext();
126         }
127 
128         mIntentFilter = new IntentFilter();
129     }
130 
131     @Test
testConstructor()132     public void testConstructor() throws MalformedMimeTypeException {
133 
134         IntentFilter filter = new IntentFilter();
135         verifyContent(filter, null, null);
136 
137         filter = new IntentFilter(ACTION);
138         verifyContent(filter, ACTION, null);
139 
140         final IntentFilter actionTypeFilter = new IntentFilter(ACTION, DATA_STATIC_TYPE);
141         verifyContent(actionTypeFilter, ACTION, DATA_STATIC_TYPE);
142 
143         filter = new IntentFilter(actionTypeFilter);
144         verifyContent(filter, ACTION, DATA_STATIC_TYPE);
145 
146         final String dataType = "testdataType";
147         try {
148             new IntentFilter(ACTION, dataType);
149             fail("Should throw MalformedMimeTypeException ");
150         } catch (MalformedMimeTypeException e) {
151             // expected
152         }
153     }
154 
155     /**
156      * Assert that the given filter contains the given action and dataType. If
157      * action or dataType are null, assert that the filter has no actions or
158      * dataTypes registered.
159      */
verifyContent(IntentFilter filter, String action, String dataType)160     private void verifyContent(IntentFilter filter, String action, String dataType) {
161         if (action != null) {
162             assertEquals(1, filter.countActions());
163             assertEquals(action, filter.getAction(0));
164         } else {
165             assertEquals(0, filter.countActions());
166         }
167         if (dataType != null) {
168             assertEquals(1, filter.countDataTypes());
169             assertEquals(dataType, filter.getDataType(0));
170             assertEquals(1, filter.countStaticDataTypes());
171         } else {
172             assertEquals(0, filter.countDataTypes());
173             assertEquals(0, filter.countStaticDataTypes());
174         }
175     }
176 
177     @Test
testCategories()178     public void testCategories() {
179         for (int i = 0; i < 10; i++) {
180             mIntentFilter.addCategory(CATEGORY + i);
181         }
182         assertEquals(10, mIntentFilter.countCategories());
183         Iterator<String> iter = mIntentFilter.categoriesIterator();
184         String actual = null;
185         int i = 0;
186         while (iter.hasNext()) {
187             actual = iter.next();
188             assertEquals(CATEGORY + i, actual);
189             assertEquals(CATEGORY + i, mIntentFilter.getCategory(i));
190             assertTrue(mIntentFilter.hasCategory(CATEGORY + i));
191             assertFalse(mIntentFilter.hasCategory(CATEGORY + i + 10));
192             i++;
193         }
194         IntentFilter filter = new Match(null, new String[]{"category1"}, null, null, null, null);
195         checkMatches(filter,
196                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null),
197                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
198                         new String[]{"category1"}, null, null),
199                 new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null,
200                         new String[]{"category2"}, null, null),
201                 new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null, new String[]{
202                         "category1", "category2"}, null, null));
203 
204         filter = new Match(null, new String[]{"category1", "category2"}, null, null, null, null);
205         checkMatches(filter,
206                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null),
207                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
208                         new String[]{"category1"}, null, null),
209                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
210                         new String[]{"category2"}, null, null),
211                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, new String[]{
212                         "category1", "category2"}, null, null),
213                 new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null,
214                         new String[]{"category3"}, null, null),
215                 new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null, new String[]{
216                         "category1", "category2", "category3"}, null, null));
217     }
218 
219     @Test
testMimeTypes()220     public void testMimeTypes() throws Exception {
221         IntentFilter filter = new Match(null, null, new String[]{"which1/what1"}, null, null,
222                 null);
223         checkMatches(filter,
224                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
225                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
226                         null),
227                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
228                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
229                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/what2", null),
230                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/*", null),
231                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null));
232 
233         filter = new Match(null, null, new String[]{"which1/what1", "which2/what2"}, null, null,
234                 null);
235         checkMatches(filter,
236                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
237                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
238                         null),
239                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
240                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
241                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/what2",
242                         null),
243                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/*", null),
244                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null),
245                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which3/what3", null));
246 
247         filter = new Match(null, null, new String[]{"which1/*"}, null, null, null);
248         checkMatches(filter,
249                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
250                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
251                         null),
252                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
253                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
254                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/what2", null),
255                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/*", null),
256                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what2",
257                         null),
258                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which3/what3", null));
259 
260         filter = new Match(null, null, new String[]{"*/*"}, null, null, null);
261         checkMatches(filter,
262                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
263                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
264                         null),
265                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
266                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
267                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/what2",
268                         null),
269                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/*", null),
270                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what2",
271                         null),
272                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which3/what3",
273                         null));
274     }
275 
276     @Test
testDynamicMimeTypes()277     public void testDynamicMimeTypes() {
278         IntentFilter filter = new Match()
279                 .addDynamicMimeTypes(new String[] { "which1/what1" });
280         checkMatches(filter,
281                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
282                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
283                         null),
284                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
285                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
286                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/what2", null),
287                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/*", null),
288                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null));
289 
290         filter = new Match()
291                 .addDynamicMimeTypes(new String[] { "which1/what1", "which2/what2" });
292         checkMatches(filter,
293                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
294                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
295                         null),
296                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
297                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
298                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/what2",
299                         null),
300                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/*", null),
301                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null),
302                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which3/what3", null));
303 
304         filter = new Match()
305                 .addDynamicMimeTypes(new String[] { "which1/*" });
306         checkMatches(filter,
307                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
308                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
309                         null),
310                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
311                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
312                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/what2", null),
313                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/*", null),
314                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what2",
315                         null),
316                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which3/what3", null));
317 
318         filter = new Match()
319                 .addDynamicMimeTypes(new String[] { "*/*" });
320         checkMatches(filter,
321                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
322                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
323                         null),
324                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
325                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
326                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/what2",
327                         null),
328                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/*", null),
329                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what2",
330                         null),
331                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which3/what3",
332                         null));
333     }
334 
335     @Test
testClearDynamicMimeTypesWithStaticType()336     public void testClearDynamicMimeTypesWithStaticType() {
337         IntentFilter filter = new Match()
338                 .addMimeTypes(new String[] {"which1/what1"})
339                 .addDynamicMimeTypes(new String[] { "which2/what2" });
340 
341         checkMatches(filter, new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
342                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
343                         null),
344                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
345                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
346                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/what2",
347                         null),
348                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which2/*", null),
349                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null),
350                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which3/what3", null));
351 
352         filter.clearDynamicDataTypes();
353 
354         checkMatches(filter,
355                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
356                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
357                         null),
358                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
359                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
360                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/what2", null),
361                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/*", null),
362                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null));
363     }
364 
365     @Test
testClearDynamicMimeTypesWithAction()366     public void testClearDynamicMimeTypesWithAction() {
367         IntentFilter filter = new Match()
368                 .addActions(new String[] {"action1"})
369                 .addDynamicMimeTypes(new String[] { "which1/what1" });
370 
371         checkMatches(filter,
372                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, null, null),
373                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/what1",
374                         null),
375                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "which1/*", null),
376                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null, "*/*", null),
377                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/what2", null),
378                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which2/*", null),
379                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null, "which1/what2", null));
380 
381         filter.clearDynamicDataTypes();
382 
383         checkMatches(filter,
384                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null),
385                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action1", null, null, null),
386                 new MatchCondition(IntentFilter.NO_MATCH_TYPE, "action1", null, "which2/what2",
387                         null));
388     }
389 
390     @Test
testAccessPriority()391     public void testAccessPriority() {
392         final int expected = 1;
393         mIntentFilter.setPriority(expected);
394         assertEquals(expected, mIntentFilter.getPriority());
395     }
396 
397     @Test
testDataSchemes()398     public void testDataSchemes() {
399         for (int i = 0; i < 10; i++) {
400             mIntentFilter.addDataScheme(DATA_SCHEME + i);
401         }
402         assertEquals(10, mIntentFilter.countDataSchemes());
403         final Iterator<String> iter = mIntentFilter.schemesIterator();
404         String actual = null;
405         int i = 0;
406         while (iter.hasNext()) {
407             actual = iter.next();
408             assertEquals(DATA_SCHEME + i, actual);
409             assertEquals(DATA_SCHEME + i, mIntentFilter.getDataScheme(i));
410             assertTrue(mIntentFilter.hasDataScheme(DATA_SCHEME + i));
411             assertFalse(mIntentFilter.hasDataScheme(DATA_SCHEME + i + 10));
412             i++;
413         }
414         IntentFilter filter = new Match(null, null, null, new String[]{"scheme1"}, null, null);
415         checkMatches(filter,
416                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
417                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_SCHEME, "scheme1:foo"),
418                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme2:foo"));
419 
420         filter = new Match(null, null, null, new String[]{"scheme1", "scheme2"}, null, null);
421         checkMatches(filter,
422                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
423                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_SCHEME, "scheme1:foo"),
424                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_SCHEME, "scheme2:foo"),
425                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme3:foo"));
426     }
427 
428     @Test
testCreate()429     public void testCreate() {
430         IntentFilter filter = IntentFilter.create(ACTION, DATA_STATIC_TYPE);
431         assertNotNull(filter);
432         verifyContent(filter, ACTION, DATA_STATIC_TYPE);
433     }
434 
435     @Test
testSchemeSpecificParts()436     public void testSchemeSpecificParts() throws Exception {
437         IntentFilter filter = new Match(null, null, null, new String[]{"scheme"},
438                 null, null, null, null, new String[]{"ssp1", "2ssp"},
439                 new int[]{PATTERN_LITERAL, PATTERN_LITERAL});
440         checkMatches(filter,
441                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
442                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1"),
443                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:2ssp"),
444                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ssp"),
445                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ssp12"));
446         filter = new Match(null, null, null, new String[]{"scheme"},
447                 null, null, null, null, new String[]{"ssp1", "2ssp"},
448                 new int[]{PATTERN_PREFIX, PATTERN_PREFIX});
449         checkMatches(filter,
450                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
451                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1"),
452                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:2ssp"),
453                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ssp"),
454                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp12"));
455         filter = new Match(null, null, null, new String[]{"scheme"},
456                 null, null, null, null, new String[]{"p1", "sp", ".file"},
457                 new int[]{PATTERN_SUFFIX, PATTERN_SUFFIX, PATTERN_SUFFIX});
458         checkMatches(filter,
459                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
460                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1"),
461                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:2ssp"),
462                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:something.file"),
463                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp"),
464                 MatchCondition.data(NO_MATCH_DATA, "scheme:ssp12"));
465         checkMatches(new IntentFilter[]{
466                         filterForSchemeAndSchemeSpecificPart("scheme", "ssp.*",
467                                 PATTERN_ADVANCED_GLOB),
468                         filterForSchemeAndSchemeSpecificPart("scheme", "ssp.*",
469                                 PATTERN_SIMPLE_GLOB)},
470                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
471                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1"),
472                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp"),
473                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ss"));
474         checkMatches(new IntentFilter[]{
475                         filterForSchemeAndSchemeSpecificPart("scheme", ".*",
476                                 PATTERN_ADVANCED_GLOB),
477                         filterForSchemeAndSchemeSpecificPart("scheme", ".*",
478                                 PATTERN_SIMPLE_GLOB)},
479                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
480                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1"),
481                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp"),
482                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:"));
483         checkMatches(new IntentFilter[]{
484                         filterForSchemeAndSchemeSpecificPart("scheme", "a1*b",
485                                 PATTERN_ADVANCED_GLOB),
486                         filterForSchemeAndSchemeSpecificPart("scheme", "a1*b",
487                                 PATTERN_SIMPLE_GLOB)},
488                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
489                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ab"),
490                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a1b"),
491                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a11b"),
492                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a2b"),
493                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a1bc"),
494                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a"));
495         checkMatches(new IntentFilter[]{
496                         filterForSchemeAndSchemeSpecificPart("scheme", "a1*",
497                                 PATTERN_ADVANCED_GLOB),
498                         filterForSchemeAndSchemeSpecificPart("scheme", "a1*",
499                                 PATTERN_SIMPLE_GLOB)},
500                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
501                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a1"),
502                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ab"),
503                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a11"),
504                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a1b"),
505                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a11"),
506                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a2"));
507         checkMatches(new IntentFilter[]{
508                         filterForSchemeAndSchemeSpecificPart("scheme", "a\\.*b",
509                                 PATTERN_ADVANCED_GLOB),
510                         filterForSchemeAndSchemeSpecificPart("scheme", "a\\.*b",
511                                 PATTERN_SIMPLE_GLOB)},
512                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
513                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ab"),
514                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.b"),
515                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a..b"),
516                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a2b"),
517                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a.bc"),
518                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:"));
519         checkMatches(new IntentFilter[]{
520                         filterForSchemeAndSchemeSpecificPart("scheme", "a[.1-2]*b",
521                                 PATTERN_ADVANCED_GLOB),
522                         filterForSchemeAndSchemeSpecificPart("scheme", "a.*b",
523                                 PATTERN_SIMPLE_GLOB)},
524                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
525                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ab"),
526                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.b"),
527                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.1b"),
528                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a2b"),
529                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a.bc"),
530                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:"));
531         checkMatches(new IntentFilter[]{
532                         filterForSchemeAndSchemeSpecificPart("scheme", "a.*",
533                                 PATTERN_ADVANCED_GLOB),
534                         filterForSchemeAndSchemeSpecificPart("scheme", "a.*",
535                                 PATTERN_SIMPLE_GLOB)},
536                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
537                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ab"),
538                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.b"),
539                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.1b"),
540                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a2b"),
541                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.bc"),
542                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:"));
543         checkMatches(new IntentFilter[]{
544                         filterForSchemeAndSchemeSpecificPart("scheme", "a.\\*b",
545                                 PATTERN_ADVANCED_GLOB),
546                         filterForSchemeAndSchemeSpecificPart("scheme", "a.\\*b",
547                                 PATTERN_SIMPLE_GLOB)},
548                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
549                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ab"),
550                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.*b"),
551                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a1*b"),
552                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a2b"),
553                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a.bc"),
554                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:"));
555         checkMatches(new IntentFilter[]{
556                         filterForSchemeAndSchemeSpecificPart("scheme", "a.\\*",
557                                 PATTERN_ADVANCED_GLOB),
558                         filterForSchemeAndSchemeSpecificPart("scheme", "a.\\*",
559                                 PATTERN_SIMPLE_GLOB)},
560                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
561                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ab"),
562                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a.*"),
563                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:a1*"),
564                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:a1b"));
565     }
566 
filterForSchemeAndSchemeSpecificPart(String scheme, String ssp, int matchType)567     private Match filterForSchemeAndSchemeSpecificPart(String scheme, String ssp, int matchType) {
568         return new Match(null, null, null, new String[]{scheme},
569                 null, null, null, null, new String[]{ssp},
570                 new int[]{matchType});
571     }
572 
573     @Test
testSchemeSpecificPartsWithWildCards()574     public void testSchemeSpecificPartsWithWildCards() throws Exception {
575         IntentFilter filter = new Match(null, null, null, new String[]{"scheme"},
576                 null, null, null, null, new String[]{"ssp1"},
577                 new int[]{PATTERN_LITERAL, PATTERN_LITERAL});
578         checkMatches(filter,
579                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null, true),
580                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:ssp1", true),
581                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "*:ssp1", true),
582                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "scheme:*", true),
583                 MatchCondition.data(MATCH_CATEGORY_SCHEME_SPECIFIC_PART, "*:*", true),
584                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:ssp12", true));
585 
586         checkMatches(filter,
587                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*:ssp1", false),
588                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme:*", false),
589                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*:*", false));
590     }
591 
592     @Test
testAuthorities()593     public void testAuthorities() {
594         for (int i = 0; i < 10; i++) {
595             mIntentFilter.addDataAuthority(HOST + i, String.valueOf(PORT + i));
596         }
597         assertEquals(10, mIntentFilter.countDataAuthorities());
598 
599         final Iterator<AuthorityEntry> iter = mIntentFilter.authoritiesIterator();
600         AuthorityEntry actual = null;
601         int i = 0;
602         while (iter.hasNext()) {
603             actual = iter.next();
604             assertEquals(HOST + i, actual.getHost());
605             assertEquals(PORT + i, actual.getPort());
606             AuthorityEntry ae = new AuthorityEntry(HOST + i, String.valueOf(PORT + i));
607             assertEquals(ae.getHost(), mIntentFilter.getDataAuthority(i).getHost());
608             assertEquals(ae.getPort(), mIntentFilter.getDataAuthority(i).getPort());
609             Uri uri = Uri.parse("http://" + HOST + i + ":" + String.valueOf(PORT + i));
610             assertTrue(mIntentFilter.hasDataAuthority(uri));
611             Uri uri2 = Uri.parse("http://" + HOST + i + 10 + ":" + PORT + i + 10);
612             assertFalse(mIntentFilter.hasDataAuthority(uri2));
613             i++;
614         }
615         IntentFilter filter = new Match(null, null, null, new String[]{"scheme1"},
616                 new String[]{"authority1"}, new String[]{null});
617         checkMatches(filter,
618                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
619                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:foo"),
620                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://authority1/"),
621                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority2/"),
622                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://authority1:100/"));
623 
624         filter = new Match(null, null, null, new String[]{"scheme1"},
625                 new String[]{"authority1"}, new String[]{"100"});
626         checkMatches(filter,
627                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
628                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:foo"),
629                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1/"),
630                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority2/"),
631                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "scheme1://authority1:100/"),
632                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1:200/"));
633 
634         filter = new Match(null, null, null, new String[]{"scheme1"},
635                 new String[]{"authority1", "authority2"}, new String[]{"100", null});
636         checkMatches(filter,
637                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
638                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:foo"),
639                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1/"),
640                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://authority2/"),
641                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "scheme1://authority1:100/"),
642                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1:200/"));
643     }
644 
645     @Test
testAuthoritiesWithWildcards()646     public void testAuthoritiesWithWildcards() throws Exception {
647         IntentFilter filter = new Match(null, null, null, new String[]{"scheme1"},
648                 new String[]{"authority1"}, new String[]{null});
649         checkMatches(filter,
650                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null, true),
651                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:*", true),
652                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*/", true),
653                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*:100/", true),
654                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*/", false),
655                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*:100/", false));
656 
657         filter = new Match(null, null, null, new String[]{"scheme1"},
658                 new String[]{"authority1"}, new String[]{"100"});
659         checkMatches(filter,
660                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null, true),
661                 MatchCondition.data(IntentFilter.NO_MATCH_DATA,       "scheme1:*", true),
662                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*/", true),
663                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*:100/", true),
664                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*:200/", true),
665                 MatchCondition.data(IntentFilter.NO_MATCH_DATA,       "*:foo", true),
666                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "*://authority1/", true),
667                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "*://authority1:100/", true),
668                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "*://authority1:200/", true),
669                 MatchCondition.data(IntentFilter.NO_MATCH_DATA,       "*:*", true),
670                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "*://*/", true),
671                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "*://*:100/", true),
672                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "*://*:200/", true));
673 
674         checkMatches(filter,
675                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*/", false),
676                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://*:100/", false),
677                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://authority1:100/", false),
678                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://*/", false),
679                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "*://*:100/", false));
680 
681         filter = new Match(null, null, null, new String[]{"scheme1"},
682                 new String[]{"*"}, null);
683         checkMatches(filter,
684                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://", true),
685                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://", false),
686                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://*", true));
687     }
688 
689     @Test
testDataTypes()690     public void testDataTypes() throws MalformedMimeTypeException {
691         for (int i = 0; i < 10; i++) {
692             mIntentFilter.addDataType(DATA_STATIC_TYPE + i);
693         }
694         assertEquals(10, mIntentFilter.countDataTypes());
695         assertEquals(10, mIntentFilter.countStaticDataTypes());
696         final Iterator<String> iter = mIntentFilter.typesIterator();
697         String actual;
698         int i = 0;
699         while (iter.hasNext()) {
700             actual = iter.next();
701             assertEquals(DATA_STATIC_TYPE + i, actual);
702             assertEquals(DATA_STATIC_TYPE + i, mIntentFilter.getDataType(i));
703             assertTrue(mIntentFilter.hasDataType(DATA_STATIC_TYPE + i));
704             assertFalse(mIntentFilter.hasDataType(DATA_STATIC_TYPE + i + 10));
705             i++;
706         }
707     }
708 
709     @Test
testDynamicDataTypes()710     public void testDynamicDataTypes() throws MalformedMimeTypeException {
711         for (int i = 0; i < 10; i++) {
712             mIntentFilter.addDynamicDataType(DATA_DYNAMIC_TYPE + i);
713         }
714         assertEquals(10, mIntentFilter.countDataTypes());
715         assertEquals(0, mIntentFilter.countStaticDataTypes());
716 
717         final Iterator<String> iter = mIntentFilter.typesIterator();
718         String actual;
719         int i = 0;
720         while (iter.hasNext()) {
721             actual = iter.next();
722             assertEquals(DATA_DYNAMIC_TYPE + i, actual);
723             assertEquals(DATA_DYNAMIC_TYPE + i, mIntentFilter.getDataType(i));
724             assertTrue(mIntentFilter.hasDataType(DATA_DYNAMIC_TYPE + i));
725             assertFalse(mIntentFilter.hasDataType(DATA_DYNAMIC_TYPE + i + 10));
726             i++;
727         }
728     }
729 
730     @Test
testClearDynamicDataTypes()731     public void testClearDynamicDataTypes() throws MalformedMimeTypeException {
732         for (int i = 0; i < 10; i++) {
733             mIntentFilter.addDataType(DATA_STATIC_TYPE + i);
734             mIntentFilter.addDynamicDataType(DATA_DYNAMIC_TYPE + i);
735         }
736         assertEquals(20, mIntentFilter.countDataTypes());
737         assertEquals(10, mIntentFilter.countStaticDataTypes());
738 
739         mIntentFilter.clearDynamicDataTypes();
740 
741         assertEquals(10, mIntentFilter.countDataTypes());
742         assertEquals(10, mIntentFilter.countStaticDataTypes());
743 
744         final Iterator<String> iter = mIntentFilter.typesIterator();
745         String actual;
746         int i = 0;
747         while (iter.hasNext()) {
748             actual = iter.next();
749             assertEquals(DATA_STATIC_TYPE + i, actual);
750             assertEquals(DATA_STATIC_TYPE + i, mIntentFilter.getDataType(i));
751             assertTrue(mIntentFilter.hasDataType(DATA_STATIC_TYPE + i));
752             assertFalse(mIntentFilter.hasDataType(DATA_DYNAMIC_TYPE + i));
753             i++;
754         }
755     }
756 
757     @Test
testMimeGroups()758     public void testMimeGroups() {
759         for (int i = 0; i < 10; i++) {
760             mIntentFilter.addMimeGroup(MIME_GROUP + i);
761         }
762         assertEquals(10, mIntentFilter.countMimeGroups());
763         final Iterator<String> iter = mIntentFilter.mimeGroupsIterator();
764         String actual = null;
765         int i = 0;
766         while (iter.hasNext()) {
767             actual = iter.next();
768             assertEquals(MIME_GROUP + i, actual);
769             assertEquals(MIME_GROUP + i, mIntentFilter.getMimeGroup(i));
770             assertTrue(mIntentFilter.hasMimeGroup(MIME_GROUP + i));
771             assertFalse(mIntentFilter.hasMimeGroup(MIME_GROUP + i + 10));
772             i++;
773         }
774     }
775 
776     @Test
testAppEnumerationMatchesMimeGroups()777     public void testAppEnumerationMatchesMimeGroups() {
778         IntentFilter filter = new Match(new String[]{ACTION}, null, null, new String[]{"scheme1"},
779                 new String[]{"authority1"}, null).addMimeGroups(new String[]{"test"});
780 
781         // assume any mime type or no mime type matches a filter with a mimegroup defined.
782         checkMatches(filter,
783                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE,
784                         ACTION, null, "img/jpeg", "scheme1://authority1", true),
785                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE,
786                         ACTION, null, null, "scheme1://authority1", true),
787                 new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE,
788                         ACTION, null, "*/*", "scheme1://authority1", true));
789     }
790 
791     @Test
testMatchData()792     public void testMatchData() throws MalformedMimeTypeException {
793         int expected = IntentFilter.MATCH_CATEGORY_EMPTY + IntentFilter.MATCH_ADJUSTMENT_NORMAL;
794         assertEquals(expected, mIntentFilter.matchData(null, null, null));
795         assertEquals(expected, mIntentFilter.matchData(null, DATA_SCHEME, null));
796 
797         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, URI));
798         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(DATA_STATIC_TYPE,
799                 DATA_SCHEME, URI));
800 
801         mIntentFilter.addDataScheme(DATA_SCHEME);
802         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(DATA_STATIC_TYPE,
803                 "mDataSchemestest", URI));
804         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(DATA_STATIC_TYPE, "",
805                 URI));
806 
807         expected = IntentFilter.MATCH_CATEGORY_SCHEME + IntentFilter.MATCH_ADJUSTMENT_NORMAL;
808         assertEquals(expected, mIntentFilter.matchData(null, DATA_SCHEME, URI));
809         assertEquals(IntentFilter.NO_MATCH_TYPE, mIntentFilter.matchData(DATA_STATIC_TYPE,
810                 DATA_SCHEME, URI));
811 
812         mIntentFilter.addDataType(DATA_STATIC_TYPE);
813         assertEquals(IntentFilter.MATCH_CATEGORY_TYPE + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
814                 mIntentFilter.matchData(DATA_STATIC_TYPE, DATA_SCHEME, URI));
815 
816         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
817         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, URI));
818 
819         final Uri uri = Uri.parse("http://" + HOST + ":" + PORT);
820         mIntentFilter.addDataPath(DATA_PATH, PatternMatcher.PATTERN_LITERAL);
821         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri));
822     }
823 
824     @Test
825     @DisabledOnRavenwood
826     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testMatchDataWithRelRefGroups()827     public void testMatchDataWithRelRefGroups() {
828         Uri uri = Uri.parse("https://" + HOST + "/path?query=string&cat=gizmo#fragment");
829         Uri uri2 = Uri.parse("https://" + HOST + "/path?query=string;cat=gizmo#fragment");
830         mIntentFilter.addDataScheme(DATA_SCHEME);
831         mIntentFilter.addDataAuthority(HOST, null);
832         assertEquals(MATCH_CATEGORY_HOST + MATCH_ADJUSTMENT_NORMAL,
833                 mIntentFilter.matchData(null, DATA_SCHEME, uri));
834 
835         // PATH matches so group match
836         UriRelativeFilterGroup matchGroup = new UriRelativeFilterGroup(ACTION_ALLOW);
837         matchGroup.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
838         mIntentFilter.addUriRelativeFilterGroup(matchGroup);
839         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
840                 mIntentFilter.matchData(null, DATA_SCHEME, uri));
841         mIntentFilter.clearUriRelativeFilterGroups();
842 
843         // PATH does not match so group does not match
844         UriRelativeFilterGroup noMatchGroup = new UriRelativeFilterGroup(ACTION_ALLOW);
845         noMatchGroup.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/trail"));
846         mIntentFilter.addUriRelativeFilterGroup(noMatchGroup);
847         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri));
848         mIntentFilter.clearUriRelativeFilterGroups();
849 
850         // PATH and QUERY match so group match
851         UriRelativeFilterGroup matchGroup1 = new UriRelativeFilterGroup(ACTION_ALLOW);
852         matchGroup1.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
853         matchGroup1.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_SIMPLE_GLOB, ".*"));
854         mIntentFilter.addUriRelativeFilterGroup(matchGroup1);
855         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
856                 mIntentFilter.matchData(null, DATA_SCHEME, uri));
857         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
858                 mIntentFilter.matchData(null, DATA_SCHEME, uri2));
859         mIntentFilter.clearUriRelativeFilterGroups();
860 
861         // PATH match but QUERY does not match so group does not match
862         UriRelativeFilterGroup noMatchGroup1 = new UriRelativeFilterGroup(ACTION_ALLOW);
863         noMatchGroup1.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
864         noMatchGroup1.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_PREFIX, "query"));
865         noMatchGroup1.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_SUFFIX, "widget"));
866         mIntentFilter.addUriRelativeFilterGroup(noMatchGroup1);
867         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri));
868         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri2));
869         mIntentFilter.clearUriRelativeFilterGroups();
870 
871         // PATH, QUERY, and FRAGMENT all match so group matches
872         UriRelativeFilterGroup matchGroup2 = new UriRelativeFilterGroup(ACTION_ALLOW);
873         matchGroup2.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
874         matchGroup2.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_PREFIX, "query"));
875         matchGroup2.addUriRelativeFilter(new UriRelativeFilter(FRAGMENT, PATTERN_SIMPLE_GLOB,
876                 "fr.*"));
877         mIntentFilter.addUriRelativeFilterGroup(matchGroup2);
878         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
879                 mIntentFilter.matchData(null, DATA_SCHEME, uri));
880         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
881                 mIntentFilter.matchData(null, DATA_SCHEME, uri2));
882         mIntentFilter.clearUriRelativeFilterGroups();
883 
884         // PATH, QUERY, and FRAGMENT all match but group is disallow
885         // and intent filter will not match
886         UriRelativeFilterGroup disallowGroup = new UriRelativeFilterGroup(ACTION_BLOCK);
887         disallowGroup.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
888         disallowGroup.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_PREFIX, "query"));
889         disallowGroup.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_SUFFIX, "gizmo"));
890         disallowGroup.addUriRelativeFilter(new UriRelativeFilter(FRAGMENT, PATTERN_SIMPLE_GLOB,
891                 "fr.*"));
892         mIntentFilter.addUriRelativeFilterGroup(disallowGroup);
893         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri));
894         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri2));
895         mIntentFilter.clearUriRelativeFilterGroups();
896 
897         // Since disallow group is defined first it will match but prevent the
898         // intent filter from matching even though though a matching group is
899         // defined after the disallow group.
900         mIntentFilter.addUriRelativeFilterGroup(disallowGroup);
901         mIntentFilter.addUriRelativeFilterGroup(matchGroup);
902         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri));
903         assertEquals(NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, uri2));
904         mIntentFilter.clearUriRelativeFilterGroups();
905 
906         // First group will not match so check the next group. The second group will
907         // match so the disallowed group will not be checked and the intent filter
908         // will match.
909         mIntentFilter.addUriRelativeFilterGroup(noMatchGroup);
910         mIntentFilter.addUriRelativeFilterGroup(matchGroup);
911         mIntentFilter.addUriRelativeFilterGroup(disallowGroup);
912         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
913                 mIntentFilter.matchData(null, DATA_SCHEME, uri));
914         assertEquals(MATCH_CATEGORY_PATH + MATCH_ADJUSTMENT_NORMAL,
915                 mIntentFilter.matchData(null, DATA_SCHEME, uri2));
916     }
917 
918     @Test
testActions()919     public void testActions() {
920         for (int i = 0; i < 10; i++) {
921             mIntentFilter.addAction(ACTION + i);
922         }
923         assertEquals(10, mIntentFilter.countActions());
924         final Iterator<String> iter = mIntentFilter.actionsIterator();
925         String actual = null;
926         int i = 0;
927         while (iter.hasNext()) {
928             actual = iter.next();
929             assertEquals(ACTION + i, actual);
930             assertEquals(ACTION + i, mIntentFilter.getAction(i));
931             assertTrue(mIntentFilter.hasAction(ACTION + i));
932             assertFalse(mIntentFilter.hasAction(ACTION + i + 10));
933             assertTrue(mIntentFilter.matchAction(ACTION + i));
934             assertFalse(mIntentFilter.matchAction(ACTION + i + 10));
935             i++;
936         }
937         IntentFilter filter = new Match(new String[]{"action1"}, null, null, null, null, null);
938         checkMatches(filter,
939                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null),
940                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action1", null, null, null),
941                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action2", null, null, null));
942 
943         filter = new Match(new String[]{"action1", "action2"}, null, null, null, null, null);
944         checkMatches(filter,
945                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null),
946                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action1", null, null, null),
947                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action2", null, null, null),
948                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action3", null, null, null),
949                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action1", null, null, null, false,
950                         Arrays.asList("action1", "action2")),
951                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action2", null, null, null, false,
952                         Arrays.asList("action1", "action2")),
953                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action1", null, null, null,
954                         false, Arrays.asList("action2")));
955     }
956 
957     @Test
testActionWildCards()958     public void testActionWildCards() throws Exception {
959         IntentFilter filter =
960                 new Match(new String[]{"action1", "action2"}, null, null, null, null, null);
961         checkMatches(filter,
962                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null, null, null, null, true),
963                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "*", null, null, null, true),
964                 new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "*", null, null, null, true,
965                         Arrays.asList("action1")),
966                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "*", null, null, null, true,
967                         Arrays.asList("action1", "action2")),
968                 new MatchCondition(
969                         IntentFilter.NO_MATCH_ACTION, "action3", null, null, null, true));
970 
971         checkMatches(filter,
972                 new MatchCondition(IntentFilter.NO_MATCH_ACTION, "*", null, null, null, false));
973 
974     }
975 
976     @Test
testAppEnumerationContactProviders()977     public void testAppEnumerationContactProviders() throws Exception {
978         // sample contact source
979         IntentFilter filter = new Match(new String[]{Intent.ACTION_VIEW},
980                 new String[]{Intent.CATEGORY_DEFAULT},
981                 new String[]{"vnd.android.cursor.item/vnd.com.someapp.profile"},
982                 new String[]{"content"},
983                 new String[]{"com.android.contacts"},
984                 null /*ports*/);
985 
986         // app that would like to match all contact sources
987         checkMatches(filter,
988                 new MatchCondition(MATCH_CATEGORY_TYPE,
989                         Intent.ACTION_VIEW,
990                         null /*categories*/,
991                         "vnd.android.cursor.item/*",
992                         "content://com.android.contacts",
993                         true));
994     }
995 
996     @Test
testAppEnumerationDocumentEditor()997     public void testAppEnumerationDocumentEditor() throws Exception {
998         // sample document editor
999         IntentFilter filter = new Match(
1000                 new String[]{
1001                         Intent.ACTION_VIEW,
1002                         Intent.ACTION_EDIT,
1003                         "com.app.android.intent.action.APP_EDIT",
1004                         "com.app.android.intent.action.APP_VIEW"},
1005                 new String[]{Intent.CATEGORY_DEFAULT},
1006                 new String[]{
1007                         "application/msword",
1008                         "application/vnd.oasis.opendocument.text",
1009                         "application/rtf",
1010                         "text/rtf",
1011                         "text/plain",
1012                         "application/pdf",
1013                         "application/x-pdf",
1014                         "application/docm"},
1015                 null /*schemes*/,
1016                 null /*authorities*/,
1017                 null /*ports*/);
1018 
1019         // app that would like to match all doc editors
1020         checkMatches(filter,
1021                 new MatchCondition(MATCH_CATEGORY_TYPE,
1022                         Intent.ACTION_VIEW,
1023                         new String[]{Intent.CATEGORY_DEFAULT},
1024                         "*/*",
1025                         "content://com.example.fileprovider",
1026                         true));
1027 
1028     }
1029 
1030     @Test
testAppEnumerationDeepLinks()1031     public void testAppEnumerationDeepLinks() throws Exception {
1032         // Sample app that supports deep-links
1033         IntentFilter filter = new Match(
1034                 new String[]{Intent.ACTION_VIEW},
1035                 new String[]{
1036                         Intent.CATEGORY_DEFAULT,
1037                         Intent.CATEGORY_BROWSABLE},
1038                 null /*types*/,
1039                 new String[]{"http", "https"},
1040                 new String[]{"arbitrary-site.com"},
1041                 null /*ports*/);
1042 
1043         // Browser that would like to see all deep-linkable http/s app, but not all apps
1044         checkMatches(filter,
1045                 new MatchCondition(MATCH_CATEGORY_HOST,
1046                         Intent.ACTION_VIEW,
1047                         new String[]{Intent.CATEGORY_BROWSABLE},
1048                         null,
1049                         "https://*",
1050                         true));
1051         checkMatches(filter,
1052                 new MatchCondition(MATCH_CATEGORY_HOST,
1053                         Intent.ACTION_VIEW,
1054                         new String[]{Intent.CATEGORY_BROWSABLE},
1055                         null,
1056                         "http://*",
1057                         true));
1058     }
1059 
1060     @Test
testAppEnumerationCustomShareSheet()1061     public void testAppEnumerationCustomShareSheet() throws Exception {
1062         // Sample share target
1063         IntentFilter filter = new Match(
1064                 new String[]{Intent.ACTION_SEND},
1065                 new String[]{Intent.CATEGORY_DEFAULT},
1066                 new String[]{"*/*"},
1067                 null /*schemes*/,
1068                 null /*authorities*/,
1069                 null /*ports*/);
1070 
1071         // App with custom share sheet that would like to see all jpeg targets
1072         checkMatches(filter,
1073                 new MatchCondition(MATCH_CATEGORY_TYPE,
1074                         Intent.ACTION_SEND,
1075                         null /*categories*/,
1076                         "image/jpeg",
1077                         "content://com.example.fileprovider",
1078                         true));
1079         // App with custom share sheet that would like to see all jpeg targets that don't specify
1080         // a host
1081         checkMatches(filter,
1082                 new MatchCondition(MATCH_CATEGORY_TYPE,
1083                         Intent.ACTION_SEND,
1084                         null /*categories*/,
1085                         "image/jpeg",
1086                         "content:",
1087                         true));
1088     }
1089 
1090     @Test
testAppEnumerationNoHostMatchesWildcardHost()1091     public void testAppEnumerationNoHostMatchesWildcardHost() throws Exception {
1092         IntentFilter filter = new Match(
1093                 new String[]{Intent.ACTION_VIEW},
1094                 new String[]{Intent.CATEGORY_BROWSABLE},
1095                 null,
1096                 new String[]{"http", "https"},
1097                 new String[]{"*"},
1098                 null /*ports*/);
1099         checkMatches(filter,
1100                 new MatchCondition(MATCH_CATEGORY_HOST,
1101                         Intent.ACTION_VIEW,
1102                         new String[]{Intent.CATEGORY_BROWSABLE},
1103                         null,
1104                         "https://*",
1105                         true));
1106 
1107         checkMatches(filter,
1108                 new MatchCondition(MATCH_CATEGORY_HOST,
1109                         Intent.ACTION_VIEW,
1110                         new String[]{Intent.CATEGORY_BROWSABLE},
1111                         null,
1112                         "https://",
1113                         true));
1114     }
1115 
1116     @Test
testAppEnumerationNoPortMatchesPortFilter()1117     public void testAppEnumerationNoPortMatchesPortFilter() throws Exception {
1118         IntentFilter filter = new Match(
1119                 new String[]{Intent.ACTION_VIEW},
1120                 new String[]{Intent.CATEGORY_BROWSABLE},
1121                 null,
1122                 new String[]{"http", "https"},
1123                 new String[]{"*"},
1124                 new String[]{"81"});
1125         checkMatches(filter,
1126                 new MatchCondition(MATCH_CATEGORY_HOST,
1127                         Intent.ACTION_VIEW,
1128                         new String[]{Intent.CATEGORY_BROWSABLE},
1129                         null,
1130                         "https://something",
1131                         true));
1132     }
1133 
1134     @Test
testAppEnumerationBrowser()1135     public void testAppEnumerationBrowser() throws Exception {
1136         IntentFilter appWithWebLink = new Match(
1137                 new String[]{Intent.ACTION_VIEW},
1138                 new String[]{Intent.CATEGORY_BROWSABLE},
1139                 null,
1140                 new String[]{"http", "https"},
1141                 new String[]{"some.app.domain"},
1142                 null);
1143 
1144         IntentFilter appWithWildcardWebLink = new Match(
1145                 new String[]{Intent.ACTION_VIEW},
1146                 new String[]{Intent.CATEGORY_BROWSABLE},
1147                 null,
1148                 new String[]{"http", "https"},
1149                 new String[]{"*.app.domain"},
1150                 null);
1151 
1152         IntentFilter browserFilterWithWildcard = new Match(
1153                 new String[]{Intent.ACTION_VIEW},
1154                 new String[]{Intent.CATEGORY_BROWSABLE},
1155                 null,
1156                 new String[]{"http", "https"},
1157                 new String[]{"*"},
1158                 null);
1159 
1160         IntentFilter browserFilterWithoutWildcard = new Match(
1161                 new String[]{Intent.ACTION_VIEW},
1162                 new String[]{Intent.CATEGORY_BROWSABLE},
1163                 null,
1164                 new String[]{"http", "https"},
1165                 null,
1166                 null);
1167 
1168         checkMatches(browserFilterWithWildcard,
1169                 new MatchCondition(MATCH_CATEGORY_HOST,
1170                 Intent.ACTION_VIEW,
1171                 new String[]{Intent.CATEGORY_BROWSABLE},
1172                 null,
1173                 "https://",
1174                 true));
1175         checkMatches(browserFilterWithoutWildcard,
1176                 new MatchCondition(IntentFilter.MATCH_CATEGORY_SCHEME | MATCH_ADJUSTMENT_NORMAL,
1177                 Intent.ACTION_VIEW,
1178                 new String[]{Intent.CATEGORY_BROWSABLE},
1179                 null,
1180                 "https://",
1181                 true));
1182         checkMatches(appWithWebLink,
1183                 new MatchCondition(NO_MATCH_DATA,
1184                 Intent.ACTION_VIEW,
1185                 new String[]{Intent.CATEGORY_BROWSABLE},
1186                 null,
1187                 "https://",
1188                 true));
1189         checkMatches(appWithWildcardWebLink,
1190                 new MatchCondition(NO_MATCH_DATA,
1191                 Intent.ACTION_VIEW,
1192                 new String[]{Intent.CATEGORY_BROWSABLE},
1193                 null,
1194                 "https://",
1195                 true));
1196     }
1197 
1198     @Test
testWriteToXml()1199     public void testWriteToXml() throws IllegalArgumentException, IllegalStateException,
1200             IOException, MalformedMimeTypeException, XmlPullParserException {
1201         XmlSerializer xml;
1202         ByteArrayOutputStream out;
1203 
1204         xml = Xml.newSerializer();
1205         out = new ByteArrayOutputStream();
1206         xml.setOutput(out, "utf-8");
1207         mIntentFilter.addAction(ACTION);
1208         mIntentFilter.addCategory(CATEGORY);
1209         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1210         mIntentFilter.addDataPath(DATA_PATH, 1);
1211         mIntentFilter.addDataScheme(DATA_SCHEME);
1212         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1213         mIntentFilter.addDynamicDataType(DATA_DYNAMIC_TYPE);
1214         mIntentFilter.addMimeGroup(MIME_GROUP);
1215         mIntentFilter.writeToXml(xml);
1216         xml.flush();
1217         final XmlPullParser parser = Xml.newPullParser();
1218         final InputStream in = new ByteArrayInputStream(out.toByteArray());
1219         parser.setInput(in, "utf-8");
1220         final IntentFilter intentFilter = new IntentFilter();
1221         intentFilter.readFromXml(parser);
1222         assertEquals(ACTION, intentFilter.getAction(0));
1223         assertEquals(CATEGORY, intentFilter.getCategory(0));
1224         assertTrue(intentFilter.hasExactStaticDataType(DATA_STATIC_TYPE));
1225         assertTrue(intentFilter.hasExactDynamicDataType(DATA_DYNAMIC_TYPE));
1226         assertEquals(MIME_GROUP, intentFilter.getMimeGroup(0));
1227         assertEquals(DATA_SCHEME, intentFilter.getDataScheme(0));
1228         assertEquals(DATA_PATH, intentFilter.getDataPath(0).getPath());
1229         assertEquals(HOST, intentFilter.getDataAuthority(0).getHost());
1230         assertEquals(PORT, intentFilter.getDataAuthority(0).getPort());
1231         out.close();
1232     }
1233 
1234     @Test
1235     @DisabledOnRavenwood
1236     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testWriteToXmlWithRelRefGroup()1237     public void testWriteToXmlWithRelRefGroup() throws IllegalArgumentException,
1238             IllegalStateException, IOException, MalformedMimeTypeException, XmlPullParserException {
1239         XmlSerializer xml;
1240         ByteArrayOutputStream out;
1241         UriRelativeFilterGroup relRefGroup = new UriRelativeFilterGroup(ACTION_ALLOW);
1242         relRefGroup.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
1243         relRefGroup.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_SIMPLE_GLOB, "q*"));
1244 
1245         xml = Xml.newSerializer();
1246         out = new ByteArrayOutputStream();
1247         xml.setOutput(out, "utf-8");
1248         mIntentFilter.addAction(ACTION);
1249         mIntentFilter.addCategory(CATEGORY);
1250         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1251         mIntentFilter.addDataPath(DATA_PATH, 1);
1252         mIntentFilter.addDataScheme(DATA_SCHEME);
1253         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1254         mIntentFilter.addDynamicDataType(DATA_DYNAMIC_TYPE);
1255         mIntentFilter.addMimeGroup(MIME_GROUP);
1256         mIntentFilter.addUriRelativeFilterGroup(relRefGroup);
1257         mIntentFilter.writeToXml(xml);
1258         xml.flush();
1259         final XmlPullParser parser = Xml.newPullParser();
1260         final InputStream in = new ByteArrayInputStream(out.toByteArray());
1261         parser.setInput(in, "utf-8");
1262         final IntentFilter intentFilter = new IntentFilter();
1263         intentFilter.readFromXml(parser);
1264         assertEquals(ACTION, intentFilter.getAction(0));
1265         assertEquals(CATEGORY, intentFilter.getCategory(0));
1266         assertTrue(intentFilter.hasExactStaticDataType(DATA_STATIC_TYPE));
1267         assertTrue(intentFilter.hasExactDynamicDataType(DATA_DYNAMIC_TYPE));
1268         assertEquals(MIME_GROUP, intentFilter.getMimeGroup(0));
1269         assertEquals(DATA_SCHEME, intentFilter.getDataScheme(0));
1270         assertEquals(DATA_PATH, intentFilter.getDataPath(0).getPath());
1271         assertEquals(HOST, intentFilter.getDataAuthority(0).getHost());
1272         assertEquals(PORT, intentFilter.getDataAuthority(0).getPort());
1273         assertEquals(mIntentFilter.countUriRelativeFilterGroups(),
1274                 intentFilter.countUriRelativeFilterGroups());
1275         assertEquals(mIntentFilter.getUriRelativeFilterGroup(0).getUriRelativeFilters().size(),
1276                 intentFilter.getUriRelativeFilterGroup(0).getUriRelativeFilters().size());
1277         Iterator<UriRelativeFilter> it =
1278                 intentFilter.getUriRelativeFilterGroup(0).getUriRelativeFilters().iterator();
1279         assertTrue(relRefGroup.getUriRelativeFilters().contains(it.next()));
1280         assertTrue(relRefGroup.getUriRelativeFilters().contains(it.next()));
1281         assertFalse(it.hasNext());
1282         out.close();
1283     }
1284 
1285     @Test
testMatchCategories()1286     public void testMatchCategories() {
1287         assertNull(mIntentFilter.matchCategories(null));
1288         Set<String> cat = new HashSet<String>();
1289         assertNull(mIntentFilter.matchCategories(cat));
1290 
1291         final String expected = "mytest";
1292         cat.add(expected);
1293         assertEquals(expected, mIntentFilter.matchCategories(cat));
1294 
1295         cat = new HashSet<String>();
1296         cat.add(CATEGORY);
1297         mIntentFilter.addCategory(CATEGORY);
1298         assertNull(mIntentFilter.matchCategories(cat));
1299         cat.add(expected);
1300         assertEquals(expected, mIntentFilter.matchCategories(cat));
1301     }
1302 
1303     @Test
testMatchDataAuthority()1304     public void testMatchDataAuthority() {
1305         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchDataAuthority(null));
1306         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1307         final Uri uri = Uri.parse("http://" + HOST + ":" + PORT);
1308         assertEquals(IntentFilter.MATCH_CATEGORY_PORT, mIntentFilter.matchDataAuthority(uri));
1309     }
1310 
1311     @Test
testDescribeContents()1312     public void testDescribeContents() {
1313         assertEquals(0, mIntentFilter.describeContents());
1314     }
1315 
1316     @Test
1317     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testReadFromXml()1318     public void testReadFromXml()
1319             throws NameNotFoundException, XmlPullParserException, IOException {
1320         XmlPullParser parser = null;
1321         ActivityInfo ai = null;
1322 
1323         final ComponentName mComponentName = new ComponentName(
1324                 "android.content.cts", "android.content.cts.MockActivity");
1325         final PackageManager pm = mContext.getPackageManager();
1326         ai = pm.getActivityInfo(mComponentName, PackageManager.GET_META_DATA);
1327 
1328         parser = ai.loadXmlMetaData(pm, "android.app.intent.filter");
1329 
1330         int type;
1331         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1332                 && type != XmlPullParser.START_TAG) {
1333         }
1334 
1335         final String nodeName = parser.getName();
1336 
1337         if (!"intent-filter".equals(nodeName)) {
1338             throw new RuntimeException();
1339         }
1340 
1341         mIntentFilter.readFromXml(parser);
1342 
1343         assertEquals("testAction", mIntentFilter.getAction(0));
1344         assertEquals("testCategory", mIntentFilter.getCategory(0));
1345 
1346         assertTrue(mIntentFilter.hasExactDynamicDataType("vnd.android.cursor.dir/person"));
1347         assertTrue(mIntentFilter.hasExactStaticDataType("text/plain"));
1348 
1349         assertEquals("testMimeGroup", mIntentFilter.getMimeGroup(0));
1350         assertEquals("testScheme", mIntentFilter.getDataScheme(0));
1351         assertEquals("testHost", mIntentFilter.getDataAuthority(0).getHost());
1352         assertEquals(80, mIntentFilter.getDataAuthority(0).getPort());
1353 
1354         assertEquals("test", mIntentFilter.getDataPath(0).getPath());
1355         assertEquals("test", mIntentFilter.getDataPath(1).getPath());
1356         assertEquals("test", mIntentFilter.getDataPath(2).getPath());
1357     }
1358 
1359     @Test
testDataPaths()1360     public void testDataPaths() {
1361         for (int i = 0; i < 10; i++) {
1362             mIntentFilter.addDataPath(DATA_PATH + i, PatternMatcher.PATTERN_PREFIX);
1363         }
1364         assertEquals(10, mIntentFilter.countDataPaths());
1365         Iterator<PatternMatcher> iter = mIntentFilter.pathsIterator();
1366         PatternMatcher actual = null;
1367         int i = 0;
1368         while (iter.hasNext()) {
1369             actual = iter.next();
1370             assertEquals(DATA_PATH + i, actual.getPath());
1371             assertEquals(PatternMatcher.PATTERN_PREFIX, actual.getType());
1372             PatternMatcher p = new PatternMatcher(DATA_PATH + i, PatternMatcher.PATTERN_PREFIX);
1373             assertEquals(p.getPath(), mIntentFilter.getDataPath(i).getPath());
1374             assertEquals(p.getType(), mIntentFilter.getDataPath(i).getType());
1375             assertTrue(mIntentFilter.hasDataPath(DATA_PATH + i));
1376             assertTrue(mIntentFilter.hasDataPath(DATA_PATH + i + 10));
1377             i++;
1378         }
1379 
1380         mIntentFilter = new IntentFilter();
1381         for (i = 0; i < 10; i++) {
1382             mIntentFilter.addDataPath(DATA_PATH + i, PatternMatcher.PATTERN_SUFFIX);
1383         }
1384         assertEquals(10, mIntentFilter.countDataPaths());
1385         iter = mIntentFilter.pathsIterator();
1386         i = 0;
1387         while (iter.hasNext()) {
1388             actual = iter.next();
1389             assertEquals(DATA_PATH + i, actual.getPath());
1390             assertEquals(PatternMatcher.PATTERN_SUFFIX, actual.getType());
1391             PatternMatcher p = new PatternMatcher(DATA_PATH + i, PatternMatcher.PATTERN_SUFFIX);
1392             assertEquals(p.getPath(), mIntentFilter.getDataPath(i).getPath());
1393             assertEquals(p.getType(), mIntentFilter.getDataPath(i).getType());
1394             assertTrue(mIntentFilter.hasDataPath(DATA_PATH + i));
1395             assertTrue(mIntentFilter.hasDataPath("a" + DATA_PATH + i));
1396             i++;
1397         }
1398 
1399         mIntentFilter = new IntentFilter();
1400         i = 0;
1401         for (i = 0; i < 10; i++) {
1402             mIntentFilter.addDataPath(DATA_PATH + i, PatternMatcher.PATTERN_LITERAL);
1403         }
1404         assertEquals(10, mIntentFilter.countDataPaths());
1405         iter = mIntentFilter.pathsIterator();
1406         i = 0;
1407         while (iter.hasNext()) {
1408             actual = iter.next();
1409             assertEquals(DATA_PATH + i, actual.getPath());
1410             assertEquals(PatternMatcher.PATTERN_LITERAL, actual.getType());
1411             PatternMatcher p = new PatternMatcher(DATA_PATH + i, PatternMatcher.PATTERN_LITERAL);
1412             assertEquals(p.getPath(), mIntentFilter.getDataPath(i).getPath());
1413             assertEquals(p.getType(), mIntentFilter.getDataPath(i).getType());
1414             assertTrue(mIntentFilter.hasDataPath(DATA_PATH + i));
1415             assertFalse(mIntentFilter.hasDataPath(DATA_PATH + i + 10));
1416             i++;
1417         }
1418         mIntentFilter = new IntentFilter();
1419         i = 0;
1420         for (i = 0; i < 10; i++) {
1421             mIntentFilter.addDataPath(DATA_PATH + i, PatternMatcher.PATTERN_SIMPLE_GLOB);
1422         }
1423         assertEquals(10, mIntentFilter.countDataPaths());
1424         iter = mIntentFilter.pathsIterator();
1425         i = 0;
1426         while (iter.hasNext()) {
1427             actual = iter.next();
1428             assertEquals(DATA_PATH + i, actual.getPath());
1429             assertEquals(PatternMatcher.PATTERN_SIMPLE_GLOB, actual.getType());
1430             PatternMatcher p = new PatternMatcher(DATA_PATH + i,
1431                     PatternMatcher.PATTERN_SIMPLE_GLOB);
1432             assertEquals(p.getPath(), mIntentFilter.getDataPath(i).getPath());
1433             assertEquals(p.getType(), mIntentFilter.getDataPath(i).getType());
1434             assertTrue(mIntentFilter.hasDataPath(DATA_PATH + i));
1435             assertFalse(mIntentFilter.hasDataPath(DATA_PATH + i + 10));
1436             i++;
1437         }
1438 
1439         mIntentFilter = new IntentFilter();
1440         for (i = 0; i < 10; i++) {
1441             mIntentFilter.addDataPath(DATA_PATH + i, PatternMatcher.PATTERN_ADVANCED_GLOB);
1442         }
1443         assertEquals(10, mIntentFilter.countDataPaths());
1444         iter = mIntentFilter.pathsIterator();
1445         i = 0;
1446         while (iter.hasNext()) {
1447             actual = iter.next();
1448             assertEquals(DATA_PATH + i, actual.getPath());
1449             assertEquals(PatternMatcher.PATTERN_ADVANCED_GLOB, actual.getType());
1450             PatternMatcher p = new PatternMatcher(DATA_PATH + i,
1451                     PatternMatcher.PATTERN_ADVANCED_GLOB);
1452             assertEquals(p.getPath(), mIntentFilter.getDataPath(i).getPath());
1453             assertEquals(p.getType(), mIntentFilter.getDataPath(i).getType());
1454             assertTrue(mIntentFilter.hasDataPath(DATA_PATH + i));
1455             assertFalse(mIntentFilter.hasDataPath(DATA_PATH + i + 10));
1456             i++;
1457         }
1458 
1459         IntentFilter filter = new Match(null, null, null, new String[]{"scheme1"},
1460                 new String[]{"authority1"}, new String[]{null});
1461         checkMatches(filter,
1462                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
1463                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:foo"),
1464                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://authority1/"),
1465                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority2/"),
1466                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://authority1:100/"));
1467 
1468         filter = new Match(null, null, null, new String[]{"scheme1"},
1469                 new String[]{"authority1"}, new String[]{"100"});
1470         checkMatches(filter,
1471                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
1472                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:foo"),
1473                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1/"),
1474                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority2/"),
1475                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "scheme1://authority1:100/"),
1476                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1:200/"));
1477 
1478         filter = new Match(null, null, null, new String[]{"scheme1"},
1479                 new String[]{"authority1", "authority2"}, new String[]{"100", null});
1480         checkMatches(filter,
1481                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, null),
1482                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1:foo"),
1483                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1/"),
1484                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_HOST, "scheme1://authority2/"),
1485                 MatchCondition.data(IntentFilter.MATCH_CATEGORY_PORT, "scheme1://authority1:100/"),
1486                 MatchCondition.data(IntentFilter.NO_MATCH_DATA, "scheme1://authority1:200/"));
1487     }
1488 
1489     @Test
1490     @DisabledOnRavenwood(blockedBy = ContentResolver.class)
testMatchWithIntent()1491     public void testMatchWithIntent() throws MalformedMimeTypeException {
1492         final ContentResolver resolver = mContext.getContentResolver();
1493 
1494         Intent intent = new Intent(ACTION);
1495         assertEquals(IntentFilter.NO_MATCH_ACTION, mIntentFilter.match(resolver, intent, true,
1496                 null));
1497         mIntentFilter.addAction(ACTION);
1498         assertEquals(IntentFilter.MATCH_CATEGORY_EMPTY + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1499                 mIntentFilter.match(resolver, intent, true, null));
1500 
1501         final Uri uri = Uri.parse(DATA_SCHEME + "://" + HOST + ":" + PORT);
1502         intent.setData(uri);
1503         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(resolver, intent, true, null));
1504         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1505         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(resolver, intent, true, null));
1506         intent.setType(DATA_STATIC_TYPE);
1507         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(resolver, intent, true, null));
1508 
1509         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1510 
1511         assertEquals(IntentFilter.MATCH_CATEGORY_TYPE + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1512                 mIntentFilter.match(resolver, intent, true, null));
1513         assertEquals(IntentFilter.MATCH_CATEGORY_TYPE + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1514                 mIntentFilter.match(resolver, intent, false, null));
1515         intent.addCategory(CATEGORY);
1516         assertEquals(IntentFilter.NO_MATCH_CATEGORY, mIntentFilter.match(resolver, intent, true,
1517                 null));
1518         mIntentFilter.addCategory(CATEGORY);
1519         assertEquals(IntentFilter.MATCH_CATEGORY_TYPE + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1520                 mIntentFilter.match(resolver, intent, true, null));
1521 
1522         intent.setDataAndType(uri, DATA_STATIC_TYPE);
1523         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(resolver, intent, true, null));
1524 
1525     }
1526 
1527     @Test
testMatchWithIntentData()1528     public void testMatchWithIntentData() throws MalformedMimeTypeException {
1529         Set<String> cat = new HashSet<String>();
1530         assertEquals(IntentFilter.NO_MATCH_ACTION, mIntentFilter.match(ACTION, null, null, null,
1531                 null, null));
1532         mIntentFilter.addAction(ACTION);
1533 
1534         assertEquals(IntentFilter.MATCH_CATEGORY_EMPTY + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1535                 mIntentFilter.match(ACTION, null, null, null, null, null));
1536         assertEquals(IntentFilter.MATCH_CATEGORY_EMPTY + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1537                 mIntentFilter.match(ACTION, null, DATA_SCHEME, null, null, null));
1538 
1539         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.matchData(null, DATA_SCHEME, URI));
1540 
1541         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1542                 DATA_SCHEME, URI, null, null));
1543 
1544         mIntentFilter.addDataScheme(DATA_SCHEME);
1545         assertEquals(IntentFilter.NO_MATCH_TYPE, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1546                 DATA_SCHEME, URI, null, null));
1547         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE, "",
1548                 URI, null, null));
1549         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1550 
1551         assertEquals(IntentFilter.MATCH_CATEGORY_TYPE + IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1552                 mIntentFilter.match(ACTION, DATA_STATIC_TYPE, DATA_SCHEME, URI, null, null));
1553 
1554         assertEquals(IntentFilter.NO_MATCH_TYPE, mIntentFilter.match(ACTION, null, DATA_SCHEME,
1555                 URI, null, null));
1556 
1557         assertEquals(IntentFilter.NO_MATCH_TYPE, mIntentFilter.match(ACTION, null, DATA_SCHEME,
1558                 URI, cat, null));
1559 
1560         cat.add(CATEGORY);
1561         assertEquals(IntentFilter.NO_MATCH_CATEGORY, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1562                 DATA_SCHEME, URI, cat, null));
1563         cat = new HashSet<String>();
1564         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1565         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, null, DATA_SCHEME,
1566                 URI, null, null));
1567         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1568                 DATA_SCHEME, URI, null, null));
1569 
1570         final Uri uri = Uri.parse(DATA_SCHEME + "://" + HOST + ":" + PORT);
1571         mIntentFilter.addDataPath(DATA_PATH, PatternMatcher.PATTERN_LITERAL);
1572         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1573                 DATA_SCHEME, uri, null, null));
1574         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1575                 DATA_SCHEME, URI, null, null));
1576 
1577         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1578                 DATA_SCHEME, URI, cat, null));
1579         cat.add(CATEGORY);
1580         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1581                 DATA_SCHEME, URI, cat, null));
1582         mIntentFilter.addCategory(CATEGORY);
1583         assertEquals(IntentFilter.NO_MATCH_DATA, mIntentFilter.match(ACTION, DATA_STATIC_TYPE,
1584                 DATA_SCHEME, URI, cat, null));
1585     }
1586 
1587     @Test
testWriteToParcel()1588     public void testWriteToParcel() throws MalformedMimeTypeException {
1589         mIntentFilter.addAction(ACTION);
1590         mIntentFilter.addCategory(CATEGORY);
1591         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1592         mIntentFilter.addDataPath(DATA_PATH, 1);
1593         mIntentFilter.addDataScheme(DATA_SCHEME);
1594         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1595         mIntentFilter.addDynamicDataType(DATA_DYNAMIC_TYPE);
1596         mIntentFilter.addMimeGroup(MIME_GROUP);
1597         Parcel parcel = Parcel.obtain();
1598         mIntentFilter.writeToParcel(parcel, 1);
1599         parcel.setDataPosition(0);
1600         IntentFilter target = IntentFilter.CREATOR.createFromParcel(parcel);
1601         assertEquals(mIntentFilter.getAction(0), target.getAction(0));
1602         assertEquals(mIntentFilter.getCategory(0), target.getCategory(0));
1603         assertEquals(mIntentFilter.getDataAuthority(0).getHost(),
1604                 target.getDataAuthority(0).getHost());
1605         assertEquals(mIntentFilter.getDataAuthority(0).getPort(),
1606                 target.getDataAuthority(0).getPort());
1607         assertEquals(mIntentFilter.getDataPath(0).getPath(), target.getDataPath(0).getPath());
1608         assertEquals(mIntentFilter.getDataScheme(0), target.getDataScheme(0));
1609         assertEquals(mIntentFilter.getDataType(0), target.getDataType(0));
1610         assertEquals(mIntentFilter.getDataType(1), target.getDataType(1));
1611         assertEquals(mIntentFilter.countStaticDataTypes(), target.countStaticDataTypes());
1612         assertEquals(mIntentFilter.countDataTypes(), target.countDataTypes());
1613         assertEquals(mIntentFilter.getMimeGroup(0), target.getMimeGroup(0));
1614     }
1615 
1616     @Test
1617     @DisabledOnRavenwood
1618     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testWriteToParcelWithRelRefGroup()1619     public void testWriteToParcelWithRelRefGroup() throws MalformedMimeTypeException {
1620         UriRelativeFilterGroup relRefGroup = new UriRelativeFilterGroup(ACTION_ALLOW);
1621         relRefGroup.addUriRelativeFilter(new UriRelativeFilter(PATH, PATTERN_LITERAL, "/path"));
1622         relRefGroup.addUriRelativeFilter(new UriRelativeFilter(QUERY, PATTERN_SIMPLE_GLOB, "q*"));
1623 
1624         mIntentFilter.addAction(ACTION);
1625         mIntentFilter.addCategory(CATEGORY);
1626         mIntentFilter.addDataAuthority(HOST, String.valueOf(PORT));
1627         mIntentFilter.addDataPath(DATA_PATH, 1);
1628         mIntentFilter.addDataScheme(DATA_SCHEME);
1629         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1630         mIntentFilter.addDynamicDataType(DATA_DYNAMIC_TYPE);
1631         mIntentFilter.addMimeGroup(MIME_GROUP);
1632         mIntentFilter.addUriRelativeFilterGroup(relRefGroup);
1633         Parcel parcel = Parcel.obtain();
1634         mIntentFilter.writeToParcel(parcel, 1);
1635         parcel.setDataPosition(0);
1636         IntentFilter target = IntentFilter.CREATOR.createFromParcel(parcel);
1637         assertEquals(mIntentFilter.getAction(0), target.getAction(0));
1638         assertEquals(mIntentFilter.getCategory(0), target.getCategory(0));
1639         assertEquals(mIntentFilter.getDataAuthority(0).getHost(),
1640                 target.getDataAuthority(0).getHost());
1641         assertEquals(mIntentFilter.getDataAuthority(0).getPort(),
1642                 target.getDataAuthority(0).getPort());
1643         assertEquals(mIntentFilter.getDataPath(0).getPath(), target.getDataPath(0).getPath());
1644         assertEquals(mIntentFilter.getDataScheme(0), target.getDataScheme(0));
1645         assertEquals(mIntentFilter.getDataType(0), target.getDataType(0));
1646         assertEquals(mIntentFilter.getDataType(1), target.getDataType(1));
1647         assertEquals(mIntentFilter.countStaticDataTypes(), target.countStaticDataTypes());
1648         assertEquals(mIntentFilter.countDataTypes(), target.countDataTypes());
1649         assertEquals(mIntentFilter.getMimeGroup(0), target.getMimeGroup(0));
1650         assertEquals(mIntentFilter.countUriRelativeFilterGroups(),
1651                 target.countUriRelativeFilterGroups());
1652         assertEquals(mIntentFilter.getUriRelativeFilterGroup(0).getUriRelativeFilters().size(),
1653                 target.getUriRelativeFilterGroup(0).getUriRelativeFilters().size());
1654         Iterator<UriRelativeFilter> it =
1655                 target.getUriRelativeFilterGroup(0).getUriRelativeFilters().iterator();
1656         assertTrue(relRefGroup.getUriRelativeFilters().contains(it.next()));
1657         assertTrue(relRefGroup.getUriRelativeFilters().contains(it.next()));
1658         assertFalse(it.hasNext());
1659     }
1660 
1661     @Test
testAddDataType()1662     public void testAddDataType() throws MalformedMimeTypeException {
1663         try {
1664             mIntentFilter.addDataType("test");
1665             fail("should throw MalformedMimeTypeException");
1666         } catch (MalformedMimeTypeException e) {
1667             // expected
1668         }
1669 
1670         mIntentFilter.addDataType(DATA_STATIC_TYPE);
1671         assertEquals(DATA_STATIC_TYPE, mIntentFilter.getDataType(0));
1672     }
1673 
1674     private static class Match extends IntentFilter {
Match()1675         Match() {
1676         }
1677 
Match(String[] actions, String[] categories, String[] mimeTypes, String[] schemes, String[] authorities, String[] ports)1678         Match(String[] actions, String[] categories, String[] mimeTypes, String[] schemes,
1679                 String[] authorities, String[] ports) {
1680             if (actions != null) {
1681                 addActions(actions);
1682             }
1683             if (categories != null) {
1684                 for (int i = 0; i < categories.length; i++) {
1685                     addCategory(categories[i]);
1686                 }
1687             }
1688             if (mimeTypes != null) {
1689                 for (int i = 0; i < mimeTypes.length; i++) {
1690                     try {
1691                         addDataType(mimeTypes[i]);
1692                     } catch (IntentFilter.MalformedMimeTypeException e) {
1693                         throw new RuntimeException("Bad mime type", e);
1694                     }
1695                 }
1696             }
1697             if (schemes != null) {
1698                 for (int i = 0; i < schemes.length; i++) {
1699                     addDataScheme(schemes[i]);
1700                 }
1701             }
1702             if (authorities != null) {
1703                 for (int i = 0; i < authorities.length; i++) {
1704                     addDataAuthority(authorities[i], ports != null ? ports[i] : null);
1705                 }
1706             }
1707         }
1708 
Match(String[] actions, String[] categories, String[] mimeTypes, String[] schemes, String[] authorities, String[] ports, String[] paths, int[] pathTypes)1709         Match(String[] actions, String[] categories, String[] mimeTypes, String[] schemes,
1710                 String[] authorities, String[] ports, String[] paths, int[] pathTypes) {
1711             this(actions, categories, mimeTypes, schemes, authorities, ports);
1712             if (paths != null) {
1713                 for (int i = 0; i < paths.length; i++) {
1714                     addDataPath(paths[i], pathTypes[i]);
1715                 }
1716             }
1717         }
1718 
Match(String[] actions, String[] categories, String[] mimeTypes, String[] schemes, String[] authorities, String[] ports, String[] paths, int[] pathTypes, String[] ssps, int[] sspTypes)1719         Match(String[] actions, String[] categories, String[] mimeTypes, String[] schemes,
1720                 String[] authorities, String[] ports, String[] paths, int[] pathTypes,
1721                 String[] ssps, int[] sspTypes) {
1722             this(actions, categories, mimeTypes, schemes, authorities, ports, paths, pathTypes);
1723             if (ssps != null) {
1724                 for (int i = 0; i < ssps.length; i++) {
1725                     addDataSchemeSpecificPart(ssps[i], sspTypes[i]);
1726                 }
1727             }
1728         }
1729 
addDynamicMimeTypes(String[] dynamicMimeTypes)1730         Match addDynamicMimeTypes(String[] dynamicMimeTypes) {
1731             for (int i = 0; i < dynamicMimeTypes.length; i++) {
1732                 try {
1733                     addDynamicDataType(dynamicMimeTypes[i]);
1734                 } catch (IntentFilter.MalformedMimeTypeException e) {
1735                     throw new RuntimeException("Bad mime type", e);
1736                 }
1737             }
1738             return this;
1739         }
1740 
addMimeGroups(String[] mimeGroups)1741         Match addMimeGroups(String[] mimeGroups) {
1742             for (int i = 0; i < mimeGroups.length; i++) {
1743                 addMimeGroup(mimeGroups[i]);
1744             }
1745             return this;
1746         }
1747 
addMimeTypes(String[] mimeTypes)1748         Match addMimeTypes(String[] mimeTypes) {
1749             for (int i = 0; i < mimeTypes.length; i++) {
1750                 try {
1751                     addDataType(mimeTypes[i]);
1752                 } catch (IntentFilter.MalformedMimeTypeException e) {
1753                     throw new RuntimeException("Bad mime type", e);
1754                 }
1755             }
1756             return this;
1757         }
1758 
addActions(String[] actions)1759         Match addActions(String[] actions) {
1760             for (int i = 0; i < actions.length; i++) {
1761                 addAction(actions[i]);
1762             }
1763             return this;
1764         }
1765     }
1766 
1767     private static class MatchCondition {
1768         public final int result;
1769         public final String action;
1770         public final String mimeType;
1771         public final Uri data;
1772         public final String[] categories;
1773         public final boolean wildcardSupported;
1774         public final Collection<String> ignoredActions;
1775 
data(int result, String data)1776         public static MatchCondition data(int result, String data) {
1777             return new MatchCondition(result, null, null, null, data);
1778         }
data(int result, String data, boolean wildcardSupported)1779         public static MatchCondition data(int result, String data, boolean wildcardSupported) {
1780             return new MatchCondition(result, null, null, null, data, wildcardSupported, null);
1781         }
data(int result, String data, boolean wildcardSupported, Collection<String> ignoredActions)1782         public static MatchCondition data(int result, String data, boolean wildcardSupported,
1783                 Collection<String> ignoredActions) {
1784             return new MatchCondition(result, null, null, null, data, wildcardSupported,
1785                     ignoredActions);
1786         }
MatchCondition(int result, String action, String[] categories, String mimeType, String data)1787         MatchCondition(int result, String action, String[] categories, String mimeType,
1788                 String data) {
1789             this(result, action, categories, mimeType, data, false, null);
1790         }
MatchCondition(int result, String action, String[] categories, String mimeType, String data, boolean wildcardSupported)1791         MatchCondition(int result, String action, String[] categories, String mimeType,
1792                 String data, boolean wildcardSupported) {
1793             this(result, action, categories, mimeType, data, wildcardSupported, null);
1794         }
MatchCondition(int result, String action, String[] categories, String mimeType, String data, boolean wildcardSupported, Collection<String> ignoredActions)1795         MatchCondition(int result, String action, String[] categories, String mimeType,
1796                 String data, boolean wildcardSupported, Collection<String> ignoredActions) {
1797             this.result = result;
1798             this.action = action;
1799             this.mimeType = mimeType;
1800             this.data = data != null ? Uri.parse(data) : null;
1801             this.categories = categories;
1802             this.wildcardSupported = wildcardSupported;
1803             this.ignoredActions = ignoredActions;
1804         }
1805     }
1806 
checkMatches(IntentFilter[] filters, MatchCondition... results)1807     private static void checkMatches(IntentFilter[] filters, MatchCondition... results) {
1808         for (IntentFilter filter : filters) {
1809             checkMatches(filter, results);
1810         }
1811     }
1812 
checkMatches(IntentFilter filter, MatchCondition... results)1813     private static void checkMatches(IntentFilter filter, MatchCondition... results) {
1814         for (int i = 0; i < results.length; i++) {
1815             MatchCondition mc = results[i];
1816             HashSet<String> categories = null;
1817             if (mc.categories != null) {
1818                 for (int j = 0; j < mc.categories.length; j++) {
1819                     if (categories == null) {
1820                         categories = new HashSet<String>();
1821                     }
1822                     categories.add(mc.categories[j]);
1823                 }
1824             }
1825             int result = filter.match(mc.action, mc.mimeType, mc.data != null ? mc.data.getScheme()
1826                     : null, mc.data, categories, "test", mc.wildcardSupported, mc.ignoredActions);
1827             if ((result & IntentFilter.MATCH_CATEGORY_MASK) !=
1828                     (mc.result & IntentFilter.MATCH_CATEGORY_MASK)) {
1829                 StringBuilder msg = new StringBuilder();
1830                 msg.append("Error matching against IntentFilter:\n");
1831                 filter.dump(new StringBuilderPrinter(msg), "    ");
1832                 msg.append("Match action: ");
1833                 msg.append(mc.action);
1834                 msg.append("\nMatch mimeType: ");
1835                 msg.append(mc.mimeType);
1836                 msg.append("\nMatch data: ");
1837                 msg.append(mc.data);
1838                 msg.append("\nMatch categories: ");
1839                 if (mc.categories != null) {
1840                     for (int j = 0; j < mc.categories.length; j++) {
1841                         if (j > 0) {
1842                             msg.append(", ");
1843                         }
1844                         msg.append(mc.categories[j]);
1845                     }
1846                 }
1847                 msg.append("\nExpected result: 0x");
1848                 msg.append(Integer.toHexString(mc.result));
1849                 msg.append(", got result: 0x");
1850                 msg.append(Integer.toHexString(result));
1851                 throw new RuntimeException(msg.toString());
1852             }
1853         }
1854     }
1855 
1856     @Test
testPaths()1857     public void testPaths() throws Exception {
1858         IntentFilter filter = new Match(null, null, null,
1859                 new String[]{"scheme"}, new String[]{"authority"}, null,
1860                 new String[]{"/literal1", "/2literal"},
1861                 new int[]{PATTERN_LITERAL, PATTERN_LITERAL});
1862         checkMatches(filter,
1863                 MatchCondition.data(
1864                         IntentFilter.NO_MATCH_DATA, null),
1865                 MatchCondition.data(
1866                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/literal1"),
1867                 MatchCondition.data(
1868                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/2literal"),
1869                 MatchCondition.data(
1870                         IntentFilter.NO_MATCH_DATA, "scheme://authority/literal"),
1871                 MatchCondition.data(
1872                         IntentFilter.NO_MATCH_DATA, "scheme://authority/literal12"));
1873         filter = new Match(null, null, null,
1874                 new String[]{"scheme"}, new String[]{"authority"}, null,
1875                 new String[]{"/literal1", "/2literal"}, new int[]{PATTERN_PREFIX, PATTERN_PREFIX});
1876         checkMatches(filter,
1877                 MatchCondition.data(
1878                         IntentFilter.NO_MATCH_DATA, null),
1879                 MatchCondition.data(
1880                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/literal1"),
1881                 MatchCondition.data(
1882                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/2literal"),
1883                 MatchCondition.data(
1884                         IntentFilter.NO_MATCH_DATA, "scheme://authority/literal"),
1885                 MatchCondition.data(
1886                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/literal12"));
1887         filter = new Match(null, null, null,
1888                 new String[]{"scheme"}, new String[]{"authority"}, null,
1889                 new String[]{"literal1", "2literal"}, new int[]{PATTERN_SUFFIX, PATTERN_SUFFIX});
1890         checkMatches(filter,
1891                 MatchCondition.data(
1892                         IntentFilter.NO_MATCH_DATA, null),
1893                 MatchCondition.data(
1894                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/aliteral1"),
1895                 MatchCondition.data(
1896                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/2literal"),
1897                 MatchCondition.data(
1898                         IntentFilter.NO_MATCH_DATA, "scheme://authority/literal"),
1899                 MatchCondition.data(
1900                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/literal1"),
1901                 MatchCondition.data(
1902                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/2literal1"),
1903                 MatchCondition.data(
1904                         IntentFilter.NO_MATCH_DATA, "scheme://authority/literal1a"));
1905         filter = new Match(null, null, null,
1906                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/.*"},
1907                 new int[]{PATTERN_SIMPLE_GLOB});
1908         checkMatches(filter,
1909                 MatchCondition.data(
1910                         IntentFilter.NO_MATCH_DATA, null),
1911                 MatchCondition.data(
1912                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/literal1"),
1913                 MatchCondition.data(
1914                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/"),
1915                 MatchCondition.data(
1916                         IntentFilter.NO_MATCH_DATA, "scheme://authority"));
1917         filter = new Match(null, null, null,
1918                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{".*"},
1919                 new int[]{PATTERN_SIMPLE_GLOB});
1920         checkMatches(filter,
1921                 MatchCondition.data(
1922                         IntentFilter.NO_MATCH_DATA, null),
1923                 MatchCondition.data(
1924                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/literal1"),
1925                 MatchCondition.data(
1926                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/"),
1927                 MatchCondition.data(
1928                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority"));
1929         filter = new Match(null, null, null,
1930                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a1*b"},
1931                 new int[]{PATTERN_SIMPLE_GLOB});
1932         checkMatches(filter,
1933                 MatchCondition.data(
1934                         IntentFilter.NO_MATCH_DATA, null),
1935                 MatchCondition.data(
1936                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/ab"),
1937                 MatchCondition.data(
1938                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a1b"),
1939                 MatchCondition.data(
1940                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a11b"),
1941                 MatchCondition.data(
1942                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a2b"),
1943                 MatchCondition.data(
1944                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a1bc"),
1945                 MatchCondition.data(
1946                         IntentFilter.NO_MATCH_DATA, "scheme://authority/"));
1947         filter = new Match(null, null, null,
1948                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a1*"},
1949                 new int[]{PATTERN_SIMPLE_GLOB});
1950         checkMatches(filter,
1951                 MatchCondition.data(
1952                         IntentFilter.NO_MATCH_DATA, null),
1953                 MatchCondition.data(
1954                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a1"),
1955                 MatchCondition.data(
1956                         IntentFilter.NO_MATCH_DATA, "scheme://authority/ab"),
1957                 MatchCondition.data(
1958                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a11"),
1959                 MatchCondition.data(
1960                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a1b"),
1961                 MatchCondition.data(
1962                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a11"),
1963                 MatchCondition.data(
1964                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a2"));
1965         filter = new Match(null, null, null,
1966                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a\\.*b"},
1967                 new int[]{PATTERN_SIMPLE_GLOB});
1968         checkMatches(filter,
1969                 MatchCondition.data(
1970                         IntentFilter.NO_MATCH_DATA, null),
1971                 MatchCondition.data(
1972                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/ab"),
1973                 MatchCondition.data(
1974                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.b"),
1975                 MatchCondition.data(
1976                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a..b"),
1977                 MatchCondition.data(
1978                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a2b"),
1979                 MatchCondition.data(
1980                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a.bc"),
1981                 MatchCondition.data(
1982                         IntentFilter.NO_MATCH_DATA, "scheme://authority/"));
1983         filter = new Match(null, null, null,
1984                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a.*b"},
1985                 new int[]{PATTERN_SIMPLE_GLOB});
1986         checkMatches(filter,
1987                 MatchCondition.data(
1988                         IntentFilter.NO_MATCH_DATA, null),
1989                 MatchCondition.data(
1990                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/ab"),
1991                 MatchCondition.data(
1992                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.b"),
1993                 MatchCondition.data(
1994                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.1b"),
1995                 MatchCondition.data(
1996                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a2b"),
1997                 MatchCondition.data(
1998                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a.bc"),
1999                 MatchCondition.data(
2000                         IntentFilter.NO_MATCH_DATA, "scheme://authority/"));
2001         filter = new Match(null, null, null,
2002                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a.*"},
2003                 new int[]{PATTERN_SIMPLE_GLOB});
2004         checkMatches(filter,
2005                 MatchCondition.data(
2006                         IntentFilter.NO_MATCH_DATA, null),
2007                 MatchCondition.data(
2008                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/ab"),
2009                 MatchCondition.data(
2010                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.b"),
2011                 MatchCondition.data(
2012                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.1b"),
2013                 MatchCondition.data(
2014                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a2b"),
2015                 MatchCondition.data(
2016                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.bc"),
2017                 MatchCondition.data(
2018                         IntentFilter.NO_MATCH_DATA, "scheme://authority/"));
2019         filter = new Match(null, null, null,
2020                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a.\\*b"},
2021                 new int[]{PATTERN_SIMPLE_GLOB});
2022         checkMatches(filter,
2023                 MatchCondition.data(
2024                         IntentFilter.NO_MATCH_DATA, null),
2025                 MatchCondition.data(
2026                         IntentFilter.NO_MATCH_DATA, "scheme://authority/ab"),
2027                 MatchCondition.data(
2028                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.*b"),
2029                 MatchCondition.data(
2030                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a1*b"),
2031                 MatchCondition.data(
2032                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a2b"),
2033                 MatchCondition.data(
2034                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a.bc"),
2035                 MatchCondition.data(
2036                         IntentFilter.NO_MATCH_DATA, "scheme://authority/"));
2037         filter = new Match(null, null, null,
2038                 new String[]{"scheme"}, new String[]{"authority"}, null, new String[]{"/a.\\*"},
2039                 new int[]{PATTERN_SIMPLE_GLOB});
2040         checkMatches(filter,
2041                 MatchCondition.data(
2042                         IntentFilter.NO_MATCH_DATA, null),
2043                 MatchCondition.data(
2044                         IntentFilter.NO_MATCH_DATA, "scheme://authority/ab"),
2045                 MatchCondition.data(
2046                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a.*"),
2047                 MatchCondition.data(
2048                         IntentFilter.MATCH_CATEGORY_PATH, "scheme://authority/a1*"),
2049                 MatchCondition.data(
2050                         IntentFilter.NO_MATCH_DATA, "scheme://authority/a1b"));
2051     }
2052 
2053     @Test
testDump()2054     public void testDump() throws MalformedMimeTypeException {
2055         TestPrinter printer = new TestPrinter();
2056         String prefix = "TestIntentFilter";
2057         IntentFilter filter = new IntentFilter(ACTION, DATA_STATIC_TYPE);
2058         filter.dump(printer, prefix);
2059         assertTrue(printer.isPrintlnCalled);
2060     }
2061 
2062     private class TestPrinter implements Printer {
2063         public boolean isPrintlnCalled;
2064 
println(String x)2065         public void println(String x) {
2066             isPrintlnCalled = true;
2067         }
2068     }
2069 
2070     @Test
testAsPredicate()2071     public void testAsPredicate() throws Exception {
2072         final Predicate<Intent> pred = new IntentFilter(ACTION).asPredicate();
2073 
2074         assertTrue(pred.test(new Intent(ACTION)));
2075         assertFalse(pred.test(new Intent(CATEGORY)));
2076     }
2077 
2078     @Test
2079     @DisabledOnRavenwood(blockedBy = ContentResolver.class)
testAsPredicateWithTypeResolution()2080     public void testAsPredicateWithTypeResolution() throws Exception {
2081         final ContentResolver resolver = mContext.getContentResolver();
2082         final Predicate<Intent> pred = new IntentFilter(ACTION, DATA_STATIC_TYPE)
2083                 .asPredicateWithTypeResolution(resolver);
2084 
2085         assertTrue(pred.test(new Intent(ACTION).setDataAndType(URI, DATA_STATIC_TYPE)));
2086         assertFalse(pred.test(new Intent(ACTION).setDataAndType(URI, DATA_DYNAMIC_TYPE)));
2087     }
2088 }
2089