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.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.TestApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import java.lang.annotation.Retention; 28 import java.lang.annotation.RetentionPolicy; 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.List; 33 import java.util.Objects; 34 35 /** 36 * This class provides information for a shared library. There are 37 * four types of shared libraries: builtin - non-updatable part of 38 * the OS; dynamic - updatable backwards-compatible dynamically linked; 39 * static - non backwards-compatible emulating static linking; 40 * SDK - updatable backwards-incompatible dynamically loaded. 41 */ 42 public final class SharedLibraryInfo implements Parcelable { 43 44 /** @hide */ 45 @IntDef(flag = true, prefix = { "TYPE_" }, value = { 46 TYPE_BUILTIN, 47 TYPE_DYNAMIC, 48 TYPE_STATIC, 49 TYPE_SDK_PACKAGE, 50 }) 51 @Retention(RetentionPolicy.SOURCE) 52 public @interface Type{} 53 54 /** 55 * Shared library type: this library is a part of the OS 56 * and cannot be updated or uninstalled. 57 */ 58 public static final int TYPE_BUILTIN = 0; 59 60 /** 61 * Shared library type: this library is backwards-compatible, can 62 * be updated, and updates can be uninstalled. Clients link against 63 * the latest version of the library. 64 */ 65 public static final int TYPE_DYNAMIC = 1; 66 67 /** 68 * Shared library type: this library is <strong>not</strong> backwards 69 * -compatible, can be updated and updates can be uninstalled. Clients 70 * link against a specific version of the library. 71 * 72 * Static shared libraries simulate static linking while allowing for 73 * multiple clients to reuse the same instance of the library. 74 */ 75 public static final int TYPE_STATIC = 2; 76 77 /** 78 * SDK package shared library type: this library is <strong>not</strong> 79 * compatible between versions, can be updated and updates can be 80 * uninstalled. Clients depend on a specific version of the library. 81 * 82 * SDK packages are not loaded automatically by the OS and rely 83 * e.g. on 3P libraries to make them available for the clients. 84 */ 85 public static final int TYPE_SDK_PACKAGE = 3; 86 87 /** 88 * Constant for referring to an undefined version. 89 */ 90 public static final int VERSION_UNDEFINED = -1; 91 92 private final String mPath; 93 private final String mPackageName; 94 private final String mName; 95 private final List<String> mCodePaths; 96 97 private final long mVersion; 98 private final @Type int mType; 99 private final boolean mIsNative; 100 private final VersionedPackage mDeclaringPackage; 101 private final List<VersionedPackage> mDependentPackages; 102 private List<SharedLibraryInfo> mDependencies; 103 104 /** 105 * Creates a new instance. 106 * 107 * @param codePaths For a non {@link #TYPE_BUILTIN builtin} library, the locations of jars of 108 * this shared library. Null for builtin library. 109 * @param name The lib name. 110 * @param version The lib version if not builtin. 111 * @param type The lib type. 112 * @param declaringPackage The package that declares the library. 113 * @param dependentPackages The packages that depend on the library. 114 * @param isNative indicate if this shared lib is a native lib or not (i.e. java) 115 * 116 * @hide 117 */ SharedLibraryInfo(String path, String packageName, List<String> codePaths, String name, long version, int type, VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages, List<SharedLibraryInfo> dependencies, boolean isNative)118 public SharedLibraryInfo(String path, String packageName, List<String> codePaths, 119 String name, long version, int type, 120 VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages, 121 List<SharedLibraryInfo> dependencies, boolean isNative) { 122 mPath = path; 123 mPackageName = packageName; 124 mCodePaths = codePaths; 125 mName = name; 126 mVersion = version; 127 mType = type; 128 mDeclaringPackage = declaringPackage; 129 mDependentPackages = dependentPackages; 130 mDependencies = dependencies; 131 mIsNative = isNative; 132 } 133 SharedLibraryInfo(Parcel parcel)134 private SharedLibraryInfo(Parcel parcel) { 135 mPath = parcel.readString8(); 136 mPackageName = parcel.readString8(); 137 if (parcel.readInt() != 0) { 138 mCodePaths = Arrays.asList(parcel.createString8Array()); 139 } else { 140 mCodePaths = null; 141 } 142 mName = parcel.readString8(); 143 mVersion = parcel.readLong(); 144 mType = parcel.readInt(); 145 mDeclaringPackage = parcel.readParcelable(null, android.content.pm.VersionedPackage.class); 146 mDependentPackages = parcel.readArrayList(null, android.content.pm.VersionedPackage.class); 147 mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR); 148 mIsNative = parcel.readBoolean(); 149 } 150 151 /** 152 * Gets the type of this library. 153 * 154 * @return The library type. 155 */ getType()156 public @Type int getType() { 157 return mType; 158 } 159 160 /** 161 * Tells whether this library is a native shared library or not. 162 * 163 * @hide 164 */ 165 @TestApi isNative()166 public boolean isNative() { 167 return mIsNative; 168 } 169 170 /** 171 * Gets the library name an app defines in its manifest 172 * to depend on the library. 173 * 174 * @return The name. 175 */ getName()176 public String getName() { 177 return mName; 178 } 179 180 /** 181 * If the shared library is a jar file, returns the path of that jar. Null otherwise. 182 * Only libraries with TYPE_BUILTIN are in jar files. 183 * 184 * @return The path. 185 * 186 * @hide 187 */ getPath()188 public @Nullable String getPath() { 189 return mPath; 190 } 191 192 /** 193 * If the shared library is an apk, returns the package name. Null otherwise. 194 * Only libraries with TYPE_DYNAMIC or TYPE_STATIC are in apks. 195 * 196 * @return The package name. 197 * 198 * @hide 199 */ getPackageName()200 public @Nullable String getPackageName() { 201 return mPackageName; 202 } 203 204 /** 205 * Get all code paths for that library. 206 * 207 * @return All code paths. 208 * 209 * @hide 210 */ 211 @TestApi getAllCodePaths()212 public @NonNull List<String> getAllCodePaths() { 213 if (getPath() != null) { 214 // Builtin library. 215 ArrayList<String> list = new ArrayList<>(); 216 list.add(getPath()); 217 return list; 218 } else { 219 // Static or dynamic library. 220 return Objects.requireNonNull(mCodePaths); 221 } 222 } 223 224 /** 225 * Add a library dependency to that library. Note that this 226 * should be called under the package manager lock. 227 * 228 * @hide 229 */ addDependency(@ullable SharedLibraryInfo info)230 public void addDependency(@Nullable SharedLibraryInfo info) { 231 if (info == null) { 232 // For convenience of the caller, allow null to be passed. 233 // This can happen when we create the dependencies of builtin 234 // libraries. 235 return; 236 } 237 if (mDependencies == null) { 238 mDependencies = new ArrayList<>(); 239 } 240 mDependencies.add(info); 241 } 242 243 /** 244 * Clear all dependencies. 245 * 246 * @hide 247 */ clearDependencies()248 public void clearDependencies() { 249 mDependencies = null; 250 } 251 252 /** 253 * Gets the libraries this library directly depends on. Note that 254 * the package manager prevents recursive dependencies when installing 255 * a package. 256 * 257 * @return The dependencies. 258 * 259 * @hide 260 */ getDependencies()261 public @Nullable List<SharedLibraryInfo> getDependencies() { 262 return mDependencies; 263 } 264 265 /** 266 * @deprecated Use {@link #getLongVersion()} instead. 267 */ 268 @Deprecated getVersion()269 public @IntRange(from = -1) int getVersion() { 270 return mVersion < 0 ? (int) mVersion : (int) (mVersion & 0x7fffffff); 271 } 272 273 /** 274 * Gets the version of the library. For {@link #TYPE_STATIC static} libraries 275 * this is the declared version and for {@link #TYPE_DYNAMIC dynamic} and 276 * {@link #TYPE_BUILTIN builtin} it is {@link #VERSION_UNDEFINED} as these 277 * are not versioned. 278 * 279 * @return The version. 280 */ getLongVersion()281 public @IntRange(from = -1) long getLongVersion() { 282 return mVersion; 283 } 284 285 /** 286 * @removed 287 */ isBuiltin()288 public boolean isBuiltin() { 289 return mType == TYPE_BUILTIN; 290 } 291 292 /** 293 * @removed 294 */ isDynamic()295 public boolean isDynamic() { 296 return mType == TYPE_DYNAMIC; 297 } 298 299 /** 300 * @removed 301 */ isStatic()302 public boolean isStatic() { 303 return mType == TYPE_STATIC; 304 } 305 306 /** 307 * @hide 308 */ isSdk()309 public boolean isSdk() { 310 return mType == TYPE_SDK_PACKAGE; 311 } 312 313 /** 314 * Gets the package that declares the library. 315 * 316 * @return The package declaring the library. 317 */ getDeclaringPackage()318 public @NonNull VersionedPackage getDeclaringPackage() { 319 return mDeclaringPackage; 320 } 321 322 /** 323 * Gets the packages that depend on the library. 324 * 325 * @return The dependent packages. 326 */ getDependentPackages()327 public @NonNull List<VersionedPackage> getDependentPackages() { 328 if (mDependentPackages == null) { 329 return Collections.emptyList(); 330 } 331 return mDependentPackages; 332 } 333 334 @Override describeContents()335 public int describeContents() { 336 return 0; 337 } 338 339 @Override toString()340 public String toString() { 341 return "SharedLibraryInfo{name:" + mName + ", type:" + typeToString(mType) 342 + ", version:" + mVersion + (!getDependentPackages().isEmpty() 343 ? " has dependents" : "") + "}"; 344 } 345 346 @Override writeToParcel(Parcel parcel, int flags)347 public void writeToParcel(Parcel parcel, int flags) { 348 parcel.writeString8(mPath); 349 parcel.writeString8(mPackageName); 350 if (mCodePaths != null) { 351 parcel.writeInt(1); 352 parcel.writeString8Array(mCodePaths.toArray(new String[mCodePaths.size()])); 353 } else { 354 parcel.writeInt(0); 355 } 356 parcel.writeString8(mName); 357 parcel.writeLong(mVersion); 358 parcel.writeInt(mType); 359 parcel.writeParcelable(mDeclaringPackage, flags); 360 parcel.writeList(mDependentPackages); 361 parcel.writeTypedList(mDependencies); 362 parcel.writeBoolean(mIsNative); 363 } 364 typeToString(int type)365 private static String typeToString(int type) { 366 switch (type) { 367 case TYPE_BUILTIN: { 368 return "builtin"; 369 } 370 case TYPE_DYNAMIC: { 371 return "dynamic"; 372 } 373 case TYPE_STATIC: { 374 return "static"; 375 } 376 case TYPE_SDK_PACKAGE: { 377 return "sdk"; 378 } 379 default: { 380 return "unknown"; 381 } 382 } 383 } 384 385 public static final @android.annotation.NonNull Parcelable.Creator<SharedLibraryInfo> CREATOR = 386 new Parcelable.Creator<SharedLibraryInfo>() { 387 public SharedLibraryInfo createFromParcel(Parcel source) { 388 return new SharedLibraryInfo(source); 389 } 390 391 public SharedLibraryInfo[] newArray(int size) { 392 return new SharedLibraryInfo[size]; 393 } 394 }; 395 } 396