1 /*
2  * Copyright (C) 2024 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 package android.content.cts;
17 
18 import static android.content.UriRelativeFilterGroup.ACTION_ALLOW;
19 import static android.content.UriRelativeFilterGroup.ACTION_BLOCK;
20 import static android.os.PatternMatcher.PATTERN_LITERAL;
21 
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 
25 import android.content.UriRelativeFilter;
26 import android.content.UriRelativeFilterGroup;
27 import android.content.pm.Flags;
28 import android.net.Uri;
29 import android.platform.test.annotations.RequiresFlagsEnabled;
30 
31 import androidx.test.runner.AndroidJUnit4;
32 
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 @RunWith(AndroidJUnit4.class)
41 public class UriRelativeFilterGroupTest {
42     private static final String DOMAIN = "https://testhost";
43     private static final String PATH = "/testpath";
44     private static final String QUERY = "query=test";
45     private static final String FRAGMENT = "testfragment";
46 
47     private static final int PATH_MASK = 1;
48     private static final int QUERY_MASK = 1 << 1;
49     private static final int FRAGMENT_MASK = 1 << 2;
50 
51     private List<UriRelativeFilterGroup> mGroups = new ArrayList<>();
52 
53     @Before
clearGroups()54     public void clearGroups() {
55         mGroups.clear();
56     }
57 
58     @Test
59     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testGroupMatch()60     public void testGroupMatch() {
61         for (int i = 1; i <= 7; i++) {
62             UriRelativeFilterGroup group = maskToGroup(ACTION_ALLOW, i);
63             for (int j = 0; j <= 7; j++) {
64                 Uri uri = maskToUri(j);
65                 if ((i & j) == i) {
66                     assertTrue(group + " should match " + uri, group.matchData(uri));
67                 } else {
68                     assertFalse(group + " should not match " + uri, group.matchData(uri));
69                 }
70             }
71         }
72     }
73 
74     @Test
75     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testMatchGroupsToUri_matchAnyGroup()76     public void testMatchGroupsToUri_matchAnyGroup() {
77         mGroups.add(maskToGroup(ACTION_ALLOW, PATH_MASK));
78         mGroups.add(maskToGroup(ACTION_ALLOW, QUERY_MASK));
79         mGroups.add(maskToGroup(ACTION_ALLOW, FRAGMENT_MASK));
80         assertTrue(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(PATH_MASK)));
81         assertTrue(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(QUERY_MASK)));
82         assertTrue(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(FRAGMENT_MASK)));
83     }
84 
85     @Test
86     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testMachGroupsToUri_blockMatch()87     public void testMachGroupsToUri_blockMatch() {
88         mGroups.add(maskToGroup(ACTION_BLOCK, PATH_MASK));
89         mGroups.add(maskToGroup(ACTION_ALLOW, PATH_MASK | QUERY_MASK));
90         mGroups.add(maskToGroup(ACTION_ALLOW, FRAGMENT_MASK));
91         assertFalse(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(PATH_MASK)));
92         assertFalse(UriRelativeFilterGroup.matchGroupsToUri(mGroups,
93                 maskToUri(PATH_MASK | QUERY_MASK)));
94         assertTrue(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(FRAGMENT_MASK)));
95     }
96 
97     @Test
98     @RequiresFlagsEnabled(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS)
testMatchGroupsToUri_ignoreNonMatchingBlocks()99     public void testMatchGroupsToUri_ignoreNonMatchingBlocks() {
100         mGroups.add(maskToGroup(ACTION_BLOCK, PATH_MASK));
101         mGroups.add(maskToGroup(ACTION_ALLOW, FRAGMENT_MASK));
102         assertFalse(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(PATH_MASK)));
103         assertTrue(UriRelativeFilterGroup.matchGroupsToUri(mGroups, maskToUri(FRAGMENT_MASK)));
104     }
105 
maskToUri(int mask)106     private Uri maskToUri(int mask) {
107         String uri = DOMAIN;
108         if ((mask & PATH_MASK) > 0) {
109             uri += PATH;
110         }
111         if ((mask & QUERY_MASK) > 0) {
112             uri += "?" + QUERY;
113         }
114         if ((mask & FRAGMENT_MASK) > 0) {
115             uri += "#" + FRAGMENT;
116         }
117         return Uri.parse(uri);
118     }
119 
maskToGroup(int action, int mask)120     private UriRelativeFilterGroup maskToGroup(int action, int mask) {
121         UriRelativeFilterGroup group = new UriRelativeFilterGroup(action);
122         if ((mask & PATH_MASK) > 0) {
123             group.addUriRelativeFilter(
124                     new UriRelativeFilter(UriRelativeFilter.PATH, PATTERN_LITERAL, PATH));
125         }
126         if ((mask & QUERY_MASK) > 0) {
127             group.addUriRelativeFilter(
128                     new UriRelativeFilter(UriRelativeFilter.QUERY, PATTERN_LITERAL, QUERY));
129         }
130         if ((mask & FRAGMENT_MASK) > 0) {
131             group.addUriRelativeFilter(
132                     new UriRelativeFilter(UriRelativeFilter.FRAGMENT, PATTERN_LITERAL, FRAGMENT));
133         }
134         return group;
135     }
136 }
137