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

import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.UID_REMOVED;
import static android.net.TrafficStats.UID_TETHERING;

import android.Manifest;
import android.annotation.IntDef;
import android.app.AppOpsManager;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.telephony.TelephonyManager;

import com.android.server.LocalServices;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/** Utility methods for controlling access to network stats APIs. */
public final class NetworkStatsAccess {
    private NetworkStatsAccess() {}

    /**
     * Represents an access level for the network usage history and statistics APIs.
     *
     * <p>Access levels are in increasing order; that is, it is reasonable to check access by
     * verifying that the caller's access level is at least the minimum required level.
     */
    @IntDef({
            Level.DEFAULT,
            Level.USER,
            Level.DEVICESUMMARY,
            Level.DEVICE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Level {
        /**
         * Default, unprivileged access level.
         *
         * <p>Can only access usage for one's own UID.
         *
         * <p>Every app will have at least this access level.
         */
        int DEFAULT = 0;

        /**
         * Access level for apps which can access usage for any app running in the same user.
         *
         * <p>Granted to:
         * <ul>
         * <li>Profile owners.
         * </ul>
         */
        int USER = 1;

        /**
         * Access level for apps which can access usage summary of device. Device summary includes
         * usage by apps running in any profiles/users, however this access level does not
         * allow querying usage of individual apps running in other profiles/users.
         *
         * <p>Granted to:
         * <ul>
         * <li>Apps with the PACKAGE_USAGE_STATS permission granted. Note that this is an AppOps bit
         * so it is not necessarily sufficient to declare this in the manifest.
         * <li>Apps with the (signature/privileged) READ_NETWORK_USAGE_HISTORY permission.
         * </ul>
         */
        int DEVICESUMMARY = 2;

        /**
         * Access level for apps which can access usage for any app on the device, including apps
         * running on other users/profiles.
         *
         * <p>Granted to:
         * <ul>
         * <li>Device owners.
         * <li>Carrier-privileged applications.
         * <li>The system UID.
         * </ul>
         */
        int DEVICE = 3;
    }

    /** Returns the {@link NetworkStatsAccess.Level} for the given caller. */
    public static @NetworkStatsAccess.Level int checkAccessLevel(
            Context context, int callingUid, String callingPackage) {
        final DevicePolicyManagerInternal dpmi = LocalServices.getService(
                DevicePolicyManagerInternal.class);
        final TelephonyManager tm = (TelephonyManager)
                context.getSystemService(Context.TELEPHONY_SERVICE);
        boolean hasCarrierPrivileges = tm != null &&
                tm.checkCarrierPrivilegesForPackage(callingPackage) ==
                        TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
        boolean isDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
                DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
        if (hasCarrierPrivileges || isDeviceOwner
                || UserHandle.getAppId(callingUid) == android.os.Process.SYSTEM_UID) {
            // Carrier-privileged apps and device owners, and the system can access data usage for
            // all apps on the device.
            return NetworkStatsAccess.Level.DEVICE;
        }

        boolean hasAppOpsPermission = hasAppOpsPermission(context, callingUid, callingPackage);
        if (hasAppOpsPermission || context.checkCallingOrSelfPermission(
                READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) {
            return NetworkStatsAccess.Level.DEVICESUMMARY;
        }

        boolean isProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
                DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
        if (isProfileOwner) {
            // Apps with the AppOps permission, profile owners, and apps with the privileged
            // permission can access data usage for all apps in this user/profile.
            return NetworkStatsAccess.Level.USER;
        }

        // Everyone else gets default access (only to their own UID).
        return NetworkStatsAccess.Level.DEFAULT;
    }

    /**
     * Returns whether the given caller should be able to access the given UID when the caller has
     * the given {@link NetworkStatsAccess.Level}.
     */
    public static boolean isAccessibleToUser(int uid, int callerUid,
            @NetworkStatsAccess.Level int accessLevel) {
        switch (accessLevel) {
            case NetworkStatsAccess.Level.DEVICE:
                // Device-level access - can access usage for any uid.
                return true;
            case NetworkStatsAccess.Level.DEVICESUMMARY:
                // Can access usage for any app running in the same user, along
                // with some special uids (system, removed, or tethering) and
                // anonymized uids
                return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED
                        || uid == UID_TETHERING || uid == UID_ALL
                        || UserHandle.getUserId(uid) == UserHandle.getUserId(callerUid);
            case NetworkStatsAccess.Level.USER:
                // User-level access - can access usage for any app running in the same user, along
                // with some special uids (system, removed, or tethering).
                return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED
                        || uid == UID_TETHERING
                        || UserHandle.getUserId(uid) == UserHandle.getUserId(callerUid);
            case NetworkStatsAccess.Level.DEFAULT:
            default:
                // Default access level - can only access one's own usage.
                return uid == callerUid;
        }
    }

    private static boolean hasAppOpsPermission(
            Context context, int callingUid, String callingPackage) {
        if (callingPackage != null) {
            AppOpsManager appOps = (AppOpsManager) context.getSystemService(
                    Context.APP_OPS_SERVICE);

            final int mode = appOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS,
                    callingUid, callingPackage);
            if (mode == AppOpsManager.MODE_DEFAULT) {
                // The default behavior here is to check if PackageManager has given the app
                // permission.
                final int permissionCheck = context.checkCallingPermission(
                        Manifest.permission.PACKAGE_USAGE_STATS);
                return permissionCheck == PackageManager.PERMISSION_GRANTED;
            }
            return (mode == AppOpsManager.MODE_ALLOWED);
        }
        return false;
    }
}
