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

import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.permission.PermissionControllerManager;
import android.provider.DeviceConfig;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;

/**
 * Class that handles one-time permissions for a user
 */
public class OneTimePermissionUserManager {

    private static final String LOG_TAG = OneTimePermissionUserManager.class.getSimpleName();

    private static final boolean DEBUG = false;
    private static final long DEFAULT_KILLED_DELAY_MILLIS = 5000;
    public static final String PROPERTY_KILLED_DELAY_CONFIG_KEY =
            "one_time_permissions_killed_delay_millis";

    private final @NonNull Context mContext;
    private final @NonNull ActivityManager mActivityManager;
    private final @NonNull AlarmManager mAlarmManager;
    private final @NonNull PermissionControllerManager mPermissionControllerManager;

    private final Object mLock = new Object();

    private final BroadcastReceiver mUninstallListener = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_UID_REMOVED.equals(intent.getAction())) {
                int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                PackageInactivityListener listener = mListeners.get(uid);
                if (listener != null) {
                    if (DEBUG) {
                        Log.d(LOG_TAG, "Removing  the inactivity listener for " + uid);
                    }
                    listener.cancel();
                    mListeners.remove(uid);
                }
            }
        }
    };

    /** Maps the uid to the PackageInactivityListener */
    @GuardedBy("mLock")
    private final SparseArray<PackageInactivityListener> mListeners = new SparseArray<>();
    private final Handler mHandler;

    OneTimePermissionUserManager(@NonNull Context context) {
        mContext = context;
        mActivityManager = context.getSystemService(ActivityManager.class);
        mAlarmManager = context.getSystemService(AlarmManager.class);
        mPermissionControllerManager = context.getSystemService(PermissionControllerManager.class);
        mHandler = context.getMainThreadHandler();

        // Listen for tracked uid being uninstalled
        context.registerReceiver(mUninstallListener, new IntentFilter(Intent.ACTION_UID_REMOVED));
    }

    /**
     * Starts a one-time permission session for a given package. A one-time permission session is
     * ended if app becomes inactive. Inactivity is defined as the package's uid importance level
     * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid
     * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start
     * until going > importanceToResetTimer.
     * <p>
     * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive
     * then the session is extended until either the importance goes above
     * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which
     * will continue the session and reset the timer.
     * </p>
     * <p>
     * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}.
     * </p>
     * <p>
     * Once the session ends PermissionControllerService#onNotifyOneTimePermissionSessionTimeout
     * is invoked.
     * </p>
     * <p>
     * Note that if there is currently an active session for a package a new one isn't created and
     * the existing one isn't changed.
     * </p>
     * @param packageName The package to start a one-time permission session for
     * @param timeoutMillis Number of milliseconds for an app to be in an inactive state
     * @param importanceToResetTimer The least important level to uid must be to reset the timer
     * @param importanceToKeepSessionAlive The least important level the uid must be to keep the
     *                                    session alive
     *
     * @hide
     */
    void startPackageOneTimeSession(@NonNull String packageName, long timeoutMillis,
            int importanceToResetTimer, int importanceToKeepSessionAlive) {
        int uid;
        try {
            uid = mContext.getPackageManager().getPackageUid(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(LOG_TAG, "Unknown package name " + packageName, e);
            return;
        }

        synchronized (mLock) {
            PackageInactivityListener listener = mListeners.get(uid);
            if (listener == null) {
                listener = new PackageInactivityListener(uid, packageName, timeoutMillis,
                        importanceToResetTimer, importanceToKeepSessionAlive);
                mListeners.put(uid, listener);
            }
        }
    }

    /**
     * Stops the one-time permission session for the package. The callback to the end of session is
     * not invoked. If there is no one-time session for the package then nothing happens.
     *
     * @param packageName Package to stop the one-time permission session for
     */
    void stopPackageOneTimeSession(@NonNull String packageName) {
        int uid;
        try {
            uid = mContext.getPackageManager().getPackageUid(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(LOG_TAG, "Unknown package name " + packageName, e);
            return;
        }

        synchronized (mLock) {
            PackageInactivityListener listener = mListeners.get(uid);
            if (listener != null) {
                mListeners.remove(uid);
                listener.cancel();
            }
        }
    }

    /**
     * The delay to wait before revoking on the event an app is terminated. Recommended to be long
     * enough so that apps don't lose permission on an immediate restart
     */
    private static long getKilledDelayMillis() {
        return DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS,
                PROPERTY_KILLED_DELAY_CONFIG_KEY, DEFAULT_KILLED_DELAY_MILLIS);
    }

    /**
     * A class which watches a package for inactivity and notifies the permission controller when
     * the package becomes inactive
     */
    private class PackageInactivityListener implements AlarmManager.OnAlarmListener {

        private static final long TIMER_INACTIVE = -1;

        private final int mUid;
        private final @NonNull String mPackageName;
        private final long mTimeout;
        private final int mImportanceToResetTimer;
        private final int mImportanceToKeepSessionAlive;

        private boolean mIsAlarmSet;
        private boolean mIsFinished;

        private long mTimerStart = TIMER_INACTIVE;

        private final ActivityManager.OnUidImportanceListener mStartTimerListener;
        private final ActivityManager.OnUidImportanceListener mSessionKillableListener;
        private final ActivityManager.OnUidImportanceListener mGoneListener;

        private final Object mInnerLock = new Object();
        private final Object mToken = new Object();

        private PackageInactivityListener(int uid, @NonNull String packageName, long timeout,
                int importanceToResetTimer, int importanceToKeepSessionAlive) {

            Log.i(LOG_TAG,
                    "Start tracking " + packageName + ". uid=" + uid + " timeout=" + timeout
                            + " importanceToResetTimer=" + importanceToResetTimer
                            + " importanceToKeepSessionAlive=" + importanceToKeepSessionAlive);

            mUid = uid;
            mPackageName = packageName;
            mTimeout = timeout;
            mImportanceToResetTimer = importanceToResetTimer;
            mImportanceToKeepSessionAlive = importanceToKeepSessionAlive;

            mStartTimerListener =
                    (changingUid, importance) -> onImportanceChanged(changingUid, importance);
            mSessionKillableListener =
                    (changingUid, importance) -> onImportanceChanged(changingUid, importance);
            mGoneListener =
                    (changingUid, importance) -> onImportanceChanged(changingUid, importance);

            mActivityManager.addOnUidImportanceListener(mStartTimerListener,
                    importanceToResetTimer);
            mActivityManager.addOnUidImportanceListener(mSessionKillableListener,
                    importanceToKeepSessionAlive);
            mActivityManager.addOnUidImportanceListener(mGoneListener, IMPORTANCE_CACHED);

            onImportanceChanged(mUid, mActivityManager.getPackageImportance(packageName));
        }

        private void onImportanceChanged(int uid, int importance) {
            if (uid != mUid) {
                return;
            }

            Log.v(LOG_TAG, "Importance changed for " + mPackageName + " (" + mUid + ")."
                    + " importance=" + importance);
            synchronized (mInnerLock) {
                // Remove any pending inactivity callback
                mHandler.removeCallbacksAndMessages(mToken);

                if (importance > IMPORTANCE_CACHED) {
                    // Delay revocation in case app is restarting
                    mHandler.postDelayed(() -> {
                        int imp = mActivityManager.getUidImportance(mUid);
                        if (imp > IMPORTANCE_CACHED) {
                            onPackageInactiveLocked();
                        } else {
                            if (DEBUG) {
                                Log.d(LOG_TAG, "No longer gone after delayed revocation. "
                                        + "Rechecking for " + mPackageName + " (" + mUid + ").");
                            }
                            onImportanceChanged(mUid, imp);
                        }
                    }, mToken, getKilledDelayMillis());
                    return;
                }
                if (importance > mImportanceToResetTimer) {
                    if (mTimerStart == TIMER_INACTIVE) {
                        if (DEBUG) {
                            Log.d(LOG_TAG, "Start the timer for "
                                    + mPackageName + " (" + mUid + ").");
                        }
                        mTimerStart = System.currentTimeMillis();
                    }
                } else {
                    mTimerStart = TIMER_INACTIVE;
                }
                if (importance > mImportanceToKeepSessionAlive) {
                    setAlarmLocked();
                } else {
                    cancelAlarmLocked();
                }
            }
        }

        /**
         * Stop watching the package for inactivity
         */
        private void cancel() {
            synchronized (mInnerLock) {
                mIsFinished = true;
                cancelAlarmLocked();
                mActivityManager.removeOnUidImportanceListener(mStartTimerListener);
                mActivityManager.removeOnUidImportanceListener(mSessionKillableListener);
                mActivityManager.removeOnUidImportanceListener(mGoneListener);
            }
        }

        /**
         * Set the alarm which will callback when the package is inactive
         */
        @GuardedBy("mInnerLock")
        private void setAlarmLocked() {
            if (mIsAlarmSet) {
                return;
            }

            if (DEBUG) {
                Log.d(LOG_TAG, "Scheduling alarm for " + mPackageName + " (" + mUid + ").");
            }
            long revokeTime = mTimerStart + mTimeout;
            if (revokeTime > System.currentTimeMillis()) {
                mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, revokeTime, LOG_TAG, this,
                        mHandler);
                mIsAlarmSet = true;
            } else {
                mIsAlarmSet = true;
                onAlarm();
            }
        }

        /**
         * Cancel the alarm
         */
        @GuardedBy("mInnerLock")
        private void cancelAlarmLocked() {
            if (mIsAlarmSet) {
                if (DEBUG) {
                    Log.d(LOG_TAG, "Canceling alarm for " + mPackageName + " (" + mUid + ").");
                }
                mAlarmManager.cancel(this);
                mIsAlarmSet = false;
            }
        }

        /**
         * Called when the package is considered inactive. This is the end of the session
         */
        @GuardedBy("mInnerLock")
        private void onPackageInactiveLocked() {
            if (mIsFinished) {
                return;
            }
            if (DEBUG) {
                Log.d(LOG_TAG, "onPackageInactiveLocked stack trace for "
                        + mPackageName + " (" + mUid + ").", new RuntimeException());
            }
            mIsFinished = true;
            cancelAlarmLocked();
            mHandler.post(
                    () -> {
                        Log.i(LOG_TAG, "One time session expired for "
                                + mPackageName + " (" + mUid + ").");

                        mPermissionControllerManager.notifyOneTimePermissionSessionTimeout(
                                mPackageName);
                    });
            mActivityManager.removeOnUidImportanceListener(mStartTimerListener);
            mActivityManager.removeOnUidImportanceListener(mSessionKillableListener);
            mActivityManager.removeOnUidImportanceListener(mGoneListener);
            synchronized (mLock) {
                mListeners.remove(mUid);
            }
        }

        @Override
        public void onAlarm() {
            if (DEBUG) {
                Log.d(LOG_TAG, "Alarm received for " + mPackageName + " (" + mUid + ").");
            }
            synchronized (mInnerLock) {
                if (!mIsAlarmSet) {
                    return;
                }
                mIsAlarmSet = false;
                onPackageInactiveLocked();
            }
        }
    }
}
