• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.phone.satellite.accesscontrol;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.telephony.Rlog;
21 
22 import com.android.internal.telephony.flags.FeatureFlags;
23 import com.android.telephony.sats2range.read.SatS2RangeFileReader;
24 import com.android.telephony.sats2range.read.SuffixTableRange;
25 
26 import com.google.common.geometry.S2CellId;
27 import com.google.common.geometry.S2LatLng;
28 
29 import java.io.File;
30 import java.io.IOException;
31 import java.util.Objects;
32 
33 /**
34  * An implementation of {@link SatelliteOnDeviceAccessController} that uses
35  * {@link SatS2RangeFileReader}.
36  */
37 final class S2RangeSatelliteOnDeviceAccessController extends SatelliteOnDeviceAccessController {
38     private static final String TAG = "S2RangeSatelliteOnDeviceAccessController";
39     private static final boolean DBG = false;
40 
41     @NonNull
42     private final SatS2RangeFileReader mSatS2RangeFileReader;
43 
44     private final int mS2Level;
45 
46     /** Feature flags to control behavior and errors. */
47     @NonNull
48     private final FeatureFlags mFeatureFlags;
49 
S2RangeSatelliteOnDeviceAccessController( @onNull SatS2RangeFileReader satS2RangeFileReader, int s2Level, @NonNull FeatureFlags featureFlags)50     private S2RangeSatelliteOnDeviceAccessController(
51             @NonNull SatS2RangeFileReader satS2RangeFileReader,
52             int s2Level,
53             @NonNull FeatureFlags featureFlags) {
54         mSatS2RangeFileReader = Objects.requireNonNull(satS2RangeFileReader);
55         mS2Level = s2Level;
56         mFeatureFlags = featureFlags;
57     }
58 
59     /**
60      * Returns a new {@link S2RangeSatelliteOnDeviceAccessController} using the specified data file.
61      *
62      * @param file The input file that contains the S2-range-based access restriction information.
63      * @throws IOException              in the event of a problem while reading the underlying file.
64      * @throws IllegalArgumentException if either the S2 level defined by
65      *                                  {@code config_oem_enabled_satellite_s2cell_level} or the
66      *                                  satellite access allow defined by
67      *                                  {@code config_oem_enabled_satellite_access_allow} does not
68      *                                  match the values included in the
69      *                                  header of the input file.
70      */
create( @onNull File file, FeatureFlags featureFlags)71     public static S2RangeSatelliteOnDeviceAccessController create(
72             @NonNull File file, FeatureFlags featureFlags)
73             throws IOException, IllegalArgumentException {
74         SatS2RangeFileReader reader = SatS2RangeFileReader.open(file);
75         int s2Level = reader.getS2Level();
76         return new S2RangeSatelliteOnDeviceAccessController(reader, s2Level, featureFlags);
77     }
78 
createLocationTokenForLatLng( double latDegrees, double lngDegrees, int s2Level)79     public static LocationToken createLocationTokenForLatLng(
80             double latDegrees, double lngDegrees, int s2Level) {
81         return new LocationTokenImpl(getS2CellId(latDegrees, lngDegrees, s2Level).id());
82     }
83 
84     @Override
isSatCommunicationAllowedAtLocation(LocationToken locationToken)85     public boolean isSatCommunicationAllowedAtLocation(LocationToken locationToken)
86             throws IOException {
87         if (!(locationToken instanceof LocationTokenImpl)) {
88             throw new IllegalArgumentException("Unknown locationToken=" + locationToken);
89         }
90         LocationTokenImpl locationTokenImpl = (LocationTokenImpl) locationToken;
91         return isSatCommunicationAllowedAtLocation(locationTokenImpl.getS2CellId());
92     }
93 
94     @Override
getS2Level()95     public int getS2Level() {
96         return mS2Level;
97     }
98 
isSatCommunicationAllowedAtLocation(long s2CellId)99     private boolean isSatCommunicationAllowedAtLocation(long s2CellId) throws IOException {
100         SuffixTableRange entry = mSatS2RangeFileReader.findEntryByCellId(s2CellId);
101         if (mSatS2RangeFileReader.isAllowedList()) {
102             // The file contains an allowed list of S2 cells. Thus, satellite is allowed if an
103             // entry is found
104             return (entry != null);
105         } else {
106             // The file contains a disallowed list of S2 cells. Thus, satellite is allowed if an
107             // entry is not found
108             return (entry == null);
109         }
110     }
111 
getS2CellId(double latDegrees, double lngDegrees, int s2Level)112     private static S2CellId getS2CellId(double latDegrees, double lngDegrees, int s2Level) {
113         // Create the leaf S2 cell containing the given S2LatLng
114         S2CellId cellId = S2CellId.fromLatLng(S2LatLng.fromDegrees(latDegrees, lngDegrees));
115 
116         // Return the S2 cell at the expected S2 level
117         return cellId.parent(s2Level);
118     }
119 
120     @Override
close()121     public void close() throws IOException {
122         mSatS2RangeFileReader.close();
123     }
124 
logd(@onNull String log)125     private static void logd(@NonNull String log) {
126         Rlog.d(TAG, log);
127     }
128 
loge(@onNull String log)129     private static void loge(@NonNull String log) {
130         Rlog.e(TAG, log);
131     }
132 
133     private static class LocationTokenImpl extends LocationToken {
134 
135         private final long mS2CellId;
136 
LocationTokenImpl(long s2CellId)137         private LocationTokenImpl(long s2CellId) {
138             this.mS2CellId = s2CellId;
139         }
140 
getS2CellId()141         long getS2CellId() {
142             return mS2CellId;
143         }
144 
145         @Override
toString()146         public String toString() {
147             return DBG ? toPiiString() : "LocationToken{<redacted>}";
148         }
149 
150         @Override
toPiiString()151         public String toPiiString() {
152             return "LocationToken{"
153                     + "mS2CellId=" + mS2CellId
154                     + '}';
155         }
156 
157         @Override
equals(Object o)158         public boolean equals(Object o) {
159             if (this == o) {
160                 return true;
161             }
162             if (!(o instanceof LocationTokenImpl)) {
163                 return false;
164             }
165             LocationTokenImpl that = (LocationTokenImpl) o;
166             return mS2CellId == that.mS2CellId;
167         }
168 
169         @Override
hashCode()170         public int hashCode() {
171             return Objects.hash(mS2CellId);
172         }
173     }
174 
175     @Override
176     @Nullable
getRegionalConfigIdForLocation(@onNull LocationToken locationToken)177     public Integer getRegionalConfigIdForLocation(@NonNull LocationToken locationToken)
178             throws IOException {
179         if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
180             logd("getAccessControlConfigIdForLocation: carrierRoamingNbIotNtn is disabled");
181             return null;
182         }
183 
184         if (locationToken instanceof LocationTokenImpl locationTokenImpl) {
185             return getRegionalConfigIdForLocation(locationTokenImpl.getS2CellId());
186         } else {
187             throw new IllegalArgumentException("Unknown locationToken=" + locationToken);
188         }
189     }
190 
getRegionalConfigIdForLocation(long s2CellId)191     private Integer getRegionalConfigIdForLocation(long s2CellId) throws IOException {
192         SuffixTableRange entry = mSatS2RangeFileReader.findEntryByCellId(s2CellId);
193         return (entry == null) ? null : entry.getEntryValue();
194     }
195 }
196