• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 com.android.server.pm;
18 
19 import android.annotation.NonNull;
20 import android.content.ContentResolver;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.net.Uri;
24 import android.os.PatternMatcher;
25 import android.util.Printer;
26 
27 import com.android.server.utils.Snappable;
28 import com.android.server.utils.WatchableImpl;
29 
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Set;
35 import java.util.function.Consumer;
36 
37 /**
38  * A watched variant of {@link IntentFilter}.  The class consists of a
39  * {@link IntentFilter} attribute and methods that are identical to those in IntentFilter,
40  * forwarding to the attribute.
41  *
42  * @hide
43  */
44 public class WatchedIntentFilter
45         extends WatchableImpl
46         implements Snappable<WatchedIntentFilter> {
47 
48     // Watch for modifications made through an {@link Iterator}.
49     private class WatchedIterator<E> implements Iterator<E> {
50         private final Iterator<E> mIterator;
WatchedIterator(@onNull Iterator<E> i)51         WatchedIterator(@NonNull Iterator<E> i) {
52             mIterator = i;
53         }
hasNext()54         public boolean hasNext() {
55             return mIterator.hasNext();
56         }
next()57         public E next() {
58             return mIterator.next();
59         }
remove()60         public void remove() {
61             mIterator.remove();
62             WatchedIntentFilter.this.onChanged();
63         }
forEachRemaining(Consumer<? super E> action)64         public void forEachRemaining(Consumer<? super E> action) {
65             mIterator.forEachRemaining(action);
66             WatchedIntentFilter.this.onChanged();
67         }
68     }
69 
70     // A convenience function to wrap an iterator result, but only if it is not null.
maybeWatch(Iterator<E> i)71     private <E> Iterator<E> maybeWatch(Iterator<E> i) {
72         return i == null ? i : new WatchedIterator<>(i);
73     }
74 
75     // The wrapped {@link IntentFilter}
76     protected IntentFilter mFilter;
77 
onChanged()78     private void onChanged() {
79         dispatchChange(this);
80     }
81 
WatchedIntentFilter()82     protected WatchedIntentFilter() {
83         mFilter = new IntentFilter();
84     }
85 
86     // Convert an {@link IntentFilter} to a {@link WatchedIntentFilter}
WatchedIntentFilter(IntentFilter f)87     public WatchedIntentFilter(IntentFilter f) {
88         mFilter = new IntentFilter(f);
89     }
90 
91     // The copy constructor is used to create a snapshot of the object.
WatchedIntentFilter(WatchedIntentFilter f)92     protected WatchedIntentFilter(WatchedIntentFilter f) {
93         this(f.getIntentFilter());
94     }
95 
96     /**
97      * Create a WatchedIntentFilter based on an action
98      * @see IntentFilter#IntentFilter(String)
99      */
WatchedIntentFilter(String action)100     public WatchedIntentFilter(String action) {
101         mFilter = new IntentFilter(action);
102     }
103 
104     /**
105      * Create a WatchedIntentFilter based on an action and a data type.
106      * @see IntentFilter#IntentFilter(String, String)
107      */
WatchedIntentFilter(String action, String dataType)108     public WatchedIntentFilter(String action, String dataType)
109             throws IntentFilter.MalformedMimeTypeException {
110         mFilter = new IntentFilter(action, dataType);
111     }
112 
113     /**
114      * Return a clone of the filter represented by this object.
115      */
cloneFilter()116     public WatchedIntentFilter cloneFilter() {
117         return new WatchedIntentFilter(mFilter);
118     }
119 
120     /**
121      * Return the {@link IntentFilter} represented by this object.
122      */
getIntentFilter()123     public IntentFilter getIntentFilter() {
124         return mFilter;
125     }
126 
127     /**
128      * @see IntentFilter#setPriority(int)
129      */
setPriority(int priority)130     public final void setPriority(int priority) {
131         mFilter.setPriority(priority);
132         onChanged();
133     }
134 
135     /**
136      * @see IntentFilter#getPriority()
137      */
getPriority()138     public final int getPriority() {
139         return mFilter.getPriority();
140     }
141 
142     /**
143      * @see IntentFilter#setOrder(int)
144      */
setOrder(int order)145     public final void setOrder(int order) {
146         mFilter.setOrder(order);
147         onChanged();
148     }
149 
150     /**
151      * @see IntentFilter#getOrder()
152      */
getOrder()153     public final int getOrder() {
154         return mFilter.getOrder();
155     }
156 
157     /**
158      * @see IntentFilter#getAutoVerify()
159      */
getAutoVerify()160     public final boolean getAutoVerify() {
161         return mFilter.getAutoVerify();
162     }
163 
164     /**
165      * @see IntentFilter#handleAllWebDataURI()
166      */
handleAllWebDataURI()167     public final boolean handleAllWebDataURI() {
168         return mFilter.handleAllWebDataURI();
169     }
170 
171     /**
172      * @see IntentFilter#handlesWebUris(boolean)
173      */
handlesWebUris(boolean onlyWebSchemes)174     public final boolean handlesWebUris(boolean onlyWebSchemes) {
175         return mFilter.handlesWebUris(onlyWebSchemes);
176     }
177 
178     /**
179      * @see IntentFilter#needsVerification()
180      */
needsVerification()181     public final boolean needsVerification() {
182         return mFilter.needsVerification();
183     }
184 
185     /**
186      * @see IntentFilter#setVerified(boolean)
187      */
setVerified(boolean verified)188     public void setVerified(boolean verified) {
189         mFilter.setVerified(verified);
190         onChanged();
191     }
192 
193     /**
194      * @see IntentFilter#setVisibilityToInstantApp(int)
195      */
setVisibilityToInstantApp(int visibility)196     public void setVisibilityToInstantApp(int visibility) {
197         mFilter.setVisibilityToInstantApp(visibility);
198         onChanged();
199     }
200 
201     /**
202      * @see IntentFilter#getVisibilityToInstantApp()
203      */
getVisibilityToInstantApp()204     public int getVisibilityToInstantApp() {
205         return mFilter.getVisibilityToInstantApp();
206     }
207 
208     /**
209      * @see IntentFilter#isVisibleToInstantApp()
210      */
isVisibleToInstantApp()211     public boolean isVisibleToInstantApp() {
212         return mFilter.isVisibleToInstantApp();
213     }
214 
215     /**
216      * @see IntentFilter#isExplicitlyVisibleToInstantApp()
217      */
isExplicitlyVisibleToInstantApp()218     public boolean isExplicitlyVisibleToInstantApp() {
219         return mFilter.isExplicitlyVisibleToInstantApp();
220     }
221 
222     /**
223      * @see IntentFilter#isImplicitlyVisibleToInstantApp()
224      */
isImplicitlyVisibleToInstantApp()225     public boolean isImplicitlyVisibleToInstantApp() {
226         return mFilter.isImplicitlyVisibleToInstantApp();
227     }
228 
229     /**
230      * @see IntentFilter#addAction(String)
231      */
addAction(String action)232     public final void addAction(String action) {
233         mFilter.addAction(action);
234         onChanged();
235     }
236 
237     /**
238      * @see IntentFilter#countActions()
239      */
countActions()240     public final int countActions() {
241         return mFilter.countActions();
242     }
243 
244     /**
245      * @see IntentFilter#getAction(int)
246      */
getAction(int index)247     public final String getAction(int index) {
248         return mFilter.getAction(index);
249     }
250 
251     /**
252      * @see IntentFilter#hasAction(String)
253      */
hasAction(String action)254     public final boolean hasAction(String action) {
255         return mFilter.hasAction(action);
256     }
257 
258     /**
259      * @see IntentFilter#matchAction(String)
260      */
matchAction(String action)261     public final boolean matchAction(String action) {
262         return mFilter.matchAction(action);
263     }
264 
265     /**
266      * @see IntentFilter#actionsIterator()
267      */
actionsIterator()268     public final Iterator<String> actionsIterator() {
269         return maybeWatch(mFilter.actionsIterator());
270     }
271 
272     /**
273      * @see IntentFilter#addDataType(String)
274      */
addDataType(String type)275     public final void addDataType(String type)
276             throws IntentFilter.MalformedMimeTypeException {
277         mFilter.addDataType(type);
278         onChanged();
279     }
280 
281     /**
282      * @see IntentFilter#addDynamicDataType(String)
283      */
addDynamicDataType(String type)284     public final void addDynamicDataType(String type)
285             throws IntentFilter.MalformedMimeTypeException {
286         mFilter.addDynamicDataType(type);
287         onChanged();
288     }
289 
290     /**
291      * @see IntentFilter#clearDynamicDataTypes()
292      */
clearDynamicDataTypes()293     public final void clearDynamicDataTypes() {
294         mFilter.clearDynamicDataTypes();
295         onChanged();
296     }
297 
298     /**
299      * @see IntentFilter#countStaticDataTypes()
300      */
countStaticDataTypes()301     public int countStaticDataTypes() {
302         return mFilter.countStaticDataTypes();
303     }
304 
305     /**
306      * @see IntentFilter#hasDataType(String)
307      */
hasDataType(String type)308     public final boolean hasDataType(String type) {
309         return mFilter.hasDataType(type);
310     }
311 
312     /**
313      * @see IntentFilter#hasExactDynamicDataType(String)
314      */
hasExactDynamicDataType(String type)315     public final boolean hasExactDynamicDataType(String type) {
316         return mFilter.hasExactDynamicDataType(type);
317     }
318 
319     /**
320      * @see IntentFilter#hasExactStaticDataType(String)
321      */
hasExactStaticDataType(String type)322     public final boolean hasExactStaticDataType(String type) {
323         return mFilter.hasExactStaticDataType(type);
324     }
325 
326     /**
327      * @see IntentFilter#countDataTypes()
328      */
countDataTypes()329     public final int countDataTypes() {
330         return mFilter.countDataTypes();
331     }
332 
333     /**
334      * @see IntentFilter#getDataType(int)
335      */
getDataType(int index)336     public final String getDataType(int index) {
337         return mFilter.getDataType(index);
338     }
339 
340     /**
341      * @see IntentFilter#typesIterator()
342      */
typesIterator()343     public final Iterator<String> typesIterator() {
344         return maybeWatch(mFilter.typesIterator());
345     }
346 
347     /**
348     /**
349      * @see IntentFilter#dataTypes()
350      */
dataTypes()351     public final List<String> dataTypes() {
352         return mFilter.dataTypes();
353     }
354 
355     /**
356      * @see IntentFilter#addMimeGroup(String)
357      */
addMimeGroup(String name)358     public final void addMimeGroup(String name) {
359         mFilter.addMimeGroup(name);
360         onChanged();
361     }
362 
363     /**
364      * @see IntentFilter#hasMimeGroup(String)
365      */
hasMimeGroup(String name)366     public final boolean hasMimeGroup(String name) {
367         return mFilter.hasMimeGroup(name);
368     }
369 
370     /**
371      * @see IntentFilter#getMimeGroup(int)
372      */
getMimeGroup(int index)373     public final String getMimeGroup(int index) {
374         return mFilter.getMimeGroup(index);
375     }
376 
377     /**
378      * @see IntentFilter#countMimeGroups()
379      */
countMimeGroups()380     public final int countMimeGroups() {
381         return mFilter.countMimeGroups();
382     }
383 
384     /**
385      * @see IntentAction@mimeGroupsIterator()
386      */
mimeGroupsIterator()387     public final Iterator<String> mimeGroupsIterator() {
388         return maybeWatch(mFilter.mimeGroupsIterator());
389     }
390 
391     /**
392      * @see IntentFilter#addDataScheme(String)
393      */
addDataScheme(String scheme)394     public final void addDataScheme(String scheme) {
395         mFilter.addDataScheme(scheme);
396         onChanged();
397     }
398 
399     /**
400      * @see IntentFilter#countDataSchemes()
401      */
countDataSchemes()402     public final int countDataSchemes() {
403         return mFilter.countDataSchemes();
404     }
405 
406     /**
407      * @see IntentFilter#getDataScheme(int)
408      */
getDataScheme(int index)409     public final String getDataScheme(int index) {
410         return mFilter.getDataScheme(index);
411     }
412 
413     /**
414      * @see IntentFilter#hasDataScheme(String)
415      */
hasDataScheme(String scheme)416     public final boolean hasDataScheme(String scheme) {
417         return mFilter.hasDataScheme(scheme);
418     }
419 
420     /**
421      * @see IntentFilter#schemesIterator()
422      */
schemesIterator()423     public final Iterator<String> schemesIterator() {
424         return maybeWatch(mFilter.schemesIterator());
425     }
426 
427     /**
428      * @see IntentFilter#addDataSchemeSpecificPart(String, int)
429      */
addDataSchemeSpecificPart(String ssp, int type)430     public final void addDataSchemeSpecificPart(String ssp, int type) {
431         mFilter.addDataSchemeSpecificPart(ssp, type);
432         onChanged();
433     }
434 
435     /**
436      * @see IntentFilter#addDataSchemeSpecificPart(PatternMatcher)
437      */
addDataSchemeSpecificPart(PatternMatcher ssp)438     public final void addDataSchemeSpecificPart(PatternMatcher ssp) {
439         mFilter.addDataSchemeSpecificPart(ssp);
440         onChanged();
441     }
442 
443     /**
444      * @see IntentFilter#countDataSchemeSpecificParts()
445      */
countDataSchemeSpecificParts()446     public final int countDataSchemeSpecificParts() {
447         return mFilter.countDataSchemeSpecificParts();
448     }
449 
450     /**
451      * @see IntentFilter#getDataSchemeSpecificPart(int)
452      */
getDataSchemeSpecificPart(int index)453     public final PatternMatcher getDataSchemeSpecificPart(int index) {
454         return mFilter.getDataSchemeSpecificPart(index);
455     }
456 
457     /**
458      * @see IntentFilter#hasDataSchemeSpecificPart(String)
459      */
hasDataSchemeSpecificPart(String data)460     public final boolean hasDataSchemeSpecificPart(String data) {
461         return mFilter.hasDataSchemeSpecificPart(data);
462     }
463 
464     /**
465      * @see IntentFilter#schemeSpecificPartsIterator()
466      */
schemeSpecificPartsIterator()467     public final Iterator<PatternMatcher> schemeSpecificPartsIterator() {
468         return maybeWatch(mFilter.schemeSpecificPartsIterator());
469     }
470 
471     /**
472      * @see IntentFilter#addDataAuthority(String, String)
473      */
addDataAuthority(String host, String port)474     public final void addDataAuthority(String host, String port) {
475         mFilter.addDataAuthority(host, port);
476         onChanged();
477     }
478 
479     /**
480      * @see IntentFilter#addDataAuthority(IntentFilter.AuthorityEntry)
481      */
addDataAuthority(IntentFilter.AuthorityEntry ent)482     public final void addDataAuthority(IntentFilter.AuthorityEntry ent) {
483         mFilter.addDataAuthority(ent);
484         onChanged();
485     }
486 
487     /**
488      * @see IntentFilter#countDataAuthorities()
489      */
countDataAuthorities()490     public final int countDataAuthorities() {
491         return mFilter.countDataAuthorities();
492     }
493 
494     /**
495      * @see IntentFilter#getDataAuthority(int)
496      */
getDataAuthority(int index)497     public final IntentFilter.AuthorityEntry getDataAuthority(int index) {
498         return mFilter.getDataAuthority(index);
499     }
500 
501     /**
502      * @see IntentFilter#hasDataAuthority(Uri)
503      */
hasDataAuthority(Uri data)504     public final boolean hasDataAuthority(Uri data) {
505         return mFilter.hasDataAuthority(data);
506     }
507 
508     /**
509      * @see IntentFilter#authoritiesIterator()
510      */
authoritiesIterator()511     public final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator() {
512         return maybeWatch(mFilter.authoritiesIterator());
513     }
514 
515     /**
516      * @see IntentFilter#addDataPath(String, int)
517      */
addDataPath(String path, int type)518     public final void addDataPath(String path, int type) {
519         mFilter.addDataPath(path, type);
520         onChanged();
521     }
522 
523     /**
524      * @see IntentFilter#addDataPath(PatternMatcher)
525      */
addDataPath(PatternMatcher path)526     public final void addDataPath(PatternMatcher path) {
527         mFilter.addDataPath(path);
528         onChanged();
529     }
530 
531     /**
532      * @see IntentFilter#countDataPaths()
533      */
countDataPaths()534     public final int countDataPaths() {
535         return mFilter.countDataPaths();
536     }
537 
538     /**
539      * @see IntentFilter#getDataPath(int)
540      */
getDataPath(int index)541     public final PatternMatcher getDataPath(int index) {
542         return mFilter.getDataPath(index);
543     }
544 
545     /**
546      * @see IntentFilter#hasDataPath(String)
547      */
hasDataPath(String data)548     public final boolean hasDataPath(String data) {
549         return mFilter.hasDataPath(data);
550     }
551 
552     /**
553      * @see IntentFilter#pathsIterator()
554      */
pathsIterator()555     public final Iterator<PatternMatcher> pathsIterator() {
556         return maybeWatch(mFilter.pathsIterator());
557     }
558 
559     /**
560      * @see IntentFilter#matchDataAuthority(Uri)
561      */
matchDataAuthority(Uri data)562     public final int matchDataAuthority(Uri data) {
563         return mFilter.matchDataAuthority(data);
564     }
565 
566     /**
567      * @see IntentFilter#matchDataAuthority(Uri, boolean)
568      */
matchDataAuthority(Uri data, boolean wildcardSupported)569     public final int matchDataAuthority(Uri data, boolean wildcardSupported) {
570         return mFilter.matchDataAuthority(data, wildcardSupported);
571     }
572 
573     /**
574      * @see IntentFilter#matchData(String, String, Uri)
575      */
matchData(String type, String scheme, Uri data)576     public final int matchData(String type, String scheme, Uri data) {
577         return mFilter.matchData(type, scheme, data);
578     }
579 
580     /**
581      * @see IntentFilter#addCategory(String)
582      */
addCategory(String category)583     public final void addCategory(String category) {
584         mFilter.addCategory(category);
585     }
586 
587     /**
588      * @see IntentFilter#countCategories()
589      */
countCategories()590     public final int countCategories() {
591         return mFilter.countCategories();
592     }
593 
594     /**
595      * @see IntentFilter#getCategory(int)
596      */
getCategory(int index)597     public final String getCategory(int index) {
598         return mFilter.getCategory(index);
599     }
600 
601     /**
602      * @see IntentFilter#hasCategory(String)
603      */
hasCategory(String category)604     public final boolean hasCategory(String category) {
605         return mFilter.hasCategory(category);
606     }
607 
608     /**
609      * @see IntentFilter#categoriesIterator()
610      */
categoriesIterator()611     public final Iterator<String> categoriesIterator() {
612         return maybeWatch(mFilter.categoriesIterator());
613     }
614 
615     /**
616      * @see IntentFilter#matchCategories(Set<String>)
617      */
matchCategories(Set<String> categories)618     public final String matchCategories(Set<String> categories) {
619         return mFilter.matchCategories(categories);
620     }
621 
622     /**
623      * @see IntentFilter#match(ContentResolver, Intent, boolean, String)
624      */
match(ContentResolver resolver, Intent intent, boolean resolve, String logTag)625     public final int match(ContentResolver resolver, Intent intent,
626             boolean resolve, String logTag) {
627         return mFilter.match(resolver, intent,
628                 resolve, logTag);
629     }
630 
631     /**
632      * @see IntentFilter#match(String, String, String, Uri, Set<String>, String)
633      */
match(String action, String type, String scheme, Uri data, Set<String> categories, String logTag)634     public final int match(String action, String type, String scheme,
635             Uri data, Set<String> categories, String logTag) {
636         return mFilter.match(action, type, scheme,
637                 data, categories, logTag);
638     }
639 
640     /**
641      * @see IntentFilter#match(String, String, String, Uri, Set<String>, String, boolean,
642             Collection<String> ignoreActions)
643      */
match(String action, String type, String scheme, Uri data, Set<String> categories, String logTag, boolean supportWildcards, Collection<String> ignoreActions)644     public final int match(String action, String type, String scheme,
645             Uri data, Set<String> categories, String logTag, boolean supportWildcards,
646             Collection<String> ignoreActions) {
647         return mFilter.match(action, type, scheme,
648                 data, categories, logTag, supportWildcards,
649                 ignoreActions);
650     }
651 
652     /**
653      * @see IntentFilter#dump(Printer, String)
654      */
dump(Printer du, String prefix)655     public void dump(Printer du, String prefix) {
656         mFilter.dump(du, prefix);
657     }
658 
659     /**
660      * @see IntentFilter#describeContents()
661      */
describeContents()662     public final int describeContents() {
663         return mFilter.describeContents();
664     }
665 
666     /**
667      * @see IntentFilter#debugCheck()
668      */
debugCheck()669     public boolean debugCheck() {
670         return mFilter.debugCheck();
671     }
672 
673     /**
674      * @see IntentFilter#checkDataPathAndSchemeSpecificParts()
675      */
checkDataPathAndSchemeSpecificParts()676     public boolean checkDataPathAndSchemeSpecificParts() {
677         return mFilter.checkDataPathAndSchemeSpecificParts();
678     }
679 
680     /**
681      * @see IntentFilter#getHostsList()
682      */
getHostsList()683     public ArrayList<String> getHostsList() {
684         return mFilter.getHostsList();
685     }
686 
687     /**
688      * @see IntentFilter#getHosts()
689      */
getHosts()690     public String[] getHosts() {
691         return mFilter.getHosts();
692     }
693 
694     /**
695      * Convert a list of {@link IntentFilter} into a list of {@link WatchedIntentFilter}
696      */
toWatchedIntentFilterList(List<IntentFilter> inList)697     public static List<WatchedIntentFilter> toWatchedIntentFilterList(List<IntentFilter> inList) {
698         ArrayList<WatchedIntentFilter> outList = new ArrayList<>();
699         for (int i = 0; i < inList.size(); i++) {
700             outList.add(new WatchedIntentFilter(inList.get(i)));
701         }
702         return outList;
703     }
704 
705     /**
706      * Convert a list of {@link IntentFilter} into a list of {@link WatchedIntentFilter}
707      */
toIntentFilterList(List<WatchedIntentFilter> inList)708     public static List<IntentFilter> toIntentFilterList(List<WatchedIntentFilter> inList) {
709         ArrayList<IntentFilter> outList = new ArrayList<>();
710         for (int i = 0; i < inList.size(); i++) {
711             outList.add(inList.get(i).getIntentFilter());
712         }
713         return outList;
714     }
715 
716     /**
717      * Create a snapshot by cloning the object.
718      */
snapshot()719     public WatchedIntentFilter snapshot() {
720         return new WatchedIntentFilter(this);
721     }
722 }
723