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

Commit 782c1fd1 authored by Ray Chen's avatar Ray Chen Committed by Gerrit Code Review
Browse files

Merge changes from topic "VPN_ICON" into main

* changes:
  Adjust the NetworkRequest configuration used by SecurityController
  Design of the VPN icon reflects the invalidated status
  Update the VPN icon to reflect the validation status of the VPN network
parents 4c2e9d3c 7575405f
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2023, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="17dp"
    android:height="17dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h4V9H12.09zM18,13hv3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H18V13z"/>
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M22,10h-2v8h2V10z"/>
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M22,20h-2v2h2V20z"/>
</vector>
+36 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2023, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="17dp"
    android:height="17dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h4V9H12.09zM18,13hv3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H18V13z"/>
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M22,10h-2v8h2V10z"/>
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M22,20h-2v2h2V20z"/>
</vector>
+13 −3
Original line number Diff line number Diff line
@@ -118,15 +118,25 @@ public class StatusBarSignalPolicy implements SignalCallback,

    private void updateVpn() {
        boolean vpnVisible = mSecurityController.isVpnEnabled();
        int vpnIconId = currentVpnIconId(mSecurityController.isVpnBranded());
        int vpnIconId = currentVpnIconId(
                mSecurityController.isVpnBranded(),
                mSecurityController.isVpnValidated());

        mIconController.setIcon(mSlotVpn, vpnIconId,
                mContext.getResources().getString(R.string.accessibility_vpn_on));
        mIconController.setIconVisibility(mSlotVpn, vpnVisible);
    }

    private int currentVpnIconId(boolean isBranded) {
        return isBranded ? R.drawable.stat_sys_branded_vpn : R.drawable.stat_sys_vpn_ic;
    private int currentVpnIconId(boolean isBranded, boolean isValidated) {
        if (isBranded) {
            return isValidated
                    ? R.drawable.stat_sys_branded_vpn
                    : R.drawable.stat_sys_no_internet_branded_vpn;
        } else {
            return isValidated
                    ? R.drawable.stat_sys_vpn_ic
                    : R.drawable.stat_sys_no_internet_vpn_ic;
        }
    }

    /**
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public interface SecurityController extends CallbackController<SecurityControlle
    boolean isNetworkLoggingEnabled();
    boolean isVpnEnabled();
    boolean isVpnRestricted();
    /** Whether the VPN network is validated. */
    boolean isVpnValidated();
    /** Whether the VPN app should use branded VPN iconography.  */
    boolean isVpnBranded();
    String getPrimaryVpnName();
+122 −1
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package com.android.systemui.statusbar.policy;

import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;

import android.annotation.Nullable;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManager;
@@ -32,7 +35,9 @@ import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.VpnManager;
import android.os.Handler;
@@ -76,7 +81,10 @@ public class SecurityControllerImpl implements SecurityController {
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private static final NetworkRequest REQUEST =
            new NetworkRequest.Builder().clearCapabilities().build();
            new NetworkRequest.Builder()
                    .clearCapabilities()
                    .addTransportType(TRANSPORT_VPN)
                    .build();
    private static final int NO_NETWORK = -1;

    private static final String VPN_BRANDED_META_DATA = "com.android.systemui.IS_BRANDED";
@@ -99,6 +107,8 @@ public class SecurityControllerImpl implements SecurityController {
    private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
    private int mCurrentUserId;
    private int mVpnUserId;
    @GuardedBy("mNetworkProperties")
    private final SparseArray<NetworkProperties> mNetworkProperties = new SparseArray<>();

    // Key: userId, Value: whether the user has CACerts installed
    // Needs to be cached here since the query has to be asynchronous
@@ -162,6 +172,21 @@ public class SecurityControllerImpl implements SecurityController {
            pw.print(mCurrentVpns.valueAt(i).user);
        }
        pw.println("}");
        pw.print("  mNetworkProperties={");
        synchronized (mNetworkProperties) {
            for (int i = 0; i < mNetworkProperties.size(); ++i) {
                if (i > 0) {
                    pw.print(", ");
                }
                pw.print(mNetworkProperties.keyAt(i));
                pw.print("={");
                pw.print(mNetworkProperties.valueAt(i).interfaceName);
                pw.print(", ");
                pw.print(mNetworkProperties.valueAt(i).validated);
                pw.print("}");
            }
        }
        pw.println("}");
    }

    @Override
@@ -303,6 +328,26 @@ public class SecurityControllerImpl implements SecurityController {
        return isVpnPackageBranded(packageName);
    }

    @Override
    public boolean isVpnValidated() {
        // Prioritize reporting the network status of the parent user.
        final VpnConfig primaryVpnConfig = mCurrentVpns.get(mVpnUserId);
        if (primaryVpnConfig != null) {
            return getVpnValidationStatus(primaryVpnConfig);
        }
        // Identify any Unvalidated status in each active VPN network within other profiles.
        for (int profileId : mUserManager.getEnabledProfileIds(mVpnUserId)) {
            final VpnConfig vpnConfig = mCurrentVpns.get(profileId);
            if (vpnConfig == null) {
                continue;
            }
            if (!getVpnValidationStatus(vpnConfig)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean hasCACertInCurrentUser() {
        Boolean hasCACerts = mHasCACerts.get(mCurrentUserId);
@@ -491,11 +536,74 @@ public class SecurityControllerImpl implements SecurityController {
        @Override
        public void onLost(Network network) {
            if (DEBUG) Log.d(TAG, "onLost " + network.getNetId());
            synchronized (mNetworkProperties) {
                mNetworkProperties.delete(network.getNetId());
            }
            updateState();
            fireCallbacks();
        };


        @Override
        public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
            if (DEBUG) Log.d(TAG, "onCapabilitiesChanged " + network.getNetId());
            final NetworkProperties properties;
            synchronized (mNetworkProperties) {
                properties = mNetworkProperties.get(network.getNetId());
            }
            // When a new network appears, the system first notifies the application about
            // its capabilities through onCapabilitiesChanged. This initial notification
            // will be skipped because the interface information is included in the
            // subsequent onLinkPropertiesChanged call. After validating the network, the
            // system might send another onCapabilitiesChanged notification if the network
            // becomes validated.
            if (properties == null) {
                return;
            }
            final boolean validated = nc.hasCapability(NET_CAPABILITY_VALIDATED);
            if (properties.validated != validated) {
                properties.validated = validated;
                fireCallbacks();
            }
        }

        @Override
        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
            if (DEBUG) Log.d(TAG, "onLinkPropertiesChanged " + network.getNetId());
            final String interfaceName = linkProperties.getInterfaceName();
            if (interfaceName == null) {
                Log.w(TAG, "onLinkPropertiesChanged event with null interface");
                return;
            }
            synchronized (mNetworkProperties) {
                final NetworkProperties properties = mNetworkProperties.get(network.getNetId());
                if (properties == null) {
                    mNetworkProperties.put(
                            network.getNetId(),
                            new NetworkProperties(interfaceName, false));
                } else {
                    properties.interfaceName = interfaceName;
                }
            }
        }
    };

    /**
     *  Retrieve the validation status of the VPN network associated with the given VpnConfig.
     */
    private boolean getVpnValidationStatus(@NonNull VpnConfig vpnConfig) {
        synchronized (mNetworkProperties) {
            // Find the network has the same interface as the VpnConfig
            for (int i = 0; i < mNetworkProperties.size(); ++i) {
                if (mNetworkProperties.valueAt(i).interfaceName.equals(vpnConfig.interfaze)) {
                    return mNetworkProperties.valueAt(i).validated;
                }
            }
        }
        // If no matching network is found, consider it validated.
        return true;
    }

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override public void onReceive(Context context, Intent intent) {
            if (KeyChain.ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) {
@@ -506,4 +614,17 @@ public class SecurityControllerImpl implements SecurityController {
            }
        }
    };

    /**
     *  A data class to hold specific Network properties received through the NetworkCallback.
     */
    private static class NetworkProperties {
        public String interfaceName;
        public boolean validated;

        NetworkProperties(@NonNull String interfaceName, boolean validated) {
            this.interfaceName = interfaceName;
            this.validated = validated;
        }
    }
}
Loading