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

import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.function.IntPredicate;

/**
 * A per-process controller to decide whether the process can start activity or foreground service
 * (especially from background). All methods of this class must be thread safe. The caller does not
 * need to hold WM lock, e.g. lock contention of WM lock shouldn't happen when starting service.
 */
class BackgroundLaunchProcessController {
    private static final String TAG =
            TAG_WITH_CLASS_NAME ? "BackgroundLaunchProcessController" : TAG_ATM;

    /** It is {@link ActivityTaskManagerService#hasActiveVisibleWindow(int)}. */
    private final IntPredicate mUidHasActiveVisibleWindowPredicate;

    private final @Nullable BackgroundActivityStartCallback mBackgroundActivityStartCallback;

    /**
     * A set of tokens that currently contribute to this process being temporarily allowed
     * to start activities even if it's not in the foreground. The values of this map are optional
     * (can be null) and are used to trace back the grant to the notification token mechanism.
     */
    @GuardedBy("this")
    private @Nullable ArrayMap<Binder, IBinder> mBackgroundActivityStartTokens;

    /** Set of UIDs of clients currently bound to this process. */
    @GuardedBy("this")
    private @Nullable IntArray mBoundClientUids;

    BackgroundLaunchProcessController(@NonNull IntPredicate uidHasActiveVisibleWindowPredicate,
            @Nullable BackgroundActivityStartCallback callback) {
        mUidHasActiveVisibleWindowPredicate = uidHasActiveVisibleWindowPredicate;
        mBackgroundActivityStartCallback = callback;
    }

    boolean areBackgroundActivityStartsAllowed(int pid, int uid, String packageName,
            boolean appSwitchAllowed, boolean isCheckingForFgsStart,
            boolean hasActivityInVisibleTask, boolean hasBackgroundActivityStartPrivileges,
            long lastStopAppSwitchesTime, long lastActivityLaunchTime,
            long lastActivityFinishTime) {
        // If app switching is not allowed, we ignore all the start activity grace period
        // exception so apps cannot start itself in onPause() after pressing home button.
        if (appSwitchAllowed) {
            // Allow if any activity in the caller has either started or finished very recently, and
            // it must be started or finished after last stop app switches time.
            final long now = SystemClock.uptimeMillis();
            if (now - lastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
                    || now - lastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
                // If activity is started and finished before stop app switch time, we should not
                // let app to be able to start background activity even it's in grace period.
                if (lastActivityLaunchTime > lastStopAppSwitchesTime
                        || lastActivityFinishTime > lastStopAppSwitchesTime) {
                    if (DEBUG_ACTIVITY_STARTS) {
                        Slog.d(TAG, "[Process(" + pid
                                + ")] Activity start allowed: within "
                                + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
                    }
                    return true;
                }
                if (DEBUG_ACTIVITY_STARTS) {
                    Slog.d(TAG, "[Process(" + pid + ")] Activity start within "
                            + ACTIVITY_BG_START_GRACE_PERIOD_MS
                            + "ms grace period but also within stop app switch window");
                }

            }
        }
        // Allow if the proc is instrumenting with background activity starts privs.
        if (hasBackgroundActivityStartPrivileges) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "[Process(" + pid
                        + ")] Activity start allowed: process instrumenting with background "
                        + "activity starts privileges");
            }
            return true;
        }
        // Allow if the caller has an activity in any foreground task.
        if (appSwitchAllowed && hasActivityInVisibleTask) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "[Process(" + pid
                        + ")] Activity start allowed: process has activity in foreground task");
            }
            return true;
        }
        // Allow if the caller is bound by a UID that's currently foreground.
        if (isBoundByForegroundUid()) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "[Process(" + pid
                        + ")] Activity start allowed: process bound by foreground uid");
            }
            return true;
        }
        // Allow if the flag was explicitly set.
        if (isBackgroundStartAllowedByToken(uid, packageName, isCheckingForFgsStart)) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "[Process(" + pid
                        + ")] Activity start allowed: process allowed by token");
            }
            return true;
        }
        return false;
    }

    /**
     * If there are no tokens, we don't allow *by token*. If there are tokens and
     * isCheckingForFgsStart is false, we ask the callback if the start is allowed for these tokens,
     * otherwise if there is no callback we allow.
     */
    private boolean isBackgroundStartAllowedByToken(int uid, String packageName,
            boolean isCheckingForFgsStart) {
        synchronized (this) {
            if (mBackgroundActivityStartTokens == null
                    || mBackgroundActivityStartTokens.isEmpty()) {
                return false;
            }
            if (isCheckingForFgsStart) {
                // BG-FGS-start only checks if there is a token.
                return true;
            }

            if (mBackgroundActivityStartCallback == null) {
                // We have tokens but no callback to decide => allow.
                return true;
            }
            // The callback will decide.
            return mBackgroundActivityStartCallback.isActivityStartAllowed(
                    mBackgroundActivityStartTokens.values(), uid, packageName);
        }
    }

    private boolean isBoundByForegroundUid() {
        synchronized (this) {
            if (mBoundClientUids != null) {
                for (int i = mBoundClientUids.size() - 1; i >= 0; i--) {
                    if (mUidHasActiveVisibleWindowPredicate.test(mBoundClientUids.get(i))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    void setBoundClientUids(ArraySet<Integer> boundClientUids) {
        synchronized (this) {
            if (boundClientUids == null || boundClientUids.isEmpty()) {
                mBoundClientUids = null;
                return;
            }
            if (mBoundClientUids == null) {
                mBoundClientUids = new IntArray();
            } else {
                mBoundClientUids.clear();
            }
            for (int i = boundClientUids.size() - 1; i >= 0; i--) {
                mBoundClientUids.add(boundClientUids.valueAt(i));
            }
        }
    }

    /**
     * Allows background activity starts using token {@code entity}. Optionally, you can provide
     * {@code originatingToken} if you have one such originating token, this is useful for tracing
     * back the grant in the case of the notification token.
     *
     * If {@code entity} is already added, this method will update its {@code originatingToken}.
     */
    void addOrUpdateAllowBackgroundActivityStartsToken(Binder entity,
            @Nullable IBinder originatingToken) {
        synchronized (this) {
            if (mBackgroundActivityStartTokens == null) {
                mBackgroundActivityStartTokens = new ArrayMap<>();
            }
            mBackgroundActivityStartTokens.put(entity, originatingToken);
        }
    }

    /**
     * Removes token {@code entity} that allowed background activity starts added via {@link
     * #addOrUpdateAllowBackgroundActivityStartsToken(Binder, IBinder)}.
     */
    void removeAllowBackgroundActivityStartsToken(Binder entity) {
        synchronized (this) {
            if (mBackgroundActivityStartTokens != null) {
                mBackgroundActivityStartTokens.remove(entity);
            }
        }
    }

    /**
     * Returns whether this process is allowed to close system dialogs via a background activity
     * start token that allows the close system dialogs operation (eg. notification).
     */
    boolean canCloseSystemDialogsByToken(int uid) {
        if (mBackgroundActivityStartCallback == null) {
            return false;
        }
        synchronized (this) {
            if (mBackgroundActivityStartTokens == null
                    || mBackgroundActivityStartTokens.isEmpty()) {
                return false;
            }
            return mBackgroundActivityStartCallback.canCloseSystemDialogs(
                    mBackgroundActivityStartTokens.values(), uid);
        }
    }

    void dump(PrintWriter pw, String prefix) {
        synchronized (this) {
            if (mBackgroundActivityStartTokens != null
                    && !mBackgroundActivityStartTokens.isEmpty()) {
                pw.print(prefix);
                pw.println("Background activity start tokens (token: originating token):");
                for (int i = mBackgroundActivityStartTokens.size() - 1; i >= 0; i--) {
                    pw.print(prefix);
                    pw.print("  - ");
                    pw.print(mBackgroundActivityStartTokens.keyAt(i));
                    pw.print(": ");
                    pw.println(mBackgroundActivityStartTokens.valueAt(i));
                }
            }
            if (mBoundClientUids != null && mBoundClientUids.size() > 0) {
                pw.print(prefix);
                pw.print("BoundClientUids:");
                pw.println(Arrays.toString(mBoundClientUids.toArray()));
            }
        }
    }
}
