/*
 * Copyright (C) 2018 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.app.admin;

import static android.app.admin.DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS;
import static android.app.admin.DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE;
import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS;
import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID;
import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URI;
import static android.app.admin.DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT;
import static android.app.admin.DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.security.KeyChain;
import android.util.Log;

/**
 * Base class for delegated apps to handle callbacks related to their delegated capabilities.
 *
 * <p>Delegated apps are apps that receive additional capabilities from the profile owner or
 * device owner apps. Some of these capabilities involve the framework calling into the apps.
 * To receive these callbacks, delegated apps should subclass this class and override the
 * appropriate methods here. The subclassed receiver needs to be published in the app's
 * manifest, with appropriate intent filters to mark which callbacks the receiver is interested
 * in. An app can have multiple receivers as long as they listen for disjoint set of callbacks.
 * For the manifest definitions, it must be protected by the
 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission to ensure only
 * the system can trigger these callbacks.
 *
 * <p>The callback methods happen on the main thread of the process.  Thus long running
 * operations must be done on another thread.  Note that because a receiver
 * is done once returning from its onReceive function, such long-running operations
 * should probably be done in a {@link Service}.
 *
 * @see DevicePolicyManager#setDelegatedScopes
 * @see DeviceAdminReceiver
 */
public class DelegatedAdminReceiver extends BroadcastReceiver {
    private static final String TAG = "DelegatedAdminReceiver";

    /**
     * Allows this receiver to select the alias for a private key and certificate pair for
     * authentication.  If this method returns null, the default {@link android.app.Activity} will
     * be shown that lets the user pick a private key and certificate pair.
     * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
     * the default {@link android.app.Activity} will not be shown and the user will not be allowed
     * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
     * receive {@code null} back.
     *
     * <p> This callback is only applicable if the delegated app has
     * {@link DevicePolicyManager#DELEGATION_CERT_SELECTION} capability. Additionally, it must
     * declare an intent filter for {@link DeviceAdminReceiver#ACTION_CHOOSE_PRIVATE_KEY_ALIAS}
     * in the receiver's manifest in order to receive this callback. The default implementation
     * simply throws {@link UnsupportedOperationException}.
     *
     * @param context The running context as per {@link #onReceive}.
     * @param intent The received intent as per {@link #onReceive}.
     * @param uid The uid of the app asking for the private key and certificate pair.
     * @param uri The URI to authenticate, may be null.
     * @param alias The alias preselected by the client, or null.
     * @return The private key alias to return and grant access to.
     * @see KeyChain#choosePrivateKeyAlias
     */
    public @Nullable String onChoosePrivateKeyAlias(@NonNull Context context,
            @NonNull Intent intent, int uid, @Nullable Uri uri, @Nullable String alias) {
        throw new UnsupportedOperationException("onChoosePrivateKeyAlias should be implemented");
    }

    /**
     * Called each time a new batch of network logs can be retrieved. This callback method will only
     * ever be called when network logging is enabled. The logs can only be retrieved while network
     * logging is enabled.
     *
     * <p>If a secondary user or profile is created, this callback won't be received until all users
     * become affiliated again (even if network logging is enabled). It will also no longer be
     * possible to retrieve the network logs batch with the most recent {@code batchToken} provided
     * by this callback. See {@link DevicePolicyManager#setAffiliationIds}.
     *
     * <p> This callback is only applicable if the delegated app has
     * {@link DevicePolicyManager#DELEGATION_NETWORK_LOGGING} capability. Additionally, it must
     * declare an intent filter for {@link DeviceAdminReceiver#ACTION_NETWORK_LOGS_AVAILABLE} in the
     * receiver's manifest in order to receive this callback. The default implementation
     * simply throws {@link UnsupportedOperationException}.
     *
     * @param context The running context as per {@link #onReceive}.
     * @param intent The received intent as per {@link #onReceive}.
     * @param batchToken The token representing the current batch of network logs.
     * @param networkLogsCount The total count of events in the current batch of network logs.
     * @see DevicePolicyManager#retrieveNetworkLogs
     */
    public void onNetworkLogsAvailable(@NonNull Context context, @NonNull Intent intent,
            long batchToken, @IntRange(from = 1) int networkLogsCount) {
        throw new UnsupportedOperationException("onNetworkLogsAvailable should be implemented");
    }

    /**
     * Intercept delegated device administrator broadcasts. Implementations should not override
     * this method; implement the convenience callbacks for each action instead.
     */
    @Override
    public final void onReceive(@NonNull Context context, @NonNull Intent intent) {
        String action = intent.getAction();

        if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
            int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
            Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
            String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
            String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
            setResultData(chosenAlias);
        } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) {
            long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1);
            int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0);
            onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
        } else {
            Log.w(TAG, "Unhandled broadcast: " + action);
        }
    }
}
