Add logic to SatelliteAccessController class

Bug: 313773568
Test: atest SatelliteAccessControllerTest
atest SatelliteManagerTestOnMockService

Change-Id: I5eb3651baed905187cb27040a2135199e9f5c24d
diff --git a/utils/satellite/tools/Android.bp b/utils/satellite/tools/Android.bp
index 9aacdd9..d48b911 100644
--- a/utils/satellite/tools/Android.bp
+++ b/utils/satellite/tools/Android.bp
@@ -39,6 +39,15 @@
     ],
 }
 
+// A tool to look up a location in the input binary satellite S2 file.
+java_binary_host {
+    name: "satellite_location_lookup",
+    main_class: "com.android.telephony.tools.sats2.SatS2LocationLookup",
+    static_libs: [
+        "satellite-s2storage-tools",
+    ],
+}
+
 // A tool to create a test satellite S2 file.
 java_binary_host {
     name: "satellite_createsats2file_test",
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
index b701a7b..bc25d6b 100644
--- a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
@@ -30,18 +30,19 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.Scanner;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 /** A util class for creating a satellite S2 file from the list of S2 cells. */
 public final class SatS2FileCreator {
     /**
      * @param inputFile The input text file containing the list of S2 Cell IDs. Each line in the
-     *                  file contains a number in the range of a signed-64bit number which
+     *                  file contains a number in the range of an unsigned-64bit number which
      *                  represents the ID of a S2 cell.
      * @param s2Level The S2 level of all S2 cells in the input file.
      * @param isAllowedList {@code true} means the input file contains an allowed list of S2 cells.
@@ -57,12 +58,12 @@
         System.out.println("Number of S2 cells read from file:" + s2Cells.size());
 
         // Convert the input list of S2 Cells into the list of sorted S2CellId
-        List<S2CellId> sortedS2CellIds = s2Cells.stream()
-                .map(x -> new S2CellId(x))
-                .collect(Collectors.toList());
+        System.out.println("Denormalizing S2 Cell IDs to the expected s2 level=" + s2Level);
+        List<S2CellId> sortedS2CellIds = denormalize(s2Cells, s2Level);
         // IDs of S2CellId are converted to unsigned long numbers, which will be then used to
         // compare S2CellId.
         Collections.sort(sortedS2CellIds);
+        System.out.println("Number of S2 cell IDs:" + sortedS2CellIds.size());
 
         // Compress the list of S2CellId into S2 ranges
         List<SatS2Range> satS2Ranges = createSatS2Ranges(sortedS2CellIds, s2Level);
@@ -132,25 +133,56 @@
      * Read a list of S2 cells from the inputFile.
      *
      * @param inputFile A file containing the list of S2 cells. Each line in the inputFile contains
-     *                  a long number - the ID of a S2 cell.
+     *                  an unsigned long number - the ID of a S2 cell.
      * @return A list of S2 cells.
      */
     private static List<Long> readS2CellsFromFile(String inputFile) throws Exception {
         List<Long> s2Cells = new ArrayList();
         InputStream inputStream = new FileInputStream(inputFile);
         try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) {
-            while (scanner.hasNextLong()) {
-                s2Cells.add(scanner.nextLong());
-            }
-            if (scanner.hasNextLine()) {
-                throw new IllegalStateException("Input s2 cell file has invalid format, "
-                        + "current line=" + scanner.nextLine());
+            while (scanner.hasNextLine()) {
+                String line = scanner.nextLine();
+                try {
+                    s2Cells.add(Long.parseUnsignedLong(line));
+                } catch (Exception ex) {
+                    throw new IllegalStateException("Input s2 cell file has invalid format, "
+                            + "current line=" + line);
+                }
             }
         }
         return s2Cells;
     }
 
     /**
+     * Convert the list of S2 Cell numbers into the list of S2 Cell IDs at the expected level.
+     */
+    private static List<S2CellId> denormalize(List<Long> s2CellNumbers, int s2Level) {
+        Set<S2CellId> result = new HashSet<>();
+        for (long s2CellNumber : s2CellNumbers) {
+            S2CellId s2CellId = new S2CellId(s2CellNumber);
+            if (s2CellId.level() == s2Level) {
+                if (!result.contains(s2CellId)) {
+                    result.add(s2CellId);
+                }
+            } else if (s2CellId.level() < s2Level) {
+                S2CellId childEnd = s2CellId.childEnd(s2Level);
+                for (s2CellId = s2CellId.childBegin(s2Level); !s2CellId.equals(childEnd);
+                        s2CellId = s2CellId.next()) {
+                    if (!result.contains(s2CellId)) {
+                        result.add(s2CellId);
+                    }
+                }
+            } else {
+                S2CellId parent = s2CellId.parent(s2Level);
+                if (!result.contains(parent)) {
+                    result.add(parent);
+                }
+            }
+        }
+        return new ArrayList(result);
+    }
+
+    /**
      * Compress the list of sorted S2CellId into S2 ranges.
      *
      * @param sortedS2CellIds List of S2CellId sorted in ascending order.
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2LocationLookup.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2LocationLookup.java
new file mode 100644
index 0000000..444ff8d
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2LocationLookup.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.google.common.geometry.S2CellId;
+import com.google.common.geometry.S2LatLng;
+
+import java.io.File;
+
+/** A util class for checking if a location is in the input satellite S2 file. */
+public final class SatS2LocationLookup {
+    /**
+     *  A util method for checking if a location is in the input satellite S2 file.
+     */
+    public static void main(String[] args) throws Exception {
+        Arguments arguments = new Arguments();
+        JCommander.newBuilder()
+                .addObject(arguments)
+                .build()
+                .parse(args);
+
+        try (SatS2RangeFileReader satS2RangeFileReader =
+                     SatS2RangeFileReader.open(new File(arguments.inputFile))) {
+            S2CellId s2CellId = getS2CellId(arguments.latDegrees, arguments.lngDegrees,
+                    satS2RangeFileReader.getS2Level());
+            System.out.println("s2CellId=" + Long.toUnsignedString(s2CellId.id()));
+            if (satS2RangeFileReader.findEntryByCellId(s2CellId.id()) == null) {
+                System.out.println("The input file does not contain the input location");
+            } else {
+                System.out.println("The input file contains the input location");
+            }
+        }
+    }
+
+    private static S2CellId getS2CellId(double latDegrees, double lngDegrees, int s2Level) {
+        // Create the leaf S2 cell containing the given S2LatLng
+        S2CellId cellId = S2CellId.fromLatLng(S2LatLng.fromDegrees(latDegrees, lngDegrees));
+
+        // Return the S2 cell at the expected S2 level
+        return cellId.parent(s2Level);
+    }
+
+    private static class Arguments {
+        @Parameter(names = "--input-file",
+                description = "sat s2 file",
+                required = true)
+        public String inputFile;
+
+        @Parameter(names = "--lat-degrees",
+                description = "lat degress of the location",
+                required = true)
+        public double latDegrees;
+
+        @Parameter(names = "--lng-degrees",
+                description = "lng degress of the location",
+                required = true)
+        public double lngDegrees;
+    }
+}