[go: nahoru, domu]

13d5f551cd5905c835bb789406763764a8a9a73deJason Monk/*
23d5f551cd5905c835bb789406763764a8a9a73deJason Monk * Copyright (C) 2014 The Android Open Source Project
33d5f551cd5905c835bb789406763764a8a9a73deJason Monk *
43d5f551cd5905c835bb789406763764a8a9a73deJason Monk * Licensed under the Apache License, Version 2.0 (the "License");
53d5f551cd5905c835bb789406763764a8a9a73deJason Monk * you may not use this file except in compliance with the License.
63d5f551cd5905c835bb789406763764a8a9a73deJason Monk * You may obtain a copy of the License at
73d5f551cd5905c835bb789406763764a8a9a73deJason Monk *
83d5f551cd5905c835bb789406763764a8a9a73deJason Monk *      http://www.apache.org/licenses/LICENSE-2.0
93d5f551cd5905c835bb789406763764a8a9a73deJason Monk *
103d5f551cd5905c835bb789406763764a8a9a73deJason Monk * Unless required by applicable law or agreed to in writing, software
113d5f551cd5905c835bb789406763764a8a9a73deJason Monk * distributed under the License is distributed on an "AS IS" BASIS,
123d5f551cd5905c835bb789406763764a8a9a73deJason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133d5f551cd5905c835bb789406763764a8a9a73deJason Monk * See the License for the specific language governing permissions and
143d5f551cd5905c835bb789406763764a8a9a73deJason Monk * limitations under the License.
153d5f551cd5905c835bb789406763764a8a9a73deJason Monk */
163d5f551cd5905c835bb789406763764a8a9a73deJason Monkpackage com.android.systemui.statusbar.policy;
173d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1824ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinekimport android.app.ActivityManager;
193d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.app.admin.DevicePolicyManager;
203d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.content.Context;
213d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.content.pm.PackageManager.NameNotFoundException;
229cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Leeimport android.content.pm.UserInfo;
233d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.net.ConnectivityManager;
243d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.net.ConnectivityManager.NetworkCallback;
253d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.net.IConnectivityManager;
2692b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monkimport android.net.Network;
273d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.net.NetworkCapabilities;
283d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.net.NetworkRequest;
293d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.os.RemoteException;
303d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.os.ServiceManager;
319cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Leeimport android.os.UserHandle;
329cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Leeimport android.os.UserManager;
333d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport android.util.Log;
349cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Leeimport android.util.SparseArray;
353d5f551cd5905c835bb789406763764a8a9a73deJason Monk
36acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggiimport com.android.internal.annotations.GuardedBy;
376795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Leeimport com.android.internal.net.LegacyVpnInfo;
383d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport com.android.internal.net.VpnConfig;
39472834518e2d23172189ee34e98c51f868628a90Robin Leeimport com.android.systemui.R;
403d5f551cd5905c835bb789406763764a8a9a73deJason Monk
413d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport java.io.FileDescriptor;
423d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport java.io.PrintWriter;
433d5f551cd5905c835bb789406763764a8a9a73deJason Monkimport java.util.ArrayList;
443d5f551cd5905c835bb789406763764a8a9a73deJason Monk
453d5f551cd5905c835bb789406763764a8a9a73deJason Monkpublic class SecurityControllerImpl implements SecurityController {
463d5f551cd5905c835bb789406763764a8a9a73deJason Monk
473d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private static final String TAG = "SecurityController";
483d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
493d5f551cd5905c835bb789406763764a8a9a73deJason Monk
503d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private static final NetworkRequest REQUEST = new NetworkRequest.Builder()
513d5f551cd5905c835bb789406763764a8a9a73deJason Monk            .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
523d5f551cd5905c835bb789406763764a8a9a73deJason Monk            .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
533d5f551cd5905c835bb789406763764a8a9a73deJason Monk            .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
543d5f551cd5905c835bb789406763764a8a9a73deJason Monk            .build();
5592b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk    private static final int NO_NETWORK = -1;
5692b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk
573d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private final Context mContext;
583d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private final ConnectivityManager mConnectivityManager;
599cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee    private final IConnectivityManager mConnectivityManagerService;
603d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private final DevicePolicyManager mDevicePolicyManager;
619cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee    private final UserManager mUserManager;
62acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi
63acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi    @GuardedBy("mCallbacks")
64acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi    private final ArrayList<SecurityControllerCallback> mCallbacks = new ArrayList<>();
653d5f551cd5905c835bb789406763764a8a9a73deJason Monk
66472834518e2d23172189ee34e98c51f868628a90Robin Lee    private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
6724ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek    private int mCurrentUserId;
6863204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee    private int mVpnUserId;
693d5f551cd5905c835bb789406763764a8a9a73deJason Monk
703d5f551cd5905c835bb789406763764a8a9a73deJason Monk    public SecurityControllerImpl(Context context) {
713d5f551cd5905c835bb789406763764a8a9a73deJason Monk        mContext = context;
723d5f551cd5905c835bb789406763764a8a9a73deJason Monk        mDevicePolicyManager = (DevicePolicyManager)
733d5f551cd5905c835bb789406763764a8a9a73deJason Monk                context.getSystemService(Context.DEVICE_POLICY_SERVICE);
743d5f551cd5905c835bb789406763764a8a9a73deJason Monk        mConnectivityManager = (ConnectivityManager)
753d5f551cd5905c835bb789406763764a8a9a73deJason Monk                context.getSystemService(Context.CONNECTIVITY_SERVICE);
769cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee        mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
779cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
789cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee        mUserManager = (UserManager)
799cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee                context.getSystemService(Context.USER_SERVICE);
803d5f551cd5905c835bb789406763764a8a9a73deJason Monk
813d5f551cd5905c835bb789406763764a8a9a73deJason Monk        // TODO: re-register network callback on user change.
823d5f551cd5905c835bb789406763764a8a9a73deJason Monk        mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
8363204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee        onUserSwitched(ActivityManager.getCurrentUser());
843d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
853d5f551cd5905c835bb789406763764a8a9a73deJason Monk
863d5f551cd5905c835bb789406763764a8a9a73deJason Monk    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
873d5f551cd5905c835bb789406763764a8a9a73deJason Monk        pw.println("SecurityController state:");
88472834518e2d23172189ee34e98c51f868628a90Robin Lee        pw.print("  mCurrentVpns={");
89472834518e2d23172189ee34e98c51f868628a90Robin Lee        for (int i = 0 ; i < mCurrentVpns.size(); i++) {
90472834518e2d23172189ee34e98c51f868628a90Robin Lee            if (i > 0) {
91472834518e2d23172189ee34e98c51f868628a90Robin Lee                pw.print(", ");
92472834518e2d23172189ee34e98c51f868628a90Robin Lee            }
93472834518e2d23172189ee34e98c51f868628a90Robin Lee            pw.print(mCurrentVpns.keyAt(i));
94472834518e2d23172189ee34e98c51f868628a90Robin Lee            pw.print('=');
95472834518e2d23172189ee34e98c51f868628a90Robin Lee            pw.print(mCurrentVpns.valueAt(i).user);
96472834518e2d23172189ee34e98c51f868628a90Robin Lee        }
97472834518e2d23172189ee34e98c51f868628a90Robin Lee        pw.println("}");
983d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
993d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1003d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
101c8a5a555f1482d0f45b538eb898d6ee7e26552a6Makoto Onuki    public boolean isDeviceManaged() {
102c8a5a555f1482d0f45b538eb898d6ee7e26552a6Makoto Onuki        return mDevicePolicyManager.isDeviceManaged();
1033d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1043d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1053d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
1063d5f551cd5905c835bb789406763764a8a9a73deJason Monk    public String getDeviceOwnerName() {
107c8a5a555f1482d0f45b538eb898d6ee7e26552a6Makoto Onuki        return mDevicePolicyManager.getDeviceOwnerNameOnAnyUser();
1083d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1093d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1103d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
1119cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee    public boolean hasProfileOwner() {
112472834518e2d23172189ee34e98c51f868628a90Robin Lee        return mDevicePolicyManager.getProfileOwnerAsUser(mCurrentUserId) != null;
1133d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1143d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1153d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
1169cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee    public String getProfileOwnerName() {
1177f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov        for (int profileId : mUserManager.getProfileIdsWithDisabled(mCurrentUserId)) {
1187f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov            String name = mDevicePolicyManager.getProfileOwnerNameAsUser(profileId);
1199cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            if (name != null) {
1209cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee                return name;
1219cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            }
1229cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee        }
1239cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee        return null;
1243d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1253d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1263d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
127472834518e2d23172189ee34e98c51f868628a90Robin Lee    public String getPrimaryVpnName() {
12863204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee        VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
129472834518e2d23172189ee34e98c51f868628a90Robin Lee        if (cfg != null) {
13063204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee            return getNameForVpnConfig(cfg, new UserHandle(mVpnUserId));
131472834518e2d23172189ee34e98c51f868628a90Robin Lee        } else {
132472834518e2d23172189ee34e98c51f868628a90Robin Lee            return null;
133472834518e2d23172189ee34e98c51f868628a90Robin Lee        }
134472834518e2d23172189ee34e98c51f868628a90Robin Lee    }
135472834518e2d23172189ee34e98c51f868628a90Robin Lee
136472834518e2d23172189ee34e98c51f868628a90Robin Lee    @Override
137472834518e2d23172189ee34e98c51f868628a90Robin Lee    public String getProfileVpnName() {
1387f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov        for (int profileId : mUserManager.getProfileIdsWithDisabled(mVpnUserId)) {
1397f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov            if (profileId == mVpnUserId) {
140472834518e2d23172189ee34e98c51f868628a90Robin Lee                continue;
141472834518e2d23172189ee34e98c51f868628a90Robin Lee            }
1427f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov            VpnConfig cfg = mCurrentVpns.get(profileId);
143472834518e2d23172189ee34e98c51f868628a90Robin Lee            if (cfg != null) {
1447f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov                return getNameForVpnConfig(cfg, UserHandle.of(profileId));
145472834518e2d23172189ee34e98c51f868628a90Robin Lee            }
146472834518e2d23172189ee34e98c51f868628a90Robin Lee        }
147472834518e2d23172189ee34e98c51f868628a90Robin Lee        return null;
148472834518e2d23172189ee34e98c51f868628a90Robin Lee    }
149472834518e2d23172189ee34e98c51f868628a90Robin Lee
150472834518e2d23172189ee34e98c51f868628a90Robin Lee    @Override
1519cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee    public boolean isVpnEnabled() {
1527f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov        for (int profileId : mUserManager.getProfileIdsWithDisabled(mVpnUserId)) {
1537f98aa4aa93497692f200c553d2d6fff402e3de2Fyodor Kupolov            if (mCurrentVpns.get(profileId) != null) {
154472834518e2d23172189ee34e98c51f868628a90Robin Lee                return true;
155472834518e2d23172189ee34e98c51f868628a90Robin Lee            }
156472834518e2d23172189ee34e98c51f868628a90Robin Lee        }
157472834518e2d23172189ee34e98c51f868628a90Robin Lee        return false;
1583d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1593d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1603d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
16180d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee    public boolean isVpnRestricted() {
16280d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee        UserHandle currentUser = new UserHandle(mCurrentUserId);
16380d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee        return mUserManager.getUserInfo(mCurrentUserId).isRestricted()
16480d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee                || mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, currentUser);
16580d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee    }
16680d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee
16780d505367a5b51ea20e272e582c242ac30df3c9aRobin Lee    @Override
1683128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    public void removeCallback(SecurityControllerCallback callback) {
169acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi        synchronized (mCallbacks) {
170acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            if (callback == null) return;
171acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            if (DEBUG) Log.d(TAG, "removeCallback " + callback);
172acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            mCallbacks.remove(callback);
173acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi        }
1743d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1753d5f551cd5905c835bb789406763764a8a9a73deJason Monk
1763d5f551cd5905c835bb789406763764a8a9a73deJason Monk    @Override
1773128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    public void addCallback(SecurityControllerCallback callback) {
178acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi        synchronized (mCallbacks) {
179acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            if (callback == null || mCallbacks.contains(callback)) return;
180acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            if (DEBUG) Log.d(TAG, "addCallback " + callback);
181acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            mCallbacks.add(callback);
182acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi        }
1833d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
1843d5f551cd5905c835bb789406763764a8a9a73deJason Monk
18524ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek    @Override
18624ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek    public void onUserSwitched(int newUserId) {
18724ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek        mCurrentUserId = newUserId;
1881c36315a36962321dfe870b07e28b04a1d6777e9Fyodor Kupolov        final UserInfo newUserInfo = mUserManager.getUserInfo(newUserId);
1891c36315a36962321dfe870b07e28b04a1d6777e9Fyodor Kupolov        if (newUserInfo.isRestricted()) {
19063204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee            // VPN for a restricted profile is routed through its owner user
1911c36315a36962321dfe870b07e28b04a1d6777e9Fyodor Kupolov            mVpnUserId = newUserInfo.restrictedProfileParentId;
19263204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee        } else {
19363204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee            mVpnUserId = mCurrentUserId;
19463204eeafe7a51953d346717639f3e6eeb1f9bd5Robin Lee        }
19524ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek        fireCallbacks();
19624ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek    }
19724ac55e658f955c330fff4bb143cfc6af37e40bfSelim Cinek
198472834518e2d23172189ee34e98c51f868628a90Robin Lee    private String getNameForVpnConfig(VpnConfig cfg, UserHandle user) {
199472834518e2d23172189ee34e98c51f868628a90Robin Lee        if (cfg.legacy) {
200472834518e2d23172189ee34e98c51f868628a90Robin Lee            return mContext.getString(R.string.legacy_vpn_name);
201472834518e2d23172189ee34e98c51f868628a90Robin Lee        }
202472834518e2d23172189ee34e98c51f868628a90Robin Lee        // The package name for an active VPN is stored in the 'user' field of its VpnConfig
203472834518e2d23172189ee34e98c51f868628a90Robin Lee        final String vpnPackage = cfg.user;
204472834518e2d23172189ee34e98c51f868628a90Robin Lee        try {
205472834518e2d23172189ee34e98c51f868628a90Robin Lee            Context userContext = mContext.createPackageContextAsUser(mContext.getPackageName(),
206472834518e2d23172189ee34e98c51f868628a90Robin Lee                    0 /* flags */, user);
207472834518e2d23172189ee34e98c51f868628a90Robin Lee            return VpnConfig.getVpnLabel(userContext, vpnPackage).toString();
208472834518e2d23172189ee34e98c51f868628a90Robin Lee        } catch (NameNotFoundException nnfe) {
209472834518e2d23172189ee34e98c51f868628a90Robin Lee            Log.e(TAG, "Package " + vpnPackage + " is not present", nnfe);
210472834518e2d23172189ee34e98c51f868628a90Robin Lee            return null;
211472834518e2d23172189ee34e98c51f868628a90Robin Lee        }
212472834518e2d23172189ee34e98c51f868628a90Robin Lee    }
213472834518e2d23172189ee34e98c51f868628a90Robin Lee
2143d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private void fireCallbacks() {
215acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi        synchronized (mCallbacks) {
216acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            for (SecurityControllerCallback callback : mCallbacks) {
217acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi                callback.onStateChanged();
218acace94c1739b08ea72dc6c2f49cf29bce6c1dacJorim Jaggi            }
2193d5f551cd5905c835bb789406763764a8a9a73deJason Monk        }
2203d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
2213d5f551cd5905c835bb789406763764a8a9a73deJason Monk
2223d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private void updateState() {
2239cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee        // Find all users with an active VPN
224472834518e2d23172189ee34e98c51f868628a90Robin Lee        SparseArray<VpnConfig> vpns = new SparseArray<>();
2253d5f551cd5905c835bb789406763764a8a9a73deJason Monk        try {
226472834518e2d23172189ee34e98c51f868628a90Robin Lee            for (UserInfo user : mUserManager.getUsers()) {
227472834518e2d23172189ee34e98c51f868628a90Robin Lee                VpnConfig cfg = mConnectivityManagerService.getVpnConfig(user.id);
2286795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                if (cfg == null) {
2296795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                    continue;
2306795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                } else if (cfg.legacy) {
2316795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                    // Legacy VPNs should do nothing if the network is disconnected. Third-party
2326795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                    // VPN warnings need to continue as traffic can still go to the app.
2336795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                    LegacyVpnInfo legacyVpn = mConnectivityManagerService.getLegacyVpnInfo(user.id);
2346795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                    if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
2356795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                        continue;
2366795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                    }
237472834518e2d23172189ee34e98c51f868628a90Robin Lee                }
2386795a2aeafa6df8a5e8e3045d29991d33c8db33fRobin Lee                vpns.put(user.id, cfg);
2393d5f551cd5905c835bb789406763764a8a9a73deJason Monk            }
2409cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee        } catch (RemoteException rme) {
2419cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            // Roll back to previous state
2429cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            Log.e(TAG, "Unable to list active VPNs", rme);
2439cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            return;
2443d5f551cd5905c835bb789406763764a8a9a73deJason Monk        }
245472834518e2d23172189ee34e98c51f868628a90Robin Lee        mCurrentVpns = vpns;
2463d5f551cd5905c835bb789406763764a8a9a73deJason Monk    }
2473d5f551cd5905c835bb789406763764a8a9a73deJason Monk
2483d5f551cd5905c835bb789406763764a8a9a73deJason Monk    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
24992b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        @Override
25092b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        public void onAvailable(Network network) {
2519cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            if (DEBUG) Log.d(TAG, "onAvailable " + network.netId);
2529cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            updateState();
2539cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            fireCallbacks();
25492b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        };
25592b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk
25692b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        // TODO Find another way to receive VPN lost.  This may be delayed depending on
25792b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        // how long the VPN connection is held on to.
25892b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        @Override
25992b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        public void onLost(Network network) {
26092b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk            if (DEBUG) Log.d(TAG, "onLost " + network.netId);
2619cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            updateState();
2629cb1d5f6418da8cecdee58114c6e97b80c1b153fRobin Lee            fireCallbacks();
26392b5c8196b7cff36a8dc0431a30c014e0467c7cfJason Monk        };
2643d5f551cd5905c835bb789406763764a8a9a73deJason Monk    };
2653d5f551cd5905c835bb789406763764a8a9a73deJason Monk}
266