blob: c1614587ea35158c516c464c9378217fa0386b1f [file] [log] [blame]
Jason Monk3d5f5512014-07-25 11:17:28 -04001/*
2 * Copyright (C) 2014 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 */
16package com.android.systemui.statusbar.policy;
17
Selim Cinek24ac55e2014-08-27 12:51:45 +020018import android.app.ActivityManager;
Jason Monk3d5f5512014-07-25 11:17:28 -040019import android.app.admin.DevicePolicyManager;
phweisse375fc42017-04-19 20:15:06 +020020import android.content.BroadcastReceiver;
Jason Monk3d5f5512014-07-25 11:17:28 -040021import android.content.Context;
phweisse375fc42017-04-19 20:15:06 +020022import android.content.Intent;
23import android.content.IntentFilter;
Daniel Nishi39566392016-03-24 15:06:57 -070024import android.content.pm.ApplicationInfo;
25import android.content.pm.PackageManager;
Jason Monk3d5f5512014-07-25 11:17:28 -040026import android.content.pm.PackageManager.NameNotFoundException;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010027import android.content.pm.UserInfo;
Jason Monk3d5f5512014-07-25 11:17:28 -040028import android.net.ConnectivityManager;
29import android.net.ConnectivityManager.NetworkCallback;
30import android.net.IConnectivityManager;
Jason Monk92b5c812014-08-21 13:44:18 -040031import android.net.Network;
Jason Monk3d5f5512014-07-25 11:17:28 -040032import android.net.NetworkCapabilities;
33import android.net.NetworkRequest;
phweisse375fc42017-04-19 20:15:06 +020034import android.os.AsyncTask;
35import android.os.Handler;
Jason Monk3d5f5512014-07-25 11:17:28 -040036import android.os.RemoteException;
37import android.os.ServiceManager;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010038import android.os.UserHandle;
39import android.os.UserManager;
phweisse375fc42017-04-19 20:15:06 +020040import android.security.KeyChain;
41import android.security.KeyChain.KeyChainConnection;
42import android.util.ArrayMap;
Jason Monk3d5f5512014-07-25 11:17:28 -040043import android.util.Log;
phweisse375fc42017-04-19 20:15:06 +020044import android.util.Pair;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010045import android.util.SparseArray;
Jason Monk3d5f5512014-07-25 11:17:28 -040046
Jorim Jaggiacace942015-08-28 11:46:10 -070047import com.android.internal.annotations.GuardedBy;
Robin Lee6795a2ae2015-07-06 19:20:59 -070048import com.android.internal.net.LegacyVpnInfo;
Jason Monk3d5f5512014-07-25 11:17:28 -040049import com.android.internal.net.VpnConfig;
Robin Lee47283452015-06-01 10:57:03 -070050import com.android.systemui.R;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000051import com.android.systemui.broadcast.BroadcastDispatcher;
Dave Mankofff4736812019-10-18 17:25:50 -040052import com.android.systemui.dagger.qualifiers.BgHandler;
Jason Monk9c7844c2017-01-18 15:21:53 -050053import com.android.systemui.settings.CurrentUserTracker;
Jason Monk3d5f5512014-07-25 11:17:28 -040054
55import java.io.FileDescriptor;
56import java.io.PrintWriter;
57import java.util.ArrayList;
58
Jason Monk196d6392018-12-20 13:25:34 -050059import javax.inject.Inject;
60import javax.inject.Singleton;
61
62/**
63 */
64@Singleton
Jason Monk9c7844c2017-01-18 15:21:53 -050065public class SecurityControllerImpl extends CurrentUserTracker implements SecurityController {
Jason Monk3d5f5512014-07-25 11:17:28 -040066
67 private static final String TAG = "SecurityController";
68 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
69
70 private static final NetworkRequest REQUEST = new NetworkRequest.Builder()
71 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
72 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
73 .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
Chalard Jean5b0c7c62018-03-09 20:52:15 +090074 .setUids(null)
Jason Monk3d5f5512014-07-25 11:17:28 -040075 .build();
Jason Monk92b5c812014-08-21 13:44:18 -040076 private static final int NO_NETWORK = -1;
77
Daniel Nishi39566392016-03-24 15:06:57 -070078 private static final String VPN_BRANDED_META_DATA = "com.android.systemui.IS_BRANDED";
79
phweisse375fc42017-04-19 20:15:06 +020080 private static final int CA_CERT_LOADING_RETRY_TIME_IN_MS = 30_000;
81
Jason Monk3d5f5512014-07-25 11:17:28 -040082 private final Context mContext;
83 private final ConnectivityManager mConnectivityManager;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010084 private final IConnectivityManager mConnectivityManagerService;
Jason Monk3d5f5512014-07-25 11:17:28 -040085 private final DevicePolicyManager mDevicePolicyManager;
Daniel Nishi39566392016-03-24 15:06:57 -070086 private final PackageManager mPackageManager;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010087 private final UserManager mUserManager;
Jason Monk61936ee2018-12-21 12:41:34 -050088 private final Handler mBgHandler;
Jorim Jaggiacace942015-08-28 11:46:10 -070089
90 @GuardedBy("mCallbacks")
91 private final ArrayList<SecurityControllerCallback> mCallbacks = new ArrayList<>();
Jason Monk3d5f5512014-07-25 11:17:28 -040092
Robin Lee47283452015-06-01 10:57:03 -070093 private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
Selim Cinek24ac55e2014-08-27 12:51:45 +020094 private int mCurrentUserId;
Robin Lee63204ee2015-06-04 01:53:01 +010095 private int mVpnUserId;
Jason Monk3d5f5512014-07-25 11:17:28 -040096
phweisse375fc42017-04-19 20:15:06 +020097 // Key: userId, Value: whether the user has CACerts installed
98 // Needs to be cached here since the query has to be asynchronous
99 private ArrayMap<Integer, Boolean> mHasCACerts = new ArrayMap<Integer, Boolean>();
100
Jason Monk196d6392018-12-20 13:25:34 -0500101 /**
102 */
103 @Inject
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000104 public SecurityControllerImpl(Context context, @BgHandler Handler bgHandler,
105 BroadcastDispatcher broadcastDispatcher) {
106 this(context, bgHandler, broadcastDispatcher, null);
phweiss0dbf9592017-05-11 15:31:27 +0200107 }
108
Jason Monk61936ee2018-12-21 12:41:34 -0500109 public SecurityControllerImpl(Context context, Handler bgHandler,
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000110 BroadcastDispatcher broadcastDispatcher, SecurityControllerCallback callback) {
111 super(broadcastDispatcher);
Jason Monk3d5f5512014-07-25 11:17:28 -0400112 mContext = context;
Jason Monk61936ee2018-12-21 12:41:34 -0500113 mBgHandler = bgHandler;
Jason Monk3d5f5512014-07-25 11:17:28 -0400114 mDevicePolicyManager = (DevicePolicyManager)
115 context.getSystemService(Context.DEVICE_POLICY_SERVICE);
116 mConnectivityManager = (ConnectivityManager)
117 context.getSystemService(Context.CONNECTIVITY_SERVICE);
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100118 mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
119 ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
Daniel Nishi39566392016-03-24 15:06:57 -0700120 mPackageManager = context.getPackageManager();
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100121 mUserManager = (UserManager)
122 context.getSystemService(Context.USER_SERVICE);
Jason Monk3d5f5512014-07-25 11:17:28 -0400123
phweiss0dbf9592017-05-11 15:31:27 +0200124 addCallback(callback);
125
phweisse375fc42017-04-19 20:15:06 +0200126 IntentFilter filter = new IntentFilter();
127 filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
phweiss1a50c522019-10-21 19:41:09 +0200128 filter.addAction(Intent.ACTION_USER_UNLOCKED);
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000129 broadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, bgHandler, UserHandle.ALL);
phweisse375fc42017-04-19 20:15:06 +0200130
Jason Monk3d5f5512014-07-25 11:17:28 -0400131 // TODO: re-register network callback on user change.
132 mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
Robin Lee63204ee2015-06-04 01:53:01 +0100133 onUserSwitched(ActivityManager.getCurrentUser());
Jason Monk9c7844c2017-01-18 15:21:53 -0500134 startTracking();
Jason Monk3d5f5512014-07-25 11:17:28 -0400135 }
136
137 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
138 pw.println("SecurityController state:");
Robin Lee47283452015-06-01 10:57:03 -0700139 pw.print(" mCurrentVpns={");
140 for (int i = 0 ; i < mCurrentVpns.size(); i++) {
141 if (i > 0) {
142 pw.print(", ");
143 }
144 pw.print(mCurrentVpns.keyAt(i));
145 pw.print('=');
146 pw.print(mCurrentVpns.valueAt(i).user);
147 }
148 pw.println("}");
Jason Monk3d5f5512014-07-25 11:17:28 -0400149 }
150
151 @Override
Makoto Onukic8a5a552015-11-19 14:29:12 -0800152 public boolean isDeviceManaged() {
153 return mDevicePolicyManager.isDeviceManaged();
Jason Monk3d5f5512014-07-25 11:17:28 -0400154 }
155
156 @Override
157 public String getDeviceOwnerName() {
Makoto Onukic8a5a552015-11-19 14:29:12 -0800158 return mDevicePolicyManager.getDeviceOwnerNameOnAnyUser();
Jason Monk3d5f5512014-07-25 11:17:28 -0400159 }
160
161 @Override
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100162 public boolean hasProfileOwner() {
Robin Lee47283452015-06-01 10:57:03 -0700163 return mDevicePolicyManager.getProfileOwnerAsUser(mCurrentUserId) != null;
Selim Cinek24ac55e2014-08-27 12:51:45 +0200164 }
165
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100166 @Override
167 public String getProfileOwnerName() {
Fyodor Kupolov7f98aa42016-04-07 14:56:25 -0700168 for (int profileId : mUserManager.getProfileIdsWithDisabled(mCurrentUserId)) {
169 String name = mDevicePolicyManager.getProfileOwnerNameAsUser(profileId);
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100170 if (name != null) {
171 return name;
172 }
173 }
174 return null;
175 }
Selim Cinek24ac55e2014-08-27 12:51:45 +0200176
177 @Override
Bartosz Fabianowski46bea2e2016-12-06 01:20:29 +0100178 public CharSequence getDeviceOwnerOrganizationName() {
179 return mDevicePolicyManager.getDeviceOwnerOrganizationName();
180 }
181
182 @Override
phweiss774c6542017-04-12 19:32:55 +0200183 public CharSequence getWorkProfileOrganizationName() {
184 final int profileId = getWorkProfileUserId(mCurrentUserId);
185 if (profileId == UserHandle.USER_NULL) return null;
186 return mDevicePolicyManager.getOrganizationNameForUser(profileId);
187 }
188
189 @Override
Robin Lee47283452015-06-01 10:57:03 -0700190 public String getPrimaryVpnName() {
Robin Lee63204ee2015-06-04 01:53:01 +0100191 VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
Robin Lee47283452015-06-01 10:57:03 -0700192 if (cfg != null) {
Robin Lee63204ee2015-06-04 01:53:01 +0100193 return getNameForVpnConfig(cfg, new UserHandle(mVpnUserId));
Robin Lee47283452015-06-01 10:57:03 -0700194 } else {
195 return null;
196 }
197 }
198
phweiss774c6542017-04-12 19:32:55 +0200199 private int getWorkProfileUserId(int userId) {
200 for (final UserInfo userInfo : mUserManager.getProfiles(userId)) {
201 if (userInfo.isManagedProfile()) {
202 return userInfo.id;
203 }
204 }
205 return UserHandle.USER_NULL;
206 }
207
Robin Lee47283452015-06-01 10:57:03 -0700208 @Override
phweiss774c6542017-04-12 19:32:55 +0200209 public boolean hasWorkProfile() {
210 return getWorkProfileUserId(mCurrentUserId) != UserHandle.USER_NULL;
211 }
212
213 @Override
214 public String getWorkProfileVpnName() {
215 final int profileId = getWorkProfileUserId(mVpnUserId);
216 if (profileId == UserHandle.USER_NULL) return null;
217 VpnConfig cfg = mCurrentVpns.get(profileId);
218 if (cfg != null) {
219 return getNameForVpnConfig(cfg, UserHandle.of(profileId));
Robin Lee47283452015-06-01 10:57:03 -0700220 }
221 return null;
222 }
223
224 @Override
phweissa4e169e2016-11-24 16:20:57 +0100225 public boolean isNetworkLoggingEnabled() {
226 return mDevicePolicyManager.isNetworkLoggingEnabled(null);
227 }
228
229 @Override
Jason Monk3d5f5512014-07-25 11:17:28 -0400230 public boolean isVpnEnabled() {
Fyodor Kupolov7f98aa42016-04-07 14:56:25 -0700231 for (int profileId : mUserManager.getProfileIdsWithDisabled(mVpnUserId)) {
232 if (mCurrentVpns.get(profileId) != null) {
Robin Lee47283452015-06-01 10:57:03 -0700233 return true;
234 }
235 }
236 return false;
Jason Monk3d5f5512014-07-25 11:17:28 -0400237 }
238
239 @Override
Robin Lee80d50532015-10-06 15:58:30 +0100240 public boolean isVpnRestricted() {
241 UserHandle currentUser = new UserHandle(mCurrentUserId);
242 return mUserManager.getUserInfo(mCurrentUserId).isRestricted()
243 || mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, currentUser);
244 }
245
246 @Override
Daniel Nishi39566392016-03-24 15:06:57 -0700247 public boolean isVpnBranded() {
248 VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
249 if (cfg == null) {
250 return false;
251 }
252
253 String packageName = getPackageNameForVpnConfig(cfg);
254 if (packageName == null) {
255 return false;
256 }
257
258 return isVpnPackageBranded(packageName);
259 }
260
261 @Override
phweiss774c6542017-04-12 19:32:55 +0200262 public boolean hasCACertInCurrentUser() {
phweisse375fc42017-04-19 20:15:06 +0200263 Boolean hasCACerts = mHasCACerts.get(mCurrentUserId);
264 return hasCACerts != null && hasCACerts.booleanValue();
phweiss774c6542017-04-12 19:32:55 +0200265 }
266
267 @Override
268 public boolean hasCACertInWorkProfile() {
phweisse375fc42017-04-19 20:15:06 +0200269 int userId = getWorkProfileUserId(mCurrentUserId);
270 if (userId == UserHandle.USER_NULL) return false;
271 Boolean hasCACerts = mHasCACerts.get(userId);
272 return hasCACerts != null && hasCACerts.booleanValue();
phweiss774c6542017-04-12 19:32:55 +0200273 }
274
275 @Override
Jason Monk3128f122014-09-03 13:18:57 -0400276 public void removeCallback(SecurityControllerCallback callback) {
Jorim Jaggiacace942015-08-28 11:46:10 -0700277 synchronized (mCallbacks) {
278 if (callback == null) return;
279 if (DEBUG) Log.d(TAG, "removeCallback " + callback);
280 mCallbacks.remove(callback);
281 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400282 }
283
284 @Override
Jason Monk3128f122014-09-03 13:18:57 -0400285 public void addCallback(SecurityControllerCallback callback) {
Jorim Jaggiacace942015-08-28 11:46:10 -0700286 synchronized (mCallbacks) {
287 if (callback == null || mCallbacks.contains(callback)) return;
288 if (DEBUG) Log.d(TAG, "addCallback " + callback);
289 mCallbacks.add(callback);
290 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400291 }
292
Selim Cinek24ac55e2014-08-27 12:51:45 +0200293 @Override
294 public void onUserSwitched(int newUserId) {
295 mCurrentUserId = newUserId;
Fyodor Kupolov1c363152015-09-02 13:27:21 -0700296 final UserInfo newUserInfo = mUserManager.getUserInfo(newUserId);
297 if (newUserInfo.isRestricted()) {
Robin Lee63204ee2015-06-04 01:53:01 +0100298 // VPN for a restricted profile is routed through its owner user
Fyodor Kupolov1c363152015-09-02 13:27:21 -0700299 mVpnUserId = newUserInfo.restrictedProfileParentId;
Robin Lee63204ee2015-06-04 01:53:01 +0100300 } else {
301 mVpnUserId = mCurrentUserId;
302 }
Selim Cinek24ac55e2014-08-27 12:51:45 +0200303 fireCallbacks();
304 }
305
phweiss1a50c522019-10-21 19:41:09 +0200306 private void refreshCACerts(int userId) {
307 new CACertLoader().execute(userId);
phweisse375fc42017-04-19 20:15:06 +0200308 }
309
Robin Lee47283452015-06-01 10:57:03 -0700310 private String getNameForVpnConfig(VpnConfig cfg, UserHandle user) {
311 if (cfg.legacy) {
312 return mContext.getString(R.string.legacy_vpn_name);
313 }
314 // The package name for an active VPN is stored in the 'user' field of its VpnConfig
315 final String vpnPackage = cfg.user;
316 try {
317 Context userContext = mContext.createPackageContextAsUser(mContext.getPackageName(),
318 0 /* flags */, user);
319 return VpnConfig.getVpnLabel(userContext, vpnPackage).toString();
320 } catch (NameNotFoundException nnfe) {
321 Log.e(TAG, "Package " + vpnPackage + " is not present", nnfe);
322 return null;
323 }
324 }
325
Jason Monk3d5f5512014-07-25 11:17:28 -0400326 private void fireCallbacks() {
Jorim Jaggiacace942015-08-28 11:46:10 -0700327 synchronized (mCallbacks) {
328 for (SecurityControllerCallback callback : mCallbacks) {
329 callback.onStateChanged();
330 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400331 }
332 }
333
334 private void updateState() {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100335 // Find all users with an active VPN
Robin Lee47283452015-06-01 10:57:03 -0700336 SparseArray<VpnConfig> vpns = new SparseArray<>();
Jason Monk3d5f5512014-07-25 11:17:28 -0400337 try {
Robin Lee47283452015-06-01 10:57:03 -0700338 for (UserInfo user : mUserManager.getUsers()) {
339 VpnConfig cfg = mConnectivityManagerService.getVpnConfig(user.id);
Robin Lee6795a2ae2015-07-06 19:20:59 -0700340 if (cfg == null) {
341 continue;
342 } else if (cfg.legacy) {
343 // Legacy VPNs should do nothing if the network is disconnected. Third-party
344 // VPN warnings need to continue as traffic can still go to the app.
345 LegacyVpnInfo legacyVpn = mConnectivityManagerService.getLegacyVpnInfo(user.id);
346 if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
347 continue;
348 }
Robin Lee47283452015-06-01 10:57:03 -0700349 }
Robin Lee6795a2ae2015-07-06 19:20:59 -0700350 vpns.put(user.id, cfg);
Jason Monk3d5f5512014-07-25 11:17:28 -0400351 }
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100352 } catch (RemoteException rme) {
353 // Roll back to previous state
354 Log.e(TAG, "Unable to list active VPNs", rme);
355 return;
Jason Monk3d5f5512014-07-25 11:17:28 -0400356 }
Robin Lee47283452015-06-01 10:57:03 -0700357 mCurrentVpns = vpns;
Jason Monk3d5f5512014-07-25 11:17:28 -0400358 }
359
Daniel Nishi39566392016-03-24 15:06:57 -0700360 private String getPackageNameForVpnConfig(VpnConfig cfg) {
361 if (cfg.legacy) {
362 return null;
363 }
364 return cfg.user;
365 }
366
367 private boolean isVpnPackageBranded(String packageName) {
368 boolean isBranded;
369 try {
370 ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
371 PackageManager.GET_META_DATA);
372 if (info == null || info.metaData == null || !info.isSystemApp()) {
373 return false;
374 }
375 isBranded = info.metaData.getBoolean(VPN_BRANDED_META_DATA, false);
376 } catch (NameNotFoundException e) {
377 return false;
378 }
379 return isBranded;
380 }
381
Jason Monk3d5f5512014-07-25 11:17:28 -0400382 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
Jason Monk92b5c812014-08-21 13:44:18 -0400383 @Override
384 public void onAvailable(Network network) {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100385 if (DEBUG) Log.d(TAG, "onAvailable " + network.netId);
386 updateState();
387 fireCallbacks();
Jason Monk92b5c812014-08-21 13:44:18 -0400388 };
389
390 // TODO Find another way to receive VPN lost. This may be delayed depending on
391 // how long the VPN connection is held on to.
392 @Override
393 public void onLost(Network network) {
394 if (DEBUG) Log.d(TAG, "onLost " + network.netId);
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100395 updateState();
396 fireCallbacks();
Jason Monk92b5c812014-08-21 13:44:18 -0400397 };
Jason Monk3d5f5512014-07-25 11:17:28 -0400398 };
phweisse375fc42017-04-19 20:15:06 +0200399
400 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
401 @Override public void onReceive(Context context, Intent intent) {
402 if (KeyChain.ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) {
phweiss1a50c522019-10-21 19:41:09 +0200403 refreshCACerts(getSendingUserId());
404 } else if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
405 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
406 if (userId != UserHandle.USER_NULL) refreshCACerts(userId);
phweisse375fc42017-04-19 20:15:06 +0200407 }
408 }
409 };
410
411 protected class CACertLoader extends AsyncTask<Integer, Void, Pair<Integer, Boolean> > {
412
413 @Override
414 protected Pair<Integer, Boolean> doInBackground(Integer... userId) {
415 try (KeyChainConnection conn = KeyChain.bindAsUser(mContext,
416 UserHandle.of(userId[0]))) {
417 boolean hasCACerts = !(conn.getService().getUserCaAliases().getList().isEmpty());
418 return new Pair<Integer, Boolean>(userId[0], hasCACerts);
419 } catch (RemoteException | InterruptedException | AssertionError e) {
phweiss6f9cb152018-09-10 11:12:43 +0200420 Log.i(TAG, "failed to get CA certs", e);
phweisse375fc42017-04-19 20:15:06 +0200421 return new Pair<Integer, Boolean>(userId[0], null);
422 }
423 }
424
425 @Override
426 protected void onPostExecute(Pair<Integer, Boolean> result) {
427 if (DEBUG) Log.d(TAG, "onPostExecute " + result);
428 if (result.second != null) {
429 mHasCACerts.put(result.first, result.second);
430 fireCallbacks();
431 }
432 }
433 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400434}