/*
 * Copyright (C) 2016 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.pm;

import static android.content.Intent.FLAG_ACTIVITY_MATCH_EXTERNAL;

import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_RESOLUTION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_RESOLUTION_STATUS;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.InstantAppIntentFilter;
import android.content.pm.InstantAppRequest;
import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.server.pm.InstantAppResolverConnection.ConnectionException;
import com.android.server.pm.InstantAppResolverConnection.PhaseTwoCallback;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/** @hide */
public abstract class InstantAppResolver {
    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
    private static final String TAG = "PackageManager";

    private static final int RESOLUTION_SUCCESS = 0;
    private static final int RESOLUTION_FAILURE = 1;
    /** Binding to the external service timed out */
    private static final int RESOLUTION_BIND_TIMEOUT = 2;
    /** The call to retrieve an instant application response timed out */
    private static final int RESOLUTION_CALL_TIMEOUT = 3;

    @IntDef(flag = true, prefix = { "RESOLUTION_" }, value = {
            RESOLUTION_SUCCESS,
            RESOLUTION_FAILURE,
            RESOLUTION_BIND_TIMEOUT,
            RESOLUTION_CALL_TIMEOUT,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ResolutionStatus {}

    private static MetricsLogger sMetricsLogger;

    private static MetricsLogger getLogger() {
        if (sMetricsLogger == null) {
            sMetricsLogger = new MetricsLogger();
        }
        return sMetricsLogger;
    }

    /**
     * Returns an intent with potential PII removed from the original intent. Fields removed
     * include extras and the host + path of the data, if defined.
     */
    public static Intent sanitizeIntent(Intent origIntent) {
        final Intent sanitizedIntent;
        sanitizedIntent = new Intent(origIntent.getAction());
        Set<String> categories = origIntent.getCategories();
        if (categories != null) {
            for (String category : categories) {
                sanitizedIntent.addCategory(category);
            }
        }
        Uri sanitizedUri = origIntent.getData() == null
                ? null
                : Uri.fromParts(origIntent.getScheme(), "", "");
        sanitizedIntent.setDataAndType(sanitizedUri, origIntent.getType());
        sanitizedIntent.addFlags(origIntent.getFlags());
        sanitizedIntent.setPackage(origIntent.getPackage());
        return sanitizedIntent;
    }

    public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(
            InstantAppResolverConnection connection, InstantAppRequest requestObj) {
        final long startTime = System.currentTimeMillis();
        final String token = UUID.randomUUID().toString();
        if (DEBUG_INSTANT) {
            Log.d(TAG, "[" + token + "] Phase1; resolving");
        }
        final Intent origIntent = requestObj.origIntent;
        final Intent sanitizedIntent = sanitizeIntent(origIntent);

        AuxiliaryResolveInfo resolveInfo = null;
        @ResolutionStatus int resolutionStatus = RESOLUTION_SUCCESS;
        try {
            final List<InstantAppResolveInfo> instantAppResolveInfoList =
                    connection.getInstantAppResolveInfoList(sanitizedIntent,
                            requestObj.digest.getDigestPrefixSecure(), requestObj.userId, token);
            if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
                resolveInfo = InstantAppResolver.filterInstantAppIntent(
                        instantAppResolveInfoList, origIntent, requestObj.resolvedType,
                        requestObj.userId, origIntent.getPackage(), requestObj.digest, token);
            }
        } catch (ConnectionException e) {
            if (e.failure == ConnectionException.FAILURE_BIND) {
                resolutionStatus = RESOLUTION_BIND_TIMEOUT;
            } else if (e.failure == ConnectionException.FAILURE_CALL) {
                resolutionStatus = RESOLUTION_CALL_TIMEOUT;
            } else {
                resolutionStatus = RESOLUTION_FAILURE;
            }
        }
        // Only log successful instant application resolution
        if (requestObj.resolveForStart && resolutionStatus == RESOLUTION_SUCCESS) {
            logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE, startTime, token,
                    resolutionStatus);
        }
        if (DEBUG_INSTANT && resolveInfo == null) {
            if (resolutionStatus == RESOLUTION_BIND_TIMEOUT) {
                Log.d(TAG, "[" + token + "] Phase1; bind timed out");
            } else if (resolutionStatus == RESOLUTION_CALL_TIMEOUT) {
                Log.d(TAG, "[" + token + "] Phase1; call timed out");
            } else if (resolutionStatus != RESOLUTION_SUCCESS) {
                Log.d(TAG, "[" + token + "] Phase1; service connection error");
            } else {
                Log.d(TAG, "[" + token + "] Phase1; No results matched");
            }
        }
        // if the match external flag is set, return an empty resolve info instead of a null result.
        if (resolveInfo == null && (origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
            return new AuxiliaryResolveInfo(token, false, createFailureIntent(origIntent, token),
                    null /* filters */);
        }
        return resolveInfo;
    }

    public static void doInstantAppResolutionPhaseTwo(Context context,
            InstantAppResolverConnection connection, InstantAppRequest requestObj,
            ActivityInfo instantAppInstaller, Handler callbackHandler) {
        final long startTime = System.currentTimeMillis();
        final String token = requestObj.responseObj.token;
        if (DEBUG_INSTANT) {
            Log.d(TAG, "[" + token + "] Phase2; resolving");
        }
        final Intent origIntent = requestObj.origIntent;
        final Intent sanitizedIntent = sanitizeIntent(origIntent);

        final PhaseTwoCallback callback = new PhaseTwoCallback() {
            @Override
            void onPhaseTwoResolved(List<InstantAppResolveInfo> instantAppResolveInfoList,
                    long startTime) {
                final Intent failureIntent;
                if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
                    final AuxiliaryResolveInfo instantAppIntentInfo =
                            InstantAppResolver.filterInstantAppIntent(
                                    instantAppResolveInfoList, origIntent, null /*resolvedType*/,
                                    0 /*userId*/, origIntent.getPackage(), requestObj.digest,
                                    token);
                    if (instantAppIntentInfo != null) {
                        failureIntent = instantAppIntentInfo.failureIntent;
                    } else {
                        failureIntent = null;
                    }
                } else {
                    failureIntent = null;
                }
                final Intent installerIntent = buildEphemeralInstallerIntent(
                        requestObj.origIntent,
                        sanitizedIntent,
                        failureIntent,
                        requestObj.callingPackage,
                        requestObj.verificationBundle,
                        requestObj.resolvedType,
                        requestObj.userId,
                        requestObj.responseObj.installFailureActivity,
                        token,
                        false /*needsPhaseTwo*/,
                        requestObj.responseObj.filters);
                installerIntent.setComponent(new ComponentName(
                        instantAppInstaller.packageName, instantAppInstaller.name));

                logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO, startTime, token,
                        requestObj.responseObj.filters != null ? RESOLUTION_SUCCESS : RESOLUTION_FAILURE);

                context.startActivity(installerIntent);
            }
        };
        try {
            connection.getInstantAppIntentFilterList(sanitizedIntent,
                    requestObj.digest.getDigestPrefixSecure(), requestObj.userId, token, callback,
                    callbackHandler, startTime);
        } catch (ConnectionException e) {
            @ResolutionStatus int resolutionStatus = RESOLUTION_FAILURE;
            if (e.failure == ConnectionException.FAILURE_BIND) {
                resolutionStatus = RESOLUTION_BIND_TIMEOUT;
            }
            logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO, startTime, token,
                    resolutionStatus);
            if (DEBUG_INSTANT) {
                if (resolutionStatus == RESOLUTION_BIND_TIMEOUT) {
                    Log.d(TAG, "[" + token + "] Phase2; bind timed out");
                } else {
                    Log.d(TAG, "[" + token + "] Phase2; service connection error");
                }
            }
        }
    }

    /**
     * Builds and returns an intent to launch the instant installer.
     */
    public static Intent buildEphemeralInstallerIntent(
            @NonNull Intent origIntent,
            @NonNull Intent sanitizedIntent,
            @Nullable Intent failureIntent,
            @NonNull String callingPackage,
            @Nullable Bundle verificationBundle,
            @NonNull String resolvedType,
            int userId,
            @Nullable ComponentName installFailureActivity,
            @Nullable String token,
            boolean needsPhaseTwo,
            List<AuxiliaryResolveInfo.AuxiliaryFilter> filters) {
        // Construct the intent that launches the instant installer
        int flags = origIntent.getFlags();
        final Intent intent = new Intent();
        intent.setFlags(flags
                | Intent.FLAG_ACTIVITY_NO_HISTORY
                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        if (token != null) {
            intent.putExtra(Intent.EXTRA_INSTANT_APP_TOKEN, token);
        }
        if (origIntent.getData() != null) {
            intent.putExtra(Intent.EXTRA_INSTANT_APP_HOSTNAME, origIntent.getData().getHost());
        }
        intent.putExtra(Intent.EXTRA_INSTANT_APP_ACTION, origIntent.getAction());
        intent.putExtra(Intent.EXTRA_INTENT, sanitizedIntent);

        if (needsPhaseTwo) {
            intent.setAction(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
        } else {
            // We have all of the data we need; just start the installer without a second phase
            if (failureIntent != null || installFailureActivity != null) {
                // Intent that is launched if the package couldn't be installed for any reason.
                try {
                    final Intent onFailureIntent;
                    if (installFailureActivity != null) {
                        onFailureIntent = new Intent();
                        onFailureIntent.setComponent(installFailureActivity);
                        if (filters != null && filters.size() == 1) {
                            onFailureIntent.putExtra(Intent.EXTRA_SPLIT_NAME,
                                    filters.get(0).splitName);
                        }
                        onFailureIntent.putExtra(Intent.EXTRA_INTENT, origIntent);
                    } else {
                        onFailureIntent = failureIntent;
                    }
                    final IIntentSender failureIntentTarget = ActivityManager.getService()
                            .getIntentSender(
                                    ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                                    null /*token*/, null /*resultWho*/, 1 /*requestCode*/,
                                    new Intent[] { onFailureIntent },
                                    new String[] { resolvedType },
                                    PendingIntent.FLAG_CANCEL_CURRENT
                                            | PendingIntent.FLAG_ONE_SHOT
                                            | PendingIntent.FLAG_IMMUTABLE,
                                    null /*bOptions*/, userId);
                    IntentSender failureSender = new IntentSender(failureIntentTarget);
                    // TODO(b/72700831): remove populating old extra
                    intent.putExtra(Intent.EXTRA_INSTANT_APP_FAILURE, failureSender);
                } catch (RemoteException ignore) { /* ignore; same process */ }
            }

            // Intent that is launched if the package was installed successfully.
            final Intent successIntent = new Intent(origIntent);
            successIntent.setLaunchToken(token);
            try {
                final IIntentSender successIntentTarget = ActivityManager.getService()
                        .getIntentSender(
                                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                                null /*token*/, null /*resultWho*/, 0 /*requestCode*/,
                                new Intent[] { successIntent },
                                new String[] { resolvedType },
                                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
                                        | PendingIntent.FLAG_IMMUTABLE,
                                null /*bOptions*/, userId);
                IntentSender successSender = new IntentSender(successIntentTarget);
                intent.putExtra(Intent.EXTRA_INSTANT_APP_SUCCESS, successSender);
            } catch (RemoteException ignore) { /* ignore; same process */ }
            if (verificationBundle != null) {
                intent.putExtra(Intent.EXTRA_VERIFICATION_BUNDLE, verificationBundle);
            }
            intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);

            if (filters != null) {
                Bundle resolvableFilters[] = new Bundle[filters.size()];
                for (int i = 0, max = filters.size(); i < max; i++) {
                    Bundle resolvableFilter = new Bundle();
                    AuxiliaryResolveInfo.AuxiliaryFilter filter = filters.get(i);
                    resolvableFilter.putBoolean(Intent.EXTRA_UNKNOWN_INSTANT_APP,
                            filter.resolveInfo != null
                                    && filter.resolveInfo.shouldLetInstallerDecide());
                    resolvableFilter.putString(Intent.EXTRA_PACKAGE_NAME, filter.packageName);
                    resolvableFilter.putString(Intent.EXTRA_SPLIT_NAME, filter.splitName);
                    resolvableFilter.putLong(Intent.EXTRA_LONG_VERSION_CODE, filter.versionCode);
                    resolvableFilter.putBundle(Intent.EXTRA_INSTANT_APP_EXTRAS, filter.extras);
                    resolvableFilters[i] = resolvableFilter;
                    if (i == 0) {
                        // for backwards compat, always set the first result on the intent and add
                        // the int version code
                        intent.putExtras(resolvableFilter);
                        intent.putExtra(Intent.EXTRA_VERSION_CODE, (int) filter.versionCode);
                    }
                }
                intent.putExtra(Intent.EXTRA_INSTANT_APP_BUNDLES, resolvableFilters);
            }
            intent.setAction(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
        }
        return intent;
    }

    private static AuxiliaryResolveInfo filterInstantAppIntent(
            List<InstantAppResolveInfo> instantAppResolveInfoList,
            Intent origIntent, String resolvedType, int userId, String packageName,
            InstantAppDigest digest, String token) {
        final int[] shaPrefix = digest.getDigestPrefix();
        final byte[][] digestBytes = digest.getDigestBytes();
        boolean requiresSecondPhase = false;
        ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null;
        boolean requiresPrefixMatch = origIntent.isWebIntent() || (shaPrefix.length > 0
                        && (origIntent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0);
        for (InstantAppResolveInfo instantAppResolveInfo : instantAppResolveInfoList) {
            if (requiresPrefixMatch && instantAppResolveInfo.shouldLetInstallerDecide()) {
                Slog.d(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest"
                        + " required; ignoring");
                continue;
            }
            byte[] filterDigestBytes = instantAppResolveInfo.getDigestBytes();
            // Only include matching digests if we have a prefix and we're either dealing with a
            // prefixed request or the resolveInfo specifies digest details.
            if (shaPrefix.length > 0 && (requiresPrefixMatch || filterDigestBytes.length > 0)) {
                boolean matchFound = false;
                // Go in reverse order so we match the narrowest scope first.
                for (int i = shaPrefix.length - 1; i >= 0; --i) {
                    if (Arrays.equals(digestBytes[i], filterDigestBytes)) {
                        matchFound = true;
                        break;
                    }
                }
                if (!matchFound) {
                    continue;
                }
            }
            // We matched a resolve info; resolve the filters to see if anything matches completely.
            List<AuxiliaryResolveInfo.AuxiliaryFilter> matchFilters = computeResolveFilters(
                    origIntent, resolvedType, userId, packageName, token, instantAppResolveInfo);
            if (matchFilters != null) {
                if (matchFilters.isEmpty()) {
                    requiresSecondPhase = true;
                }
                if (filters == null) {
                    filters = new ArrayList<>(matchFilters);
                } else {
                    filters.addAll(matchFilters);
                }
            }
        }
        if (filters != null && !filters.isEmpty()) {
            return new AuxiliaryResolveInfo(token, requiresSecondPhase,
                    createFailureIntent(origIntent, token), filters);
        }
        // Hash or filter mis-match; no instant apps for this domain.
        return null;
    }

    /**
     * Creates a failure intent for the installer to send in the case that the instant app cannot be
     * launched for any reason.
     */
    private static Intent createFailureIntent(Intent origIntent, String token) {
        final Intent failureIntent = new Intent(origIntent);
        failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
        failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
        failureIntent.setLaunchToken(token);
        return failureIntent;
    }

    /**
     * Returns one of three states: <p/>
     * <ul>
     *     <li>{@code null} if there are no matches will not be; resolution is unnecessary.</li>
     *     <li>An empty list signifying that a 2nd phase of resolution is required.</li>
     *     <li>A populated list meaning that matches were found and should be sent directly to the
     *     installer</li>
     * </ul>
     *
     */
    private static List<AuxiliaryResolveInfo.AuxiliaryFilter> computeResolveFilters(
            Intent origIntent, String resolvedType, int userId, String packageName, String token,
            InstantAppResolveInfo instantAppInfo) {
        if (instantAppInfo.shouldLetInstallerDecide()) {
            return Collections.singletonList(
                    new AuxiliaryResolveInfo.AuxiliaryFilter(
                            instantAppInfo, null /* splitName */,
                            instantAppInfo.getExtras()));
        }
        if (packageName != null
                && !packageName.equals(instantAppInfo.getPackageName())) {
            return null;
        }
        final List<InstantAppIntentFilter> instantAppFilters =
                instantAppInfo.getIntentFilters();
        if (instantAppFilters == null || instantAppFilters.isEmpty()) {
            // No filters on web intent; no matches, 2nd phase unnecessary.
            if (origIntent.isWebIntent()) {
                return null;
            }
            // No filters; we need to start phase two
            if (DEBUG_INSTANT) {
                Log.d(TAG, "No app filters; go to phase 2");
            }
            return Collections.emptyList();
        }
        final ComponentResolver.InstantAppIntentResolver instantAppResolver =
                new ComponentResolver.InstantAppIntentResolver();
        for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
            final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
            final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
            if (splitFilters == null || splitFilters.isEmpty()) {
                continue;
            }
            for (int k = splitFilters.size() - 1; k >= 0; --k) {
                IntentFilter filter = splitFilters.get(k);
                Iterator<IntentFilter.AuthorityEntry> authorities =
                        filter.authoritiesIterator();
                // ignore http/s-only filters.
                if ((authorities == null || !authorities.hasNext())
                        && (filter.hasDataScheme("http") || filter.hasDataScheme("https"))
                        && filter.hasAction(Intent.ACTION_VIEW)
                        && filter.hasCategory(Intent.CATEGORY_BROWSABLE)) {
                    continue;
                }
                instantAppResolver.addFilter(
                        new AuxiliaryResolveInfo.AuxiliaryFilter(
                                filter,
                                instantAppInfo,
                                instantAppFilter.getSplitName(),
                                instantAppInfo.getExtras()
                        ));
            }
        }
        List<AuxiliaryResolveInfo.AuxiliaryFilter> matchedResolveInfoList =
                instantAppResolver.queryIntent(
                        origIntent, resolvedType, false /*defaultOnly*/, userId);
        if (!matchedResolveInfoList.isEmpty()) {
            if (DEBUG_INSTANT) {
                Log.d(TAG, "[" + token + "] Found match(es); " + matchedResolveInfoList);
            }
            return matchedResolveInfoList;
        } else if (DEBUG_INSTANT) {
            Log.d(TAG, "[" + token + "] No matches found"
                    + " package: " + instantAppInfo.getPackageName()
                    + ", versionCode: " + instantAppInfo.getVersionCode());
        }
        return null;
    }

    private static void logMetrics(int action, long startTime, String token,
            @ResolutionStatus int status) {
        final LogMaker logMaker = new LogMaker(action)
                .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
                .addTaggedData(FIELD_INSTANT_APP_RESOLUTION_DELAY_MS,
                        new Long(System.currentTimeMillis() - startTime))
                .addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, token)
                .addTaggedData(FIELD_INSTANT_APP_RESOLUTION_STATUS, new Integer(status));
        getLogger().write(logMaker);
    }
}
