Merge "Add extra debug logging" into udc-dev
diff --git a/core/java/android/service/notification/TEST_MAPPING b/core/java/android/service/notification/TEST_MAPPING
new file mode 100644
index 0000000..59b2bc1
--- /dev/null
+++ b/core/java/android/service/notification/TEST_MAPPING
@@ -0,0 +1,49 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsNotificationTestCases",
+ "options": [
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.LargeTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksUiServicesTests",
+ "options": [
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.LargeTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsNotificationTestCases"
+ }
+ ]
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 9fcd207..e1a3f3a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -55,6 +55,7 @@
import android.util.IntProperty;
import android.util.Log;
import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -459,7 +460,9 @@
if (mManageButton != null) {
int visibility = mManageButton.getVisibility();
removeView(mManageButton);
- mManageButton = (AlphaOptimizedButton) LayoutInflater.from(getContext()).inflate(
+ ContextThemeWrapper ctw = new ContextThemeWrapper(getContext(),
+ com.android.internal.R.style.Theme_DeviceDefault_DayNight);
+ mManageButton = (AlphaOptimizedButton) LayoutInflater.from(ctw).inflate(
R.layout.bubble_manage_button, this /* parent */, false /* attach */);
addView(mManageButton);
mManageButton.setVisibility(visibility);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 32680da..38bb447 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -359,6 +359,51 @@
codec to use a previously created {@linkplain #createPersistentInputSurface persistent input
surface} by calling {@link #setInputSurface}.
+ <h4 id=EncoderProfiles><a name="EncoderProfiles"></a>Encoder Profiles</h4>
+ <p>
+ When using an encoder, it is recommended to set the desired codec {@link MediaFormat#KEY_PROFILE
+ profile} during {@link #configure configure()}. (This is only meaningful for
+ {@link MediaFormat#KEY_MIME media formats} for which profiles are defined.)
+ <p>
+ If a profile is not specified during {@code configure}, the encoder will choose a profile for the
+ session based on the available information. We will call this value the <i>default profile</i>.
+ The selection of the default profile is device specific and may not be deterministic
+ (could be ad hoc or even experimental). The encoder may choose a default profile that is not
+ suitable for the intended encoding session, which may result in the encoder ultimately rejecting
+ the session.
+ <p>
+ The encoder may reject the encoding session if the configured (or default if unspecified) profile
+ does not support the codec input (mainly the {@link MediaFormat#KEY_COLOR_FORMAT color format} for
+ video/image codecs, or the {@link MediaFormat#KEY_PCM_ENCODING sample encoding} and the {@link
+ MediaFormat#KEY_CHANNEL_COUNT number of channels} for audio codecs, but also possibly
+ {@link MediaFormat#KEY_WIDTH width}, {@link MediaFormat#KEY_HEIGHT height},
+ {@link MediaFormat#KEY_FRAME_RATE frame rate}, {@link MediaFormat#KEY_BIT_RATE bitrate} or
+ {@link MediaFormat#KEY_SAMPLE_RATE sample rate}.)
+ Alternatively, the encoder may choose to (but is not required to) convert the input to support the
+ selected (or default) profile - or adjust the chosen profile based on the presumed or detected
+ input format - to ensure a successful encoding session. <b>Note</b>: Converting the input to match
+ an incompatible profile will in most cases result in decreased codec performance.
+ <p>
+ To ensure backward compatibility, the following guarantees are provided by Android:
+ <ul>
+ <li>The default video encoder profile always supports 8-bit YUV 4:2:0 color format ({@link
+ CodecCapabilities#COLOR_FormatYUV420Flexible COLOR_FormatYUV420Flexible} and equivalent
+ {@link CodecCapabilities#colorFormats supported formats}) for both Surface and ByteBuffer modes.
+ <li>The default video encoder profile always supports the default 8-bit RGBA color format in
+ Surface mode even if no such formats are enumerated in the {@link CodecCapabilities#colorFormats
+ supported formats}.
+ </ul>
+ <p class=note>
+ <b>Note</b>: the accepted profile can be queried through the {@link #getOutputFormat output
+ format} of the encoder after {@code configure} to allow applications to set up their
+ codec input to a format supported by the encoder profile.
+ <p>
+ <b>Implication:</b>
+ <ul>
+ <li>Applications that want to encode 4:2:2, 4:4:4, 10+ bit or HDR video input <b>MUST</b> configure
+ a suitable profile for encoders.
+ </ul>
+
<h4 id=CSD><a name="CSD"></a>Codec-specific Data</h4>
<p>
Some formats, notably AAC audio and MPEG4, H.264 and H.265 video formats require the actual data
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index b1b7d40..46db777 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -1136,11 +1136,14 @@
* may fail if other parameters are not compatible with the desired
* profile or if the desired profile is not supported, but it may also
* fail silently (where the encoder ends up using a different, compatible profile.)
+ * <p>
+ * It is recommended that the profile is set for all encoders. For more information, see
+ * the <i>Encoder Profiles</i> section of the {@link MediaCodec} API reference.
* <p class="note">
* <strong>Note:</strong> Codecs are free to use all the available
* coding tools at the specified profile, but may ultimately choose to not do so.
* <p class="note">
- * <strong>Note:</strong> When configuring video encoders, profile must be
+ * <strong>Note:</strong> When configuring video encoders, profile (if set) must be
* set together with {@link #KEY_LEVEL level}.
*
* @see MediaCodecInfo.CodecCapabilities#profileLevels
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 2dafbcb..a78509d 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -66,8 +66,9 @@
)
val originName: String? = when (requestInfo?.type) {
- RequestInfo.TYPE_CREATE -> requestInfo.createCredentialRequest?.origin
- RequestInfo.TYPE_GET -> requestInfo.getCredentialRequest?.origin
+ RequestInfo.TYPE_CREATE -> processHttpsOrigin(
+ requestInfo.createCredentialRequest?.origin)
+ RequestInfo.TYPE_GET -> processHttpsOrigin(requestInfo.getCredentialRequest?.origin)
else -> null
}
@@ -247,6 +248,9 @@
}
companion object {
+ private const val HTTPS = "https://"
+ private const val FORWARD_SLASH = "/"
+
fun sendCancellationCode(
cancelCode: Int,
requestToken: IBinder?,
@@ -266,5 +270,17 @@
CancelUiRequest::class.java
)
}
+
+ /** Removes "https://", and the trailing slash if present for an https request. */
+ private fun processHttpsOrigin(origin: String?): String? {
+ var processed = origin
+ if (processed?.startsWith(HTTPS) == true) { // Removes "https://"
+ processed = processed.substring(HTTPS.length)
+ if (processed?.endsWith(FORWARD_SLASH) == true) { // Removes the trailing slash
+ processed = processed.substring(0, processed.length - 1)
+ }
+ }
+ return processed
+ }
}
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
index 519ae0a..e050604 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
@@ -148,11 +148,11 @@
*/
val isEnabled: Boolean = true,
/**
- * If the affordance is disabled, this is a set of instruction messages to be shown to the
- * user when the disabled affordance is selected. The instructions should help the user
- * figure out what to do in order to re-neable this affordance.
+ * If the affordance is disabled, this is the explanation to be shown to the user when the
+ * disabled affordance is selected. The instructions should help the user figure out what to
+ * do in order to re-neable this affordance.
*/
- val enablementInstructions: List<String>? = null,
+ val enablementExplanation: String? = null,
/**
* If the affordance is disabled, this is a label for a button shown together with the set
* of instruction messages when the disabled affordance is selected. The button should help
@@ -326,10 +326,10 @@
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
.IS_ENABLED
)
- val enablementInstructionsColumnIndex =
+ val enablementExplanationColumnIndex =
cursor.getColumnIndex(
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
- .ENABLEMENT_INSTRUCTIONS
+ .ENABLEMENT_EXPLANATION
)
val enablementActionTextColumnIndex =
cursor.getColumnIndex(
@@ -351,7 +351,7 @@
nameColumnIndex == -1 ||
iconColumnIndex == -1 ||
isEnabledColumnIndex == -1 ||
- enablementInstructionsColumnIndex == -1 ||
+ enablementExplanationColumnIndex == -1 ||
enablementActionTextColumnIndex == -1 ||
enablementActionIntentColumnIndex == -1 ||
configureIntentColumnIndex == -1
@@ -367,13 +367,8 @@
name = cursor.getString(nameColumnIndex),
iconResourceId = cursor.getInt(iconColumnIndex),
isEnabled = cursor.getInt(isEnabledColumnIndex) == 1,
- enablementInstructions =
- cursor
- .getString(enablementInstructionsColumnIndex)
- ?.split(
- Contract.LockScreenQuickAffordances.AffordanceTable
- .ENABLEMENT_INSTRUCTIONS_DELIMITER
- ),
+ enablementExplanation =
+ cursor.getString(enablementExplanationColumnIndex),
enablementActionText =
cursor.getString(enablementActionTextColumnIndex),
enablementActionIntent =
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
index 7f5fb25..b6d5ef3 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -81,7 +81,6 @@
const val TABLE_NAME = "affordances"
val URI: Uri =
LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
- const val ENABLEMENT_INSTRUCTIONS_DELIMITER = "]["
object Columns {
/** String. Unique ID for this affordance. */
@@ -96,11 +95,10 @@
/** Integer. `1` if the affordance is enabled or `0` if it disabled. */
const val IS_ENABLED = "is_enabled"
/**
- * String. List of strings, delimited by [ENABLEMENT_INSTRUCTIONS_DELIMITER] to be
- * shown to the user if the affordance is disabled and the user selects the
- * affordance.
+ * String. Text to be shown to the user if the affordance is disabled and the user
+ * selects the affordance.
*/
- const val ENABLEMENT_INSTRUCTIONS = "enablement_instructions"
+ const val ENABLEMENT_EXPLANATION = "enablement_explanation"
/**
* String. Optional label for a button that, when clicked, opens a destination
* activity where the user can re-enable the disabled affordance.
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e779672..663efea 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3016,52 +3016,54 @@
-->
<string name="keyguard_affordance_enablement_dialog_action_template">Open <xliff:g id="appName" example="Wallet">%1$s</xliff:g></string>
- <!--
- Requirement for the wallet app to be available for the user to use. This is shown as part of a
- bulleted list of requirements. When all requirements are met, the app can be accessed through a
- shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ <!---
+ Explains that the wallet app is not available because it is not installed. This is shown as part
+ of a dialog that explains to the user why they cannot select this shortcut for their lock screen
+ right now.
+ [CHAR LIMIT=NONE].
-->
- <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1">• The app is set up</string>
+ <string name="wallet_quick_affordance_unavailable_install_the_app">To add the Wallet app as a shortcut, make sure the app is installed</string>
- <!--
- Requirement for the wallet app to be available for the user to use. This is shown as part of a
- bulleted list of requirements. When all requirements are met, the app can be accessed through a
- shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ <!---
+ Explains that the wallet app is not available because it is not installed. This is shown as part
+ of a dialog that explains to the user why they cannot select this shortcut for their lock screen
+ right now.
+ [CHAR LIMIT=NONE].
-->
- <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2">• At least one card has been added to Wallet</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app">To add the Wallet app as a shortcut, make sure at least one card has been added</string>
<!--
Requirement for the QR code scanner functionality to be available for the user to use. This is
shown as part of a bulleted list of requirements. When all requirements are met, the piece of
functionality can be accessed through a shortcut button on the lock screen. [CHAR LIMIT=NONE].
-->
- <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction">• Install a camera app</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation">To add the QR code scanner as a shortcut, make sure a camera app is installed</string>
<!--
- Requirement for the home app to be available for the user to use. This is shown as part of a
- bulleted list of requirements. When all requirements are met, the app can be accessed through a
- shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ Explains that the lock screen shortcut for the "home" app is not available because the app isn't
+ installed. This is shown as part of a dialog that explains to the user why they cannot select
+ this shortcut for their lock screen right now. [CHAR LIMIT=NONE].
-->
- <string name="keyguard_affordance_enablement_dialog_home_instruction_1">• The app is set up</string>
+ <string name="home_quick_affordance_unavailable_install_the_app">To add the Home app as a shortcut, make sure the app is installed</string>
<!--
- Requirement for the home app to be available for the user to use. This is shown as part of a
- bulleted list of requirements. When all requirements are met, the app can be accessed through a
- shortcut button on the lock screen. [CHAR LIMIT=NONE].
+ Explains that the lock screen shortcut for the "home" app is not available because the app isn't
+ configured. This is shown as part of a dialog that explains to the user why they cannot select
+ this shortcut for their lock screen right now. [CHAR LIMIT=NONE].
-->
- <string name="keyguard_affordance_enablement_dialog_home_instruction_2">• At least one device is available</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app">• At least one device is available</string>
<!---
- Requirement for the notes app to be available for the user to use. This is shown as part of a
- bulleted list of requirements. When all requirements are met, the app can be accessed through a
- shortcut button on the lock screen. [CHAR LIMIT=NONE] -->
- <string name="keyguard_affordance_enablement_dialog_notes_app_instruction">Select a default notes app to use the notetaking shortcut</string>
+ Explains that the notes app is not available. This is shown as part of a dialog that explains to
+ the user why they cannot select this shortcut for their lock screen right now.
+ [CHAR LIMIT=NONE].
+ -->
+ <string name="notes_app_quick_affordance_unavailable_explanation">Select a default notes app to use the notetaking shortcut</string>
<!---
The action to make the lock screen shortcut for the notes app to be available for the user to
- use. This is shown as the action button in the dialog listing the requirements. When all
- requirements are met, the app can be accessed through a shortcut button on the lock screen.
- [CHAR LIMIT=NONE] -->
+ use. This is shown as the action button in the dialog explaining why the shortcut isn't
+ available. [CHAR LIMIT=NONE] -->
<string name="keyguard_affordance_enablement_dialog_notes_app_action">Select app</string>
<!--
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
index 064a44a..bc07139 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
@@ -283,7 +283,7 @@
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON,
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.IS_ENABLED,
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
- .ENABLEMENT_INSTRUCTIONS,
+ .ENABLEMENT_EXPLANATION,
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
.ENABLEMENT_ACTION_TEXT,
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
@@ -299,10 +299,7 @@
representation.name,
representation.iconResourceId,
if (representation.isEnabled) 1 else 0,
- representation.instructions?.joinToString(
- Contract.LockScreenQuickAffordances.AffordanceTable
- .ENABLEMENT_INSTRUCTIONS_DELIMITER
- ),
+ representation.explanation,
representation.actionText,
representation.actionIntent?.toUri(Intent.URI_INTENT_SCHEME),
representation.configureIntent?.toUri(Intent.URI_INTENT_SCHEME),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index 0991b5f..f3fc809 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -83,18 +83,31 @@
currentServices.isNullOrEmpty() && !componentPackageName.isNullOrEmpty() -> {
// No home app installed but we know which app we want to install.
return disabledPickerState(
+ explanation =
+ context.getString(
+ R.string.home_quick_affordance_unavailable_install_the_app
+ ),
actionText = context.getString(R.string.install_app),
actionIntent = appStoreIntent(context, componentPackageName),
)
}
currentServices.isNullOrEmpty() && componentPackageName.isNullOrEmpty() -> {
// No home app installed and we don't know which app we want to install.
- return disabledPickerState()
+ return disabledPickerState(
+ explanation =
+ context.getString(
+ R.string.home_quick_affordance_unavailable_install_the_app
+ ),
+ )
}
!hasFavorites -> {
// Home app installed but no favorites selected.
val activityClass = component.getControlsUiController().get().resolveActivity()
return disabledPickerState(
+ explanation =
+ context.getString(
+ R.string.home_quick_affordance_unavailable_configure_the_app
+ ),
actionText = context.getString(R.string.controls_open_app),
actionIntent =
Intent().apply {
@@ -188,21 +201,14 @@
}
private fun disabledPickerState(
+ explanation: String,
actionText: String? = null,
actionIntent: Intent? = null,
): KeyguardQuickAffordanceConfig.PickerScreenState.Disabled {
check(actionIntent == null || actionText != null)
return KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
- instructions =
- listOf(
- context.getString(
- R.string.keyguard_affordance_enablement_dialog_home_instruction_1
- ),
- context.getString(
- R.string.keyguard_affordance_enablement_dialog_home_instruction_2
- ),
- ),
+ explanation = explanation,
actionText = actionText,
actionIntent = actionIntent,
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index 42fe9bc..320d158 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -87,8 +87,8 @@
* described in the instructions.
*/
data class Disabled(
- /** List of human-readable instructions for setting up the quick affordance. */
- val instructions: List<String>,
+ /** Human-readable explanation as to why the quick affordance is current disabled. */
+ val explanation: String,
/**
* Optional text to display on a button that the user can click to start a flow to go
* and set up the quick affordance and make it enabled.
@@ -101,7 +101,7 @@
val actionIntent: Intent? = null,
) : PickerScreenState() {
init {
- check(instructions.isNotEmpty()) { "Instructions must not be empty!" }
+ check(explanation.isNotEmpty()) { "Explanation must not be empty!" }
check(
(actionText.isNullOrEmpty() && actionIntent == null) ||
(!actionText.isNullOrEmpty() && actionIntent != null)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index 0d54ab9..20ed549 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -80,16 +80,14 @@
return when {
!controller.isAvailableOnDevice ->
KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
- !controller.isAbleToOpenCameraApp ->
+ !controller.isAbleToOpenCameraApp -> {
KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
- instructions =
- listOf(
- context.getString(
- R.string
- .keyguard_affordance_enablement_dialog_qr_scanner_instruction
- ),
+ explanation =
+ context.getString(
+ R.string.qr_scanner_quick_affordance_unavailable_explanation
),
)
+ }
else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 9db3c22..c019d21 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -100,19 +100,20 @@
return when {
!walletController.walletClient.isWalletServiceAvailable ->
KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
- !isWalletAvailable() || queryCards().isEmpty() -> {
+ !isWalletAvailable() ->
KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
- instructions =
- listOf(
- context.getString(
- R.string.keyguard_affordance_enablement_dialog_wallet_instruction_1
- ),
- context.getString(
- R.string.keyguard_affordance_enablement_dialog_wallet_instruction_2
- ),
+ explanation =
+ context.getString(
+ R.string.wallet_quick_affordance_unavailable_install_the_app
),
)
- }
+ queryCards().isEmpty() ->
+ KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+ explanation =
+ context.getString(
+ R.string.wallet_quick_affordance_unavailable_configure_the_app
+ ),
+ )
else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default()
}
}
@@ -147,9 +148,7 @@
}
private fun isWalletAvailable() =
- with(walletController.walletClient) {
- isWalletServiceAvailable && isWalletFeatureAvailable
- }
+ with(walletController.walletClient) { isWalletServiceAvailable && isWalletFeatureAvailable }
private fun state(
isFeatureEnabled: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index bd3b83c..34f6b4d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -175,7 +175,7 @@
iconResourceId = config.pickerIconResourceId,
isEnabled =
pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.Default,
- instructions = disabledPickerState?.instructions,
+ explanation = disabledPickerState?.explanation,
actionText = disabledPickerState?.actionText,
actionIntent =
disabledPickerState?.actionIntent?.apply {
@@ -191,6 +191,7 @@
},
)
}
+ .sortedBy { it.name }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 2275337..ea9c2b2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -35,6 +35,7 @@
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
+import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry
@@ -77,6 +78,7 @@
private val logger: KeyguardQuickAffordancesMetricsLogger,
private val devicePolicyManager: DevicePolicyManager,
private val dockManager: DockManager,
+ private val biometricSettingsRepository: BiometricSettingsRepository,
@Background private val backgroundDispatcher: CoroutineDispatcher,
@Application private val appContext: Context,
) {
@@ -107,9 +109,10 @@
quickAffordanceAlwaysVisible(position),
keyguardInteractor.isDozing,
keyguardInteractor.isKeyguardShowing,
- keyguardInteractor.isQuickSettingsVisible
- ) { affordance, isDozing, isKeyguardShowing, isQuickSettingsVisible ->
- if (!isDozing && isKeyguardShowing && !isQuickSettingsVisible) {
+ keyguardInteractor.isQuickSettingsVisible,
+ biometricSettingsRepository.isCurrentUserInLockdown,
+ ) { affordance, isDozing, isKeyguardShowing, isQuickSettingsVisible, isUserInLockdown ->
+ if (!isDozing && isKeyguardShowing && !isQuickSettingsVisible && !isUserInLockdown) {
affordance
} else {
KeyguardQuickAffordanceModel.Hidden
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
index 3c96eaf..c6320de 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardQuickAffordancePickerRepresentation.kt
@@ -32,8 +32,8 @@
/** Whether this quick affordance is enabled. */
val isEnabled: Boolean = true,
- /** If not enabled, the list of user-visible steps to re-enable it. */
- val instructions: List<String>? = null,
+ /** If not enabled, a user-visible explanation as to why. */
+ val explanation: String? = null,
/**
* If not enabled, an optional label for a button that takes the user to a destination where
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index 8da7cec..f02d362 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -122,17 +122,18 @@
isEnabled && isDefaultNotesAppSet -> PickerScreenState.Default()
isEnabled -> {
PickerScreenState.Disabled(
- listOf(
+ explanation =
context.getString(
- R.string.keyguard_affordance_enablement_dialog_notes_app_instruction
- )
- ),
- context.getString(
- R.string.keyguard_affordance_enablement_dialog_notes_app_action
- ),
- Intent(ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE).apply {
- setPackage(context.packageName)
- }
+ R.string.notes_app_quick_affordance_unavailable_explanation
+ ),
+ actionText =
+ context.getString(
+ R.string.keyguard_affordance_enablement_dialog_notes_app_action
+ ),
+ actionIntent =
+ Intent(ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE).apply {
+ setPackage(context.packageName)
+ },
)
}
else -> PickerScreenState.UnavailableOnDevice
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index b848d2e..109c1cf 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -930,6 +930,7 @@
showRingerDrawer();
}
});
+ updateSelectedRingerContainerDescription(mIsRingerDrawerOpen);
mRingerDrawerVibrate.setOnClickListener(
new RingerDrawerItemClickListener(RINGER_MODE_VIBRATE));
@@ -992,6 +993,18 @@
: 0;
}
+ @VisibleForTesting String getSelectedRingerContainerDescription() {
+ return mSelectedRingerContainer.getContentDescription().toString();
+ }
+
+ @VisibleForTesting void toggleRingerDrawer(boolean show) {
+ if (show) {
+ showRingerDrawer();
+ } else {
+ hideRingerDrawer();
+ }
+ }
+
/** Animates in the ringer drawer. */
private void showRingerDrawer() {
if (mIsRingerDrawerOpen) {
@@ -1069,12 +1082,7 @@
.start();
}
- // When the ringer drawer is open, tapping the currently selected ringer will set the ringer
- // to the current ringer mode. Change the content description to that, instead of the 'tap
- // to change ringer mode' default.
- mSelectedRingerContainer.setContentDescription(
- mContext.getString(getStringDescriptionResourceForRingerMode(
- mState.ringerModeInternal)));
+ updateSelectedRingerContainerDescription(true);
mIsRingerDrawerOpen = true;
}
@@ -1120,14 +1128,38 @@
.translationY(0f)
.start();
- // When the drawer is closed, tapping the selected ringer drawer will open it, allowing the
- // user to change the ringer.
- mSelectedRingerContainer.setContentDescription(
- mContext.getString(R.string.volume_ringer_change));
+ updateSelectedRingerContainerDescription(false);
mIsRingerDrawerOpen = false;
}
+
+ /**
+ * @param open false to set the description when drawer is closed
+ */
+ private void updateSelectedRingerContainerDescription(boolean open) {
+ if (mState == null) return;
+
+ String currentMode = mContext.getString(getStringDescriptionResourceForRingerMode(
+ mState.ringerModeInternal));
+ String tapToSelect;
+
+ if (open) {
+ // When the ringer drawer is open, tapping the currently selected ringer will set the
+ // ringer to the current ringer mode. Change the content description to that, instead of
+ // the 'tap to change ringer mode' default.
+ tapToSelect = "";
+
+ } else {
+ // When the drawer is closed, tapping the selected ringer drawer will open it, allowing
+ // the user to change the ringer. The user needs to know that, and also the current mode
+ currentMode += ", ";
+ tapToSelect = mContext.getString(R.string.volume_ringer_change);
+ }
+
+ mSelectedRingerContainer.setContentDescription(currentMode + tapToSelect);
+ }
+
private void initSettingsH(int lockTaskModeState) {
if (mSettingsView != null) {
mSettingsView.setVisibility(
@@ -1703,7 +1735,7 @@
});
}
- private int getStringDescriptionResourceForRingerMode(int mode) {
+ @VisibleForTesting int getStringDescriptionResourceForRingerMode(int mode) {
switch (mode) {
case RINGER_MODE_SILENT:
return R.string.volume_ringer_status_silent;
@@ -1785,6 +1817,7 @@
updateVolumeRowH(row);
}
updateRingerH();
+ updateSelectedRingerContainerDescription(mIsRingerDrawerOpen);
mWindow.setTitle(composeWindowTitle());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 8ee7d3e..cdc99af3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -42,6 +42,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
@@ -98,6 +99,7 @@
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
private lateinit var dockManager: DockManagerFake
+ private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
private lateinit var underTest: CustomizationProvider
private lateinit var testScope: TestScope
@@ -111,6 +113,7 @@
whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
dockManager = DockManagerFake()
+ biometricSettingsRepository = FakeBiometricSettingsRepository()
underTest = CustomizationProvider()
val testDispatcher = UnconfinedTestDispatcher()
@@ -197,6 +200,7 @@
logger = logger,
devicePolicyManager = devicePolicyManager,
dockManager = dockManager,
+ biometricSettingsRepository = biometricSettingsRepository,
backgroundDispatcher = testDispatcher,
appContext = mContext,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index 26c0ea4..7510373 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -53,7 +53,7 @@
MockitoAnnotations.initMocks(this)
whenever(controller.intent).thenReturn(INTENT_1)
- underTest = QrCodeScannerKeyguardQuickAffordanceConfig(mock(), controller)
+ underTest = QrCodeScannerKeyguardQuickAffordanceConfig(context, controller)
}
@Test
@@ -77,22 +77,21 @@
}
@Test
- fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() =
- runBlockingTest {
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
+ fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() = runBlockingTest {
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
- whenever(controller.intent).thenReturn(INTENT_2)
- callbackCaptor.value.onQRCodeScannerActivityChanged()
+ whenever(controller.intent).thenReturn(INTENT_2)
+ callbackCaptor.value.onQRCodeScannerActivityChanged()
- assertVisibleState(latest)
+ assertVisibleState(latest)
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
fun affordance_scannerPreferenceChanged_deliversVisibleModel() = runBlockingTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index fb21847..2c90d53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
@@ -239,6 +240,7 @@
@JvmField @Parameter(4) var startActivity: Boolean = false
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
private lateinit var dockManager: DockManagerFake
+ private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
private lateinit var userTracker: UserTracker
@Before
@@ -250,6 +252,7 @@
homeControls =
FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS)
dockManager = DockManagerFake()
+ biometricSettingsRepository = FakeBiometricSettingsRepository()
val quickAccessWallet =
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
@@ -339,6 +342,7 @@
logger = logger,
devicePolicyManager = devicePolicyManager,
dockManager = dockManager,
+ biometricSettingsRepository = biometricSettingsRepository,
backgroundDispatcher = testDispatcher,
appContext = mContext,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 1d5971c..7cab680 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -40,6 +40,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
@@ -97,6 +98,7 @@
private lateinit var qrCodeScanner: FakeKeyguardQuickAffordanceConfig
private lateinit var featureFlags: FakeFeatureFlags
private lateinit var dockManager: DockManagerFake
+ private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
@Before
fun setUp() {
@@ -119,6 +121,7 @@
testScope = TestScope(testDispatcher)
dockManager = DockManagerFake()
+ biometricSettingsRepository = FakeBiometricSettingsRepository()
val localUserSelectionManager =
KeyguardQuickAffordanceLocalUserSelectionManager(
@@ -201,6 +204,7 @@
logger = logger,
devicePolicyManager = devicePolicyManager,
dockManager = dockManager,
+ biometricSettingsRepository = biometricSettingsRepository,
backgroundDispatcher = testDispatcher,
appContext = context,
)
@@ -314,6 +318,24 @@
}
@Test
+ fun quickAffordance_hiddenWhenUserIsInLockdownMode() =
+ testScope.runTest {
+ biometricSettingsRepository.setIsUserInLockdown(true)
+ quickAccessWallet.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ )
+ )
+
+ val collectedValue by
+ collectLastValue(
+ underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
+ )
+
+ assertThat(collectedValue).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
+ }
+
+ @Test
fun quickAffordance_bottomStartAffordanceHiddenWhileDozing() =
testScope.runTest {
repository.setIsDozing(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 8a36dbc..73fe380 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -39,6 +39,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -110,6 +111,7 @@
private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
private lateinit var qrCodeScannerAffordanceConfig: FakeKeyguardQuickAffordanceConfig
private lateinit var dockManager: DockManagerFake
+ private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
@Before
fun setUp() {
@@ -126,6 +128,7 @@
qrCodeScannerAffordanceConfig =
FakeKeyguardQuickAffordanceConfig(BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER)
dockManager = DockManagerFake()
+ biometricSettingsRepository = FakeBiometricSettingsRepository()
registry =
FakeKeyguardQuickAffordanceRegistry(
mapOf(
@@ -240,6 +243,7 @@
logger = logger,
devicePolicyManager = devicePolicyManager,
dockManager = dockManager,
+ biometricSettingsRepository = biometricSettingsRepository,
backgroundDispatcher = testDispatcher,
appContext = mContext,
),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
index cc64cc2..58c762e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
@@ -296,8 +296,8 @@
assertThat(pickerScreenState is KeyguardQuickAffordanceConfig.PickerScreenState.Disabled)
.isTrue()
val disabled = pickerScreenState as KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
- assertThat(disabled.instructions)
- .isEqualTo(listOf("Select a default notes app to use the notetaking shortcut"))
+ assertThat(disabled.explanation)
+ .isEqualTo("Select a default notes app to use the notetaking shortcut")
assertThat(disabled.actionText).isEqualTo("Select app")
assertThat(disabled.actionIntent?.action)
.isEqualTo(ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 85b1ec1..b0c1486 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -89,7 +89,6 @@
import org.junit.Assert;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -103,7 +102,6 @@
/**
* Tests for {@link NotificationStackScrollLayout}.
*/
-@Ignore("b/255552856")
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -375,20 +373,6 @@
}
@Test
- public void testAppearFractionCalculation() {
- // appear start position
- when(mNotificationShelf.getIntrinsicHeight()).thenReturn(100);
- // because it's the same as shelf height, appear start position equals shelf height
- mStackScroller.mStatusBarHeight = 100;
- // appear end position
- when(mEmptyShadeView.getHeight()).thenReturn(200);
-
- assertEquals(0f, mStackScroller.calculateAppearFraction(100));
- assertEquals(1f, mStackScroller.calculateAppearFraction(200));
- assertEquals(0.5f, mStackScroller.calculateAppearFraction(150));
- }
-
- @Test
public void testAppearFractionCalculationIsNotNegativeWhenShelfBecomesSmaller() {
// this situation might occur if status bar height is defined in pixels while shelf height
// in dp and screen density changes - appear start position
@@ -590,6 +574,7 @@
@Test
public void testReInflatesFooterViews() {
+ when(mEmptyShadeView.getTextResource()).thenReturn(R.string.empty_shade_text);
clearInvocations(mStackScroller);
mStackScroller.reinflateViews();
verify(mStackScroller).setFooterView(any());
@@ -916,7 +901,7 @@
mStackScroller.setHasFilteredOutSeenNotifications(true);
mStackScroller.updateEmptyShadeView(true, false);
- verify(mEmptyShadeView).setFooterText(not(0));
+ verify(mEmptyShadeView).setFooterText(not(eq(0)));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 8f725be..2ea6368 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -16,11 +16,16 @@
package com.android.systemui.volume;
+import static android.media.AudioManager.RINGER_MODE_NORMAL;
+import static android.media.AudioManager.RINGER_MODE_SILENT;
+import static android.media.AudioManager.RINGER_MODE_VIBRATE;
+
import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN;
import static com.android.systemui.volume.Events.SHOW_REASON_UNKNOWN;
import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -293,7 +298,7 @@
@Test
public void testSelectVibrateFromDrawer() {
final State initialUnsetState = new State();
- initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL;
+ initialUnsetState.ringerModeInternal = RINGER_MODE_NORMAL;
mDialog.onStateChangedH(initialUnsetState);
mActiveRinger.performClick();
@@ -307,7 +312,7 @@
@Test
public void testSelectMuteFromDrawer() {
final State initialUnsetState = new State();
- initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL;
+ initialUnsetState.ringerModeInternal = RINGER_MODE_NORMAL;
mDialog.onStateChangedH(initialUnsetState);
mActiveRinger.performClick();
@@ -329,7 +334,7 @@
// Make sure we've actually changed the ringer mode.
verify(mVolumeDialogController, times(1)).setRingerMode(
- AudioManager.RINGER_MODE_NORMAL, false);
+ RINGER_MODE_NORMAL, false);
}
/**
@@ -511,6 +516,85 @@
}
}
+ private enum RingerDrawerState {INIT, OPEN, CLOSE}
+
+ @Test
+ public void ringerModeNormal_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_NORMAL, RingerDrawerState.INIT);
+ }
+
+ @Test
+ public void ringerModeSilent_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_SILENT, RingerDrawerState.INIT);
+ }
+
+ @Test
+ public void ringerModeVibrate_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_VIBRATE, RingerDrawerState.INIT);
+ }
+
+ @Test
+ public void ringerModeNormal_openDrawer_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_NORMAL, RingerDrawerState.OPEN);
+ }
+
+ @Test
+ public void ringerModeSilent_openDrawer_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_SILENT, RingerDrawerState.OPEN);
+ }
+
+ @Test
+ public void ringerModeVibrate_openDrawer_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_VIBRATE, RingerDrawerState.OPEN);
+ }
+
+ @Test
+ public void ringerModeNormal_closeDrawer_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_NORMAL, RingerDrawerState.CLOSE);
+ }
+
+ @Test
+ public void ringerModeSilent_closeDrawer_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_SILENT, RingerDrawerState.CLOSE);
+ }
+
+ @Test
+ public void ringerModeVibrate_closeDrawer_ringerContainerDescribesItsState() {
+ assertRingerContainerDescribesItsState(RINGER_MODE_VIBRATE, RingerDrawerState.CLOSE);
+ }
+
+ /**
+ * The content description should include ringer state, and the correct one.
+ */
+ private void assertRingerContainerDescribesItsState(int ringerMode,
+ RingerDrawerState drawerState) {
+ State state = createShellState();
+ state.ringerModeInternal = ringerMode;
+ mDialog.onStateChangedH(state);
+
+ mDialog.show(SHOW_REASON_UNKNOWN);
+
+ if (drawerState != RingerDrawerState.INIT) {
+ // in both cases we first open the drawer
+ mDialog.toggleRingerDrawer(true);
+
+ if (drawerState == RingerDrawerState.CLOSE) {
+ mDialog.toggleRingerDrawer(false);
+ }
+ }
+
+ String ringerContainerDescription = mDialog.getSelectedRingerContainerDescription();
+ String ringerDescription = mContext.getString(
+ mDialog.getStringDescriptionResourceForRingerMode(ringerMode));
+
+ if (drawerState == RingerDrawerState.OPEN) {
+ assertEquals(ringerDescription, ringerContainerDescription);
+ } else {
+ assertNotSame(ringerDescription, ringerContainerDescription);
+ assertTrue(ringerContainerDescription.startsWith(ringerDescription));
+ }
+ }
+
@After
public void teardown() {
if (mDialog != null) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5c1dad9..92e73f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13785,7 +13785,8 @@
if (action.startsWith("android.intent.action.USER_")
|| action.startsWith("android.intent.action.PACKAGE_")
|| action.startsWith("android.intent.action.UID_")
- || action.startsWith("android.intent.action.EXTERNAL_")) {
+ || action.startsWith("android.intent.action.EXTERNAL_")
+ || action.startsWith("android.bluetooth.")) {
if (DEBUG_BROADCAST) {
Slog.wtf(TAG,
"System internals registering for " + filter.toLongString()
diff --git a/services/core/java/com/android/server/notification/TEST_MAPPING b/services/core/java/com/android/server/notification/TEST_MAPPING
new file mode 100644
index 0000000..59b2bc1
--- /dev/null
+++ b/services/core/java/com/android/server/notification/TEST_MAPPING
@@ -0,0 +1,49 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsNotificationTestCases",
+ "options": [
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.LargeTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksUiServicesTests",
+ "options": [
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.LargeTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.LargeTest"
+ }
+ ]
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsNotificationTestCases"
+ }
+ ]
+}