blob: ae0291bee7019f0bfcbf0f395e55eb1b9613a923 [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
18import android.app.admin.DevicePolicyManager;
19import android.content.Context;
20import android.content.Intent;
Jason Monk3d5f5512014-07-25 11:17:28 -040021import android.content.pm.PackageManager.NameNotFoundException;
22import android.net.ConnectivityManager;
23import android.net.ConnectivityManager.NetworkCallback;
24import android.net.IConnectivityManager;
25import android.net.NetworkCapabilities;
26import android.net.NetworkRequest;
27import android.os.RemoteException;
28import android.os.ServiceManager;
29import android.text.TextUtils;
30import android.util.Log;
31
32import com.android.internal.net.VpnConfig;
33
34import java.io.FileDescriptor;
35import java.io.PrintWriter;
36import java.util.ArrayList;
37
38public class SecurityControllerImpl implements SecurityController {
39
40 private static final String TAG = "SecurityController";
41 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
42
43 private static final NetworkRequest REQUEST = new NetworkRequest.Builder()
44 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
45 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
46 .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
47 .build();
48 private final Context mContext;
49 private final ConnectivityManager mConnectivityManager;
50 private final IConnectivityManager mConnectivityService = IConnectivityManager.Stub.asInterface(
51 ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
52 private final DevicePolicyManager mDevicePolicyManager;
53 private final ArrayList<VpnCallback> mCallbacks = new ArrayList<VpnCallback>();
54
55 private boolean mIsVpnEnabled;
56 private VpnConfig mVpnConfig;
57 private String mVpnName;
58
59 public SecurityControllerImpl(Context context) {
60 mContext = context;
61 mDevicePolicyManager = (DevicePolicyManager)
62 context.getSystemService(Context.DEVICE_POLICY_SERVICE);
63 mConnectivityManager = (ConnectivityManager)
64 context.getSystemService(Context.CONNECTIVITY_SERVICE);
65
66 // TODO: re-register network callback on user change.
67 mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
68 }
69
70 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
71 pw.println("SecurityController state:");
72 pw.print(" mIsVpnEnabled="); pw.println(mIsVpnEnabled);
73 pw.print(" mVpnConfig="); pw.println(mVpnConfig);
74 pw.print(" mVpnName="); pw.println(mVpnName);
75 }
76
77 @Override
78 public boolean hasDeviceOwner() {
79 return !TextUtils.isEmpty(mDevicePolicyManager.getDeviceOwner());
80 }
81
82 @Override
83 public String getDeviceOwnerName() {
84 return mDevicePolicyManager.getDeviceOwnerName();
85 }
86
87 @Override
88 public boolean isVpnEnabled() {
89 // TODO: Remove once using NetworkCallback for updates.
90 updateState();
91
92 return mIsVpnEnabled;
93 }
94
95 @Override
96 public boolean isLegacyVpn() {
97 return mVpnConfig.legacy;
98 }
99
100 @Override
101 public String getVpnApp() {
102 return mVpnName;
103 }
104
105 @Override
106 public String getLegacyVpnName() {
107 return mVpnConfig.session;
108 }
109
110 @Override
Jeff Davidson05542602014-08-11 14:07:27 -0700111 public void disconnectFromVpn() {
Jason Monk3d5f5512014-07-25 11:17:28 -0400112 try {
Jeff Davidson05542602014-08-11 14:07:27 -0700113 if (isLegacyVpn()) {
114 mConnectivityService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN);
115 } else {
116 // Prevent this app from initiating VPN connections in the future without user
117 // intervention.
118 mConnectivityService.setVpnPackageAuthorization(false);
119
120 mConnectivityService.prepareVpn(mVpnConfig.user, VpnConfig.LEGACY_VPN);
121 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400122 } catch (Exception e) {
123 Log.e(TAG, "Unable to disconnect from VPN", e);
124 }
125 }
126
127 @Override
128 public void addCallback(VpnCallback callback) {
129 if (callback == null) return;
130 if (DEBUG) Log.d(TAG, "removeCallback " + callback);
131 mCallbacks.remove(callback);
132 }
133
134 @Override
135 public void removeCallback(VpnCallback callback) {
136 if (callback == null || mCallbacks.contains(callback)) return;
137 if (DEBUG) Log.d(TAG, "addCallback " + callback);
138 mCallbacks.add(callback);
139 }
140
141 private void fireCallbacks() {
142 for (VpnCallback callback : mCallbacks) {
143 callback.onVpnStateChanged();
144 }
145 }
146
147 private void updateState() {
148 try {
149 mVpnConfig = mConnectivityService.getVpnConfig();
150
151 // TODO: Remove once using NetworkCallback for updates.
152 mIsVpnEnabled = mVpnConfig != null;
153
154 if (mVpnConfig != null && !mVpnConfig.legacy) {
Jeff Davidson05542602014-08-11 14:07:27 -0700155 mVpnName = VpnConfig.getVpnLabel(mContext, mVpnConfig.user).toString();
Jason Monk3d5f5512014-07-25 11:17:28 -0400156 }
157 } catch (RemoteException | NameNotFoundException e) {
158 Log.w(TAG, "Unable to get current VPN", e);
159 }
160 }
161
162 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
163 public void onCapabilitiesChanged(android.net.Network network,
164 android.net.NetworkCapabilities networkCapabilities) {
165 if (DEBUG) Log.d(TAG, "onCapabilitiesChanged " + networkCapabilities);
166 mIsVpnEnabled = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
167 updateState();
168 fireCallbacks();
169 }
170 };
171
172}