Return list of packages

Test: aconfig_storage_file.test.java
Change-Id: I98d8e52df87b6aaccf8f21c5e136c3af803d2b72
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
index 9571568..1fbcb85 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/ByteBufferReader.java
@@ -63,4 +63,8 @@
     public void position(int newPosition) {
         mByteBuffer.position(newPosition);
     }
+
+    public int position() {
+        return mByteBuffer.position();
+    }
 }
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
index a45d12a..1e7c2ca 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java
@@ -19,10 +19,16 @@
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 public class PackageTable {
 
+    private static final int FINGERPRINT_BYTES = 8;
+    // int: mPackageId + int: mBooleanStartIndex + int: mNextOffset
+    private static final int NODE_SKIP_BYTES = 12;
+
     private Header mHeader;
     private ByteBufferReader mReader;
 
@@ -60,6 +66,18 @@
         return null;
     }
 
+    public List<String> getPackageList() {
+        List<String> list = new ArrayList<>(mHeader.mNumPackages);
+        mReader.position(mHeader.mNodeOffset);
+        int fingerprintBytes = mHeader.mVersion == 1 ? 0 : FINGERPRINT_BYTES;
+        int skipBytes = fingerprintBytes + NODE_SKIP_BYTES;
+        for (int i = 0; i < mHeader.mNumPackages; i++) {
+            list.add(mReader.readString());
+            mReader.position(mReader.position() + skipBytes);
+        }
+        return list;
+    }
+
     public Header getHeader() {
         return mHeader;
     }
diff --git a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/StorageFileProvider.java b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/StorageFileProvider.java
index f1a4e26..f75ac36 100644
--- a/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/StorageFileProvider.java
+++ b/tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/StorageFileProvider.java
@@ -39,13 +39,15 @@
     private static final String PMAP_FILE_EXT = ".package.map";
     private static final String FMAP_FILE_EXT = ".flag.map";
     private static final String VAL_FILE_EXT = ".val";
+    private static final StorageFileProvider DEFAULT_INSTANCE =
+            new StorageFileProvider(DEFAULT_MAP_PATH, DEFAULT_BOOT_PATH);
 
     private final String mMapPath;
     private final String mBootPath;
 
     /** @hide */
     public static StorageFileProvider getDefaultProvider() {
-        return new StorageFileProvider(DEFAULT_MAP_PATH, DEFAULT_BOOT_PATH);
+        return DEFAULT_INSTANCE;
     }
 
     /** @hide */
@@ -82,7 +84,9 @@
 
     /** @hide */
     public PackageTable getPackageTable(String container) {
-        return getPackageTable(Paths.get(mMapPath, container + PMAP_FILE_EXT));
+        return PackageTable.fromBytes(
+                mapStorageFile(
+                        Paths.get(mMapPath, container + PMAP_FILE_EXT), FileType.PACKAGE_MAP));
     }
 
     /** @hide */
@@ -97,11 +101,6 @@
                 mapStorageFile(Paths.get(mBootPath, container + VAL_FILE_EXT), FileType.FLAG_VAL));
     }
 
-    /** @hide */
-    public static PackageTable getPackageTable(Path path) {
-        return PackageTable.fromBytes(mapStorageFile(path, FileType.PACKAGE_MAP));
-    }
-
     // Map a storage file given file path
     private static MappedByteBuffer mapStorageFile(Path file, FileType type) {
         FileChannel channel = null;
diff --git a/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java b/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
index 5906d8b..812ce35 100644
--- a/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
+++ b/tools/aconfig/aconfig_storage_file/tests/srcs/PackageTableTest.java
@@ -27,6 +27,9 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import java.util.HashSet;
+import java.util.Set;
+
 @RunWith(JUnit4.class)
 public class PackageTableTest {
 
@@ -121,4 +124,22 @@
         assertEquals(4431940502274857964L, node2.getPackageFingerprint());
         assertEquals(-2213514155997929241L, node4.getPackageFingerprint());
     }
+
+    @Test
+    public void testPackageTable_getPackageList() throws Exception {
+        PackageTable packageTable =
+                PackageTable.fromBytes(TestDataUtils.getTestPackageMapByteBuffer(2));
+        Set<String> packages = new HashSet<>(packageTable.getPackageList());
+        assertEquals(3, packages.size());
+        assertTrue(packages.contains("com.android.aconfig.storage.test_1"));
+        assertTrue(packages.contains("com.android.aconfig.storage.test_2"));
+        assertTrue(packages.contains("com.android.aconfig.storage.test_4"));
+
+        packageTable = PackageTable.fromBytes(TestDataUtils.getTestPackageMapByteBuffer(1));
+        packages = new HashSet<>(packageTable.getPackageList());
+        assertEquals(3, packages.size());
+        assertTrue(packages.contains("com.android.aconfig.storage.test_1"));
+        assertTrue(packages.contains("com.android.aconfig.storage.test_2"));
+        assertTrue(packages.contains("com.android.aconfig.storage.test_4"));
+    }
 }