Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52cf4c47 authored by Zhi Dou's avatar Zhi Dou Committed by Gerrit Code Review
Browse files

Merge "create AconfigPackageImpl" into main

parents cf2c4319 afb25696
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -41,6 +41,10 @@ public class ByteBufferReader {
        return this.mByteBuffer.getInt();
    }

    public long readLong() {
        return this.mByteBuffer.getLong();
    }

    public String readString() {
        int length = readInt();
        byte[] bytes = new byte[length];
+12 −0
Original line number Diff line number Diff line
@@ -124,8 +124,10 @@ public class PackageTable {

        private String mPackageName;
        private int mPackageId;
        private long mPackageFingerprint;
        private int mBooleanStartIndex;
        private int mNextOffset;
        private boolean mHasPackageFingerprint;

        private static Node fromBytes(ByteBufferReader reader, int version) {
            switch (version) {
@@ -153,9 +155,11 @@ public class PackageTable {
            Node node = new Node();
            node.mPackageName = reader.readString();
            node.mPackageId = reader.readInt();
            node.mPackageFingerprint = reader.readLong();
            node.mBooleanStartIndex = reader.readInt();
            node.mNextOffset = reader.readInt();
            node.mNextOffset = node.mNextOffset == 0 ? -1 : node.mNextOffset;
            node.mHasPackageFingerprint = true;
            return node;
        }

@@ -189,6 +193,10 @@ public class PackageTable {
            return mPackageId;
        }

        public long getPackageFingerprint() {
            return mPackageFingerprint;
        }

        public int getBooleanStartIndex() {
            return mBooleanStartIndex;
        }
@@ -196,5 +204,9 @@ public class PackageTable {
        public int getNextOffset() {
            return mNextOffset;
        }

        public boolean hasPackageFingerprint() {
            return mHasPackageFingerprint;
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.aconfig.storage.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import android.aconfig.storage.FileType;
import android.aconfig.storage.PackageTable;
@@ -66,5 +67,9 @@ public class PackageTableTest {
        assertEquals(159, node1.getNextOffset());
        assertEquals(-1, node2.getNextOffset());
        assertEquals(-1, node4.getNextOffset());

        assertFalse(node1.hasPackageFingerprint());
        assertFalse(node2.hasPackageFingerprint());
        assertFalse(node4.hasPackageFingerprint());
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -154,6 +154,8 @@ java_library {
java_library {
    name: "aconfig_storage_reader_java",
    srcs: [
        "srcs/android/aconfig/storage/AconfigPackageImpl.java",
        "srcs/android/aconfig/storage/StorageFileProvider.java",
        "srcs/android/aconfig/storage/StorageInternalReader.java",
    ],
    libs: [
@@ -175,6 +177,8 @@ java_library {
java_library {
    name: "aconfig_storage_reader_java_none",
    srcs: [
        "srcs/android/aconfig/storage/AconfigPackageImpl.java",
        "srcs/android/aconfig/storage/StorageFileProvider.java",
        "srcs/android/aconfig/storage/StorageInternalReader.java",
    ],
    libs: [
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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 android.aconfig.storage;

import android.os.StrictMode;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/** @hide */
public class AconfigPackageImpl {
    private FlagTable mFlagTable;
    private FlagValueList mFlagValueList;
    private PackageTable.Node mPNode;

    /** @hide */
    public static AconfigPackageImpl load(String packageName, StorageFileProvider fileProvider) {
        AconfigPackageImpl aPackage = new AconfigPackageImpl();
        if (!aPackage.init(null, packageName, fileProvider)) {
            return null;
        }
        return aPackage;
    }

    /** @hide */
    public static AconfigPackageImpl load(
            String packageGroupName, String packageName, StorageFileProvider fileProvider) {
        if (packageGroupName == null) {
            return null;
        }
        AconfigPackageImpl aPackage = new AconfigPackageImpl();
        if (!aPackage.init(packageGroupName, packageName, fileProvider)) {
            return null;
        }
        return aPackage;
    }

    /** @hide */
    public boolean getBooleanFlagValue(String flagName, boolean defaultValue) {
        FlagTable.Node fNode = mFlagTable.get(mPNode.getPackageId(), flagName);
        // no such flag in this package
        if (fNode == null) return defaultValue;
        int index = fNode.getFlagIndex() + mPNode.getBooleanStartIndex();
        return mFlagValueList.getBoolean(index);
    }

    /** @hide */
    public boolean getBooleanFlagValue(int index) {
        return mFlagValueList.getBoolean(index + mPNode.getBooleanStartIndex());
    }

    /** @hide */
    public long getPackageFingerprint() {
        return mPNode.getPackageFingerprint();
    }

    /** @hide */
    public boolean hasPackageFingerprint() {
        return mPNode.hasPackageFingerprint();
    }

    private boolean init(
            String packageGroupName, String packageName, StorageFileProvider fileProvider) {
        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
        String container = packageGroupName;
        try {
            // for devices don't have new storage directly return
            if (!fileProvider.containerFileExists(null)) {
                return false;
            }
            PackageTable.Node pNode = null;

            if (container == null) {
                PackageTable pTable = null;
                // check if device has flag files on the system partition
                // if the device has then search system partition first
                container = "system";
                if (fileProvider.containerFileExists(container)) {
                    pTable = fileProvider.getPackageTable(container);
                    pNode = pTable.get(packageName);
                }
                List<Path> mapFiles = new ArrayList<>();
                if (pNode == null) {
                    mapFiles = fileProvider.listPackageMapFiles();
                    if (mapFiles.isEmpty()) return false;
                }

                for (Path p : mapFiles) {
                    pTable = StorageFileProvider.getPackageTable(p);
                    pNode = pTable.get(packageName);
                    if (pNode != null) {
                        container = pTable.getHeader().getContainer();
                        break;
                    }
                }
            } else {
                pNode = fileProvider.getPackageTable(container).get(packageName);
            }

            if (pNode == null) {
                // for the case package is not found in all container, return instead of throwing
                // error
                return false;
            }

            mFlagTable = fileProvider.getFlagTable(container);
            mFlagValueList = fileProvider.getFlagValueList(container);
            mPNode = pNode;
        } catch (Exception e) {
            throw new AconfigStorageException(
                    String.format(
                            "cannot load package %s, from container %s", packageName, container),
                    e);
        } finally {
            StrictMode.setThreadPolicy(oldPolicy);
        }
        return true;
    }
}
Loading