Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76ce8473 authored by Fyodor Kupolov's avatar Fyodor Kupolov Committed by Android (Google) Code Review
Browse files

Merge "Fixed VPN support for restricted profiles in split system user model"

parents d26df2d6 1c36315a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ interface IUserManager {
    UserInfo getUserInfo(int userHandle);
    long getUserCreationTime(int userHandle);
    boolean isRestricted();
    boolean canHaveRestrictedProfile(int userId);
    int getUserSerialNumber(int userHandle);
    int getUserHandle(int userSerialNumber);
    Bundle getUserRestrictions(int userHandle);
+13 −0
Original line number Diff line number Diff line
@@ -631,6 +631,19 @@ public class UserManager {
        }
    }

    /**
     * Checks if specified user can have restricted profile.
     * @hide
     */
    public boolean canHaveRestrictedProfile(int userId) {
        try {
            return mService.canHaveRestrictedProfile(userId);
        } catch (RemoteException re) {
            Log.w(TAG, "Could not check if user can have restricted profile", re);
            return false;
        }
    }

    /**
     * Checks if the calling app is running as a guest user.
     * @return whether the caller is a guest user.
+3 −3
Original line number Diff line number Diff line
@@ -182,10 +182,10 @@ public class SecurityControllerImpl implements SecurityController {
    @Override
    public void onUserSwitched(int newUserId) {
        mCurrentUserId = newUserId;
        if (mUserManager.getUserInfo(newUserId).isRestricted()) {
        final UserInfo newUserInfo = mUserManager.getUserInfo(newUserId);
        if (newUserInfo.isRestricted()) {
            // VPN for a restricted profile is routed through its owner user
            // TODO: http://b/22950929
            mVpnUserId = UserHandle.USER_SYSTEM;
            mVpnUserId = newUserInfo.restrictedProfileParentId;
        } else {
            mVpnUserId = mCurrentUserId;
        }
+26 −0
Original line number Diff line number Diff line
@@ -754,6 +754,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_USER_STARTING);
        intentFilter.addAction(Intent.ACTION_USER_STOPPING);
        intentFilter.addAction(Intent.ACTION_USER_ADDED);
        intentFilter.addAction(Intent.ACTION_USER_REMOVED);
        mContext.registerReceiverAsUser(
                mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);

@@ -3525,6 +3527,26 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
    }

    private void onUserAdded(int userId) {
        synchronized(mVpns) {
            final int vpnsSize = mVpns.size();
            for (int i = 0; i < vpnsSize; i++) {
                Vpn vpn = mVpns.valueAt(i);
                vpn.onUserAdded(userId);
            }
        }
    }

    private void onUserRemoved(int userId) {
        synchronized(mVpns) {
            final int vpnsSize = mVpns.size();
            for (int i = 0; i < vpnsSize; i++) {
                Vpn vpn = mVpns.valueAt(i);
                vpn.onUserRemoved(userId);
            }
        }
    }

    private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -3536,6 +3558,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
                onUserStart(userId);
            } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
                onUserStop(userId);
            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
                onUserAdded(userId);
            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                onUserRemoved(userId);
            }
        }
    };
+21 −45
Original line number Diff line number Diff line
@@ -20,9 +20,6 @@ import static android.Manifest.permission.BIND_VPN_SERVICE;
import static android.net.ConnectivityManager.NETID_UNSET;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.os.UserHandle.PER_USER_RANGE;
import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;

import android.Manifest;
import android.app.AppGlobals;
@@ -34,13 +31,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.IpPrefix;
import android.net.LinkAddress;
@@ -126,7 +121,6 @@ public class Vpn {
    /* list of users using this VPN. */
    @GuardedBy("this")
    private List<UidRange> mVpnUsers = null;
    private BroadcastReceiver mUserIntentReceiver = null;

    // Handle of user initiating VPN.
    private final int mUserHandle;
@@ -146,31 +140,6 @@ public class Vpn {
        } catch (RemoteException e) {
            Log.wtf(TAG, "Problem registering observer", e);
        }
        // TODO: http://b/22950929
        if (userHandle == UserHandle.USER_SYSTEM) {
            // Owner's VPN also needs to handle restricted users
            mUserIntentReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    final String action = intent.getAction();
                    final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                            UserHandle.USER_NULL);
                    if (userHandle == UserHandle.USER_NULL) return;

                    if (Intent.ACTION_USER_ADDED.equals(action)) {
                        onUserAdded(userHandle);
                    } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                        onUserRemoved(userHandle);
                    }
                }
            };

            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_USER_ADDED);
            intentFilter.addAction(Intent.ACTION_USER_REMOVED);
            mContext.registerReceiverAsUser(
                    mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
        }

        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_VPN, 0, NETWORKTYPE, "");
        // TODO: Copy metered attribute and bandwidths from physical transport, b/16207332
@@ -439,8 +408,8 @@ public class Vpn {
        }

        addVpnUserLocked(mUserHandle);
        // If we are owner assign all Restricted Users to this VPN
        if (mUserHandle == UserHandle.USER_OWNER) {
        // If the user can have restricted profiles, assign all its restricted profiles to this VPN
        if (canHaveRestrictedProfile(mUserHandle)) {
            token = Binder.clearCallingIdentity();
            List<UserInfo> users;
            try {
@@ -449,7 +418,7 @@ public class Vpn {
                Binder.restoreCallingIdentity(token);
            }
            for (UserInfo user : users) {
                if (user.isRestricted()) {
                if (user.isRestricted() && (user.restrictedProfileParentId == mUserHandle)) {
                    addVpnUserLocked(user.id);
                }
            }
@@ -457,6 +426,15 @@ public class Vpn {
        mNetworkAgent.addUidRanges(mVpnUsers.toArray(new UidRange[mVpnUsers.size()]));
    }

    private boolean canHaveRestrictedProfile(int userId) {
        long token = Binder.clearCallingIdentity();
        try {
            return UserManager.get(mContext).canHaveRestrictedProfile(userId);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    private void agentDisconnect(NetworkInfo networkInfo, NetworkAgent networkAgent) {
        networkInfo.setIsAvailable(false);
        networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
@@ -681,12 +659,11 @@ public class Vpn {
        mStatusIntent = null;
    }

    private void onUserAdded(int userHandle) {
        // If the user is restricted tie them to the owner's VPN
    public void onUserAdded(int userHandle) {
        // If the user is restricted tie them to the parent user's VPN
        UserInfo user = UserManager.get(mContext).getUserInfo(userHandle);
        if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle) {
            synchronized(Vpn.this) {
            UserManager mgr = UserManager.get(mContext);
            UserInfo user = mgr.getUserInfo(userHandle);
            if (user.isRestricted()) {
                try {
                    addVpnUserLocked(userHandle);
                    if (mNetworkAgent != null) {
@@ -700,12 +677,11 @@ public class Vpn {
        }
    }

    private void onUserRemoved(int userHandle) {
    public void onUserRemoved(int userHandle) {
        // clean up if restricted
        UserInfo user = UserManager.get(mContext).getUserInfo(userHandle);
        if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle) {
            synchronized(Vpn.this) {
            UserManager mgr = UserManager.get(mContext);
            UserInfo user = mgr.getUserInfo(userHandle);
            if (user.isRestricted()) {
                try {
                    removeVpnUserLocked(userHandle);
                } catch (Exception e) {
Loading