/*
 * Copyright (C) 2017 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.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import android.widget.Toast;

import java.util.List;

/**
 * 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 master switch)
         */
        DENIED_SOFT,
        /**
         * Indicates that the denial is due to a misconfigured app (e.g. missing entry in manifest)
         */
        DENIED_HARD,
    }

    public static class LocationPermissionQuery {
        public final String callingPackage;
        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, int callingUid, int callingPid,
                int minSdkVersionForCoarse, int minSdkVersionForFine, boolean logAsInfo,
                String method) {
            this.callingPackage = callingPackage;
            this.callingUid = callingUid;
            this.callingPid = callingPid;
            this.minSdkVersionForCoarse = minSdkVersionForCoarse;
            this.minSdkVersionForFine = minSdkVersionForFine;
            this.logAsInfo = logAsInfo;
            this.method = method;
        }

        public static class Builder {
            private String mCallingPackage;
            private int mCallingUid;
            private int mCallingPid;
            private int mMinSdkVersionForCoarse = Integer.MAX_VALUE;
            private int mMinSdkVersionForFine = Integer.MAX_VALUE;
            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 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. Defaults to INT_MAX (which means don't check)
             */
            public Builder setMinSdkVersionForCoarse(
                    int minSdkVersionForCoarse) {
                mMinSdkVersionForCoarse = minSdkVersionForCoarse;
                return this;
            }

            /**
             * Apps that target at least this sdk version will be checked for fine location
             * permission. Defaults to INT_MAX (which means don't check)
             */
            public Builder setMinSdkVersionForFine(
                    int minSdkVersionForFine) {
                mMinSdkVersionForFine = minSdkVersionForFine;
                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;
            }

            public LocationPermissionQuery build() {
                return new LocationPermissionQuery(mCallingPackage, 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 (Build.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 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(AppOpsManager.permissionToOpCode(permissionToCheck),
                            query.callingUid, query.callingPackage);
            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;
        }
    }

    public static LocationPermissionResult checkLocationPermission(
            Context context, LocationPermissionQuery query) {
        // Always allow the phone process and system server 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.ROOT_UID) {
            return LocationPermissionResult.ALLOWED;
        }

        // Check the system-wide requirements. If the location master 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 grandfathering 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.getUserId(uid))) {
            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, uid, pid);
    }

    private 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));
    }

    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) {
        long token = Binder.clearCallingIdentity();
        try {
            final int currentUser = ActivityManager.getCurrentUser();
            final int callingUserId = UserHandle.getUserId(uid);
            if (callingUserId == currentUser) {
                return true;
            } else {
                List<UserInfo> userProfiles = context.getSystemService(
                        UserManager.class).getProfiles(currentUser);
                for (UserInfo user : userProfiles) {
                    if (user.id == callingUserId) {
                        return true;
                    }
                }
            }
            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;
    }
}