PackageSharedLibraryUpdater.java revision aa1a911d9a0f797748b001c41bd8df2f517b318c
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 */
16package android.content.pm;
17
18import android.annotation.NonNull;
19import android.annotation.Nullable;
20import android.os.Build;
21
22import com.android.internal.annotations.VisibleForTesting;
23import com.android.internal.util.ArrayUtils;
24
25import java.util.ArrayList;
26
27/**
28 * Base for classes that update a {@link PackageParser.Package}'s shared libraries.
29 *
30 * @hide
31 */
32@VisibleForTesting
33public 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