diff options
8 files changed, 250 insertions, 21 deletions
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 444f0f016b85..078f9d73ffec 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -24,17 +24,36 @@ android:outlineProvider="none" android:elevation="5dp" > <!-- Put it above the status bar header --> - <com.android.systemui.statusbar.phone.KeyguardIndicationTextView - android:id="@+id/keyguard_indication_text" + <LinearLayout + android:id="@+id/keyguard_indication_area" + android:forceHasOverlappingRendering="false" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" android:layout_gravity="bottom|center_horizontal" - android:gravity="center_horizontal" - android:textStyle="italic" - android:textColor="#ffffff" - android:textAppearance="?android:attr/textAppearanceSmall" - android:accessibilityLiveRegion="polite" /> + android:orientation="vertical"> + + <com.android.systemui.statusbar.phone.KeyguardIndicationTextView + android:id="@+id/keyguard_indication_enterprise_disclosure" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:textStyle="italic" + android:textColor="#ffffff" + android:textAppearance="?android:attr/textAppearanceSmall" + android:visibility="gone" /> + + <com.android.systemui.statusbar.phone.KeyguardIndicationTextView + android:id="@+id/keyguard_indication_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:textStyle="italic" + android:textColor="#ffffff" + android:textAppearance="?android:attr/textAppearanceSmall" + android:accessibilityLiveRegion="polite" /> + + </LinearLayout> <FrameLayout android:id="@+id/preview_container" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 5fec64777a05..af1fc593cccc 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -840,6 +840,12 @@ <!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] --> <string name="keyguard_unlock">Swipe up to unlock</string> + <!-- Text on keyguard screen indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] --> + <string name="do_disclosure_generic">This device is managed</string> + + <!-- Text on keyguard screen indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=40] --> + <string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string> + <!-- Shows when people have clicked on the phone icon [CHAR LIMIT=60] --> <string name="phone_hint">Swipe from icon for phone</string> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 0ef9715259c2..218c1bbae48c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import android.app.ActivityManager; +import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -36,6 +37,7 @@ import android.text.TextUtils; import android.text.format.Formatter; import android.util.Log; import android.view.View; +import android.view.ViewGroup; import com.android.internal.app.IBatteryStats; import com.android.keyguard.KeyguardUpdateMonitor; @@ -58,7 +60,9 @@ public class KeyguardIndicationController { private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300; private final Context mContext; + private final ViewGroup mIndicationArea; private final KeyguardIndicationTextView mTextView; + private final KeyguardIndicationTextView mDisclosure; private final UserManager mUserManager; private final IBatteryStats mBatteryInfo; @@ -78,10 +82,16 @@ public class KeyguardIndicationController { private int mChargingWattage; private String mMessageToShowOnScreenOn; - public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView, - LockIcon lockIcon) { + private final DevicePolicyManager mDevicePolicyManager; + + public KeyguardIndicationController(Context context, ViewGroup indicationArea, + LockIcon lockIcon) { mContext = context; - mTextView = textView; + mIndicationArea = indicationArea; + mTextView = (KeyguardIndicationTextView) indicationArea.findViewById( + R.id.keyguard_indication_text); + mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById( + R.id.keyguard_indication_enterprise_disclosure); mLockIcon = lockIcon; Resources res = context.getResources(); @@ -92,14 +102,39 @@ public class KeyguardIndicationController { mBatteryInfo = IBatteryStats.Stub.asInterface( ServiceManager.getService(BatteryStats.SERVICE_NAME)); + mDevicePolicyManager = (DevicePolicyManager) context.getSystemService( + Context.DEVICE_POLICY_SERVICE); + KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitor); context.registerReceiverAsUser(mTickReceiver, UserHandle.SYSTEM, new IntentFilter(Intent.ACTION_TIME_TICK), null, null); + + updateDisclosure(); + } + + private void updateDisclosure() { + if (mDevicePolicyManager == null) { + return; + } + + if (mDevicePolicyManager.isDeviceManaged()) { + final CharSequence organizationName = + mDevicePolicyManager.getDeviceOwnerOrganizationName(); + if (organizationName != null) { + mDisclosure.switchIndication(mContext.getResources().getString( + R.string.do_disclosure_with_name, organizationName)); + } else { + mDisclosure.switchIndication(R.string.do_disclosure_generic); + } + mDisclosure.setVisibility(View.VISIBLE); + } else { + mDisclosure.setVisibility(View.GONE); + } } public void setVisible(boolean visible) { mVisible = visible; - mTextView.setVisibility(visible ? View.VISIBLE : View.GONE); + mIndicationArea.setVisibility(visible ? View.VISIBLE : View.GONE); if (visible) { hideTransientIndication(); updateIndication(); @@ -242,6 +277,13 @@ public class KeyguardIndicationController { } @Override + public void onKeyguardVisibilityChanged(boolean showing) { + if (showing) { + updateDisclosure(); + } + } + + @Override public void onFingerprintHelp(int msgId, String helpString) { KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); if (!updateMonitor.isUnlockingWithFingerprintAllowed()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 89defec6f94c..daa57c63ad9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -107,6 +107,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private KeyguardAffordanceView mRightAffordanceView; private KeyguardAffordanceView mLeftAffordanceView; private LockIcon mLockIcon; + private ViewGroup mIndicationArea; + private TextView mEnterpriseDisclosure; private TextView mIndicationText; private ViewGroup mPreviewContainer; @@ -208,6 +210,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mRightAffordanceView = (KeyguardAffordanceView) findViewById(R.id.camera_button); mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button); mLockIcon = (LockIcon) findViewById(R.id.lock_icon); + mIndicationArea = (ViewGroup) findViewById(R.id.keyguard_indication_area); + mEnterpriseDisclosure = (TextView) findViewById( + R.id.keyguard_indication_enterprise_disclosure); mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text); watchForCameraPolicyChanges(); updateCameraVisibility(); @@ -252,13 +257,16 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL super.onConfigurationChanged(newConfig); int indicationBottomMargin = getResources().getDimensionPixelSize( R.dimen.keyguard_indication_margin_bottom); - MarginLayoutParams mlp = (MarginLayoutParams) mIndicationText.getLayoutParams(); + MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams(); if (mlp.bottomMargin != indicationBottomMargin) { mlp.bottomMargin = indicationBottomMargin; - mIndicationText.setLayoutParams(mlp); + mIndicationArea.setLayoutParams(mlp); } // Respect font size setting. + mEnterpriseDisclosure.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize( + com.android.internal.R.dimen.text_size_small_material)); mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize( com.android.internal.R.dimen.text_size_small_material)); @@ -595,8 +603,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL return mLockIcon; } - public View getIndicationView() { - return mIndicationText; + public View getIndicationArea() { + return mIndicationArea; } @Override @@ -658,8 +666,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL if (mRightAffordanceView.getVisibility() == View.VISIBLE) { startFinishDozeAnimationElement(mRightAffordanceView, delay); } - mIndicationText.setAlpha(0f); - mIndicationText.animate() + mIndicationArea.setAlpha(0f); + mIndicationArea.animate() .alpha(1f) .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN) .setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 570d5d40064f..f16c8346d1b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -1006,14 +1006,14 @@ public abstract class PanelView extends FrameLayout { }); animator.start(); mHeightAnimator = animator; - mKeyguardBottomArea.getIndicationView().animate() + mKeyguardBottomArea.getIndicationArea().animate() .translationY(-mHintDistance) .setDuration(250) .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) .withEndAction(new Runnable() { @Override public void run() { - mKeyguardBottomArea.getIndicationView().animate() + mKeyguardBottomArea.getIndicationArea().animate() .translationY(0) .setDuration(450) .setInterpolator(mBounceInterpolator) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 2a5fc6eabcb0..2b74c84759e5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -857,8 +857,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mKeyguardBottomArea.setActivityStarter(this); mKeyguardBottomArea.setAssistManager(mAssistManager); mKeyguardIndicationController = new KeyguardIndicationController(mContext, - (KeyguardIndicationTextView) mStatusBarWindow.findViewById( - R.id.keyguard_indication_text), + (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area), mKeyguardBottomArea.getLockIcon()); mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController); diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml index 6e17cf404854..b03189cb77ce 100644 --- a/packages/SystemUI/tests/AndroidManifest.xml +++ b/packages/SystemUI/tests/AndroidManifest.xml @@ -26,6 +26,7 @@ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE" /> + <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" /> <application> <uses-library android:name="android.test.runner" /> diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java new file mode 100644 index 000000000000..639c8daf586b --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -0,0 +1,154 @@ +/* + * 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 + */ + +package com.android.systemui.statusbar; + +import android.app.admin.DevicePolicyManager; +import android.app.trust.TrustManager; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.Looper; +import android.support.test.runner.AndroidJUnit4; +import android.telephony.SubscriptionManager; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.View; +import android.view.ViewGroup; + +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.phone.KeyguardIndicationTextView; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class KeyguardIndicationControllerTest extends SysuiTestCase { + + private final String ORGANIZATION_NAME = "organization"; + private final String DISCLOSURE_WITH_ORGANIZATION_NAME = "managed by organization"; + + private Context mContext = mock(Context.class); + private DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class); + private ViewGroup mIndicationArea = mock(ViewGroup.class); + private KeyguardIndicationTextView mDisclosure = mock(KeyguardIndicationTextView.class); + + private KeyguardIndicationController mController; + + @Before + public void setUp() throws Exception { + final Resources resources = mock(Resources.class); + when(mContext.getResources()).thenReturn(resources); + when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class)); + when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class)); + when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)).thenReturn( + mock(SubscriptionManager.class)); + when(mContext.getSystemService(Context.TRUST_SERVICE)).thenReturn( + mock(TrustManager.class)); + when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn( + mDevicePolicyManager); + + when(resources.getString(R.string.do_disclosure_with_name, ORGANIZATION_NAME)) + .thenReturn(DISCLOSURE_WITH_ORGANIZATION_NAME); + + when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure)) + .thenReturn(mDisclosure); + } + + private void createController() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + mController = new KeyguardIndicationController(mContext, mIndicationArea, null); + } + + @Test + public void unmanaged() { + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false); + createController(); + + verify(mDisclosure).setVisibility(View.GONE); + verifyNoMoreInteractions(mDisclosure); + } + + @Test + public void managedNoOwnerName() { + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); + when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null); + createController(); + + verify(mDisclosure).setVisibility(View.VISIBLE); + verify(mDisclosure).switchIndication(R.string.do_disclosure_generic); + verifyNoMoreInteractions(mDisclosure); + } + + @Test + public void managedOwnerName() { + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); + when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME); + createController(); + + verify(mDisclosure).setVisibility(View.VISIBLE); + verify(mDisclosure).switchIndication(DISCLOSURE_WITH_ORGANIZATION_NAME); + verifyNoMoreInteractions(mDisclosure); + } + + @Test + public void updateOnTheFly() { + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false); + createController(); + + final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); + reset(mDisclosure); + + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); + when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null); + monitor.onKeyguardVisibilityChanged(true); + + verify(mDisclosure).setVisibility(View.VISIBLE); + verify(mDisclosure).switchIndication(R.string.do_disclosure_generic); + verifyNoMoreInteractions(mDisclosure); + reset(mDisclosure); + + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); + when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME); + monitor.onKeyguardVisibilityChanged(false); + monitor.onKeyguardVisibilityChanged(true); + + verify(mDisclosure).setVisibility(View.VISIBLE); + verify(mDisclosure).switchIndication(DISCLOSURE_WITH_ORGANIZATION_NAME); + verifyNoMoreInteractions(mDisclosure); + reset(mDisclosure); + + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false); + monitor.onKeyguardVisibilityChanged(false); + monitor.onKeyguardVisibilityChanged(true); + + verify(mDisclosure).setVisibility(View.GONE); + verifyNoMoreInteractions(mDisclosure); + } +} |