• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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