diff options
9 files changed, 394 insertions, 125 deletions
diff --git a/packages/SystemUI/res/drawable/ic_info_outline.xml b/packages/SystemUI/res/drawable/ic_info_outline.xml new file mode 100644 index 000000000000..a4a3e9aab239 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_info_outline.xml @@ -0,0 +1,25 @@ +<!-- + 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="32dp" + android:height="32dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/> +</vector> diff --git a/packages/SystemUI/res/layout/quick_settings_footer.xml b/packages/SystemUI/res/layout/quick_settings_footer.xml index 8667a5a8f5cd..bb1b288cf3bf 100644 --- a/packages/SystemUI/res/layout/quick_settings_footer.xml +++ b/packages/SystemUI/res/layout/quick_settings_footer.xml @@ -14,41 +14,31 @@ See the License for the specific language governing permissions and limitations under the License. --> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" android:paddingBottom="@dimen/qs_tile_padding_top" - android:paddingTop="@dimen/qs_tile_padding_top" > + android:paddingTop="@dimen/qs_tile_padding_top" + android:paddingStart="@dimen/qs_footer_padding_start" + android:paddingEnd="@dimen/qs_footer_padding_end" + android:gravity="center_vertical" + android:background="?android:attr/colorPrimaryDark" > <TextView android:id="@+id/footer_text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_centerHorizontal="true" - android:textSize="@dimen/qs_tile_text_size" /> + android:gravity="start" + android:layout_weight="1" + android:textAppearance="@style/TextAppearance.QS.TileLabel" + android:textColor="?android:attr/textColorSecondary"/> <ImageView android:id="@+id/footer_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerVertical="true" - android:layout_marginEnd="8dp" - android:layout_toStartOf="@id/footer_text" - android:contentDescription="@null" - android:src="@drawable/ic_qs_vpn" - android:visibility="invisible" /> - - <!-- Only shown if both images are visible --> - <ImageView - android:id="@+id/footer_icon2" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerVertical="true" - android:layout_marginEnd="8dp" - android:layout_toStartOf="@id/footer_icon" + android:layout_width="@dimen/qs_footer_icon_size" + android:layout_height="@dimen/qs_footer_icon_size" android:contentDescription="@null" - android:src="@drawable/ic_qs_network_logging" - android:visibility="invisible" /> + android:src="@drawable/ic_info_outline" /> -</RelativeLayout> +</LinearLayout> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 9c7a6a00a4fb..1a3e6ce16985 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -263,6 +263,9 @@ <dimen name="qs_detail_item_icon_size">24dp</dimen> <dimen name="qs_detail_item_icon_marginStart">0dp</dimen> <dimen name="qs_detail_item_icon_marginEnd">20dp</dimen> + <dimen name="qs_footer_padding_start">16dp</dimen> + <dimen name="qs_footer_padding_end">24dp</dimen> + <dimen name="qs_footer_icon_size">16dp</dimen> <!-- Desired qs icon overlay size. --> <dimen name="qs_detail_icon_overlay_size">24dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 38485c729b21..f5e096ebbbef 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -98,9 +98,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { setupTileLayout(); - mFooter = new QSSecurityFooter(this, context); - addView(mFooter.getView()); - mPageIndicator = LayoutInflater.from(context).inflate( R.layout.qs_page_indicator, this, false); addView(mPageIndicator); @@ -110,6 +107,9 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { addDivider(); + mFooter = new QSSecurityFooter(this, context); + addView(mFooter.getView()); + updateResources(); mBrightnessController = new BrightnessController(getContext(), diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index 5b9d95d3e2c0..51c6ad88a2af 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -1,4 +1,3 @@ - /* * Copyright (C) 2014 The Android Open Source Project * @@ -51,24 +50,21 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic private final View mRootView; private final TextView mFooterText; private final ImageView mFooterIcon; - private final ImageView mFooterIcon2; private final Context mContext; private final Callback mCallback = new Callback(); private final SecurityController mSecurityController; private final ActivityStarter mActivityStarter; private final Handler mMainHandler; + private final View mDivider; private AlertDialog mDialog; private QSTileHost mHost; protected H mHandler; private boolean mIsVisible; - private boolean mIsIconVisible; - private boolean mIsIcon2Visible; private CharSequence mFooterTextContent = null; private int mFooterTextId; private int mFooterIconId; - private int mFooterIcon2Id; public QSSecurityFooter(QSPanel qsPanel, Context context) { mRootView = LayoutInflater.from(context) @@ -76,14 +72,13 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic mRootView.setOnClickListener(this); mFooterText = (TextView) mRootView.findViewById(R.id.footer_text); mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon); - mFooterIcon2 = (ImageView) mRootView.findViewById(R.id.footer_icon2); - mFooterIconId = R.drawable.ic_qs_vpn; - mFooterIcon2Id = R.drawable.ic_qs_network_logging; + mFooterIconId = R.drawable.ic_info_outline; mContext = context; mMainHandler = new Handler(Looper.getMainLooper()); mActivityStarter = Dependency.get(ActivityStarter.class); mSecurityController = Dependency.get(SecurityController.class); mHandler = new H(Dependency.get(Dependency.BG_LOOPER)); + mDivider = qsPanel == null ? null : qsPanel.getDivider(); } public void setHostEnvironment(QSTileHost host) { @@ -130,43 +125,100 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic } private void handleRefreshState() { - boolean isVpnEnabled = mSecurityController.isVpnEnabled(); - boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled(); - mIsIconVisible = isVpnEnabled || isNetworkLoggingEnabled; - mIsIcon2Visible = isVpnEnabled && isNetworkLoggingEnabled; - if (mSecurityController.isDeviceManaged()) { - final CharSequence organizationName = - mSecurityController.getDeviceOwnerOrganizationName(); - if (organizationName != null) { - mFooterTextContent = mContext.getResources().getString( - R.string.do_disclosure_with_name, organizationName); - } else { - mFooterTextContent = - mContext.getResources().getString(R.string.do_disclosure_generic); + final boolean isDeviceManaged = mSecurityController.isDeviceManaged(); + final boolean hasWorkProfile = mSecurityController.hasWorkProfile(); + final boolean hasCACerts = mSecurityController.hasCACertInCurrentUser(); + final boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile(); + final boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled(); + final String vpnName = mSecurityController.getPrimaryVpnName(); + final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName(); + final CharSequence organizationName = mSecurityController.getDeviceOwnerOrganizationName(); + final CharSequence workProfileName = mSecurityController.getWorkProfileOrganizationName(); + // Update visibility of footer + mIsVisible = isDeviceManaged || hasCACerts || hasCACertsInWorkProfile || + vpnName != null || vpnNameWorkProfile != null; + // Update the string + mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile, + hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName, + vpnNameWorkProfile, organizationName, workProfileName); + // Update the icon + int footerIconId = vpnName != null || vpnNameWorkProfile != null + ? R.drawable.ic_qs_vpn + : R.drawable.ic_info_outline; + if (mFooterIconId != footerIconId) { + mFooterIconId = footerIconId; + mMainHandler.post(mUpdateIcon); + } + mMainHandler.post(mUpdateDisplayState); + } + + protected CharSequence getFooterText(boolean isDeviceManaged, boolean hasWorkProfile, + boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled, + String vpnName, String vpnNameWorkProfile, CharSequence organizationName, + CharSequence workProfileName) { + if (isDeviceManaged) { + if (hasCACerts || hasCACertsInWorkProfile || isNetworkLoggingEnabled) { + if (organizationName == null) { + return mContext.getString( + R.string.quick_settings_disclosure_management_monitoring); + } + return mContext.getString( + R.string.quick_settings_disclosure_named_management_monitoring, + organizationName); } - mIsVisible = true; - int footerIconId = isVpnEnabled - ? R.drawable.ic_qs_vpn - : R.drawable.ic_qs_network_logging; - if (mFooterIconId != footerIconId) { - mFooterIconId = footerIconId; - mMainHandler.post(mUpdateIcon); + if (vpnName != null && vpnNameWorkProfile != null) { + if (organizationName == null) { + return mContext.getString(R.string.quick_settings_disclosure_management_vpns); + } + return mContext.getString(R.string.quick_settings_disclosure_named_management_vpns, + organizationName); } - } else { - boolean isBranded = mSecurityController.isVpnBranded(); - mFooterTextContent = mContext.getResources().getText( - isBranded ? R.string.branded_vpn_footer : R.string.vpn_footer); - // Update the VPN footer icon, if needed. - int footerIconId = isVpnEnabled - ? (isBranded ? R.drawable.ic_qs_branded_vpn : R.drawable.ic_qs_vpn) - : R.drawable.ic_qs_network_logging; - if (mFooterIconId != footerIconId) { - mFooterIconId = footerIconId; - mMainHandler.post(mUpdateIcon); + if (vpnName != null || vpnNameWorkProfile != null) { + if (organizationName == null) { + return mContext.getString( + R.string.quick_settings_disclosure_management_named_vpn, + vpnName != null ? vpnName : vpnNameWorkProfile); + } + return mContext.getString( + R.string.quick_settings_disclosure_named_management_named_vpn, + organizationName, + vpnName != null ? vpnName : vpnNameWorkProfile); } - mIsVisible = mIsIconVisible; + if (organizationName == null) { + return mContext.getString(R.string.quick_settings_disclosure_management); + } + return mContext.getString(R.string.quick_settings_disclosure_named_management, + organizationName); + } // end if(isDeviceManaged) + if (hasCACertsInWorkProfile) { + if (workProfileName == null) { + return mContext.getString( + R.string.quick_settings_disclosure_managed_profile_monitoring); + } + return mContext.getString( + R.string.quick_settings_disclosure_named_managed_profile_monitoring, + workProfileName); } - mMainHandler.post(mUpdateDisplayState); + if (hasCACerts) { + return mContext.getString(R.string.quick_settings_disclosure_monitoring); + } + if (vpnName != null && vpnNameWorkProfile != null) { + return mContext.getString(R.string.quick_settings_disclosure_vpns); + } + if (vpnNameWorkProfile != null) { + return mContext.getString(R.string.quick_settings_disclosure_managed_profile_named_vpn, + vpnNameWorkProfile); + } + if (vpnName != null) { + if (hasWorkProfile) { + return mContext.getString( + R.string.quick_settings_disclosure_personal_profile_named_vpn, + vpnName); + } + return mContext.getString(R.string.quick_settings_disclosure_named_vpn, + vpnName); + } + return null; } @Override @@ -182,18 +234,15 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic final String profileOwnerPackage = mSecurityController.getProfileOwnerName(); final boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled(); final String primaryVpn = mSecurityController.getPrimaryVpnName(); - final String profileVpn = mSecurityController.getProfileVpnName(); + final String profileVpn = mSecurityController.getWorkProfileVpnName(); final CharSequence deviceOwnerOrganization = mSecurityController.getDeviceOwnerOrganizationName(); boolean hasProfileOwner = mSecurityController.hasProfileOwner(); - boolean isBranded = deviceOwnerPackage == null && mSecurityController.isVpnBranded(); mDialog = new SystemUIDialog(mContext); - if (!isBranded) { - mDialog.setTitle(getTitle(deviceOwnerPackage)); - } + mDialog.setTitle(getTitle(deviceOwnerPackage)); CharSequence msg = getMessage(deviceOwnerPackage, profileOwnerPackage, primaryVpn, - profileVpn, deviceOwnerOrganization, hasProfileOwner, isBranded); + profileVpn, deviceOwnerOrganization, hasProfileOwner); if (deviceOwnerPackage == null) { mDialog.setMessage(msg); if (mSecurityController.isVpnEnabled() && !mSecurityController.isVpnRestricted()) { @@ -235,7 +284,7 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic } } - mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(isBranded), this); + mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this); mDialog.show(); mDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } @@ -244,13 +293,13 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic return mContext.getString(R.string.status_bar_settings_settings_button); } - private String getPositiveButton(boolean isBranded) { - return mContext.getString(isBranded ? android.R.string.ok : R.string.quick_settings_done); + private String getPositiveButton() { + return mContext.getString(R.string.quick_settings_done); } protected CharSequence getMessage(String deviceOwnerPackage, String profileOwnerPackage, String primaryVpn, String profileVpn, CharSequence deviceOwnerOrganization, - boolean hasProfileOwner, boolean isBranded) { + boolean hasProfileOwner) { if (deviceOwnerPackage != null) { final SpannableStringBuilder message = new SpannableStringBuilder(); if (deviceOwnerOrganization != null) { @@ -273,13 +322,8 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic return mContext.getString(R.string.monitoring_description_app_personal_work, profileOwnerPackage, profileVpn, primaryVpn); } else { - if (isBranded) { - return mContext.getString(R.string.branded_monitoring_description_app_personal, - primaryVpn); - } else { - return mContext.getString(R.string.monitoring_description_app_personal, - primaryVpn); - } + return mContext.getString(R.string.monitoring_description_app_personal, + primaryVpn); } } else if (profileVpn != null) { return mContext.getString(R.string.monitoring_description_app_work, @@ -305,7 +349,6 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic @Override public void run() { mFooterIcon.setImageResource(mFooterIconId); - mFooterIcon2.setImageResource(mFooterIcon2Id); } }; @@ -316,8 +359,7 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic mFooterText.setText(mFooterTextContent); } mRootView.setVisibility(mIsVisible ? View.VISIBLE : View.GONE); - mFooterIcon.setVisibility(mIsIconVisible ? View.VISIBLE : View.INVISIBLE); - mFooterIcon2.setVisibility(mIsIcon2Visible ? View.VISIBLE : View.INVISIBLE); + if (mDivider != null) mDivider.setVisibility(mIsVisible ? View.GONE : View.VISIBLE); } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java index 3f8e41ae39d5..1fb9b691d525 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java @@ -23,16 +23,20 @@ public interface SecurityController extends CallbackController<SecurityControlle /** Whether the device has device owner, even if not on this user. */ boolean isDeviceManaged(); boolean hasProfileOwner(); + boolean hasWorkProfile(); String getDeviceOwnerName(); String getProfileOwnerName(); CharSequence getDeviceOwnerOrganizationName(); + CharSequence getWorkProfileOrganizationName(); boolean isNetworkLoggingEnabled(); boolean isVpnEnabled(); boolean isVpnRestricted(); /** Whether the VPN app should use branded VPN iconography. */ boolean isVpnBranded(); String getPrimaryVpnName(); - String getProfileVpnName(); + String getWorkProfileVpnName(); + boolean hasCACertInCurrentUser(); + boolean hasCACertInWorkProfile(); void onUserSwitched(int newUserId); public interface SecurityControllerCallback { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 19ced235dc1e..fcb728939e88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -138,6 +138,13 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi } @Override + public CharSequence getWorkProfileOrganizationName() { + final int profileId = getWorkProfileUserId(mCurrentUserId); + if (profileId == UserHandle.USER_NULL) return null; + return mDevicePolicyManager.getOrganizationNameForUser(profileId); + } + + @Override public String getPrimaryVpnName() { VpnConfig cfg = mCurrentVpns.get(mVpnUserId); if (cfg != null) { @@ -147,17 +154,28 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi } } - @Override - public String getProfileVpnName() { - for (int profileId : mUserManager.getProfileIdsWithDisabled(mVpnUserId)) { - if (profileId == mVpnUserId) { - continue; - } - VpnConfig cfg = mCurrentVpns.get(profileId); - if (cfg != null) { - return getNameForVpnConfig(cfg, UserHandle.of(profileId)); + private int getWorkProfileUserId(int userId) { + for (final UserInfo userInfo : mUserManager.getProfiles(userId)) { + if (userInfo.isManagedProfile()) { + return userInfo.id; } } + return UserHandle.USER_NULL; + } + + @Override + public boolean hasWorkProfile() { + return getWorkProfileUserId(mCurrentUserId) != UserHandle.USER_NULL; + } + + @Override + public String getWorkProfileVpnName() { + final int profileId = getWorkProfileUserId(mVpnUserId); + if (profileId == UserHandle.USER_NULL) return null; + VpnConfig cfg = mCurrentVpns.get(profileId); + if (cfg != null) { + return getNameForVpnConfig(cfg, UserHandle.of(profileId)); + } return null; } @@ -199,6 +217,18 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi } @Override + public boolean hasCACertInCurrentUser() { + //TODO: implement + return false; + } + + @Override + public boolean hasCACertInWorkProfile() { + //TODO: implement + return false; + } + + @Override public void removeCallback(SecurityControllerCallback callback) { synchronized (mCallbacks) { if (callback == null) return; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java index 1ff373c95c14..ff644d8bb618 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java @@ -40,6 +40,15 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +/* + * Compile and run the whole SystemUI test suite: + runtest --path frameworks/base/packages/SystemUI/tests + * + * Compile and run just this class: + runtest --path \ + frameworks/base/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +*/ + @SmallTest @RunWith(AndroidJUnit4.class) public class QSSecurityFooterTest extends SysuiTestCase { @@ -47,11 +56,11 @@ public class QSSecurityFooterTest extends SysuiTestCase { private final String MANAGING_ORGANIZATION = "organization"; private final String DEVICE_OWNER_PACKAGE = "TestDPC"; private final String VPN_PACKAGE = "TestVPN"; + private final String VPN_PACKAGE_2 = "TestVPN 2"; private ViewGroup mRootView; private TextView mFooterText; private TestableImageView mFooterIcon; - private TestableImageView mFooterIcon2; private QSSecurityFooter mFooter; private SecurityController mSecurityController = mock(SecurityController.class); @@ -69,15 +78,12 @@ public class QSSecurityFooterTest extends SysuiTestCase { mRootView = (ViewGroup) mFooter.getView(); mFooterText = (TextView) mRootView.findViewById(R.id.footer_text); mFooterIcon = (TestableImageView) mRootView.findViewById(R.id.footer_icon); - mFooterIcon2 = (TestableImageView) mRootView.findViewById(R.id.footer_icon2); mFooter.setHostEnvironment(null); } @Test public void testUnmanaged() { when(mSecurityController.isDeviceManaged()).thenReturn(false); - when(mSecurityController.isVpnEnabled()).thenReturn(false); - when(mSecurityController.isVpnBranded()).thenReturn(false); mFooter.refreshState(); waitForIdleSync(mFooter.mHandler); @@ -91,8 +97,12 @@ public class QSSecurityFooterTest extends SysuiTestCase { mFooter.refreshState(); waitForIdleSync(mFooter.mHandler); - assertEquals(mContext.getString(R.string.do_disclosure_generic), mFooterText.getText()); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_management), + mFooterText.getText()); assertEquals(View.VISIBLE, mRootView.getVisibility()); + assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); + // -1 == never set. + assertEquals(-1, mFooterIcon.getLastImageResource()); } @Test @@ -103,37 +113,100 @@ public class QSSecurityFooterTest extends SysuiTestCase { mFooter.refreshState(); waitForIdleSync(mFooter.mHandler); - assertEquals(mContext.getString(R.string.do_disclosure_with_name, MANAGING_ORGANIZATION), + assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management, + MANAGING_ORGANIZATION), mFooterText.getText()); assertEquals(View.VISIBLE, mRootView.getVisibility()); + assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); + // -1 == never set. + assertEquals(-1, mFooterIcon.getLastImageResource()); } @Test public void testNetworkLoggingEnabled() { when(mSecurityController.isDeviceManaged()).thenReturn(true); when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); - when(mSecurityController.isVpnEnabled()).thenReturn(false); mFooter.refreshState(); waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), + mFooterText.getText()); assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); - assertEquals(R.drawable.ic_qs_network_logging, mFooterIcon.getLastImageResource()); - assertEquals(View.INVISIBLE, mFooterIcon2.getVisibility()); + // -1 == never set. + assertEquals(-1, mFooterIcon.getLastImageResource()); + + // Same situation, but with organization name set + when(mSecurityController.getDeviceOwnerOrganizationName()) + .thenReturn(MANAGING_ORGANIZATION); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString( + R.string.quick_settings_disclosure_named_management_monitoring, + MANAGING_ORGANIZATION), + mFooterText.getText()); } @Test - public void testVpnEnabled() { + public void testManagedCACertsInstalled() { + when(mSecurityController.isDeviceManaged()).thenReturn(true); + when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), + mFooterText.getText()); + } + + @Test + public void testManagedOneVpnEnabled() { when(mSecurityController.isDeviceManaged()).thenReturn(true); - when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(false); when(mSecurityController.isVpnEnabled()).thenReturn(true); - when(mSecurityController.isVpnBranded()).thenReturn(false); + when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); mFooter.refreshState(); waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_named_vpn, + VPN_PACKAGE), + mFooterText.getText()); assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); - // -1 == never set. - assertEquals(-1, mFooterIcon.getLastImageResource()); - assertEquals(View.INVISIBLE, mFooterIcon2.getVisibility()); + assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + + // Same situation, but with organization name set + when(mSecurityController.getDeviceOwnerOrganizationName()) + .thenReturn(MANAGING_ORGANIZATION); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString( + R.string.quick_settings_disclosure_named_management_named_vpn, + MANAGING_ORGANIZATION, VPN_PACKAGE), + mFooterText.getText()); + } + + @Test + public void testManagedTwoVpnsEnabled() { + when(mSecurityController.isDeviceManaged()).thenReturn(true); + when(mSecurityController.isVpnEnabled()).thenReturn(true); + when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); + when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_vpns), + mFooterText.getText()); + assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); + assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + + // Same situation, but with organization name set + when(mSecurityController.getDeviceOwnerOrganizationName()) + .thenReturn(MANAGING_ORGANIZATION); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management_vpns, + MANAGING_ORGANIZATION), + mFooterText.getText()); } @Test @@ -141,15 +214,101 @@ public class QSSecurityFooterTest extends SysuiTestCase { when(mSecurityController.isDeviceManaged()).thenReturn(true); when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); when(mSecurityController.isVpnEnabled()).thenReturn(true); - when(mSecurityController.isVpnBranded()).thenReturn(false); + when(mSecurityController.getPrimaryVpnName()).thenReturn("VPN Test App"); mFooter.refreshState(); waitForIdleSync(mFooter.mHandler); assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); - assertEquals(View.VISIBLE, mFooterIcon2.getVisibility()); + assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), + mFooterText.getText()); + } + + @Test + public void testWorkProfileCACertsInstalled() { + when(mSecurityController.isDeviceManaged()).thenReturn(false); + when(mSecurityController.hasCACertInWorkProfile()).thenReturn(true); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); // -1 == never set. assertEquals(-1, mFooterIcon.getLastImageResource()); - assertEquals(-1, mFooterIcon2.getLastImageResource()); + assertEquals(mContext.getString( + R.string.quick_settings_disclosure_managed_profile_monitoring), + mFooterText.getText()); + + // Same situation, but with organization name set + when(mSecurityController.getWorkProfileOrganizationName()) + .thenReturn(MANAGING_ORGANIZATION); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString( + R.string.quick_settings_disclosure_named_managed_profile_monitoring, + MANAGING_ORGANIZATION), + mFooterText.getText()); + } + + @Test + public void testCACertsInstalled() { + when(mSecurityController.isDeviceManaged()).thenReturn(false); + when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + // -1 == never set. + assertEquals(-1, mFooterIcon.getLastImageResource()); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_monitoring), + mFooterText.getText()); + } + + @Test + public void testTwoVpnsEnabled() { + when(mSecurityController.isVpnEnabled()).thenReturn(true); + when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); + when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_vpns), + mFooterText.getText()); + } + + @Test + public void testWorkProfileVpnEnabled() { + when(mSecurityController.isVpnEnabled()).thenReturn(true); + when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(mContext.getString( + R.string.quick_settings_disclosure_managed_profile_named_vpn, + VPN_PACKAGE_2), + mFooterText.getText()); + } + + @Test + public void testVpnEnabled() { + when(mSecurityController.isVpnEnabled()).thenReturn(true); + when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_vpn, + VPN_PACKAGE), + mFooterText.getText()); + + when(mSecurityController.hasWorkProfile()).thenReturn(true); + mFooter.refreshState(); + + waitForIdleSync(mFooter.mHandler); + assertEquals(mContext.getString( + R.string.quick_settings_disclosure_personal_profile_named_vpn, + VPN_PACKAGE), + mFooterText.getText()); } @Test @@ -160,8 +319,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { null /* primaryVpn */, null /* profileVpn */, null /* deviceOwnerOrganization */, - false /* hasProfileOwner */, - false /* isBranded */)); + false /* hasProfileOwner */)); } @Test @@ -172,8 +330,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { VPN_PACKAGE, null /* profileVpn */, null /* deviceOwnerOrganization */, - false /* hasProfileOwner */, - false /* isBranded */)); + false /* hasProfileOwner */)); } @Test @@ -184,8 +341,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { null /* primaryVpn */, null /* profileVpn */, MANAGING_ORGANIZATION, - false /* hasProfileOwner */, - false /* isBranded */)); + false /* hasProfileOwner */)); } @Test @@ -196,8 +352,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { VPN_PACKAGE, null /* profileVpn */, MANAGING_ORGANIZATION, - false /* hasProfileOwner */, - false /* isBranded */)); + false /* hasProfileOwner */)); } private CharSequence getExpectedMessage(boolean hasDeviceOwnerOrganization, boolean hasVPN) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java index 157b8a04720b..fee5e32398c4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java @@ -36,6 +36,11 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa } @Override + public boolean hasWorkProfile() { + return false; + } + + @Override public String getDeviceOwnerName() { return null; } @@ -51,6 +56,11 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa } @Override + public CharSequence getWorkProfileOrganizationName() { + return null; + } + + @Override public boolean isNetworkLoggingEnabled() { return false; } @@ -76,11 +86,21 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa } @Override - public String getProfileVpnName() { + public String getWorkProfileVpnName() { return null; } @Override + public boolean hasCACertInCurrentUser() { + return false; + } + + @Override + public boolean hasCACertInWorkProfile() { + return false; + } + + @Override public void onUserSwitched(int newUserId) { } |