1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app.admin; 18 19 import static android.app.admin.DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS; 20 import static android.app.admin.DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE; 21 import static android.app.admin.DeviceAdminReceiver.ACTION_SECURITY_LOGS_AVAILABLE; 22 import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS; 23 import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID; 24 import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URI; 25 import static android.app.admin.DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT; 26 import static android.app.admin.DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN; 27 28 import android.annotation.IntRange; 29 import android.annotation.NonNull; 30 import android.annotation.Nullable; 31 import android.app.Service; 32 import android.content.BroadcastReceiver; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.net.Uri; 36 import android.security.KeyChain; 37 import android.util.Log; 38 39 /** 40 * Base class for delegated apps to handle callbacks related to their delegated capabilities. 41 * 42 * <p>Delegated apps are apps that receive additional capabilities from the profile owner or 43 * device owner apps. Some of these capabilities involve the framework calling into the apps. 44 * To receive these callbacks, delegated apps should subclass this class and override the 45 * appropriate methods here. The subclassed receiver needs to be published in the app's 46 * manifest, with appropriate intent filters to mark which callbacks the receiver is interested 47 * in. An app can have multiple receivers as long as they listen for disjoint set of callbacks. 48 * For the manifest definitions, it must be protected by the 49 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission to ensure only 50 * the system can trigger these callbacks. 51 * 52 * <p>The callback methods happen on the main thread of the process. Thus long running 53 * operations must be done on another thread. Note that because a receiver 54 * is done once returning from its onReceive function, such long-running operations 55 * should probably be done in a {@link Service}. 56 * 57 * @see DevicePolicyManager#setDelegatedScopes 58 * @see DeviceAdminReceiver 59 */ 60 public class DelegatedAdminReceiver extends BroadcastReceiver { 61 private static final String TAG = "DelegatedAdminReceiver"; 62 63 /** 64 * Allows this receiver to select the alias for a private key and certificate pair for 65 * authentication. If this method returns null, the default {@link android.app.Activity} will 66 * be shown that lets the user pick a private key and certificate pair. 67 * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED}, 68 * the default {@link android.app.Activity} will not be shown and the user will not be allowed 69 * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will 70 * receive {@code null} back. 71 * 72 * <p> This callback is only applicable if the delegated app has 73 * {@link DevicePolicyManager#DELEGATION_CERT_SELECTION} capability. Additionally, it must 74 * declare an intent filter for {@link DeviceAdminReceiver#ACTION_CHOOSE_PRIVATE_KEY_ALIAS} 75 * in the receiver's manifest in order to receive this callback. The default implementation 76 * simply throws {@link UnsupportedOperationException}. 77 * 78 * @param context The running context as per {@link #onReceive}. 79 * @param intent The received intent as per {@link #onReceive}. 80 * @param uid The uid of the app asking for the private key and certificate pair. 81 * @param uri The URI to authenticate, may be null. 82 * @param alias The alias preselected by the client, or null. 83 * @return The private key alias to return and grant access to. 84 * @see KeyChain#choosePrivateKeyAlias 85 */ onChoosePrivateKeyAlias(@onNull Context context, @NonNull Intent intent, int uid, @Nullable Uri uri, @Nullable String alias)86 public @Nullable String onChoosePrivateKeyAlias(@NonNull Context context, 87 @NonNull Intent intent, int uid, @Nullable Uri uri, @Nullable String alias) { 88 throw new UnsupportedOperationException("onChoosePrivateKeyAlias should be implemented"); 89 } 90 91 /** 92 * Called each time a new batch of network logs can be retrieved. This callback method will only 93 * ever be called when network logging is enabled. The logs can only be retrieved while network 94 * logging is enabled. 95 * 96 * <p>If a secondary user or profile is created, this callback won't be received until all users 97 * become affiliated again (even if network logging is enabled). It will also no longer be 98 * possible to retrieve the network logs batch with the most recent {@code batchToken} provided 99 * by this callback. See {@link DevicePolicyManager#setAffiliationIds}. 100 * 101 * <p> This callback is only applicable if the delegated app has 102 * {@link DevicePolicyManager#DELEGATION_NETWORK_LOGGING} capability. Additionally, it must 103 * declare an intent filter for {@link DeviceAdminReceiver#ACTION_NETWORK_LOGS_AVAILABLE} in the 104 * receiver's manifest in order to receive this callback. The default implementation 105 * simply throws {@link UnsupportedOperationException}. 106 * 107 * <p> 108 * This callback is triggered by a foreground broadcast and the app should ensure that any 109 * long-running work is not executed synchronously inside the callback. 110 * 111 * @param context The running context as per {@link #onReceive}. 112 * @param intent The received intent as per {@link #onReceive}. 113 * @param batchToken The token representing the current batch of network logs. 114 * @param networkLogsCount The total count of events in the current batch of network logs. 115 * @see DevicePolicyManager#retrieveNetworkLogs 116 */ onNetworkLogsAvailable(@onNull Context context, @NonNull Intent intent, long batchToken, @IntRange(from = 1) int networkLogsCount)117 public void onNetworkLogsAvailable(@NonNull Context context, @NonNull Intent intent, 118 long batchToken, @IntRange(from = 1) int networkLogsCount) { 119 throw new UnsupportedOperationException("onNetworkLogsAvailable should be implemented"); 120 } 121 122 /** 123 * Called each time a new batch of security logs can be retrieved. This callback method will 124 * only ever be called when security logging is enabled. The logs can only be retrieved while 125 * security logging is enabled. 126 * 127 * <p>If a secondary user or profile is created, this callback won't be received until all users 128 * become affiliated again (even if security logging is enabled). It will also no longer be 129 * possible to retrieve the security logs. See {@link DevicePolicyManager#setAffiliationIds}. 130 * 131 * <p> This callback is only applicable if the delegated app has 132 * {@link DevicePolicyManager#DELEGATION_SECURITY_LOGGING} capability. Additionally, it must 133 * declare an intent filter for {@link DeviceAdminReceiver#ACTION_SECURITY_LOGS_AVAILABLE} in 134 * the receiver's manifest in order to receive this callback. The default implementation 135 * simply throws {@link UnsupportedOperationException}. 136 * 137 * <p> 138 * This callback is triggered by a foreground broadcast and the app should ensure that any 139 * long-running work is not executed synchronously inside the callback. 140 * 141 * @param context The running context as per {@link #onReceive}. 142 * @param intent The received intent as per {@link #onReceive}. 143 * @see DevicePolicyManager#retrieveSecurityLogs 144 */ onSecurityLogsAvailable(@onNull Context context, @NonNull Intent intent)145 public void onSecurityLogsAvailable(@NonNull Context context, @NonNull Intent intent) { 146 throw new UnsupportedOperationException("onSecurityLogsAvailable should be implemented"); 147 } 148 149 /** 150 * Intercept delegated device administrator broadcasts. Implementations should not override 151 * this method; implement the convenience callbacks for each action instead. 152 */ 153 @Override onReceive(@onNull Context context, @NonNull Intent intent)154 public final void onReceive(@NonNull Context context, @NonNull Intent intent) { 155 String action = intent.getAction(); 156 157 if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) { 158 int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1); 159 Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI, android.net.Uri.class); 160 String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS); 161 String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias); 162 setResultData(chosenAlias); 163 } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) { 164 long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1); 165 int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0); 166 onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount); 167 } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) { 168 onSecurityLogsAvailable(context, intent); 169 } else { 170 Log.w(TAG, "Unhandled broadcast: " + action); 171 } 172 } 173 } 174