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

import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;

import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.Slog;
import android.view.RemoteAnimationAdapter;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Wraps {@link ActivityOptions}, records binder identity, and checks permission when retrieving
 * the inner options. Also supports having two set of options: Once from the original caller, and
 * once from the caller that is overriding it, which happens when sending a {@link PendingIntent}.
 */
class SafeActivityOptions {

    private static final String TAG = TAG_WITH_CLASS_NAME ? "SafeActivityOptions" : TAG_AM;

    private final int mOriginalCallingPid;
    private final int mOriginalCallingUid;
    private int mRealCallingPid;
    private int mRealCallingUid;
    private final @Nullable ActivityOptions mOriginalOptions;
    private @Nullable ActivityOptions mCallerOptions;

    /**
     * Constructs a new instance from a bundle and records {@link Binder#getCallingPid}/
     * {@link Binder#getCallingUid}. Thus, calling identity MUST NOT be cleared when constructing
     * this object.
     *
     * @param bOptions The {@link ActivityOptions} as {@link Bundle}.
     */
    static SafeActivityOptions fromBundle(Bundle bOptions) {
        return bOptions != null
                ? new SafeActivityOptions(ActivityOptions.fromBundle(bOptions))
                : null;
    }

    /**
     * Constructs a new instance and records {@link Binder#getCallingPid}/
     * {@link Binder#getCallingUid}. Thus, calling identity MUST NOT be cleared when constructing
     * this object.
     *
     * @param options The options to wrap.
     */
    SafeActivityOptions(@Nullable ActivityOptions options) {
        mOriginalCallingPid = Binder.getCallingPid();
        mOriginalCallingUid = Binder.getCallingUid();
        mOriginalOptions = options;
    }

    /**
     * Overrides options with options from a caller and records {@link Binder#getCallingPid}/
     * {@link Binder#getCallingUid}. Thus, calling identity MUST NOT be cleared when calling this
     * method.
     */
    void setCallerOptions(@Nullable ActivityOptions options) {
        mRealCallingPid = Binder.getCallingPid();
        mRealCallingUid = Binder.getCallingUid();
        mCallerOptions = options;
    }

    /**
     * Performs permission check and retrieves the options.
     *
     * @param r The record of the being started activity.
     */
    ActivityOptions getOptions(ActivityRecord r) throws SecurityException {
        return getOptions(r.intent, r.info, r.app, r.mStackSupervisor);
    }

    /**
     * Performs permission check and retrieves the options when options are not being used to launch
     * a specific activity (i.e. a task is moved to front).
     */
    ActivityOptions getOptions(ActivityStackSupervisor supervisor) throws SecurityException {
        return getOptions(null, null, null, supervisor);
    }

    /**
     * Performs permission check and retrieves the options.
     *
     * @param intent The intent that is being launched.
     * @param aInfo The info of the activity being launched.
     * @param callerApp The record of the caller.
     */
    ActivityOptions getOptions(@Nullable Intent intent, @Nullable ActivityInfo aInfo,
            @Nullable ProcessRecord callerApp,
            ActivityStackSupervisor supervisor) throws SecurityException {
        if (mOriginalOptions != null) {
            checkPermissions(intent, aInfo, callerApp, supervisor, mOriginalOptions,
                    mOriginalCallingPid, mOriginalCallingUid);
            if (mOriginalOptions.getRemoteAnimationAdapter() != null) {
                mOriginalOptions.getRemoteAnimationAdapter().setCallingPid(mOriginalCallingPid);
            }
        }
        if (mCallerOptions != null) {
            checkPermissions(intent, aInfo, callerApp, supervisor, mCallerOptions,
                    mRealCallingPid, mRealCallingUid);
            if (mCallerOptions.getRemoteAnimationAdapter() != null) {
                mCallerOptions.getRemoteAnimationAdapter().setCallingPid(mRealCallingPid);
            }
        }
        return mergeActivityOptions(mOriginalOptions, mCallerOptions);
    }

    /**
     * @see ActivityOptions#popAppVerificationBundle
     */
    Bundle popAppVerificationBundle() {
        return mOriginalOptions != null ? mOriginalOptions.popAppVerificationBundle() : null;
    }

    private void abort() {
        if (mOriginalOptions != null) {
            ActivityOptions.abort(mOriginalOptions);
        }
        if (mCallerOptions != null) {
            ActivityOptions.abort(mCallerOptions);
        }
    }

    static void abort(@Nullable SafeActivityOptions options) {
        if (options != null) {
            options.abort();
        }
    }

    /**
     * Merges two activity options into one, with {@code options2} taking precedence in case of a
     * conflict.
     */
    @VisibleForTesting
    @Nullable ActivityOptions mergeActivityOptions(@Nullable ActivityOptions options1,
            @Nullable ActivityOptions options2) {
        if (options1 == null) {
            return options2;
        }
        if (options2 == null) {
            return options1;
        }
        final Bundle b1 = options1.toBundle();
        final Bundle b2 = options2.toBundle();
        b1.putAll(b2);
        return ActivityOptions.fromBundle(b1);
    }

    private void checkPermissions(@Nullable Intent intent, @Nullable ActivityInfo aInfo,
            @Nullable ProcessRecord callerApp, ActivityStackSupervisor supervisor,
            ActivityOptions options, int callingPid, int callingUid) {
        // If a launch task id is specified, then ensure that the caller is the recents
        // component or has the START_TASKS_FROM_RECENTS permission
        if (options.getLaunchTaskId() != INVALID_TASK_ID
                && !supervisor.mRecentTasks.isCallerRecents(callingUid)) {
            final int startInTaskPerm = supervisor.mService.checkPermission(
                    START_TASKS_FROM_RECENTS, callingPid, callingUid);
            if (startInTaskPerm == PERMISSION_DENIED) {
                final String msg = "Permission Denial: starting " + getIntentString(intent)
                        + " from " + callerApp + " (pid=" + callingPid
                        + ", uid=" + callingUid + ") with launchTaskId="
                        + options.getLaunchTaskId();
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            }
        }
        // Check if someone tries to launch an activity on a private display with a different
        // owner.
        final int launchDisplayId = options.getLaunchDisplayId();
        if (aInfo != null && launchDisplayId != INVALID_DISPLAY
                && !supervisor.isCallerAllowedToLaunchOnDisplay(callingPid, callingUid,
                        launchDisplayId, aInfo)) {
            final String msg = "Permission Denial: starting " + getIntentString(intent)
                    + " from " + callerApp + " (pid=" + callingPid
                    + ", uid=" + callingUid + ") with launchDisplayId="
                    + launchDisplayId;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        // Check if someone tries to launch an unwhitelisted activity into LockTask mode.
        final boolean lockTaskMode = options.getLockTaskMode();
        if (aInfo != null && lockTaskMode
                && !supervisor.mService.getLockTaskController().isPackageWhitelisted(
                        UserHandle.getUserId(callingUid), aInfo.packageName)) {
            final String msg = "Permission Denial: starting " + getIntentString(intent)
                    + " from " + callerApp + " (pid=" + callingPid
                    + ", uid=" + callingUid + ") with lockTaskMode=true";
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }

        // Check permission for remote animations
        final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
        if (adapter != null && supervisor.mService.checkPermission(
                CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, callingPid, callingUid)
                        != PERMISSION_GRANTED) {
            final String msg = "Permission Denial: starting " + getIntentString(intent)
                    + " from " + callerApp + " (pid=" + callingPid
                    + ", uid=" + callingUid + ") with remoteAnimationAdapter";
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
    }

    private String getIntentString(Intent intent) {
        return intent != null ? intent.toString() : "(no intent)";
    }
}
