SecurityControllerImpl.java revision 05542603dd4f1e0ea47a3dca01de3999a9a329a9
1/* 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; 21import 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 111 public void disconnectFromVpn() { 112 try { 113 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 } 122 } 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) { 155 mVpnName = VpnConfig.getVpnLabel(mContext, mVpnConfig.user).toString(); 156 } 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} 173