From d36b7acceded332bc7701695c4d5096937f403ca Mon Sep 17 00:00:00 2001 From: Beverly Date: Wed, 17 Feb 2021 10:13:23 -0500 Subject: [PATCH 1/2] Add test to allow icon-only messages For the KeyguardIndication Test: atest KeyguardIndicationTest Fixes: 180101407 Change-Id: Ie46d630d87f2a566d3b480efe173b15109b4d7ca --- .../systemui/keyguard/KeyguardIndication.java | 24 +++- ...ardIndicationRotateTextViewController.java | 8 +- .../keyguard/KeyguardIndicationTest.java | 110 ++++++++++++++++++ 3 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationTest.java diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java index d65d169511918..2873cd36409db 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; +import android.text.TextUtils; import android.view.View; /** @@ -56,7 +57,7 @@ public class KeyguardIndication { /** * Message to display */ - public @NonNull CharSequence getMessage() { + public @Nullable CharSequence getMessage() { return mMessage; } @@ -88,6 +89,17 @@ public class KeyguardIndication { return mBackground; } + @Override + public String toString() { + String str = "KeyguardIndication{"; + if (!TextUtils.isEmpty(mMessage)) str += "mMessage=" + mMessage; + if (mIcon != null) str += " mIcon=" + mIcon; + if (mOnClickListener != null) str += " mOnClickListener=" + mOnClickListener; + if (mBackground != null) str += " mBackground=" + mBackground; + str += "}"; + return str; + } + /** * KeyguardIndication Builder */ @@ -101,7 +113,7 @@ public class KeyguardIndication { public Builder() { } /** - * Required field. Message to display. + * Message to display. Indication requires a non-null message or icon. */ public Builder setMessage(@NonNull CharSequence message) { this.mMessage = message; @@ -117,9 +129,9 @@ public class KeyguardIndication { } /** - * Optional. Icon to show next to the text. Icon location changes based on language - * display direction. For LTR, icon shows to the left of the message. For RTL, icon shows - * to the right of the message. + * Icon to show next to the text. Indication requires a non-null icon or message. + * Icon location changes based on language display direction. For LTR, icon shows to the + * left of the message. For RTL, icon shows to the right of the message. */ public Builder setIcon(Drawable icon) { this.mIcon = icon; @@ -146,7 +158,7 @@ public class KeyguardIndication { * Build the KeyguardIndication. */ public KeyguardIndication build() { - if (mMessage == null && mIcon == null) { + if (TextUtils.isEmpty(mMessage) && mIcon == null) { throw new IllegalStateException("message or icon must be set"); } if (mTextColor == null) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java index 2e599de1970d6..d4678f39e404e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java @@ -19,7 +19,6 @@ package com.android.systemui.keyguard; import android.annotation.Nullable; import android.content.res.ColorStateList; import android.graphics.Color; -import android.text.TextUtils; import android.view.View; import androidx.annotation.IntDef; @@ -105,9 +104,7 @@ public class KeyguardIndicationRotateTextViewController extends public void updateIndication(@IndicationType int type, KeyguardIndication newIndication, boolean showImmediately) { final boolean hasPreviousIndication = mIndicationMessages.get(type) != null; - final boolean hasNewIndication = newIndication != null - && (!TextUtils.isEmpty(newIndication.getMessage()) - || newIndication.getIcon() != null); + final boolean hasNewIndication = newIndication != null; if (!hasNewIndication) { mIndicationMessages.remove(type); mIndicationQueue.removeIf(x -> x == type); @@ -289,8 +286,7 @@ public class KeyguardIndicationRotateTextViewController extends if (hasIndications()) { pw.println(" All messages:"); for (int type : mIndicationMessages.keySet()) { - pw.println(" type=" + type - + " message=" + mIndicationMessages.get(type).getMessage()); + pw.println(" type=" + type + " " + mIndicationMessages.get(type)); } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationTest.java new file mode 100644 index 0000000000000..b44fb8e61c32d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2021 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.keyguard; + +import static android.graphics.Color.WHITE; + +import static org.junit.Assert.assertEquals; + +import android.content.res.ColorStateList; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.drawable.Drawable; +import android.testing.AndroidTestingRunner; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidTestingRunner.class) +@SmallTest +public class KeyguardIndicationTest extends SysuiTestCase { + + @Test(expected = IllegalStateException.class) + public void testCannotCreateIndicationWithoutMessageOrIcon() { + new KeyguardIndication.Builder() + .setTextColor(ColorStateList.valueOf(WHITE)) + .build(); + } + + @Test(expected = IllegalStateException.class) + public void testCannotCreateIndicationWithoutColor() { + new KeyguardIndication.Builder() + .setMessage("message") + .build(); + } + + @Test(expected = IllegalStateException.class) + public void testCannotCreateIndicationWithEmptyMessage() { + new KeyguardIndication.Builder() + .setMessage("") + .setTextColor(ColorStateList.valueOf(WHITE)) + .build(); + } + + @Test + public void testCreateIndicationWithMessage() { + final String text = "regular indication"; + final KeyguardIndication indication = new KeyguardIndication.Builder() + .setMessage(text) + .setTextColor(ColorStateList.valueOf(WHITE)) + .build(); + assertEquals(text, indication.getMessage()); + } + + @Test + public void testCreateIndicationWithIcon() { + final KeyguardIndication indication = new KeyguardIndication.Builder() + .setIcon(mDrawable) + .setTextColor(ColorStateList.valueOf(WHITE)) + .build(); + assertEquals(mDrawable, indication.getIcon()); + } + + @Test + public void testCreateIndicationWithMessageAndIcon() { + final String text = "indication with msg and icon"; + final KeyguardIndication indication = new KeyguardIndication.Builder() + .setMessage(text) + .setIcon(mDrawable) + .setTextColor(ColorStateList.valueOf(WHITE)) + .build(); + assertEquals(text, indication.getMessage()); + assertEquals(mDrawable, indication.getIcon()); + } + + final Drawable mDrawable = new Drawable() { + @Override + public void draw(@NonNull Canvas canvas) { } + + @Override + public void setAlpha(int alpha) { } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { } + + @Override + public int getOpacity() { + return 0; + } + }; +} From 3c6fcb412e4ddeb80811be068e2051f509950b42 Mon Sep 17 00:00:00 2001 From: Beverly Date: Wed, 17 Feb 2021 10:29:55 -0500 Subject: [PATCH 2/2] Update owner info with other keyguard indications Also update the logout view with the other keyguard indications. We still update the disclosure indication separately since we don't want to trigger an IPC call each update. Test: manual Fixes: 180325775 Change-Id: Ibf5f349c80a771d8b33184dde71811137c808f3d --- .../KeyguardIndicationController.java | 96 ++++++++++--------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index c70a93b5c8947..7e2d27ac728aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -208,7 +208,6 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal mLockScreenMode); updateIndication(false /* animate */); updateDisclosure(); - updateOwnerInfo(); if (mBroadcastReceiver == null) { // Update the disclosure proactively to avoid IPC on the critical path. mBroadcastReceiver = new BroadcastReceiver() { @@ -261,18 +260,21 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal } /** - * Doesn't include owner information or disclosure which get triggered separately. + * Doesn't include disclosure which gets triggered separately. */ private void updateIndications(boolean animate, int userId) { + updateOwnerInfo(); updateBattery(animate); updateUserLocked(userId); updateTransient(); updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication()); updateAlignment(); + updateLogoutView(); updateResting(); } private void updateDisclosure() { + // avoid calling this method since it has an IPC if (whitelistIpcs(this::isOrganizationOwnedDevice)) { final CharSequence organizationName = getOrganizationOwnedDeviceOrganizationName(); final CharSequence disclosure = organizationName != null @@ -291,7 +293,34 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal } if (isKeyguardLayoutEnabled()) { - updateIndication(false); // resting indication may need to update + updateResting(); + } + } + + private void updateOwnerInfo() { + if (!isKeyguardLayoutEnabled()) { + mRotateTextViewController.hideIndication(INDICATION_TYPE_OWNER_INFO); + return; + } + String info = mLockPatternUtils.getDeviceOwnerInfo(); + if (info == null) { + // Use the current user owner information if enabled. + final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled( + KeyguardUpdateMonitor.getCurrentUser()); + if (ownerInfoEnabled) { + info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser()); + } + } + if (info != null) { + mRotateTextViewController.updateIndication( + INDICATION_TYPE_OWNER_INFO, + new KeyguardIndication.Builder() + .setMessage(info) + .setTextColor(mInitialTextColorState) + .build(), + false); + } else { + mRotateTextViewController.hideIndication(INDICATION_TYPE_OWNER_INFO); } } @@ -400,56 +429,34 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal private void updateLogoutView() { if (!isKeyguardLayoutEnabled()) { + mRotateTextViewController.hideIndication(INDICATION_TYPE_LOGOUT); return; } final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled() && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM; - String logoutString = shouldShowLogout ? mContext.getResources().getString( - com.android.internal.R.string.global_action_logout) : null; - mRotateTextViewController.updateIndication( - INDICATION_TYPE_LOGOUT, - new KeyguardIndication.Builder() - .setMessage(logoutString) - .setTextColor(mInitialTextColorState) - .setBackground(mContext.getDrawable( - com.android.systemui.R.drawable.logout_button_background)) - .setClickListener((view) -> { - int currentUserId = KeyguardUpdateMonitor.getCurrentUser(); - try { - mIActivityManager.switchUser(UserHandle.USER_SYSTEM); - mIActivityManager.stopUser(currentUserId, true /* force */, null); - } catch (RemoteException re) { - Log.e(TAG, "Failed to logout user", re); - } - }) - .build(), - false); - updateIndication(false); // resting indication may need to update - } - - private void updateOwnerInfo() { - if (!isKeyguardLayoutEnabled()) { - return; - } - String info = mLockPatternUtils.getDeviceOwnerInfo(); - if (info == null) { - // Use the current user owner information if enabled. - final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled( - KeyguardUpdateMonitor.getCurrentUser()); - if (ownerInfoEnabled) { - info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser()); - } - } - if (info != null) { + if (shouldShowLogout) { mRotateTextViewController.updateIndication( - INDICATION_TYPE_OWNER_INFO, + INDICATION_TYPE_LOGOUT, new KeyguardIndication.Builder() - .setMessage(info) + .setMessage(mContext.getResources().getString( + com.android.internal.R.string.global_action_logout)) .setTextColor(mInitialTextColorState) + .setBackground(mContext.getDrawable( + com.android.systemui.R.drawable.logout_button_background)) + .setClickListener((view) -> { + int currentUserId = KeyguardUpdateMonitor.getCurrentUser(); + try { + mIActivityManager.switchUser(UserHandle.USER_SYSTEM); + mIActivityManager.stopUser(currentUserId, true /* force */, + null); + } catch (RemoteException re) { + Log.e(TAG, "Failed to logout user", re); + } + }) .build(), false); } else { - updateIndication(false); // resting indication may need to update + mRotateTextViewController.hideIndication(INDICATION_TYPE_LOGOUT); } } @@ -1042,7 +1049,6 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal @Override public void onUserSwitchComplete(int userId) { if (mVisible) { - updateOwnerInfo(); updateIndication(false); } } @@ -1057,7 +1063,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal @Override public void onLogoutEnabledChanged() { if (mVisible) { - updateLogoutView(); + updateIndication(false); } }