14501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki/* 24501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Copyright (C) 2017 The Android Open Source Project 34501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * 44501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 54501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * you may not use this file except in compliance with the License. 64501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * You may obtain a copy of the License at 74501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * 84501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 94501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * 104501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Unless required by applicable law or agreed to in writing, software 114501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 124501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * See the License for the specific language governing permissions and 144501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * limitations under the License. 154501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 164501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 174501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukipackage android.content.pm; 184501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 194501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukiimport android.os.Parcel; 204501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukiimport android.util.Log; 214501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 224501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukiimport java.util.ArrayList; 234501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukiimport java.util.HashMap; 244501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 254501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki/** 264501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Helper classes to read from and write to Parcel with pooled strings. 274501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * 284501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * @hide 294501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 304501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukipublic class PackageParserCacheHelper { 314501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private PackageParserCacheHelper() { 324501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 334501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 344501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private static final String TAG = "PackageParserCacheHelper"; 354501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private static final boolean DEBUG = false; 364501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 374501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 384501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Parcel read helper with a string pool. 394501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 404501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public static class ReadHelper extends Parcel.ReadWriteHelper { 414501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private final ArrayList<String> mStrings = new ArrayList<>(); 424501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 434501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private final Parcel mParcel; 444501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 454501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public ReadHelper(Parcel p) { 464501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel = p; 474501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 484501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 494501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 504501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Prepare to read from a parcel, and install itself as a read-write helper. 514501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * 524501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * (We don't do it in the constructor to avoid calling methods before the constructor 534501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * finishes.) 544501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 554501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public void startAndInstall() { 564501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mStrings.clear(); 574501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 584501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki final int poolPosition = mParcel.readInt(); 594501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki final int startPosition = mParcel.dataPosition(); 604501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 614501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki // The pool is at the end of the parcel. 624501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setDataPosition(poolPosition); 634501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.readStringList(mStrings); 644501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 654501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki // Then move back. 664501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setDataPosition(startPosition); 674501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 684501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki if (DEBUG) { 694501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki Log.i(TAG, "Read " + mStrings.size() + " strings"); 704501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki for (int i = 0; i < mStrings.size(); i++) { 714501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki Log.i(TAG, " " + i + ": \"" + mStrings.get(i) + "\""); 724501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 734501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 744501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 754501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setReadWriteHelper(this); 764501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 774501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 784501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 794501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Read an string index from a parcel, and returns the corresponding string from the pool. 804501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 814501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki @Override 824501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public String readString(Parcel p) { 834501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki return mStrings.get(p.readInt()); 844501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 854501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 864501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 874501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 884501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Parcel write helper with a string pool. 894501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 904501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public static class WriteHelper extends Parcel.ReadWriteHelper { 914501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private final ArrayList<String> mStrings = new ArrayList<>(); 924501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 934501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private final HashMap<String, Integer> mIndexes = new HashMap<>(); 944501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 954501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private final Parcel mParcel; 964501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki private final int mStartPos; 974501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 984501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 994501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Constructor. Prepare a parcel, and install it self as a read-write helper. 1004501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 1014501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public WriteHelper(Parcel p) { 1024501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel = p; 1034501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mStartPos = p.dataPosition(); 1044501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.writeInt(0); // We come back later here and write the pool position. 1054501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1064501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setReadWriteHelper(this); 1074501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1084501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1094501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 1104501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Instead of writing a string directly to a parcel, this method adds it to the pool, 1114501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * and write the index in the pool to the parcel. 1124501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 1134501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki @Override 1144501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public void writeString(Parcel p, String s) { 1154501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki final Integer cur = mIndexes.get(s); 1164501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki if (cur != null) { 1174501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki // String already in the pool. Just write the index. 1184501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki p.writeInt(cur); // Already in the pool. 1194501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki if (DEBUG) { 1204501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki Log.i(TAG, "Duplicate '" + s + "' at " + cur); 1214501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1224501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } else { 1234501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki // Not in the pool. Add to the pool, and write the index. 1244501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki final int index = mStrings.size(); 1254501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mIndexes.put(s, index); 1264501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mStrings.add(s); 1274501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1284501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki if (DEBUG) { 1294501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki Log.i(TAG, "New '" + s + "' at " + index); 1304501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1314501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1324501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki p.writeInt(index); 1334501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1344501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1354501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1364501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki /** 1374501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * Closes a parcel by appending the string pool at the end and updating the pool offset, 1384501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki * which it assumes is at the first byte. It also uninstalls itself as a read-write helper. 1394501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki */ 1404501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki public void finishAndUninstall() { 1414501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki // Uninstall first, so that writeStringList() uses the native writeString. 1424501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setReadWriteHelper(null); 1434501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1444501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki final int poolPosition = mParcel.dataPosition(); 1454501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.writeStringList(mStrings); 1464501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1474501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setDataPosition(mStartPos); 1484501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.writeInt(poolPosition); 1494501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki 1504501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki // Move back to the end. 1514501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki mParcel.setDataPosition(mParcel.dataSize()); 1524501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki if (DEBUG) { 1534501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki Log.i(TAG, "Wrote " + mStrings.size() + " strings"); 1544501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1554501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1564501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki } 1574501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki} 158