1 /* 2 * Copyright (C) 2021 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 com.android.server.pm; 18 19 import android.annotation.Nullable; 20 import android.content.pm.SharedLibraryInfo; 21 22 import com.android.server.pm.pkg.PackageStateInternal; 23 import com.android.server.utils.WatchedLongSparseArray; 24 25 import java.util.ArrayList; 26 import java.util.Collections; 27 import java.util.HashSet; 28 import java.util.List; 29 import java.util.Map; 30 import java.util.Set; 31 32 final class SharedLibraryUtils { 33 34 /** 35 * Returns false if the adding shared library already exists in the map and so could not be 36 * added. 37 */ addSharedLibraryToPackageVersionMap( Map<String, WatchedLongSparseArray<SharedLibraryInfo>> target, SharedLibraryInfo library)38 public static boolean addSharedLibraryToPackageVersionMap( 39 Map<String, WatchedLongSparseArray<SharedLibraryInfo>> target, 40 SharedLibraryInfo library) { 41 final String name = library.getName(); 42 if (target.containsKey(name)) { 43 if (library.getType() != SharedLibraryInfo.TYPE_STATIC) { 44 // We've already added this non-version-specific library to the map. 45 return false; 46 } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) { 47 // We've already added this version of a version-specific library to the map. 48 return false; 49 } 50 } else { 51 target.put(name, new WatchedLongSparseArray<>()); 52 } 53 target.get(name).put(library.getLongVersion(), library); 54 return true; 55 } 56 57 @Nullable getSharedLibraryInfo(String name, long version, Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries)58 public static SharedLibraryInfo getSharedLibraryInfo(String name, long version, 59 Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, 60 @Nullable Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries) { 61 if (newLibraries != null) { 62 final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name); 63 SharedLibraryInfo info = null; 64 if (versionedLib != null) { 65 info = versionedLib.get(version); 66 } 67 if (info != null) { 68 return info; 69 } 70 } 71 final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name); 72 if (versionedLib == null) { 73 return null; 74 } 75 return versionedLib.get(version); 76 } 77 findSharedLibraries(PackageStateInternal pkgSetting)78 public static List<SharedLibraryInfo> findSharedLibraries(PackageStateInternal pkgSetting) { 79 if (!pkgSetting.getTransientState().getUsesLibraryInfos().isEmpty()) { 80 ArrayList<SharedLibraryInfo> retValue = new ArrayList<>(); 81 Set<String> collectedNames = new HashSet<>(); 82 for (SharedLibraryInfo info : pkgSetting.getTransientState().getUsesLibraryInfos()) { 83 findSharedLibrariesRecursive(info, retValue, collectedNames); 84 } 85 return retValue; 86 } else { 87 return Collections.emptyList(); 88 } 89 } 90 findSharedLibrariesRecursive(SharedLibraryInfo info, ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames)91 private static void findSharedLibrariesRecursive(SharedLibraryInfo info, 92 ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) { 93 if (!collectedNames.contains(info.getName())) { 94 collectedNames.add(info.getName()); 95 collected.add(info); 96 97 if (info.getDependencies() != null) { 98 for (SharedLibraryInfo dep : info.getDependencies()) { 99 findSharedLibrariesRecursive(dep, collected, collectedNames); 100 } 101 } 102 } 103 } 104 105 } 106