1 /* 2 * Copyright (C) 2024 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 17 package android.aconfig.storage; 18 19 import dalvik.annotation.optimization.FastNative; 20 21 import java.io.FileInputStream; 22 import java.io.IOException; 23 import java.nio.ByteBuffer; 24 import java.nio.ByteOrder; 25 import java.nio.MappedByteBuffer; 26 import java.nio.channels.FileChannel; 27 28 public class AconfigStorageReadAPI { 29 30 // Storage file dir on device 31 private static final String STORAGEDIR = "/metadata/aconfig"; 32 33 // Stoarge file type 34 public enum StorageFileType { 35 PACKAGE_MAP, 36 FLAG_MAP, 37 FLAG_VAL, 38 FLAG_INFO 39 } 40 41 // Map a storage file given file path mapStorageFile(String file)42 public static MappedByteBuffer mapStorageFile(String file) throws IOException { 43 FileInputStream stream = new FileInputStream(file); 44 FileChannel channel = stream.getChannel(); 45 return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); 46 } 47 48 // Map a storage file given container and file type getMappedFile(String container, StorageFileType type)49 public static MappedByteBuffer getMappedFile(String container, StorageFileType type) 50 throws IOException { 51 switch (type) { 52 case PACKAGE_MAP: 53 return mapStorageFile(STORAGEDIR + "/maps/" + container + ".package.map"); 54 case FLAG_MAP: 55 return mapStorageFile(STORAGEDIR + "/maps/" + container + ".flag.map"); 56 case FLAG_VAL: 57 return mapStorageFile(STORAGEDIR + "/boot/" + container + ".val"); 58 case FLAG_INFO: 59 return mapStorageFile(STORAGEDIR + "/boot/" + container + ".info"); 60 default: 61 throw new IOException("Invalid storage file type"); 62 } 63 } 64 65 // JNI interface to get package read context 66 // @param mappedFile: memory mapped package map file 67 // @param packageName: package name 68 // @throws IOException if the passed in file is not a valid package map file 69 @FastNative getPackageReadContextImpl( ByteBuffer mappedFile, String packageName)70 private static native ByteBuffer getPackageReadContextImpl( 71 ByteBuffer mappedFile, String packageName) throws IOException; 72 73 // API to get package read context 74 // @param mappedFile: memory mapped package map file 75 // @param packageName: package name 76 // @throws IOException if the passed in file is not a valid package map file getPackageReadContext( ByteBuffer mappedFile, String packageName)77 public static PackageReadContext getPackageReadContext( 78 ByteBuffer mappedFile, String packageName) throws IOException { 79 ByteBuffer buffer = getPackageReadContextImpl(mappedFile, packageName); 80 buffer.order(ByteOrder.LITTLE_ENDIAN); 81 return new PackageReadContext(buffer.getInt(), buffer.getInt(4)); 82 } 83 84 // JNI interface to get flag read context 85 // @param mappedFile: memory mapped flag map file 86 // @param packageId: package id to represent a specific package, obtained from 87 // package map file 88 // @param flagName: flag name 89 // @throws IOException if the passed in file is not a valid flag map file 90 @FastNative getFlagReadContextImpl( ByteBuffer mappedFile, int packageId, String flagName)91 private static native ByteBuffer getFlagReadContextImpl( 92 ByteBuffer mappedFile, int packageId, String flagName) throws IOException; 93 94 // API to get flag read context 95 // @param mappedFile: memory mapped flag map file 96 // @param packageId: package id to represent a specific package, obtained from 97 // package map file 98 // @param flagName: flag name 99 // @throws IOException if the passed in file is not a valid flag map file getFlagReadContext( ByteBuffer mappedFile, int packageId, String flagName)100 public static FlagReadContext getFlagReadContext( 101 ByteBuffer mappedFile, int packageId, String flagName) throws IOException { 102 ByteBuffer buffer = getFlagReadContextImpl(mappedFile, packageId, flagName); 103 buffer.order(ByteOrder.LITTLE_ENDIAN); 104 return new FlagReadContext(buffer.getInt(), buffer.getInt(4)); 105 } 106 107 // JNI interface to get boolean flag value 108 // @param mappedFile: memory mapped flag value file 109 // @param flagIndex: flag global index in the flag value array 110 // @throws IOException if the passed in file is not a valid flag value file or the 111 // flag index went over the file boundary. 112 @FastNative getBooleanFlagValue(ByteBuffer mappedFile, int flagIndex)113 public static native boolean getBooleanFlagValue(ByteBuffer mappedFile, int flagIndex) 114 throws IOException; 115 116 @FastNative hash(String packageName)117 public static native long hash(String packageName) throws IOException; 118 119 static { 120 System.loadLibrary("aconfig_storage_read_api_rust_jni"); 121 } 122 } 123