1beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin/*
2beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * Copyright (C) 2018 The Android Open Source Project
3beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin *
4beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
5beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * you may not use this file except in compliance with the License.
6beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * You may obtain a copy of the License at
7beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin *
8beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin *      http://www.apache.org/licenses/LICENSE-2.0
9beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin *
10beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * Unless required by applicable law or agreed to in writing, software
11beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
12beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * See the License for the specific language governing permissions and
14beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * limitations under the License.
15beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin */
16beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinpackage android.content.pm;
17beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
18beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinimport android.annotation.NonNull;
19beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinimport android.annotation.Nullable;
200692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffinimport android.os.Build;
21beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
22beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinimport com.android.internal.annotations.VisibleForTesting;
23beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinimport com.android.internal.util.ArrayUtils;
24beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
25beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinimport java.util.ArrayList;
26beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
27beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin/**
28beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * Base for classes that update a {@link PackageParser.Package}'s shared libraries.
29beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin *
30beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin * @hide
31beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin */
32beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin@VisibleForTesting
33beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffinpublic abstract class PackageSharedLibraryUpdater {
34beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
35beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin    /**
36beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin     * Update the package's shared libraries.
37beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin     *
38beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin     * @param pkg the package to update.
39beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin     */
40beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin    public abstract void updatePackage(PackageParser.Package pkg);
41beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
420692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    static void removeLibrary(PackageParser.Package pkg, String libraryName) {
430692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        pkg.usesLibraries = ArrayUtils.remove(pkg.usesLibraries, libraryName);
440692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        pkg.usesOptionalLibraries =
450692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin                ArrayUtils.remove(pkg.usesOptionalLibraries, libraryName);
460692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    }
470692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
48beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin    static @NonNull
49beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin            <T> ArrayList<T> prefix(@Nullable ArrayList<T> cur, T val) {
50beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin        if (cur == null) {
51beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin            cur = new ArrayList<>();
52beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin        }
53beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin        cur.add(0, val);
54beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin        return cur;
55beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin    }
56beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin
570692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    private static boolean isLibraryPresent(ArrayList<String> usesLibraries,
58beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin            ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) {
59beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin        return ArrayUtils.contains(usesLibraries, apacheHttpLegacy)
60beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin                || ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy);
61beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin    }
620692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
630692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(PackageParser.Package pkg) {
640692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
65aa1a911d9a0f797748b001c41bd8df2f517b318cJeff Sharkey        return targetSdkVersion < Build.VERSION_CODES.P;
660692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    }
670692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
680692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    /**
690692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     * Add an implicit dependency.
700692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     *
710692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     * <p>If the package has an existing dependency on {@code existingLibrary} then prefix it with
720692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     * the {@code implicitDependency} if it is not already in the list of libraries.
730692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     *
740692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     * @param pkg the {@link PackageParser.Package} to update.
750692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     * @param existingLibrary the existing library.
760692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     * @param implicitDependency the implicit dependency to add
770692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin     */
780692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    void prefixImplicitDependency(PackageParser.Package pkg, String existingLibrary,
790692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            String implicitDependency) {
800692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        ArrayList<String> usesLibraries = pkg.usesLibraries;
810692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
820692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
830692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        if (!isLibraryPresent(usesLibraries, usesOptionalLibraries, implicitDependency)) {
840692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            if (ArrayUtils.contains(usesLibraries, existingLibrary)) {
850692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin                prefix(usesLibraries, implicitDependency);
860692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            } else if (ArrayUtils.contains(usesOptionalLibraries, existingLibrary)) {
870692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin                prefix(usesOptionalLibraries, implicitDependency);
880692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            }
890692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
900692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            pkg.usesLibraries = usesLibraries;
910692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            pkg.usesOptionalLibraries = usesOptionalLibraries;
920692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        }
930692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    }
940692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
950692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    void prefixRequiredLibrary(PackageParser.Package pkg, String libraryName) {
960692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        ArrayList<String> usesLibraries = pkg.usesLibraries;
970692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
980692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
990692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        boolean alreadyPresent = isLibraryPresent(
1000692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin                usesLibraries, usesOptionalLibraries, libraryName);
1010692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        if (!alreadyPresent) {
1020692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            usesLibraries = prefix(usesLibraries, libraryName);
1030692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin
1040692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin            pkg.usesLibraries = usesLibraries;
1050692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin        }
1060692a566a974593fc2bf9b6b19ea88509d5ce2b4Paul Duffin    }
107beee5dcdfadf4d4b34d3d6ac733be3c420746c84Paul Duffin}
108