• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.content.pm;
18 
19 import android.annotation.FlaggedApi;
20 import android.annotation.IntDef;
21 import android.annotation.IntRange;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.TestApi;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 import android.util.Pair;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.Objects;
36 
37 /**
38  * This class provides information for a shared library. There are
39  * four types of shared libraries: builtin - non-updatable part of
40  * the OS; dynamic - updatable backwards-compatible dynamically linked;
41  * static - non backwards-compatible emulating static linking;
42  * SDK - updatable backwards-incompatible dynamically loaded.
43  */
44 public final class SharedLibraryInfo implements Parcelable {
45 
46     /** @hide */
47     @IntDef(flag = true, prefix = { "TYPE_" }, value = {
48             TYPE_BUILTIN,
49             TYPE_DYNAMIC,
50             TYPE_STATIC,
51             TYPE_SDK_PACKAGE,
52     })
53     @Retention(RetentionPolicy.SOURCE)
54     public @interface Type{}
55 
56     /**
57      * Shared library type: this library is a part of the OS
58      * and cannot be updated or uninstalled.
59      */
60     public static final int TYPE_BUILTIN = 0;
61 
62     /**
63      * Shared library type: this library is backwards-compatible, can
64      * be updated, and updates can be uninstalled. Clients link against
65      * the latest version of the library.
66      */
67     public static final int TYPE_DYNAMIC = 1;
68 
69     /**
70      * Shared library type: this library is <strong>not</strong> backwards
71      * -compatible, can be updated and updates can be uninstalled. Clients
72      * link against a specific version of the library.
73      *
74      * Static shared libraries simulate static linking while allowing for
75      * multiple clients to reuse the same instance of the library.
76      */
77     public static final int TYPE_STATIC = 2;
78 
79     /**
80      * SDK package shared library type: this library is <strong>not</strong>
81      * compatible between versions, can be updated and updates can be
82      * uninstalled. Clients depend on a specific version of the library.
83      *
84      * SDK packages are not loaded automatically by the OS and rely
85      * e.g. on 3P libraries to make them available for the clients.
86      */
87     public static final int TYPE_SDK_PACKAGE = 3;
88 
89     /**
90      * Constant for referring to an undefined version.
91      */
92     public static final int VERSION_UNDEFINED = -1;
93 
94     private final String mPath;
95     private final String mPackageName;
96     private final String mName;
97     private List<String> mCodePaths;
98 
99     private final long mVersion;
100     private final @Type int mType;
101     private final boolean mIsNative;
102     private final VersionedPackage mDeclaringPackage;
103     private final List<VersionedPackage> mDependentPackages;
104 
105     private final List<VersionedPackage> mOptionalDependentPackages;
106     private List<SharedLibraryInfo> mDependencies;
107 
108     private final List<String> mCertDigests;
109 
110     /**
111      * Creates a new instance.
112      *
113      * @param codePaths         For a non {@link #TYPE_BUILTIN builtin} library, the locations of
114      *                          jars of
115      *                          this shared library. Null for builtin library.
116      * @param name              The lib name.
117      * @param version           The lib version if not builtin.
118      * @param type              The lib type.
119      * @param declaringPackage  The package that declares the library.
120      * @param dependentPackages The packages that depend on the library.
121      * @param isNative          indicate if this shared lib is a native lib or not (i.e. java)
122      * @hide
123      */
SharedLibraryInfo(String path, String packageName, List<String> codePaths, String name, long version, int type, VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages, List<SharedLibraryInfo> dependencies, boolean isNative)124     public SharedLibraryInfo(String path, String packageName, List<String> codePaths,
125             String name, long version, int type,
126             VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages,
127             List<SharedLibraryInfo> dependencies, boolean isNative) {
128         mPath = path;
129         mPackageName = packageName;
130         mCodePaths = codePaths;
131         mName = name;
132         mVersion = version;
133         mType = type;
134         mDeclaringPackage = declaringPackage;
135         mDependentPackages = dependentPackages;
136         mDependencies = dependencies;
137         mIsNative = isNative;
138         mOptionalDependentPackages = null;
139         mCertDigests = null;
140     }
141 
142     /**
143      * Creates a new instance.
144      *
145      * @param codePaths For a non {@link #TYPE_BUILTIN builtin} library, the locations of jars of
146      *                  this shared library. Null for builtin library.
147      * @param name The lib name.
148      * @param version The lib version if not builtin.
149      * @param type The lib type.
150      * @param declaringPackage The package that declares the library.
151      * @param isNative indicate if this shared lib is a native lib or not (i.e. java)
152      * @param allDependentPackages All packages that depend on the library (including the optional
153      *                             sdk libraries).
154      *
155      * @hide
156      */
SharedLibraryInfo(String path, String packageName, List<String> codePaths, String name, long version, int type, VersionedPackage declaringPackage, List<SharedLibraryInfo> dependencies, boolean isNative, Pair<List<VersionedPackage>, List<Boolean>> allDependentPackages)157     public SharedLibraryInfo(String path, String packageName, List<String> codePaths,
158             String name, long version, int type,
159             VersionedPackage declaringPackage,
160             List<SharedLibraryInfo> dependencies, boolean isNative,
161             Pair<List<VersionedPackage>, List<Boolean>> allDependentPackages) {
162         mPath = path;
163         mPackageName = packageName;
164         mCodePaths = codePaths;
165         mName = name;
166         mVersion = version;
167         mType = type;
168         mDeclaringPackage = declaringPackage;
169         mDependencies = dependencies;
170         mIsNative = isNative;
171         mCertDigests = null;
172 
173         var allDependents = allDependentPackages.first;
174         var usesLibOptional = allDependentPackages.second;
175         mDependentPackages = allDependents;
176         List<VersionedPackage> optionalDependents = null;
177         if (mType == SharedLibraryInfo.TYPE_SDK_PACKAGE
178                 && Flags.sdkLibIndependence() && allDependents != null
179                 && usesLibOptional != null
180                 && allDependents.size() == usesLibOptional.size()) {
181             for (int k = 0; k < allDependents.size(); k++) {
182                 VersionedPackage versionedPackage = allDependents.get(k);
183                 if (usesLibOptional.get(k)) {
184                     if (optionalDependents == null) {
185                         optionalDependents = new ArrayList<>();
186                     }
187                     optionalDependents.add(versionedPackage);
188                 }
189             }
190         }
191         mOptionalDependentPackages = optionalDependents;
192     }
193 
SharedLibraryInfo(Parcel parcel)194     private SharedLibraryInfo(Parcel parcel) {
195         mPath = parcel.readString8();
196         mPackageName = parcel.readString8();
197         if (parcel.readInt() != 0) {
198             mCodePaths = Arrays.asList(parcel.createString8Array());
199         } else {
200             mCodePaths = null;
201         }
202         mName = parcel.readString8();
203         mVersion = parcel.readLong();
204         mType = parcel.readInt();
205         mDeclaringPackage =
206                 parcel.readParcelable(null, android.content.pm.VersionedPackage.class);
207         mDependentPackages =
208                 parcel.readArrayList(null, android.content.pm.VersionedPackage.class);
209         mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR);
210         mIsNative = parcel.readBoolean();
211         mOptionalDependentPackages = parcel.readParcelableList(new ArrayList<>(),
212                 VersionedPackage.class.getClassLoader(), VersionedPackage.class);
213         mCertDigests = parcel.createStringArrayList();
214     }
215 
216     /**
217      * @hide
218      * @param name
219      * @param versionMajor
220      */
SharedLibraryInfo(String name, long versionMajor, int type)221     public SharedLibraryInfo(String name, long versionMajor, int type) {
222         //TODO: change to this(name, versionMajor, type, /* certDigest= */null); after flag removal
223         mPath = null;
224         mPackageName = null;
225         mName = name;
226         mVersion = versionMajor;
227         mType = type;
228         mDeclaringPackage = null;
229         mDependentPackages = null;
230         mDependencies = null;
231         mIsNative = false;
232         mOptionalDependentPackages = null;
233         mCertDigests = null;
234     }
235 
236     /**
237      * @hide
238      * @param name The lib name.
239      * @param versionMajor The lib major version.
240      * @param type The type of shared library.
241      * @param certDigests The list of certificate digests for this shared library.
242      */
243     @FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
SharedLibraryInfo(String name, long versionMajor, int type, List<String> certDigests)244     public SharedLibraryInfo(String name, long versionMajor, int type, List<String> certDigests) {
245         mPath = null;
246         mPackageName = null;
247         mName = name;
248         mVersion = versionMajor;
249         mType = type;
250         mDeclaringPackage = null;
251         mDependentPackages = null;
252         mDependencies = null;
253         mIsNative = false;
254         mOptionalDependentPackages = null;
255         mCertDigests = certDigests;
256     }
257 
258     /**
259      * Gets the type of this library.
260      *
261      * @return The library type.
262      */
getType()263     public @Type int getType() {
264         return mType;
265     }
266 
267     /**
268      * Tells whether this library is a native shared library or not.
269      *
270      * @hide
271      */
272     @TestApi
isNative()273     public boolean isNative() {
274         return mIsNative;
275     }
276 
277     /**
278      * Gets the library name an app defines in its manifest
279      * to depend on the library.
280      *
281      * @return The name.
282      */
getName()283     public String getName() {
284         return mName;
285     }
286 
287     /**
288      * If the shared library is a jar file, returns the path of that jar. Null otherwise.
289      * Only libraries with TYPE_BUILTIN are in jar files.
290      *
291      * @return The path.
292      *
293      * @hide
294      */
getPath()295     public @Nullable String getPath() {
296         return mPath;
297     }
298 
299     /**
300      * If the shared library is an apk, returns the package name. Null otherwise.
301      * Only libraries with TYPE_DYNAMIC or TYPE_STATIC are in apks.
302      *
303      * @return The package name.
304      *
305      * @hide
306      */
getPackageName()307     public @Nullable String getPackageName() {
308         return mPackageName;
309     }
310 
311     /**
312      * Get all code paths for that library.
313      *
314      * @return All code paths.
315      *
316      * @hide
317      */
318     @TestApi
getAllCodePaths()319     public @NonNull List<String> getAllCodePaths() {
320         if (getPath() != null) {
321             // Builtin library.
322             ArrayList<String> list = new ArrayList<>();
323             list.add(getPath());
324             return list;
325         } else {
326             // Static or dynamic library.
327             return Objects.requireNonNull(mCodePaths);
328         }
329     }
330 
331     /**
332      * Sets new all code paths for that library.
333      *
334      * @hide
335      */
setAllCodePaths(List<String> paths)336     public void setAllCodePaths(List<String> paths) {
337         mCodePaths = paths;
338     }
339 
340     /**
341      * Add a library dependency to that library. Note that this
342      * should be called under the package manager lock.
343      *
344      * @hide
345      */
addDependency(@ullable SharedLibraryInfo info)346     public void addDependency(@Nullable SharedLibraryInfo info) {
347         if (info == null) {
348             // For convenience of the caller, allow null to be passed.
349             // This can happen when we create the dependencies of builtin
350             // libraries.
351             return;
352         }
353         if (mDependencies == null) {
354             mDependencies = new ArrayList<>();
355         }
356         mDependencies.add(info);
357     }
358 
359     /**
360      * Clear all dependencies.
361      *
362      * @hide
363      */
clearDependencies()364     public void clearDependencies() {
365         mDependencies = null;
366     }
367 
368     /**
369      * Gets the libraries this library directly depends on. Note that
370      * the package manager prevents recursive dependencies when installing
371      * a package.
372      *
373      * @return The dependencies.
374      *
375      * @hide
376      */
getDependencies()377     public @Nullable List<SharedLibraryInfo> getDependencies() {
378         return mDependencies;
379     }
380 
381     /**
382      * @deprecated Use {@link #getLongVersion()} instead.
383      */
384     @Deprecated
getVersion()385     public @IntRange(from = -1) int getVersion() {
386         return mVersion < 0 ? (int) mVersion : (int) (mVersion & 0x7fffffff);
387     }
388 
389     /**
390      * Gets the version of the library. For {@link #TYPE_STATIC static} libraries
391      * this is the declared version and for {@link #TYPE_DYNAMIC dynamic} and
392      * {@link #TYPE_BUILTIN builtin} it is {@link #VERSION_UNDEFINED} as these
393      * are not versioned.
394      *
395      * @return The version.
396      */
getLongVersion()397     public @IntRange(from = -1) long getLongVersion() {
398         return mVersion;
399     }
400 
401     /**
402      * @removed
403      */
isBuiltin()404     public boolean isBuiltin() {
405         return mType == TYPE_BUILTIN;
406     }
407 
408     /**
409      * @removed
410      */
isDynamic()411     public boolean isDynamic() {
412         return mType == TYPE_DYNAMIC;
413     }
414 
415     /**
416      * @removed
417      */
isStatic()418     public boolean isStatic() {
419         return mType == TYPE_STATIC;
420     }
421 
422     /**
423      * @hide
424      */
isSdk()425     public boolean isSdk() {
426         return mType == TYPE_SDK_PACKAGE;
427     }
428 
429     /**
430      * Gets the package that declares the library.
431      *
432      * @return The package declaring the library.
433      */
getDeclaringPackage()434     public @NonNull VersionedPackage getDeclaringPackage() {
435         return mDeclaringPackage;
436     }
437 
438     /**
439      * Gets the packages that depend on the library.
440      *
441      * NOTE: the list also contains the result of {@link #getOptionalDependentPackages}.
442      *
443      * @return The dependent packages.
444      */
getDependentPackages()445     public @NonNull List<VersionedPackage> getDependentPackages() {
446         if (mDependentPackages == null) {
447             return Collections.emptyList();
448         }
449         return mDependentPackages;
450     }
451 
452     /**
453      * Gets the packages that optionally depend on the library.
454      *
455      * @return The dependent packages.
456      */
457     @FlaggedApi(Flags.FLAG_SDK_LIB_INDEPENDENCE)
getOptionalDependentPackages()458     public @NonNull List<VersionedPackage> getOptionalDependentPackages() {
459         if (mOptionalDependentPackages == null) {
460             return Collections.emptyList();
461         }
462         return mOptionalDependentPackages;
463     }
464 
465     /**
466      * Gets the list of certificate digests for the shared library.
467      *
468      * @return The list of certificate digests
469      */
470     @FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
getCertDigests()471     public @NonNull List<String> getCertDigests() {
472         if (mCertDigests == null) {
473             return Collections.emptyList();
474         }
475         return mCertDigests;
476     }
477 
478     @Override
describeContents()479     public int describeContents() {
480         return 0;
481     }
482 
483     @Override
toString()484     public String toString() {
485         return "SharedLibraryInfo{name:" + mName + ", type:" + typeToString(mType)
486                 + ", version:" + mVersion + (!getDependentPackages().isEmpty()
487                 ? " has dependents" : "") + "}";
488     }
489 
490     @Override
writeToParcel(Parcel parcel, int flags)491     public void writeToParcel(Parcel parcel, int flags) {
492         parcel.writeString8(mPath);
493         parcel.writeString8(mPackageName);
494         if (mCodePaths != null) {
495             parcel.writeInt(1);
496             parcel.writeString8Array(mCodePaths.toArray(new String[mCodePaths.size()]));
497         } else {
498             parcel.writeInt(0);
499         }
500         parcel.writeString8(mName);
501         parcel.writeLong(mVersion);
502         parcel.writeInt(mType);
503         parcel.writeParcelable(mDeclaringPackage, flags);
504         parcel.writeList(mDependentPackages);
505         parcel.writeTypedList(mDependencies);
506         parcel.writeBoolean(mIsNative);
507         parcel.writeParcelableList(mOptionalDependentPackages, flags);
508         parcel.writeStringList(mCertDigests);
509     }
510 
typeToString(int type)511     private static String typeToString(int type) {
512         switch (type) {
513             case TYPE_BUILTIN: {
514                 return "builtin";
515             }
516             case TYPE_DYNAMIC: {
517                 return "dynamic";
518             }
519             case TYPE_STATIC: {
520                 return "static";
521             }
522             case TYPE_SDK_PACKAGE: {
523                 return "sdk";
524             }
525             default: {
526                 return "unknown";
527             }
528         }
529     }
530 
531     public static final @android.annotation.NonNull Parcelable.Creator<SharedLibraryInfo> CREATOR =
532             new Parcelable.Creator<SharedLibraryInfo>() {
533         public SharedLibraryInfo createFromParcel(Parcel source) {
534             return new SharedLibraryInfo(source);
535         }
536 
537         public SharedLibraryInfo[] newArray(int size) {
538             return new SharedLibraryInfo[size];
539         }
540     };
541 }
542