Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2018 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 package android.content.pm;
     17 
     18 import android.annotation.NonNull;
     19 import android.annotation.Nullable;
     20 import android.os.Build;
     21 
     22 import com.android.internal.annotations.VisibleForTesting;
     23 import com.android.internal.util.ArrayUtils;
     24 
     25 import java.util.ArrayList;
     26 
     27 /**
     28  * Base for classes that update a {@link PackageParser.Package}'s shared libraries.
     29  *
     30  * @hide
     31  */
     32 @VisibleForTesting
     33 public abstract class PackageSharedLibraryUpdater {
     34 
     35     /**
     36      * Update the package's shared libraries.
     37      *
     38      * @param pkg the package to update.
     39      */
     40     public abstract void updatePackage(PackageParser.Package pkg);
     41 
     42     static void removeLibrary(PackageParser.Package pkg, String libraryName) {
     43         pkg.usesLibraries = ArrayUtils.remove(pkg.usesLibraries, libraryName);
     44         pkg.usesOptionalLibraries =
     45                 ArrayUtils.remove(pkg.usesOptionalLibraries, libraryName);
     46     }
     47 
     48     static @NonNull
     49             <T> ArrayList<T> prefix(@Nullable ArrayList<T> cur, T val) {
     50         if (cur == null) {
     51             cur = new ArrayList<>();
     52         }
     53         cur.add(0, val);
     54         return cur;
     55     }
     56 
     57     private static boolean isLibraryPresent(ArrayList<String> usesLibraries,
     58             ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) {
     59         return ArrayUtils.contains(usesLibraries, apacheHttpLegacy)
     60                 || ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy);
     61     }
     62 
     63     static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(PackageParser.Package pkg) {
     64         int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
     65         return targetSdkVersion < Build.VERSION_CODES.P;
     66     }
     67 
     68     /**
     69      * Add an implicit dependency.
     70      *
     71      * <p>If the package has an existing dependency on {@code existingLibrary} then prefix it with
     72      * the {@code implicitDependency} if it is not already in the list of libraries.
     73      *
     74      * @param pkg the {@link PackageParser.Package} to update.
     75      * @param existingLibrary the existing library.
     76      * @param implicitDependency the implicit dependency to add
     77      */
     78     void prefixImplicitDependency(PackageParser.Package pkg, String existingLibrary,
     79             String implicitDependency) {
     80         ArrayList<String> usesLibraries = pkg.usesLibraries;
     81         ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
     82 
     83         if (!isLibraryPresent(usesLibraries, usesOptionalLibraries, implicitDependency)) {
     84             if (ArrayUtils.contains(usesLibraries, existingLibrary)) {
     85                 prefix(usesLibraries, implicitDependency);
     86             } else if (ArrayUtils.contains(usesOptionalLibraries, existingLibrary)) {
     87                 prefix(usesOptionalLibraries, implicitDependency);
     88             }
     89 
     90             pkg.usesLibraries = usesLibraries;
     91             pkg.usesOptionalLibraries = usesOptionalLibraries;
     92         }
     93     }
     94 
     95     void prefixRequiredLibrary(PackageParser.Package pkg, String libraryName) {
     96         ArrayList<String> usesLibraries = pkg.usesLibraries;
     97         ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
     98 
     99         boolean alreadyPresent = isLibraryPresent(
    100                 usesLibraries, usesOptionalLibraries, libraryName);
    101         if (!alreadyPresent) {
    102             usesLibraries = prefix(usesLibraries, libraryName);
    103 
    104             pkg.usesLibraries = usesLibraries;
    105         }
    106     }
    107 }
    108