/*
 * Copyright (C) 2020 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 android.telephony;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
import android.widget.Toast;

import com.android.internal.telephony.util.TelephonyUtils;

/**
 * Helper for performing location access checks.
 * @hide
 */
public final class LocationAccessPolicy {
    private static final String TAG = "LocationAccessPolicy";
    private static final boolean DBG = false;
    public static final int MAX_SDK_FOR_ANY_ENFORCEMENT = Build.VERSION_CODES.CUR_DEVELOPMENT;

    public enum LocationPermissionResult {
        ALLOWED,
        /**
         * Indicates that the denial is due to a transient device state
         * (e.g. app-ops, location main switch)
         */
        DENIED_SOFT,
        /**
         * Indicates that the denial is due to a misconfigured app (e.g. missing entry in manifest)
         */
        DENIED_HARD,
    }

    /** Data structure for location permission query */
    public static class LocationPermissionQuery {
        public final String callingPackage;
        public final String callingFeatureId;
        public final int callingUid;
        public final int callingPid;
        public final int minSdkVersionForCoarse;
        public final int minSdkVersionForFine;
        public final boolean logAsInfo;
        public final String method;

        private LocationPermissionQuery(String callingPackage, @Nullable String callingFeatureId,
                int callingUid, int callingPid, int minSdkVersionForCoarse,
                int minSdkVersionForFine, boolean logAsInfo, String method) {
            this.callingPackage = callingPackage;
            this.callingFeatureId = callingFeatureId;
            this.callingUid = callingUid;
            this.callingPid = callingPid;
            this.minSdkVersionForCoarse = minSdkVersionForCoarse;
            this.minSdkVersionForFine = minSdkVersionForFine;
            this.logAsInfo = logAsInfo;
            this.method = method;
        }

        /** Builder for LocationPermissionQuery */
        public static class Builder {
            private String mCallingPackage;
            private String mCallingFeatureId;
            private int mCallingUid;
            private int mCallingPid;
            private int mMinSdkVersionForCoarse = -1;
            private int mMinSdkVersionForFine = -1;
            private int mMinSdkVersionForEnforcement = -1;
            private boolean mLogAsInfo = false;
            private String mMethod;

            /**
             * Mandatory parameter, used for performing permission checks.
             */
            public Builder setCallingPackage(String callingPackage) {
                mCallingPackage = callingPackage;
                return this;
            }

            /**
             * Mandatory parameter, used for performing permission checks.
             */
            public Builder setCallingFeatureId(@Nullable String callingFeatureId) {
                mCallingFeatureId = callingFeatureId;
                return this;
            }

            /**
             * Mandatory parameter, used for performing permission checks.
             */
            public Builder setCallingUid(int callingUid) {
                mCallingUid = callingUid;
                return this;
            }

            /**
             * Mandatory parameter, used for performing permission checks.
             */
            public Builder setCallingPid(int callingPid) {
                mCallingPid = callingPid;
                return this;
            }

            /**
             * Apps that target at least this sdk version will be checked for coarse location
             * permission. This method MUST be called before calling {@link #build()}. Otherwise, an
             * {@link IllegalArgumentException} will be thrown.
             *
             * Additionally, if both the argument to this method and
             * {@link #setMinSdkVersionForFine} are greater than {@link Build.VERSION_CODES#BASE},
             * you must call {@link #setMinSdkVersionForEnforcement} with the min of the two to
             * affirm that you do not want any location checks below a certain SDK version.
             * Otherwise, {@link #build} will throw an {@link IllegalArgumentException}.
             */
            public Builder setMinSdkVersionForCoarse(
                    int minSdkVersionForCoarse) {
                mMinSdkVersionForCoarse = minSdkVersionForCoarse;
                return this;
            }

            /**
             * Apps that target at least this sdk version will be checked for fine location
             * permission.  This method MUST be called before calling {@link #build()}.
             * Otherwise, an {@link IllegalArgumentException} will be thrown.
             *
             * Additionally, if both the argument to this method and
             * {@link #setMinSdkVersionForCoarse} are greater than {@link Build.VERSION_CODES#BASE},
             * you must call {@link #setMinSdkVersionForEnforcement} with the min of the two to
             * affirm that you do not want any location checks below a certain SDK version.
             * Otherwise, {@link #build} will throw an {@link IllegalArgumentException}.
             */
            public Builder setMinSdkVersionForFine(
                    int minSdkVersionForFine) {
                mMinSdkVersionForFine = minSdkVersionForFine;
                return this;
            }

            /**
             * If both the argument to {@link #setMinSdkVersionForFine} and
             * {@link #setMinSdkVersionForCoarse} are greater than {@link Build.VERSION_CODES#BASE},
             * this method must be called with the min of the two to
             * affirm that you do not want any location checks below a certain SDK version.
             */
            public Builder setMinSdkVersionForEnforcement(int minSdkVersionForEnforcement) {
                mMinSdkVersionForEnforcement = minSdkVersionForEnforcement;
                return this;
            }

            /**
             * Optional, for logging purposes only.
             */
            public Builder setMethod(String method) {
                mMethod = method;
                return this;
            }

            /**
             * If called with {@code true}, log messages will only be printed at the info level.
             */
            public Builder setLogAsInfo(boolean logAsInfo) {
                mLogAsInfo = logAsInfo;
                return this;
            }

            /** build LocationPermissionQuery */
            public LocationPermissionQuery build() {
                if (mMinSdkVersionForCoarse < 0 || mMinSdkVersionForFine < 0) {
                    throw new IllegalArgumentException("Must specify min sdk versions for"
                            + " enforcement for both coarse and fine permissions");
                }
                if (mMinSdkVersionForFine > Build.VERSION_CODES.BASE
                        && mMinSdkVersionForCoarse > Build.VERSION_CODES.BASE) {
                    if (mMinSdkVersionForEnforcement != Math.min(
                            mMinSdkVersionForCoarse, mMinSdkVersionForFine)) {
                        throw new IllegalArgumentException("setMinSdkVersionForEnforcement must be"
                                + " called.");
                    }
                }

                if (mMinSdkVersionForFine < mMinSdkVersionForCoarse) {
                    throw new IllegalArgumentException("Since fine location permission includes"
                            + " access to coarse location, the min sdk level for enforcement of"
                            + " the fine location permission must not be less than the min sdk"
                            + " level for enforcement of the coarse location permission.");
                }

                return new LocationPermissionQuery(mCallingPackage, mCallingFeatureId,
                        mCallingUid, mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine,
                        mLogAsInfo, mMethod);
            }
        }
    }

    private static void logError(Context context, LocationPermissionQuery query, String errorMsg) {
        if (query.logAsInfo) {
            Log.i(TAG, errorMsg);
            return;
        }
        Log.e(TAG, errorMsg);
        try {
            if (TelephonyUtils.IS_DEBUGGABLE) {
                Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show();
            }
        } catch (Throwable t) {
            // whatever, not important
        }
    }

    private static LocationPermissionResult appOpsModeToPermissionResult(int appOpsMode) {
        switch (appOpsMode) {
            case AppOpsManager.MODE_ALLOWED:
                return LocationPermissionResult.ALLOWED;
            case AppOpsManager.MODE_ERRORED:
                return LocationPermissionResult.DENIED_HARD;
            default:
                return LocationPermissionResult.DENIED_SOFT;
        }
    }

    private static String getAppOpsString(String manifestPermission) {
        switch (manifestPermission) {
            case Manifest.permission.ACCESS_FINE_LOCATION:
                return AppOpsManager.OPSTR_FINE_LOCATION;
            case Manifest.permission.ACCESS_COARSE_LOCATION:
                return AppOpsManager.OPSTR_COARSE_LOCATION;
            default:
                return null;
        }
    }

    private static LocationPermissionResult checkAppLocationPermissionHelper(Context context,
            LocationPermissionQuery query, String permissionToCheck) {
        String locationTypeForLog =
                Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck)
                        ? "fine" : "coarse";

        // Do the app-ops and the manifest check without any of the allow-overrides first.
        boolean hasManifestPermission = checkManifestPermission(context, query.callingPid,
                query.callingUid, permissionToCheck);

        if (hasManifestPermission) {
            // Only check the app op if the app has the permission.
            int appOpMode = context.getSystemService(AppOpsManager.class)
                    .noteOpNoThrow(getAppOpsString(permissionToCheck), query.callingUid,
                            query.callingPackage, query.callingFeatureId, null);
            if (appOpMode == AppOpsManager.MODE_ALLOWED) {
                // If the app did everything right, return without logging.
                return LocationPermissionResult.ALLOWED;
            } else {
                // If the app has the manifest permission but not the app-op permission, it means
                // that it's aware of the requirement and the user denied permission explicitly.
                // If we see this, don't let any of the overrides happen.
                Log.i(TAG, query.callingPackage + " is aware of " + locationTypeForLog + " but the"
                        + " app-ops permission is specifically denied.");
                return appOpsModeToPermissionResult(appOpMode);
            }
        }

        int minSdkVersion = Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck)
                ? query.minSdkVersionForFine : query.minSdkVersionForCoarse;

        // If the app fails for some reason, see if it should be allowed to proceed.
        if (minSdkVersion > MAX_SDK_FOR_ANY_ENFORCEMENT) {
            String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog
                    + " because we're not enforcing API " + minSdkVersion + " yet."
                    + " Please fix this app because it will break in the future. Called from "
                    + query.method;
            logError(context, query, errorMsg);
            return null;
        } else if (!isAppAtLeastSdkVersion(context, query.callingPackage, minSdkVersion)) {
            String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog
                    + " because it doesn't target API " + minSdkVersion + " yet."
                    + " Please fix this app. Called from " + query.method;
            logError(context, query, errorMsg);
            return null;
        } else {
            // If we're not allowing it due to the above two conditions, this means that the app
            // did not declare the permission in their manifest.
            return LocationPermissionResult.DENIED_HARD;
        }
    }

    /** Check if location permissions have been granted */
    public static LocationPermissionResult checkLocationPermission(
            Context context, LocationPermissionQuery query) {
        // Always allow the phone process, system server, and network stack to access location.
        // This avoid breaking legacy code that rely on public-facing APIs to access cell location,
        // and it doesn't create an info leak risk because the cell location is stored in the phone
        // process anyway, and the system server already has location access.
        if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID
                || query.callingUid == Process.NETWORK_STACK_UID
                || query.callingUid == Process.ROOT_UID) {
            return LocationPermissionResult.ALLOWED;
        }

        // Check the system-wide requirements. If the location main switch is off or
        // the app's profile isn't in foreground, return a soft denial.
        if (!checkSystemLocationAccess(context, query.callingUid, query.callingPid)) {
            return LocationPermissionResult.DENIED_SOFT;
        }

        // Do the check for fine, then for coarse.
        if (query.minSdkVersionForFine < Integer.MAX_VALUE) {
            LocationPermissionResult resultForFine = checkAppLocationPermissionHelper(
                    context, query, Manifest.permission.ACCESS_FINE_LOCATION);
            if (resultForFine != null) {
                return resultForFine;
            }
        }

        if (query.minSdkVersionForCoarse < Integer.MAX_VALUE) {
            LocationPermissionResult resultForCoarse = checkAppLocationPermissionHelper(
                    context, query, Manifest.permission.ACCESS_COARSE_LOCATION);
            if (resultForCoarse != null) {
                return resultForCoarse;
            }
        }

        // At this point, we're out of location checks to do. If the app bypassed all the previous
        // ones due to the SDK backwards compatibility schemes, allow it access.
        return LocationPermissionResult.ALLOWED;
    }


    private static boolean checkManifestPermission(Context context, int pid, int uid,
            String permissionToCheck) {
        return context.checkPermission(permissionToCheck, pid, uid)
                == PackageManager.PERMISSION_GRANTED;
    }

    private static boolean checkSystemLocationAccess(@NonNull Context context, int uid, int pid) {
        if (!isLocationModeEnabled(context, UserHandle.getUserHandleForUid(uid).getIdentifier())) {
            if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")");
            return false;
        }
        // If the user or profile is current, permission is granted.
        // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission.
        return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context, pid, uid);
    }

    /**
     * @return Whether location is enabled for the given user.
     */
    public static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) {
        LocationManager locationManager = context.getSystemService(LocationManager.class);
        if (locationManager == null) {
            Log.w(TAG, "Couldn't get location manager, denying location access");
            return false;
        }
        return locationManager.isLocationEnabledForUser(UserHandle.of(userId));
    }

    /**
     * @return An array of packages that are always allowed to access location.
     */
    public static @NonNull String[] getLocationBypassPackages(@NonNull Context context) {
        return context.getResources().getStringArray(
                com.android.internal.R.array.config_serviceStateLocationAllowedPackages);
    }

    private static boolean checkInteractAcrossUsersFull(
            @NonNull Context context, int pid, int uid) {
        return checkManifestPermission(context, pid, uid,
                Manifest.permission.INTERACT_ACROSS_USERS_FULL);
    }

    private static boolean isCurrentProfile(@NonNull Context context, int uid) {
        final long token = Binder.clearCallingIdentity();
        try {
            if (UserHandle.getUserHandleForUid(uid).getIdentifier()
                    == ActivityManager.getCurrentUser()) {
                return true;
            }
            ActivityManager activityManager = context.getSystemService(ActivityManager.class);
            if (activityManager != null) {
                return activityManager.isProfileForeground(
                        UserHandle.getUserHandleForUid(ActivityManager.getCurrentUser()));
            } else {
                return false;
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    private static boolean isAppAtLeastSdkVersion(Context context, String pkgName, int sdkVersion) {
        try {
            if (context.getPackageManager().getApplicationInfo(pkgName, 0).targetSdkVersion
                    >= sdkVersion) {
                return true;
            }
        } catch (PackageManager.NameNotFoundException e) {
            // In case of exception, assume known app (more strict checking)
            // Note: This case will never happen since checkPackage is
            // called to verify validity before checking app's version.
        }
        return false;
    }
}
