From 70b9ac0dddf5d48a087f0e5ec7d19d19463dd8c8 Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Thu, 11 Jul 2024 18:50:46 +0000 Subject: [PATCH] add storage java internal reader Test: n/a Bug: n/a Change-Id: I852ab4080bee9240549dc4be0c09dbe1f72d06b0 --- .../storage/StorageInternalReader.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java diff --git a/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java new file mode 100644 index 0000000000..ddb86dc330 --- /dev/null +++ b/tools/aconfig/aconfig_storage_read_api/srcs/android/aconfig/storage/StorageInternalReader.java @@ -0,0 +1,75 @@ +/* + * 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; + +public class StorageInternalReader { + + private static final String MAP_PATH = "/metadata/aconfig/maps/"; + private static final String BOOT_PATH = "/metadata/aconfig/boot/"; + + private PackageTable mPackageTable; + private FlagValueList mFlagValueList; + + private int mPackageBooleanStartOffset; + + public StorageInternalReader(String container, String packageName) { + this(container, packageName, MAP_PATH, BOOT_PATH); + } + + public StorageInternalReader( + String container, String packageName, String mapPath, String bootPath) { + + String packageMapFile = mapPath + container + ".package.map"; + String flagValueFile = bootPath + container + ".val"; + + mPackageTable = PackageTable.fromBytes(mapStorageFile(packageMapFile)); + mFlagValueList = FlagValueList.fromBytes(mapStorageFile(flagValueFile)); + mPackageBooleanStartOffset = getPackageBooleanStartOffset(packageName); + } + + public boolean getBooleanFlagValue(int index) { + index += mPackageBooleanStartOffset; + if (index >= mFlagValueList.size()) { + throw new AconfigStorageException("Fail to get boolean flag value"); + } + return mFlagValueList.get(index); + } + + private int getPackageBooleanStartOffset(String packageName) { + PackageTable.Node pNode = mPackageTable.get(packageName); + if (pNode == null) { + PackageTable.Header header = mPackageTable.getHeader(); + throw new AconfigStorageException( + String.format( + "Fail to get package %s from container %s", + packageName, header.getContainer())); + } + return pNode.getBooleanStartIndex(); + } + + // Map a storage file given file path + private static MappedByteBuffer mapStorageFile(String file) { + try { + FileInputStream stream = new FileInputStream(file); + FileChannel channel = stream.getChannel(); + return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); + } catch (IOException e) { + throw new AconfigStorageException( + String.format("Fail to mmap storage file %s", file), e); + } + } +}