Skip to content

Commit 55c1fe2

Browse files
Todd Kennedyandi34
authored andcommitted
DO NOT MERGE Fix intent filter priorities
Since this is a backport, there is only one rule that guards intent filter priorities: 1) Updates will NOT be granted a priority greater than the priority defined on the system image. NOTE: I had to bring in pieces of ag/526831 so intent filters could be collected and matched Bug: 27450489 Change-Id: Ifcec4d7a59e684331399abc41eea1bd6876155a4 (cherry picked from commit 60351d3)
1 parent f415bf5 commit 55c1fe2

File tree

3 files changed

+447
-5
lines changed

3 files changed

+447
-5
lines changed

core/java/android/content/IntentFilter.java

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,11 @@ public final boolean hasDataType(String type) {
564564
return mDataTypes != null && findMimeType(type);
565565
}
566566

567+
/** @hide */
568+
public final boolean hasExactDataType(String type) {
569+
return mDataTypes != null && mDataTypes.contains(type);
570+
}
571+
567572
/**
568573
* Return the number of data types in the filter.
569574
*/
@@ -681,6 +686,29 @@ public int getPort() {
681686
return mPort;
682687
}
683688

689+
/** @hide */
690+
public boolean match(AuthorityEntry other) {
691+
if (mWild != other.mWild) {
692+
return false;
693+
}
694+
if (!mHost.equals(other.mHost)) {
695+
return false;
696+
}
697+
if (mPort != other.mPort) {
698+
return false;
699+
}
700+
return true;
701+
}
702+
703+
@Override
704+
public boolean equals(Object obj) {
705+
if (obj instanceof AuthorityEntry) {
706+
final AuthorityEntry other = (AuthorityEntry)obj;
707+
return match(other);
708+
}
709+
return false;
710+
}
711+
684712
/**
685713
* Determine whether this AuthorityEntry matches the given data Uri.
686714
* <em>Note that this comparison is case-sensitive, unlike formal
@@ -715,7 +743,7 @@ public int match(Uri data) {
715743
}
716744
return MATCH_CATEGORY_HOST;
717745
}
718-
};
746+
}
719747

720748
/**
721749
* Add a new Intent data "scheme specific part" to match against. The filter must
@@ -792,6 +820,21 @@ public final boolean hasDataSchemeSpecificPart(String data) {
792820
return false;
793821
}
794822

823+
/** @hide */
824+
public final boolean hasDataSchemeSpecificPart(PatternMatcher ssp) {
825+
if (mDataSchemeSpecificParts == null) {
826+
return false;
827+
}
828+
final int numDataSchemeSpecificParts = mDataSchemeSpecificParts.size();
829+
for (int i = 0; i < numDataSchemeSpecificParts; i++) {
830+
final PatternMatcher pe = mDataSchemeSpecificParts.get(i);
831+
if (pe.getType() == ssp.getType() && pe.getPath().equals(ssp.getPath())) {
832+
return true;
833+
}
834+
}
835+
return false;
836+
}
837+
795838
/**
796839
* Return an iterator over the filter's data scheme specific parts.
797840
*/
@@ -860,6 +903,20 @@ public final boolean hasDataAuthority(Uri data) {
860903
return matchDataAuthority(data) >= 0;
861904
}
862905

906+
/** @hide */
907+
public final boolean hasDataAuthority(AuthorityEntry auth) {
908+
if (mDataAuthorities == null) {
909+
return false;
910+
}
911+
final int numDataAuthorities = mDataAuthorities.size();
912+
for (int i = 0; i < numDataAuthorities; i++) {
913+
if (mDataAuthorities.get(i).match(auth)) {
914+
return true;
915+
}
916+
}
917+
return false;
918+
}
919+
863920
/**
864921
* Return an iterator over the filter's data authorities.
865922
*/
@@ -942,6 +999,21 @@ public final boolean hasDataPath(String data) {
942999
return false;
9431000
}
9441001

1002+
/** @hide */
1003+
public final boolean hasDataPath(PatternMatcher path) {
1004+
if (mDataPaths == null) {
1005+
return false;
1006+
}
1007+
final int numDataPaths = mDataPaths.size();
1008+
for (int i = 0; i < numDataPaths; i++) {
1009+
final PatternMatcher pe = mDataPaths.get(i);
1010+
if (pe.getType() == path.getType() && pe.getPath().equals(path.getPath())) {
1011+
return true;
1012+
}
1013+
}
1014+
return false;
1015+
}
1016+
9451017
/**
9461018
* Return an iterator over the filter's data paths.
9471019
*/

services/java/com/android/server/IntentResolver.java

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,124 @@ public void addFilter(F f) {
6969
}
7070
}
7171

72+
private boolean filterEquals(IntentFilter f1, IntentFilter f2) {
73+
int s1 = f1.countActions();
74+
int s2 = f2.countActions();
75+
if (s1 != s2) {
76+
return false;
77+
}
78+
for (int i=0; i<s1; i++) {
79+
if (!f2.hasAction(f1.getAction(i))) {
80+
return false;
81+
}
82+
}
83+
s1 = f1.countCategories();
84+
s2 = f2.countCategories();
85+
if (s1 != s2) {
86+
return false;
87+
}
88+
for (int i=0; i<s1; i++) {
89+
if (!f2.hasCategory(f1.getCategory(i))) {
90+
return false;
91+
}
92+
}
93+
s1 = f1.countDataTypes();
94+
s2 = f2.countDataTypes();
95+
if (s1 != s2) {
96+
return false;
97+
}
98+
for (int i=0; i<s1; i++) {
99+
if (!f2.hasExactDataType(f1.getDataType(i))) {
100+
return false;
101+
}
102+
}
103+
s1 = f1.countDataSchemes();
104+
s2 = f2.countDataSchemes();
105+
if (s1 != s2) {
106+
return false;
107+
}
108+
for (int i=0; i<s1; i++) {
109+
if (!f2.hasDataScheme(f1.getDataScheme(i))) {
110+
return false;
111+
}
112+
}
113+
s1 = f1.countDataAuthorities();
114+
s2 = f2.countDataAuthorities();
115+
if (s1 != s2) {
116+
return false;
117+
}
118+
for (int i=0; i<s1; i++) {
119+
if (!f2.hasDataAuthority(f1.getDataAuthority(i))) {
120+
return false;
121+
}
122+
}
123+
s1 = f1.countDataPaths();
124+
s2 = f2.countDataPaths();
125+
if (s1 != s2) {
126+
return false;
127+
}
128+
for (int i=0; i<s1; i++) {
129+
if (!f2.hasDataPath(f1.getDataPath(i))) {
130+
return false;
131+
}
132+
}
133+
s1 = f1.countDataSchemeSpecificParts();
134+
s2 = f2.countDataSchemeSpecificParts();
135+
if (s1 != s2) {
136+
return false;
137+
}
138+
for (int i=0; i<s1; i++) {
139+
if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) {
140+
return false;
141+
}
142+
}
143+
return true;
144+
}
145+
146+
private ArrayList<F> collectFilters(F[] array, IntentFilter matching) {
147+
ArrayList<F> res = null;
148+
if (array != null) {
149+
for (int i=0; i<array.length; i++) {
150+
F cur = array[i];
151+
if (cur == null) {
152+
break;
153+
}
154+
if (filterEquals(cur, matching)) {
155+
if (res == null) {
156+
res = new ArrayList<F>();
157+
}
158+
res.add(cur);
159+
}
160+
}
161+
}
162+
return res;
163+
}
164+
165+
public ArrayList<F> findFilters(IntentFilter matching) {
166+
if (matching.countDataSchemes() == 1) {
167+
// Fast case.
168+
return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching);
169+
} else if (matching.countDataTypes() != 0 && matching.countActions() == 1) {
170+
// Another fast case.
171+
return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching);
172+
} else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0
173+
&& matching.countActions() == 1) {
174+
// Last fast case.
175+
return collectFilters(mActionToFilter.get(matching.getAction(0)), matching);
176+
} else {
177+
ArrayList<F> res = null;
178+
for (F cur : mFilters) {
179+
if (filterEquals(cur, matching)) {
180+
if (res == null) {
181+
res = new ArrayList<F>();
182+
}
183+
res.add(cur);
184+
}
185+
}
186+
return res;
187+
}
188+
}
189+
72190
public void removeFilter(F f) {
73191
removeFilterInternal(f);
74192
mFilters.remove(f);

0 commit comments

Comments
 (0)