1 /*
2  * Copyright (C) 2023 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.phone.satellite.accesscontrol;
18 
19 import static org.junit.Assert.assertTrue;
20 import static org.junit.Assert.fail;
21 
22 import androidx.test.ext.junit.runners.AndroidJUnit4;
23 
24 import com.android.storage.s2.S2LevelRange;
25 import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
26 import com.android.telephony.sats2range.utils.TestUtils;
27 import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
28 
29 import com.google.common.geometry.S2CellId;
30 import com.google.common.geometry.S2LatLng;
31 
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.MockitoAnnotations;
37 
38 import java.io.File;
39 import java.io.IOException;
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 @RunWith(AndroidJUnit4.class)
44 public class S2RangeSatelliteOnDeviceAccessControllerTest {
45     private File mFile;
46 
47     @Before
setUp()48     public void setUp() throws Exception {
49         MockitoAnnotations.initMocks(this);
50         mFile = File.createTempFile("test", ".data");
51         assertTrue(mFile.exists());
52     }
53 
54     @After
tearDown()55     public void tearDown() throws IOException {
56         if (mFile != null && mFile.exists()) {
57             assertTrue(mFile.delete());
58         }
59     }
60 
61     @Test
testSatelliteAccessControl_AllowedList()62     public void testSatelliteAccessControl_AllowedList() throws Exception {
63         testSatelliteAccessControl(true);
64     }
65 
66     @Test
testSatelliteAccessControl_DisallowedList()67     public void testSatelliteAccessControl_DisallowedList() throws Exception {
68         testSatelliteAccessControl(false);
69     }
70 
testSatelliteAccessControl(boolean isAllowedList)71     private void testSatelliteAccessControl(boolean isAllowedList) throws Exception {
72         SatS2RangeFileFormat fileFormat = null;
73         try {
74             fileFormat = createSatS2File(mFile, isAllowedList);
75         } catch (Exception ex) {
76             fail("Got unexpected exception in createSatS2File, ex=" + ex);
77         }
78 
79         // Validate the output block file
80         SatelliteOnDeviceAccessController accessController = null;
81         try {
82             accessController = SatelliteOnDeviceAccessController.create(mFile);
83             int s2Level = accessController.getS2Level();
84 
85             // Verify an edge cell of range 1 not in the output file
86             S2CellId s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 999));
87             S2LatLng s2LatLng = s2CellId.toLatLng();
88             SatelliteOnDeviceAccessController.LocationToken locationToken =
89                     SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
90                             s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
91             boolean isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
92             assertTrue(isAllowed != isAllowedList);
93 
94             // Verify cells in range1 present in the output file
95             for (int suffix = 1000; suffix < 2000; suffix++) {
96                 s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, suffix));
97                 s2LatLng = s2CellId.toLatLng();
98 
99                 // Lookup using location token
100                 locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
101                                 s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
102                 isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
103                 assertTrue(isAllowed == isAllowedList);
104             }
105 
106             // Verify the middle cell not in the output file
107             s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 2000));
108             s2LatLng = s2CellId.toLatLng();
109             locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
110                     s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
111             isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
112             assertTrue(isAllowed != isAllowedList);
113 
114             // Verify cells in range2 present in the output file
115             for (int suffix = 2001; suffix < 3000; suffix++) {
116                 s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, suffix));
117                 s2LatLng = s2CellId.toLatLng();
118                 locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
119                         s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
120                 isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
121                 assertTrue(isAllowed == isAllowedList);
122             }
123 
124             // Verify an edge cell of range 2 not in the output file
125             s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 3000));
126             s2LatLng = s2CellId.toLatLng();
127             locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
128                     s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
129             isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
130             assertTrue(isAllowed != isAllowedList);
131 
132             // Verify an edge cell of range 3 not in the output file
133             s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, 999));
134             s2LatLng = s2CellId.toLatLng();
135             locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
136                     s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
137             isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
138             assertTrue(isAllowed != isAllowedList);
139 
140             // Verify cells in range1 present in the output file
141             for (int suffix = 1000; suffix < 2000; suffix++) {
142                 s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, suffix));
143                 s2LatLng = s2CellId.toLatLng();
144                 locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
145                         s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
146                 isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
147                 assertTrue(isAllowed == isAllowedList);
148             }
149 
150             // Verify an edge cell of range 3 not in the output file
151             s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, 2000));
152             s2LatLng = s2CellId.toLatLng();
153             locationToken = SatelliteOnDeviceAccessController.createLocationTokenForLatLng(
154                     s2LatLng.latDegrees(), s2LatLng.lngDegrees(), s2Level);
155             isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
156             assertTrue(isAllowed != isAllowedList);
157         } catch (Exception ex) {
158             fail("Unexpected exception when validating the output ex=" + ex);
159         } finally {
160             if (accessController != null) {
161                 accessController.close();
162             }
163         }
164     }
165 
createSatS2File( File file, boolean isAllowedList)166     private SatS2RangeFileFormat createSatS2File(
167             File file, boolean isAllowedList) throws Exception {
168         SatS2RangeFileFormat fileFormat;
169         S2LevelRange range1, range2, range3;
170         try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(
171                 file, TestUtils.createS2RangeFileFormat(isAllowedList))) {
172             fileFormat = satS2RangeFileWriter.getFileFormat();
173 
174             // Two ranges that share a prefix.
175             range1 = new S2LevelRange(
176                     TestUtils.createCellId(fileFormat, 1, 1000, 1000),
177                     TestUtils.createCellId(fileFormat, 1, 1000, 2000));
178             range2 = new S2LevelRange(
179                     TestUtils.createCellId(fileFormat, 1, 1000, 2001),
180                     TestUtils.createCellId(fileFormat, 1, 1000, 3000));
181             // This range has a different prefix, so will be in a different suffix table.
182             range3 = new S2LevelRange(
183                     TestUtils.createCellId(fileFormat, 1, 1001, 1000),
184                     TestUtils.createCellId(fileFormat, 1, 1001, 2000));
185 
186             List<S2LevelRange> ranges = new ArrayList<>();
187             ranges.add(range1);
188             ranges.add(range2);
189             ranges.add(range3);
190             satS2RangeFileWriter.createSortedSuffixBlocks(ranges.iterator());
191         }
192         assertTrue(file.length() > 0);
193         return fileFormat;
194     }
195 }
196