blob: 4f47cc6943d1e4d6f64bdae94874775ba1838f0f [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;
20import android.content.Context;
Jason Monk3d5f5512014-07-25 11:17:28 -040021import android.content.pm.PackageManager.NameNotFoundException;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010022import android.content.pm.UserInfo;
Jason Monk3d5f5512014-07-25 11:17:28 -040023import android.net.ConnectivityManager;
24import android.net.ConnectivityManager.NetworkCallback;
25import android.net.IConnectivityManager;
Jason Monk92b5c812014-08-21 13:44:18 -040026import android.net.Network;
Jason Monk3d5f5512014-07-25 11:17:28 -040027import android.net.NetworkCapabilities;
28import android.net.NetworkRequest;
29import android.os.RemoteException;
30import android.os.ServiceManager;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010031import android.os.UserHandle;
32import android.os.UserManager;
Jason Monk3d5f5512014-07-25 11:17:28 -040033import android.text.TextUtils;
34import android.util.Log;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010035import android.util.SparseArray;
Jason Monk3d5f5512014-07-25 11:17:28 -040036
37import com.android.internal.net.VpnConfig;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010038import com.android.internal.net.VpnInfo;
Jason Monk3d5f5512014-07-25 11:17:28 -040039
40import java.io.FileDescriptor;
41import java.io.PrintWriter;
42import java.util.ArrayList;
43
44public class SecurityControllerImpl implements SecurityController {
45
46 private static final String TAG = "SecurityController";
47 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
48
49 private static final NetworkRequest REQUEST = new NetworkRequest.Builder()
50 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
51 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
52 .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
53 .build();
Jason Monk92b5c812014-08-21 13:44:18 -040054 private static final int NO_NETWORK = -1;
55
Jason Monk3d5f5512014-07-25 11:17:28 -040056 private final Context mContext;
57 private final ConnectivityManager mConnectivityManager;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010058 private final IConnectivityManager mConnectivityManagerService;
Jason Monk3d5f5512014-07-25 11:17:28 -040059 private final DevicePolicyManager mDevicePolicyManager;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010060 private final UserManager mUserManager;
Selim Cinek24ac55e2014-08-27 12:51:45 +020061 private final ArrayList<SecurityControllerCallback> mCallbacks
62 = new ArrayList<SecurityControllerCallback>();
Jason Monk3d5f5512014-07-25 11:17:28 -040063
Robin Lee9cb1d5f2015-04-16 17:01:49 +010064 private SparseArray<Boolean> mCurrentVpnUsers = new SparseArray<>();
Selim Cinek24ac55e2014-08-27 12:51:45 +020065 private int mCurrentUserId;
Jason Monk3d5f5512014-07-25 11:17:28 -040066
67 public SecurityControllerImpl(Context context) {
68 mContext = context;
69 mDevicePolicyManager = (DevicePolicyManager)
70 context.getSystemService(Context.DEVICE_POLICY_SERVICE);
71 mConnectivityManager = (ConnectivityManager)
72 context.getSystemService(Context.CONNECTIVITY_SERVICE);
Robin Lee9cb1d5f2015-04-16 17:01:49 +010073 mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
74 ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
75 mUserManager = (UserManager)
76 context.getSystemService(Context.USER_SERVICE);
Jason Monk3d5f5512014-07-25 11:17:28 -040077
78 // TODO: re-register network callback on user change.
79 mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
Selim Cinek24ac55e2014-08-27 12:51:45 +020080 mCurrentUserId = ActivityManager.getCurrentUser();
Jason Monk3d5f5512014-07-25 11:17:28 -040081 }
82
83 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
84 pw.println("SecurityController state:");
Robin Lee9cb1d5f2015-04-16 17:01:49 +010085 pw.print(" mCurrentVpnUsers=" + mCurrentVpnUsers);
Jason Monk3d5f5512014-07-25 11:17:28 -040086 }
87
88 @Override
89 public boolean hasDeviceOwner() {
90 return !TextUtils.isEmpty(mDevicePolicyManager.getDeviceOwner());
91 }
92
93 @Override
94 public String getDeviceOwnerName() {
95 return mDevicePolicyManager.getDeviceOwnerName();
96 }
97
98 @Override
Robin Lee9cb1d5f2015-04-16 17:01:49 +010099 public boolean hasProfileOwner() {
100 boolean result = false;
101 for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
102 result |= (mDevicePolicyManager.getProfileOwnerAsUser(profile.id) != null);
103 }
104 return result;
Selim Cinek24ac55e2014-08-27 12:51:45 +0200105 }
106
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100107 @Override
108 public String getProfileOwnerName() {
109 for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
110 String name = mDevicePolicyManager.getProfileOwnerNameAsUser(profile.id);
111 if (name != null) {
112 return name;
113 }
114 }
115 return null;
116 }
Selim Cinek24ac55e2014-08-27 12:51:45 +0200117
118 @Override
Jason Monk3d5f5512014-07-25 11:17:28 -0400119 public boolean isVpnEnabled() {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100120 return mCurrentVpnUsers.get(mCurrentUserId) != null;
Jason Monk3d5f5512014-07-25 11:17:28 -0400121 }
122
123 @Override
Jason Monk3128f122014-09-03 13:18:57 -0400124 public void removeCallback(SecurityControllerCallback callback) {
Jason Monk3d5f5512014-07-25 11:17:28 -0400125 if (callback == null) return;
126 if (DEBUG) Log.d(TAG, "removeCallback " + callback);
127 mCallbacks.remove(callback);
128 }
129
130 @Override
Jason Monk3128f122014-09-03 13:18:57 -0400131 public void addCallback(SecurityControllerCallback callback) {
Jason Monk3d5f5512014-07-25 11:17:28 -0400132 if (callback == null || mCallbacks.contains(callback)) return;
133 if (DEBUG) Log.d(TAG, "addCallback " + callback);
134 mCallbacks.add(callback);
135 }
136
Selim Cinek24ac55e2014-08-27 12:51:45 +0200137 @Override
138 public void onUserSwitched(int newUserId) {
139 mCurrentUserId = newUserId;
140 fireCallbacks();
141 }
142
Jason Monk3d5f5512014-07-25 11:17:28 -0400143 private void fireCallbacks() {
Selim Cinek24ac55e2014-08-27 12:51:45 +0200144 for (SecurityControllerCallback callback : mCallbacks) {
145 callback.onStateChanged();
Jason Monk3d5f5512014-07-25 11:17:28 -0400146 }
147 }
148
149 private void updateState() {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100150 // Find all users with an active VPN
151 SparseArray<Boolean> vpnUsers = new SparseArray<>();
Jason Monk3d5f5512014-07-25 11:17:28 -0400152 try {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100153 for (VpnInfo vpn : mConnectivityManagerService.getAllVpnInfo()) {
154 UserInfo user = mUserManager.getUserInfo(UserHandle.getUserId(vpn.ownerUid));
155 int groupId = (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID ?
156 user.profileGroupId : user.id);
Jason Monk3d5f5512014-07-25 11:17:28 -0400157
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100158 vpnUsers.put(groupId, Boolean.TRUE);
Jason Monk3d5f5512014-07-25 11:17:28 -0400159 }
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100160 } catch (RemoteException rme) {
161 // Roll back to previous state
162 Log.e(TAG, "Unable to list active VPNs", rme);
163 return;
Jason Monk3d5f5512014-07-25 11:17:28 -0400164 }
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100165 mCurrentVpnUsers = vpnUsers;
Jason Monk3d5f5512014-07-25 11:17:28 -0400166 }
167
168 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
Jason Monk92b5c812014-08-21 13:44:18 -0400169 @Override
170 public void onAvailable(Network network) {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100171 if (DEBUG) Log.d(TAG, "onAvailable " + network.netId);
172 updateState();
173 fireCallbacks();
Jason Monk92b5c812014-08-21 13:44:18 -0400174 };
175
176 // TODO Find another way to receive VPN lost. This may be delayed depending on
177 // how long the VPN connection is held on to.
178 @Override
179 public void onLost(Network network) {
180 if (DEBUG) Log.d(TAG, "onLost " + network.netId);
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100181 updateState();
182 fireCallbacks();
Jason Monk92b5c812014-08-21 13:44:18 -0400183 };
Jason Monk3d5f5512014-07-25 11:17:28 -0400184 };
185
186}