/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.webkit;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.UserHandle;
import android.util.Base64;
import android.util.Slog;
import android.webkit.UserPackage;
import android.webkit.WebViewFactory;
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Class that decides what WebView implementation to use and prepares that implementation for
 * use.
 */
class WebViewUpdater {
    private static final String TAG = WebViewUpdater.class.getSimpleName();

    private static class WebViewPackageMissingException extends Exception {
        public WebViewPackageMissingException(String message) { super(message); }
        public WebViewPackageMissingException(Exception e) { super(e); }
    }

    private static final int WAIT_TIMEOUT_MS = 1000; // KEY_DISPATCHING_TIMEOUT is 5000.

    private final static int VALIDITY_OK = 0;
    private final static int VALIDITY_INCORRECT_SDK_VERSION = 1;
    private final static int VALIDITY_INCORRECT_VERSION_CODE = 2;
    private final static int VALIDITY_INCORRECT_SIGNATURE = 3;
    private final static int VALIDITY_NO_LIBRARY_FLAG = 4;

    private Context mContext;
    private SystemInterface mSystemInterface;
    private long mMinimumVersionCode = -1;

    // Keeps track of the number of running relro creations
    private int mNumRelroCreationsStarted = 0;
    private int mNumRelroCreationsFinished = 0;
    // Implies that we need to rerun relro creation because we are using an out-of-date package
    private boolean mWebViewPackageDirty = false;
    private boolean mAnyWebViewInstalled = false;

    private int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE;

    // The WebView package currently in use (or the one we are preparing).
    private PackageInfo mCurrentWebViewPackage = null;

    private final Object mLock = new Object();

    WebViewUpdater(Context context, SystemInterface systemInterface) {
        mContext = context;
        mSystemInterface = systemInterface;
    }

    void packageStateChanged(String packageName, int changedState) {
        for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
            String webviewPackage = provider.packageName;

            if (webviewPackage.equals(packageName)) {
                boolean updateWebView = false;
                boolean removedOrChangedOldPackage = false;
                String oldProviderName = null;
                PackageInfo newPackage = null;
                synchronized(mLock) {
                    try {
                        newPackage = findPreferredWebViewPackage();
                        if (mCurrentWebViewPackage != null) {
                            oldProviderName = mCurrentWebViewPackage.packageName;
                            if (changedState == WebViewUpdateService.PACKAGE_CHANGED
                                    && newPackage.packageName.equals(oldProviderName)) {
                                // If we don't change package name we should only rerun the
                                // preparation phase if the current package has been replaced
                                // (not if it has been enabled/disabled).
                                return;
                            }
                            if (newPackage.packageName.equals(oldProviderName)
                                    && (newPackage.lastUpdateTime
                                        == mCurrentWebViewPackage.lastUpdateTime)) {
                                // If the chosen package hasn't been updated, then early-out
                                return;
                            }
                        }
                        // Only trigger update actions if the updated package is the one
                        // that will be used, or the one that was in use before the
                        // update, or if we haven't seen a valid WebView package before.
                        updateWebView =
                            provider.packageName.equals(newPackage.packageName)
                            || provider.packageName.equals(oldProviderName)
                            || mCurrentWebViewPackage == null;
                        // We removed the old package if we received an intent to remove
                        // or replace the old package.
                        removedOrChangedOldPackage =
                            provider.packageName.equals(oldProviderName);
                        if (updateWebView) {
                            onWebViewProviderChanged(newPackage);
                        }
                    } catch (WebViewPackageMissingException e) {
                        mCurrentWebViewPackage = null;
                        Slog.e(TAG, "Could not find valid WebView package to create " +
                                "relro with " + e);
                    }
                }
                if(updateWebView && !removedOrChangedOldPackage
                        && oldProviderName != null) {
                    // If the provider change is the result of adding or replacing a
                    // package that was not the previous provider then we must kill
                    // packages dependent on the old package ourselves. The framework
                    // only kills dependents of packages that are being removed.
                    mSystemInterface.killPackageDependents(oldProviderName);
                }
                return;
            }
        }
    }

    void prepareWebViewInSystemServer() {
        try {
            synchronized(mLock) {
                mCurrentWebViewPackage = findPreferredWebViewPackage();
                // Don't persist the user-chosen setting across boots if the package being
                // chosen is not used (could be disabled or uninstalled) so that the user won't
                // be surprised by the device switching to using a certain webview package,
                // that was uninstalled/disabled a long time ago, if it is installed/enabled
                // again.
                mSystemInterface.updateUserSetting(mContext,
                        mCurrentWebViewPackage.packageName);
                onWebViewProviderChanged(mCurrentWebViewPackage);
            }
        } catch (Throwable t) {
            // Log and discard errors at this stage as we must not crash the system server.
            Slog.e(TAG, "error preparing webview provider from system server", t);
        }
    }

    /**
     * Change WebView provider and provider setting and kill packages using the old provider.
     * Return the new provider (in case we are in the middle of creating relro files, or
     * replacing that provider it will not be in use directly, but will be used when the relros
     * or the replacement are done).
     */
    String changeProviderAndSetting(String newProviderName) {
        PackageInfo newPackage = updateCurrentWebViewPackage(newProviderName);
        if (newPackage == null) return "";
        return newPackage.packageName;
    }

    /**
     * Update the current WebView package.
     * @param newProviderName the package to switch to, null if no package has been explicitly
     * chosen.
     */
    PackageInfo updateCurrentWebViewPackage(String newProviderName) {
        PackageInfo oldPackage = null;
        PackageInfo newPackage = null;
        boolean providerChanged = false;
        synchronized(mLock) {
            oldPackage = mCurrentWebViewPackage;

            if (newProviderName != null) {
                mSystemInterface.updateUserSetting(mContext, newProviderName);
            }

            try {
                newPackage = findPreferredWebViewPackage();
                providerChanged = (oldPackage == null)
                        || !newPackage.packageName.equals(oldPackage.packageName);
            } catch (WebViewPackageMissingException e) {
                // If updated the Setting but don't have an installed WebView package, the
                // Setting will be used when a package is available.
                mCurrentWebViewPackage = null;
                Slog.e(TAG, "Couldn't find WebView package to use " + e);
                return null;
            }
            // Perform the provider change if we chose a new provider
            if (providerChanged) {
                onWebViewProviderChanged(newPackage);
            }
        }
        // Kill apps using the old provider only if we changed provider
        if (providerChanged && oldPackage != null) {
            mSystemInterface.killPackageDependents(oldPackage.packageName);
        }
        // Return the new provider, this is not necessarily the one we were asked to switch to,
        // but the persistent setting will now be pointing to the provider we were asked to
        // switch to anyway.
        return newPackage;
    }

    /**
     * This is called when we change WebView provider, either when the current provider is
     * updated or a new provider is chosen / takes precedence.
     */
    private void onWebViewProviderChanged(PackageInfo newPackage) {
        synchronized(mLock) {
            mAnyWebViewInstalled = true;
            if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
                mCurrentWebViewPackage = newPackage;

                // The relro creations might 'finish' (not start at all) before
                // WebViewFactory.onWebViewProviderChanged which means we might not know the
                // number of started creations before they finish.
                mNumRelroCreationsStarted = NUMBER_OF_RELROS_UNKNOWN;
                mNumRelroCreationsFinished = 0;
                mNumRelroCreationsStarted =
                    mSystemInterface.onWebViewProviderChanged(newPackage);
                // If the relro creations finish before we know the number of started creations
                // we will have to do any cleanup/notifying here.
                checkIfRelrosDoneLocked();
            } else {
                mWebViewPackageDirty = true;
            }
        }
    }

    /**
     * Fetch only the currently valid WebView packages.
     **/
    WebViewProviderInfo[] getValidWebViewPackages() {
        ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos();
        WebViewProviderInfo[] providers =
            new WebViewProviderInfo[providersAndPackageInfos.length];
        for(int n = 0; n < providersAndPackageInfos.length; n++) {
            providers[n] = providersAndPackageInfos[n].provider;
        }
        return providers;
    }

    private static class ProviderAndPackageInfo {
        public final WebViewProviderInfo provider;
        public final PackageInfo packageInfo;

        public ProviderAndPackageInfo(WebViewProviderInfo provider, PackageInfo packageInfo) {
            this.provider = provider;
            this.packageInfo = packageInfo;
        }
    }

    private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() {
        WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
        List<ProviderAndPackageInfo> providers = new ArrayList<>();
        for(int n = 0; n < allProviders.length; n++) {
            try {
                PackageInfo packageInfo =
                    mSystemInterface.getPackageInfoForProvider(allProviders[n]);
                if (isValidProvider(allProviders[n], packageInfo)) {
                    providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo));
                }
            } catch (NameNotFoundException e) {
                // Don't add non-existent packages
            }
        }
        return providers.toArray(new ProviderAndPackageInfo[providers.size()]);
    }

    /**
     * Returns either the package info of the WebView provider determined in the following way:
     * If the user has chosen a provider then use that if it is valid,
     * otherwise use the first package in the webview priority list that is valid.
     *
     */
    private PackageInfo findPreferredWebViewPackage() throws WebViewPackageMissingException {
        ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos();

        String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(mContext);

        // If the user has chosen provider, use that (if it's installed and enabled for all
        // users).
        for (ProviderAndPackageInfo providerAndPackage : providers) {
            if (providerAndPackage.provider.packageName.equals(userChosenProvider)) {
                // userPackages can contain null objects.
                List<UserPackage> userPackages =
                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext,
                                providerAndPackage.provider);
                if (isInstalledAndEnabledForAllUsers(userPackages)) {
                    return providerAndPackage.packageInfo;
                }
            }
        }

        // User did not choose, or the choice failed; use the most stable provider that is
        // installed and enabled for all users, and available by default (not through
        // user choice).
        for (ProviderAndPackageInfo providerAndPackage : providers) {
            if (providerAndPackage.provider.availableByDefault) {
                // userPackages can contain null objects.
                List<UserPackage> userPackages =
                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext,
                                providerAndPackage.provider);
                if (isInstalledAndEnabledForAllUsers(userPackages)) {
                    return providerAndPackage.packageInfo;
                }
            }
        }

        // This should never happen during normal operation (only with modified system images).
        mAnyWebViewInstalled = false;
        throw new WebViewPackageMissingException("Could not find a loadable WebView package");
    }

    /**
     * Return true iff {@param packageInfos} point to only installed and enabled packages.
     * The given packages {@param packageInfos} should all be pointing to the same package, but each
     * PackageInfo representing a different user's package.
     */
    static boolean isInstalledAndEnabledForAllUsers(
            List<UserPackage> userPackages) {
        for (UserPackage userPackage : userPackages) {
            if (!userPackage.isInstalledPackage() || !userPackage.isEnabledPackage()) {
                return false;
            }
        }
        return true;
    }

    void notifyRelroCreationCompleted() {
        synchronized (mLock) {
            mNumRelroCreationsFinished++;
            checkIfRelrosDoneLocked();
        }
    }

    WebViewProviderResponse waitForAndGetProvider() {
        PackageInfo webViewPackage = null;
        final long NS_PER_MS = 1000000;
        final long timeoutTimeMs = System.nanoTime() / NS_PER_MS + WAIT_TIMEOUT_MS;
        boolean webViewReady = false;
        int webViewStatus = WebViewFactory.LIBLOAD_SUCCESS;
        synchronized (mLock) {
            webViewReady = webViewIsReadyLocked();
            while (!webViewReady) {
                final long timeNowMs = System.nanoTime() / NS_PER_MS;
                if (timeNowMs >= timeoutTimeMs) break;
                try {
                    mLock.wait(timeoutTimeMs - timeNowMs);
                } catch (InterruptedException e) {}
                webViewReady = webViewIsReadyLocked();
            }
            // Make sure we return the provider that was used to create the relro file
            webViewPackage = mCurrentWebViewPackage;
            if (webViewReady) {
            } else if (!mAnyWebViewInstalled) {
                webViewStatus = WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES;
            } else {
                // Either the current relro creation  isn't done yet, or the new relro creatioin
                // hasn't kicked off yet (the last relro creation used an out-of-date WebView).
                webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO;
                Slog.e(TAG, "Timed out waiting for relro creation, relros started "
                        + mNumRelroCreationsStarted
                        + " relros finished " + mNumRelroCreationsFinished
                        + " package dirty? " + mWebViewPackageDirty);
            }
        }
        if (!webViewReady) Slog.w(TAG, "creating relro file timed out");
        return new WebViewProviderResponse(webViewPackage, webViewStatus);
    }

    PackageInfo getCurrentWebViewPackage() {
        synchronized(mLock) {
            return mCurrentWebViewPackage;
        }
    }

    /**
     * Returns whether WebView is ready and is not going to go through its preparation phase
     * again directly.
     */
    private boolean webViewIsReadyLocked() {
        return !mWebViewPackageDirty
            && (mNumRelroCreationsStarted == mNumRelroCreationsFinished)
            // The current package might be replaced though we haven't received an intent
            // declaring this yet, the following flag makes anyone loading WebView to wait in
            // this case.
            && mAnyWebViewInstalled;
    }

    private void checkIfRelrosDoneLocked() {
        if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
            if (mWebViewPackageDirty) {
                mWebViewPackageDirty = false;
                // If we have changed provider since we started the relro creation we need to
                // redo the whole process using the new package instead.
                try {
                    PackageInfo newPackage = findPreferredWebViewPackage();
                    onWebViewProviderChanged(newPackage);
                } catch (WebViewPackageMissingException e) {
                    mCurrentWebViewPackage = null;
                    // If we can't find any valid WebView package we are now in a state where
                    // mAnyWebViewInstalled is false, so loading WebView will be blocked and we
                    // should simply wait until we receive an intent declaring a new package was
                    // installed.
                }
            } else {
                mLock.notifyAll();
            }
        }
    }

    /**
     * Returns whether this provider is valid for use as a WebView provider.
     */
    boolean isValidProvider(WebViewProviderInfo configInfo, PackageInfo packageInfo) {
        return VALIDITY_OK == validityResult(configInfo, packageInfo);
    }

    private int validityResult(WebViewProviderInfo configInfo, PackageInfo packageInfo) {
        // Ensure the provider targets this framework release (or a later one).
        if (!UserPackage.hasCorrectTargetSdkVersion(packageInfo)) {
            return VALIDITY_INCORRECT_SDK_VERSION;
        }
        if (!versionCodeGE(packageInfo.getLongVersionCode(), getMinimumVersionCode())
                && !mSystemInterface.systemIsDebuggable()) {
            // Webview providers may be downgraded arbitrarily low, prevent that by enforcing
            // minimum version code. This check is only enforced for user builds.
            return VALIDITY_INCORRECT_VERSION_CODE;
        }
        if (!providerHasValidSignature(configInfo, packageInfo, mSystemInterface)) {
            return VALIDITY_INCORRECT_SIGNATURE;
        }
        if (WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) == null) {
            return VALIDITY_NO_LIBRARY_FLAG;
        }
        return VALIDITY_OK;
    }

    /**
     * Both versionCodes should be from a WebView provider package implemented by Chromium.
     * VersionCodes from other kinds of packages won't make any sense in this method.
     *
     * An introduction to Chromium versionCode scheme:
     * "BBBBPPPAX"
     * BBBB: 4 digit branch number. It monotonically increases over time.
     * PPP: patch number in the branch. It is padded with zeroes to the left. These three digits
     * may change their meaning in the future.
     * A: architecture digit.
     * X: A digit to differentiate APKs for other reasons.
     *
     * This method takes the "BBBB" of versionCodes and compare them.
     *
     * @return true if versionCode1 is higher than or equal to versionCode2.
     */
    private static boolean versionCodeGE(long versionCode1, long versionCode2) {
        long v1 = versionCode1 / 100000;
        long v2 = versionCode2 / 100000;

        return v1 >= v2;
    }

    /**
     * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode
     * of all available-by-default and non-fallback WebView provider packages. If there is no
     * such WebView provider package on the system, then return -1, which means all positive
     * versionCode WebView packages are accepted.
     *
     * Note that this is a private method in WebViewUpdater that handles a variable
     * (mMinimumVersionCode) which is shared between threads. Furthermore, this method does not
     * hold mLock meaning that we must take extra care to ensure this method is thread-safe.
     */
    private long getMinimumVersionCode() {
        if (mMinimumVersionCode > 0) {
            return mMinimumVersionCode;
        }

        long minimumVersionCode = -1;
        for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
            if (provider.availableByDefault && !provider.isFallback) {
                try {
                    long versionCode =
                        mSystemInterface.getFactoryPackageVersion(provider.packageName);
                    if (minimumVersionCode < 0 || versionCode < minimumVersionCode) {
                        minimumVersionCode = versionCode;
                    }
                } catch (NameNotFoundException e) {
                    // Safe to ignore.
                }
            }
        }

        mMinimumVersionCode = minimumVersionCode;
        return mMinimumVersionCode;
    }

    private static boolean providerHasValidSignature(WebViewProviderInfo provider,
            PackageInfo packageInfo, SystemInterface systemInterface) {
        // Skip checking signatures on debuggable builds, for development purposes.
        if (systemInterface.systemIsDebuggable()) return true;

        // Allow system apps to be valid providers regardless of signature.
        if (packageInfo.applicationInfo.isSystemApp()) return true;

        // We don't support packages with multiple signatures.
        if (packageInfo.signatures.length != 1) return false;

        // If any of the declared signatures match the package signature, it's valid.
        for (Signature signature : provider.signatures) {
            if (signature.equals(packageInfo.signatures[0])) return true;
        }

        return false;
    }

    void dumpState(PrintWriter pw) {
        synchronized (mLock) {
            if (mCurrentWebViewPackage == null) {
                pw.println("  Current WebView package is null");
            } else {
                pw.println(String.format("  Current WebView package (name, version): (%s, %s)",
                        mCurrentWebViewPackage.packageName,
                        mCurrentWebViewPackage.versionName));
            }
            pw.println(String.format("  Minimum targetSdkVersion: %d",
                    UserPackage.MINIMUM_SUPPORTED_SDK));
            pw.println(String.format("  Minimum WebView version code: %d",
                  mMinimumVersionCode));
            pw.println(String.format("  Number of relros started: %d",
                    mNumRelroCreationsStarted));
            pw.println(String.format("  Number of relros finished: %d",
                        mNumRelroCreationsFinished));
            pw.println(String.format("  WebView package dirty: %b", mWebViewPackageDirty));
            pw.println(String.format("  Any WebView package installed: %b",
                    mAnyWebViewInstalled));

            try {
                PackageInfo preferredWebViewPackage = findPreferredWebViewPackage();
                pw.println(String.format(
                        "  Preferred WebView package (name, version): (%s, %s)",
                        preferredWebViewPackage.packageName,
                        preferredWebViewPackage.versionName));
            } catch (WebViewPackageMissingException e) {
                pw.println(String.format("  Preferred WebView package: none"));
            }

            dumpAllPackageInformationLocked(pw);
        }
    }

    private void dumpAllPackageInformationLocked(PrintWriter pw) {
        WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
        pw.println("  WebView packages:");
        for (WebViewProviderInfo provider : allProviders) {
            List<UserPackage> userPackages =
                    mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider);
            PackageInfo systemUserPackageInfo =
                    userPackages.get(UserHandle.USER_SYSTEM).getPackageInfo();
            if (systemUserPackageInfo == null) {
                pw.println(String.format("    %s is NOT installed.", provider.packageName));
                continue;
            }

            int validity = validityResult(provider, systemUserPackageInfo);
            String packageDetails = String.format(
                    "versionName: %s, versionCode: %d, targetSdkVersion: %d",
                    systemUserPackageInfo.versionName,
                    systemUserPackageInfo.getLongVersionCode(),
                    systemUserPackageInfo.applicationInfo.targetSdkVersion);
            if (validity == VALIDITY_OK) {
                boolean installedForAllUsers = isInstalledAndEnabledForAllUsers(
                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider));
                pw.println(String.format(
                        "    Valid package %s (%s) is %s installed/enabled for all users",
                        systemUserPackageInfo.packageName,
                        packageDetails,
                        installedForAllUsers ? "" : "NOT"));
            } else {
                pw.println(String.format("    Invalid package %s (%s), reason: %s",
                        systemUserPackageInfo.packageName,
                        packageDetails,
                        getInvalidityReason(validity)));
            }
        }
    }

    private static String getInvalidityReason(int invalidityReason) {
        switch (invalidityReason) {
            case VALIDITY_INCORRECT_SDK_VERSION:
                return "SDK version too low";
            case VALIDITY_INCORRECT_VERSION_CODE:
                return "Version code too low";
            case VALIDITY_INCORRECT_SIGNATURE:
                return "Incorrect signature";
            case VALIDITY_NO_LIBRARY_FLAG:
                return "No WebView-library manifest flag";
            default:
                return "Unexcepted validity-reason";
        }
    }

}
