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