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