Add a branded VPN icon for quick settings and status bar.
If a system VPN app specifies in its meta-data that it should use the system's
branded VPN icon instead of the standard one, the Quick Settings footer and
status bar show it instead.
Bug 27146125
Change-Id: I3cfe4dda156d9147bdb339ba6bce82c72ca7393d
(cherry picked from commit 3956639122)
This commit is contained in:
24
packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml
Normal file
24
packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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="12.0dp"
|
||||
android:height="12.0dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#4DFFFFFF"
|
||||
android:pathData="M12.700000,10.000000c-0.800000,-2.300000 -3.000000,-4.000000 -5.700000,-4.000000c-3.300000,0.000000 -6.000000,2.700000 -6.000000,6.000000s2.700000,6.000000 6.000000,6.000000c2.600000,0.000000 4.800000,-1.700000 5.700000,-4.000000L17.000000,14.000000l0.000000,4.000000l4.000000,0.000000l0.000000,-4.000000l2.000000,0.000000l0.000000,-4.000000L12.700000,10.000000zM7.000000,14.000000c-1.100000,0.000000 -2.000000,-0.900000 -2.000000,-2.000000c0.000000,-1.100000 0.900000,-2.000000 2.000000,-2.000000s2.000000,0.900000 2.000000,2.000000C9.000000,13.100000 8.100000,14.000000 7.000000,14.000000z"/>
|
||||
</vector>
|
||||
28
packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml
Normal file
28
packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 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.
|
||||
-->
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:insetLeft="2.5dp"
|
||||
android:insetRight="2.5dp">
|
||||
<vector android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12.0,17.273l6.1800003,3.7269993 -1.6350002,-7.0290003 5.455,-4.7269993 -7.191,-0.6170006 -2.809,-6.627 -2.809,6.627 -7.191,0.6170006 5.455,4.7269993 -1.6349998,7.0290003z"/>
|
||||
</vector>
|
||||
</inset>
|
||||
@@ -19,6 +19,7 @@ import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -57,6 +58,7 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
private boolean mIsVisible;
|
||||
private boolean mIsIconVisible;
|
||||
private int mFooterTextId;
|
||||
private int mFooterIconId;
|
||||
|
||||
public QSFooter(QSPanel qsPanel, Context context) {
|
||||
mRootView = LayoutInflater.from(context)
|
||||
@@ -64,6 +66,7 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
mRootView.setOnClickListener(this);
|
||||
mFooterText = (TextView) mRootView.findViewById(R.id.footer_text);
|
||||
mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon);
|
||||
mFooterIconId = R.drawable.ic_qs_vpn;
|
||||
mContext = context;
|
||||
mMainHandler = new Handler();
|
||||
}
|
||||
@@ -118,6 +121,14 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene
|
||||
mIsVisible = true;
|
||||
} else {
|
||||
mFooterTextId = R.string.vpn_footer;
|
||||
// Update the VPN footer icon, if needed.
|
||||
int footerIconId = (mSecurityController.isVpnBranded()
|
||||
? R.drawable.ic_qs_branded_vpn
|
||||
: R.drawable.ic_qs_vpn);
|
||||
if (mFooterIconId != footerIconId) {
|
||||
mFooterIcon.setImageResource(footerIconId);
|
||||
mFooterIconId = footerIconId;
|
||||
}
|
||||
mIsVisible = mIsIconVisible;
|
||||
}
|
||||
mMainHandler.post(mUpdateDisplayState);
|
||||
|
||||
@@ -67,6 +67,8 @@ public class SignalClusterView
|
||||
|
||||
private boolean mNoSimsVisible = false;
|
||||
private boolean mVpnVisible = false;
|
||||
private int mVpnIconId = 0;
|
||||
private int mLastVpnIconId = -1;
|
||||
private boolean mEthernetVisible = false;
|
||||
private int mEthernetIconId = 0;
|
||||
private int mLastEthernetIconId = -1;
|
||||
@@ -164,6 +166,7 @@ public class SignalClusterView
|
||||
mSC = sc;
|
||||
mSC.addCallback(this);
|
||||
mVpnVisible = mSC.isVpnEnabled();
|
||||
mVpnIconId = currentVpnIconId(mSC.isVpnBranded());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,6 +244,7 @@ public class SignalClusterView
|
||||
@Override
|
||||
public void run() {
|
||||
mVpnVisible = mSC.isVpnEnabled();
|
||||
mVpnIconId = currentVpnIconId(mSC.isVpnBranded());
|
||||
apply();
|
||||
}
|
||||
});
|
||||
@@ -415,6 +419,15 @@ public class SignalClusterView
|
||||
if (mWifiGroup == null) return;
|
||||
|
||||
mVpn.setVisibility(mVpnVisible ? View.VISIBLE : View.GONE);
|
||||
if (mVpnVisible) {
|
||||
if (mLastVpnIconId != mVpnIconId) {
|
||||
setIconForView(mVpn, mVpnIconId);
|
||||
mLastVpnIconId = mVpnIconId;
|
||||
}
|
||||
mVpn.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mVpn.setVisibility(View.GONE);
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, String.format("vpn: %s", mVpnVisible ? "VISIBLE" : "GONE"));
|
||||
|
||||
if (mEthernetVisible) {
|
||||
@@ -543,6 +556,10 @@ public class SignalClusterView
|
||||
v.setImageTintList(ColorStateList.valueOf(tint));
|
||||
}
|
||||
|
||||
private int currentVpnIconId(boolean isBranded) {
|
||||
return isBranded ? R.drawable.stat_sys_branded_vpn : R.drawable.stat_sys_vpn_ic;
|
||||
}
|
||||
|
||||
private class PhoneState {
|
||||
private final int mSubId;
|
||||
private boolean mMobileVisible = false;
|
||||
@@ -664,4 +681,3 @@ public class SignalClusterView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ public interface SecurityController {
|
||||
String getProfileOwnerName();
|
||||
boolean isVpnEnabled();
|
||||
boolean isVpnRestricted();
|
||||
/** Whether the VPN app should use branded VPN iconography. */
|
||||
boolean isVpnBranded();
|
||||
String getPrimaryVpnName();
|
||||
String getProfileVpnName();
|
||||
void onUserSwitched(int newUserId);
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.policy;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.net.ConnectivityManager;
|
||||
@@ -54,10 +56,13 @@ public class SecurityControllerImpl implements SecurityController {
|
||||
.build();
|
||||
private static final int NO_NETWORK = -1;
|
||||
|
||||
private static final String VPN_BRANDED_META_DATA = "com.android.systemui.IS_BRANDED";
|
||||
|
||||
private final Context mContext;
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final IConnectivityManager mConnectivityManagerService;
|
||||
private final DevicePolicyManager mDevicePolicyManager;
|
||||
private final PackageManager mPackageManager;
|
||||
private final UserManager mUserManager;
|
||||
|
||||
@GuardedBy("mCallbacks")
|
||||
@@ -75,6 +80,7 @@ public class SecurityControllerImpl implements SecurityController {
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
|
||||
mPackageManager = context.getPackageManager();
|
||||
mUserManager = (UserManager)
|
||||
context.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
@@ -164,6 +170,21 @@ public class SecurityControllerImpl implements SecurityController {
|
||||
|| mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, currentUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVpnBranded() {
|
||||
VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
|
||||
if (cfg == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String packageName = getPackageNameForVpnConfig(cfg);
|
||||
if (packageName == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isVpnPackageBranded(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(SecurityControllerCallback callback) {
|
||||
synchronized (mCallbacks) {
|
||||
@@ -245,6 +266,28 @@ public class SecurityControllerImpl implements SecurityController {
|
||||
mCurrentVpns = vpns;
|
||||
}
|
||||
|
||||
private String getPackageNameForVpnConfig(VpnConfig cfg) {
|
||||
if (cfg.legacy) {
|
||||
return null;
|
||||
}
|
||||
return cfg.user;
|
||||
}
|
||||
|
||||
private boolean isVpnPackageBranded(String packageName) {
|
||||
boolean isBranded;
|
||||
try {
|
||||
ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
|
||||
PackageManager.GET_META_DATA);
|
||||
if (info == null || info.metaData == null || !info.isSystemApp()) {
|
||||
return false;
|
||||
}
|
||||
isBranded = info.metaData.getBoolean(VPN_BRANDED_META_DATA, false);
|
||||
} catch (NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
return isBranded;
|
||||
}
|
||||
|
||||
private final NetworkCallback mNetworkCallback = new NetworkCallback() {
|
||||
@Override
|
||||
public void onAvailable(Network network) {
|
||||
|
||||
Reference in New Issue
Block a user