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 final 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 /** 109 * Creates a new instance. 110 * 111 * @param codePaths For a non {@link #TYPE_BUILTIN builtin} library, the locations of 112 * jars of 113 * this shared library. Null for builtin library. 114 * @param name The lib name. 115 * @param version The lib version if not builtin. 116 * @param type The lib type. 117 * @param declaringPackage The package that declares the library. 118 * @param dependentPackages The packages that depend on the library. 119 * @param isNative indicate if this shared lib is a native lib or not (i.e. java) 120 * @hide 121 */ SharedLibraryInfo(String path, String packageName, List<String> codePaths, String name, long version, int type, VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages, List<SharedLibraryInfo> dependencies, boolean isNative)122 public SharedLibraryInfo(String path, String packageName, List<String> codePaths, 123 String name, long version, int type, 124 VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages, 125 List<SharedLibraryInfo> dependencies, boolean isNative) { 126 mPath = path; 127 mPackageName = packageName; 128 mCodePaths = codePaths; 129 mName = name; 130 mVersion = version; 131 mType = type; 132 mDeclaringPackage = declaringPackage; 133 mDependentPackages = dependentPackages; 134 mDependencies = dependencies; 135 mIsNative = isNative; 136 mOptionalDependentPackages = null; 137 } 138 139 /** 140 * Creates a new instance. 141 * 142 * @param codePaths For a non {@link #TYPE_BUILTIN builtin} library, the locations of jars of 143 * this shared library. Null for builtin library. 144 * @param name The lib name. 145 * @param version The lib version if not builtin. 146 * @param type The lib type. 147 * @param declaringPackage The package that declares the library. 148 * @param isNative indicate if this shared lib is a native lib or not (i.e. java) 149 * @param allDependentPackages All packages that depend on the library (including the optional 150 * sdk libraries). 151 * 152 * @hide 153 */ 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)154 public SharedLibraryInfo(String path, String packageName, List<String> codePaths, 155 String name, long version, int type, 156 VersionedPackage declaringPackage, 157 List<SharedLibraryInfo> dependencies, boolean isNative, 158 Pair<List<VersionedPackage>, List<Boolean>> allDependentPackages) { 159 mPath = path; 160 mPackageName = packageName; 161 mCodePaths = codePaths; 162 mName = name; 163 mVersion = version; 164 mType = type; 165 mDeclaringPackage = declaringPackage; 166 mDependencies = dependencies; 167 mIsNative = isNative; 168 169 var allDependents = allDependentPackages.first; 170 var usesLibOptional = allDependentPackages.second; 171 mDependentPackages = allDependents; 172 List<VersionedPackage> optionalDependents = null; 173 if (mType == SharedLibraryInfo.TYPE_SDK_PACKAGE 174 && Flags.sdkLibIndependence() && allDependents != null 175 && usesLibOptional != null 176 && allDependents.size() == usesLibOptional.size()) { 177 for (int k = 0; k < allDependents.size(); k++) { 178 VersionedPackage versionedPackage = allDependents.get(k); 179 if (usesLibOptional.get(k)) { 180 if (optionalDependents == null) { 181 optionalDependents = new ArrayList<>(); 182 } 183 optionalDependents.add(versionedPackage); 184 } 185 } 186 } 187 mOptionalDependentPackages = optionalDependents; 188 } 189 SharedLibraryInfo(Parcel parcel)190 private SharedLibraryInfo(Parcel parcel) { 191 mPath = parcel.readString8(); 192 mPackageName = parcel.readString8(); 193 if (parcel.readInt() != 0) { 194 mCodePaths = Arrays.asList(parcel.createString8Array()); 195 } else { 196 mCodePaths = null; 197 } 198 mName = parcel.readString8(); 199 mVersion = parcel.readLong(); 200 mType = parcel.readInt(); 201 mDeclaringPackage = 202 parcel.readParcelable(null, android.content.pm.VersionedPackage.class); 203 mDependentPackages = 204 parcel.readArrayList(null, android.content.pm.VersionedPackage.class); 205 mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR); 206 mIsNative = parcel.readBoolean(); 207 mOptionalDependentPackages = parcel.readParcelableList(new ArrayList<>(), 208 VersionedPackage.class.getClassLoader(), VersionedPackage.class); 209 } 210 211 /** 212 * Gets the type of this library. 213 * 214 * @return The library type. 215 */ getType()216 public @Type int getType() { 217 return mType; 218 } 219 220 /** 221 * Tells whether this library is a native shared library or not. 222 * 223 * @hide 224 */ 225 @TestApi isNative()226 public boolean isNative() { 227 return mIsNative; 228 } 229 230 /** 231 * Gets the library name an app defines in its manifest 232 * to depend on the library. 233 * 234 * @return The name. 235 */ getName()236 public String getName() { 237 return mName; 238 } 239 240 /** 241 * If the shared library is a jar file, returns the path of that jar. Null otherwise. 242 * Only libraries with TYPE_BUILTIN are in jar files. 243 * 244 * @return The path. 245 * 246 * @hide 247 */ getPath()248 public @Nullable String getPath() { 249 return mPath; 250 } 251 252 /** 253 * If the shared library is an apk, returns the package name. Null otherwise. 254 * Only libraries with TYPE_DYNAMIC or TYPE_STATIC are in apks. 255 * 256 * @return The package name. 257 * 258 * @hide 259 */ getPackageName()260 public @Nullable String getPackageName() { 261 return mPackageName; 262 } 263 264 /** 265 * Get all code paths for that library. 266 * 267 * @return All code paths. 268 * 269 * @hide 270 */ 271 @TestApi getAllCodePaths()272 public @NonNull List<String> getAllCodePaths() { 273 if (getPath() != null) { 274 // Builtin library. 275 ArrayList<String> list = new ArrayList<>(); 276 list.add(getPath()); 277 return list; 278 } else { 279 // Static or dynamic library. 280 return Objects.requireNonNull(mCodePaths); 281 } 282 } 283 284 /** 285 * Add a library dependency to that library. Note that this 286 * should be called under the package manager lock. 287 * 288 * @hide 289 */ addDependency(@ullable SharedLibraryInfo info)290 public void addDependency(@Nullable SharedLibraryInfo info) { 291 if (info == null) { 292 // For convenience of the caller, allow null to be passed. 293 // This can happen when we create the dependencies of builtin 294 // libraries. 295 return; 296 } 297 if (mDependencies == null) { 298 mDependencies = new ArrayList<>(); 299 } 300 mDependencies.add(info); 301 } 302 303 /** 304 * Clear all dependencies. 305 * 306 * @hide 307 */ clearDependencies()308 public void clearDependencies() { 309 mDependencies = null; 310 } 311 312 /** 313 * Gets the libraries this library directly depends on. Note that 314 * the package manager prevents recursive dependencies when installing 315 * a package. 316 * 317 * @return The dependencies. 318 * 319 * @hide 320 */ getDependencies()321 public @Nullable List<SharedLibraryInfo> getDependencies() { 322 return mDependencies; 323 } 324 325 /** 326 * @deprecated Use {@link #getLongVersion()} instead. 327 */ 328 @Deprecated getVersion()329 public @IntRange(from = -1) int getVersion() { 330 return mVersion < 0 ? (int) mVersion : (int) (mVersion & 0x7fffffff); 331 } 332 333 /** 334 * Gets the version of the library. For {@link #TYPE_STATIC static} libraries 335 * this is the declared version and for {@link #TYPE_DYNAMIC dynamic} and 336 * {@link #TYPE_BUILTIN builtin} it is {@link #VERSION_UNDEFINED} as these 337 * are not versioned. 338 * 339 * @return The version. 340 */ getLongVersion()341 public @IntRange(from = -1) long getLongVersion() { 342 return mVersion; 343 } 344 345 /** 346 * @removed 347 */ isBuiltin()348 public boolean isBuiltin() { 349 return mType == TYPE_BUILTIN; 350 } 351 352 /** 353 * @removed 354 */ isDynamic()355 public boolean isDynamic() { 356 return mType == TYPE_DYNAMIC; 357 } 358 359 /** 360 * @removed 361 */ isStatic()362 public boolean isStatic() { 363 return mType == TYPE_STATIC; 364 } 365 366 /** 367 * @hide 368 */ isSdk()369 public boolean isSdk() { 370 return mType == TYPE_SDK_PACKAGE; 371 } 372 373 /** 374 * Gets the package that declares the library. 375 * 376 * @return The package declaring the library. 377 */ getDeclaringPackage()378 public @NonNull VersionedPackage getDeclaringPackage() { 379 return mDeclaringPackage; 380 } 381 382 /** 383 * Gets the packages that depend on the library. 384 * 385 * NOTE: the list also contains the result of {@link #getOptionalDependentPackages}. 386 * 387 * @return The dependent packages. 388 */ getDependentPackages()389 public @NonNull List<VersionedPackage> getDependentPackages() { 390 if (mDependentPackages == null) { 391 return Collections.emptyList(); 392 } 393 return mDependentPackages; 394 } 395 396 /** 397 * Gets the packages that optionally depend on the library. 398 * 399 * @return The dependent packages. 400 */ 401 @FlaggedApi(Flags.FLAG_SDK_LIB_INDEPENDENCE) getOptionalDependentPackages()402 public @NonNull List<VersionedPackage> getOptionalDependentPackages() { 403 if (mOptionalDependentPackages == null) { 404 return Collections.emptyList(); 405 } 406 return mOptionalDependentPackages; 407 } 408 409 @Override describeContents()410 public int describeContents() { 411 return 0; 412 } 413 414 @Override toString()415 public String toString() { 416 return "SharedLibraryInfo{name:" + mName + ", type:" + typeToString(mType) 417 + ", version:" + mVersion + (!getDependentPackages().isEmpty() 418 ? " has dependents" : "") + "}"; 419 } 420 421 @Override writeToParcel(Parcel parcel, int flags)422 public void writeToParcel(Parcel parcel, int flags) { 423 parcel.writeString8(mPath); 424 parcel.writeString8(mPackageName); 425 if (mCodePaths != null) { 426 parcel.writeInt(1); 427 parcel.writeString8Array(mCodePaths.toArray(new String[mCodePaths.size()])); 428 } else { 429 parcel.writeInt(0); 430 } 431 parcel.writeString8(mName); 432 parcel.writeLong(mVersion); 433 parcel.writeInt(mType); 434 parcel.writeParcelable(mDeclaringPackage, flags); 435 parcel.writeList(mDependentPackages); 436 parcel.writeTypedList(mDependencies); 437 parcel.writeBoolean(mIsNative); 438 parcel.writeParcelableList(mOptionalDependentPackages, flags); 439 } 440 typeToString(int type)441 private static String typeToString(int type) { 442 switch (type) { 443 case TYPE_BUILTIN: { 444 return "builtin"; 445 } 446 case TYPE_DYNAMIC: { 447 return "dynamic"; 448 } 449 case TYPE_STATIC: { 450 return "static"; 451 } 452 case TYPE_SDK_PACKAGE: { 453 return "sdk"; 454 } 455 default: { 456 return "unknown"; 457 } 458 } 459 } 460 461 public static final @android.annotation.NonNull Parcelable.Creator<SharedLibraryInfo> CREATOR = 462 new Parcelable.Creator<SharedLibraryInfo>() { 463 public SharedLibraryInfo createFromParcel(Parcel source) { 464 return new SharedLibraryInfo(source); 465 } 466 467 public SharedLibraryInfo[] newArray(int size) { 468 return new SharedLibraryInfo[size]; 469 } 470 }; 471 } 472