summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/docs/usb_audio.md30
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java124
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt22
8 files changed, 267 insertions, 44 deletions
diff --git a/packages/SystemUI/docs/usb_audio.md b/packages/SystemUI/docs/usb_audio.md
new file mode 100644
index 000000000000..66e2df944fbc
--- /dev/null
+++ b/packages/SystemUI/docs/usb_audio.md
@@ -0,0 +1,30 @@
+# USB audio Permission and Confirmation warning dialog resource string id matrix table
+### go/support-usb-access-aoc-offload-feature
+
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | # | Permission |isUsbAudioDevice| hasAudioPlayback | hasAudioCapture | string resource ID |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 1 | TRUE | TRUE | TRUE | FALSE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 2 | TRUE | TRUE | FALSE | TRUE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 3 | TRUE | TRUE | TRUE | TRUE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 4 | TRUE | FALSE | N/A | N/A | usb_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 5 | FALSE | TRUE | TRUE | FALSE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 6 | FALSE | TRUE | FALSE | TRUE | usb_audio_device_
+ permission_prompt_warn
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 7 | FALSE | TRUE | TRUE | TRUE | usb_audio_device_
+ permission_prompt_warn
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 8 | FALSE | FALSE | N/A | N/A | usb_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index 1653e0adadb5..fb016911f913 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -29,8 +29,10 @@ import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity;
import com.android.systemui.settings.brightness.BrightnessDialog;
import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity;
import com.android.systemui.tuner.TunerActivity;
+import com.android.systemui.usb.UsbConfirmActivity;
import com.android.systemui.usb.UsbDebuggingActivity;
import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity;
+import com.android.systemui.usb.UsbPermissionActivity;
import com.android.systemui.user.CreateUserActivity;
import dagger.Binds;
@@ -80,6 +82,18 @@ public abstract class DefaultActivityBinder {
public abstract Activity bindUsbDebuggingSecondaryUserActivity(
UsbDebuggingSecondaryUserActivity activity);
+ /** Inject into UsbPermissionActivity. */
+ @Binds
+ @IntoMap
+ @ClassKey(UsbPermissionActivity.class)
+ public abstract Activity bindUsbPermissionActivity(UsbPermissionActivity activity);
+
+ /** Inject into UsbConfirmActivity. */
+ @Binds
+ @IntoMap
+ @ClassKey(UsbConfirmActivity.class)
+ public abstract Activity bindUsbConfirmActivity(UsbConfirmActivity activity);
+
/** Inject into CreateUserActivity. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
new file mode 100644
index 000000000000..e06353b3aad3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 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.usb;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.content.res.Resources;
+import android.util.Log;
+
+import com.android.systemui.R;
+
+import java.lang.annotation.Retention;
+
+import javax.inject.Inject;
+
+/**
+ * USB Audio devices warning dialog messages help class.
+ */
+public class UsbAudioWarningDialogMessage {
+ private static final String TAG = "UsbAudioWarningDialogMessage";
+
+ @Retention(SOURCE)
+ @IntDef({TYPE_PERMISSION, TYPE_CONFIRM})
+ public @interface DialogType {}
+ public static final int TYPE_PERMISSION = 0;
+ public static final int TYPE_CONFIRM = 1;
+
+ private int mDialogType;
+ private UsbDialogHelper mDialogHelper;
+
+ @Inject
+ public UsbAudioWarningDialogMessage() {
+ }
+
+ /**
+ * Initialize USB audio warning dialog message type and helper class.
+ * @param type Dialog type for Activity.
+ * @param usbDialogHelper Helper class for getting USB permission and confirm dialogs
+ */
+ public void init(@DialogType int type, UsbDialogHelper usbDialogHelper) {
+ mDialogType = type;
+ mDialogHelper = usbDialogHelper;
+ }
+
+ boolean hasRecordPermission() {
+ return mDialogHelper.packageHasAudioRecordingPermission();
+ }
+
+ boolean isUsbAudioDevice() {
+ return mDialogHelper.isUsbDevice() && (mDialogHelper.deviceHasAudioCapture()
+ || (mDialogHelper.deviceHasAudioPlayback()));
+ }
+
+ boolean hasAudioPlayback() {
+ return mDialogHelper.deviceHasAudioPlayback();
+ }
+
+ boolean hasAudioCapture() {
+ return mDialogHelper.deviceHasAudioCapture();
+ }
+
+ /**
+ * According to USB audio warning dialog matrix table to return warning message id.
+ * @return string resId for USB audio warning dialog message, otherwise {ID_NULL}.
+ * See usb_audio.md for USB audio Permission and Confirmation warning dialog resource
+ * string id matrix table.
+ */
+ public int getMessageId() {
+ if (!mDialogHelper.isUsbDevice()) {
+ return getUsbAccessoryPromptId();
+ }
+
+ if (hasRecordPermission() && isUsbAudioDevice()) {
+ // case# 1, 2, 3
+ return R.string.usb_audio_device_prompt;
+ } else if (!hasRecordPermission() && isUsbAudioDevice() && hasAudioPlayback()
+ && !hasAudioCapture()) {
+ // case# 5
+ return R.string.usb_audio_device_prompt;
+ }
+
+ if (!hasRecordPermission() && isUsbAudioDevice() && hasAudioCapture()) {
+ // case# 6,7
+ return R.string.usb_audio_device_prompt_warn;
+ }
+
+ Log.w(TAG, "Only shows title with empty content description!");
+ return Resources.ID_NULL;
+ }
+
+ /**
+ * Gets prompt dialog title.
+ * @return string id for USB prompt dialog title.
+ */
+ public int getPromptTitleId() {
+ return (mDialogType == TYPE_PERMISSION)
+ ? R.string.usb_audio_device_permission_prompt_title
+ : R.string.usb_audio_device_confirm_prompt_title;
+ }
+
+ /**
+ * Gets USB Accessory prompt message id.
+ * @return string id for USB Accessory prompt message.
+ */
+ public int getUsbAccessoryPromptId() {
+ return (mDialogType == TYPE_PERMISSION)
+ ? R.string.usb_accessory_permission_prompt : R.string.usb_accessory_confirm_prompt;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
index f4558feb69aa..6e523d88a326 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
@@ -16,7 +16,10 @@
package com.android.systemui.usb;
-import com.android.systemui.R;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import javax.inject.Inject;
/**
* Dialog shown to confirm the package to start when a USB device or accessory is attached and there
@@ -24,23 +27,35 @@ import com.android.systemui.R;
*/
public class UsbConfirmActivity extends UsbDialogActivity {
+ private UsbAudioWarningDialogMessage mUsbConfirmMessageHandler;
+
+ @Inject
+ public UsbConfirmActivity(UsbAudioWarningDialogMessage usbAudioWarningDialogMessage) {
+ mUsbConfirmMessageHandler = usbAudioWarningDialogMessage;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mUsbConfirmMessageHandler.init(UsbAudioWarningDialogMessage.TYPE_CONFIRM, mDialogHelper);
+ }
+
@Override
protected void onResume() {
super.onResume();
- final int strId;
- boolean useRecordWarning = false;
- if (mDialogHelper.isUsbDevice()) {
- useRecordWarning = mDialogHelper.deviceHasAudioCapture()
- && !mDialogHelper.packageHasAudioRecordingPermission();
- strId = useRecordWarning
- ? R.string.usb_device_confirm_prompt_warn
- : R.string.usb_device_confirm_prompt;
- } else {
- // UsbAccessory case
- strId = R.string.usb_accessory_confirm_prompt;
- }
- setAlertParams(strId);
// Only show the "always use" checkbox if there is no USB/Record warning
+ final boolean useRecordWarning = mDialogHelper.isUsbDevice()
+ && (mDialogHelper.deviceHasAudioCapture()
+ && !mDialogHelper.packageHasAudioRecordingPermission());
+
+ final int titleId = mUsbConfirmMessageHandler.getPromptTitleId();
+ final String title = getString(titleId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription());
+ final int messageId = mUsbConfirmMessageHandler.getMessageId();
+ String message = (messageId != Resources.ID_NULL)
+ ? getString(messageId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription()) : null;
+ setAlertParams(title, message);
if (!useRecordWarning) {
addAlwaysUseCheckbox();
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
index 930bc338a918..55dec5fbe344 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
@@ -41,7 +41,7 @@ abstract class UsbDialogActivity extends AlertActivity
private TextView mClearDefaultHint;
@Override
- protected final void onCreate(Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addSystemFlags(
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
@@ -87,11 +87,10 @@ abstract class UsbDialogActivity extends AlertActivity
}
}
- void setAlertParams(int strId) {
+ void setAlertParams(String title, String message) {
final AlertController.AlertParams ap = mAlertParams;
- ap.mTitle = mDialogHelper.getAppName();
- ap.mMessage = getString(strId, mDialogHelper.getAppName(),
- mDialogHelper.getDeviceDescription());
+ ap.mTitle = title;
+ ap.mMessage = message;
ap.mPositiveButtonText = getString(android.R.string.ok);
ap.mNegativeButtonText = getString(android.R.string.cancel);
ap.mPositiveButtonListener = this;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java
index d63fb86ea6d4..3f061d3113be 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java
@@ -134,6 +134,13 @@ public class UsbDialogHelper {
}
/**
+ * @return True if the intent contains a UsbDevice which can play audio.
+ */
+ public boolean deviceHasAudioPlayback() {
+ return mDevice != null && mDevice.getHasAudioPlayback();
+ }
+
+ /**
* @return True if the package has RECORD_AUDIO permission specified in its manifest.
*/
public boolean packageHasAudioRecordingPermission() {
@@ -272,15 +279,15 @@ public class UsbDialogHelper {
return desc;
}
- /**
- * Whether the calling package can set as default handler of the USB device or accessory.
- * In case of a UsbAccessory this is the case if the calling package has an intent filter for
- * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} with a usb-accessory filter matching the
- * attached accessory. In case of a UsbDevice this is the case if the calling package has an
- * intent filter for {@link UsbManager#ACTION_USB_DEVICE_ATTACHED} with a usb-device filter
- * matching the attached device.
- *
- * @return True if the package can be default for the USB device.
+ /**
+ * Whether the calling package can set as default handler of the USB device or accessory.
+ * In case of a UsbAccessory this is the case if the calling package has an intent filter for
+ * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} with a usb-accessory filter matching the
+ * attached accessory. In case of a UsbDevice this is the case if the calling package has an
+ * intent filter for {@link UsbManager#ACTION_USB_DEVICE_ATTACHED} with a usb-device filter
+ * matching the attached device.
+ *
+ * @return True if the package can be default for the USB device.
*/
public boolean canBeDefault() {
return mCanBeDefault;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index 38d634777177..9484d3a63801 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -16,7 +16,10 @@
package com.android.systemui.usb;
-import com.android.systemui.R;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import javax.inject.Inject;
/**
* Dialog shown when a package requests access to a USB device or accessory.
@@ -24,23 +27,36 @@ import com.android.systemui.R;
public class UsbPermissionActivity extends UsbDialogActivity {
private boolean mPermissionGranted = false;
+ private UsbAudioWarningDialogMessage mUsbPermissionMessageHandler;
+
+ @Inject
+ public UsbPermissionActivity(UsbAudioWarningDialogMessage usbAudioWarningDialogMessage) {
+ mUsbPermissionMessageHandler = usbAudioWarningDialogMessage;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mUsbPermissionMessageHandler.init(UsbAudioWarningDialogMessage.TYPE_PERMISSION,
+ mDialogHelper);
+ }
@Override
protected void onResume() {
super.onResume();
- final int strId;
- boolean useRecordWarning = false;
- if (mDialogHelper.isUsbDevice()) {
- useRecordWarning = mDialogHelper.deviceHasAudioCapture()
- && !mDialogHelper.packageHasAudioRecordingPermission();
- strId = useRecordWarning
- ? R.string.usb_device_permission_prompt_warn
- : R.string.usb_device_permission_prompt;
- } else {
- // UsbAccessory case
- strId = R.string.usb_accessory_permission_prompt;
- }
- setAlertParams(strId);
+ final boolean useRecordWarning = mDialogHelper.isUsbDevice()
+ && (mDialogHelper.deviceHasAudioCapture()
+ && !mDialogHelper.packageHasAudioRecordingPermission());
+
+ final int titleId = mUsbPermissionMessageHandler.getPromptTitleId();
+ final String title = getString(titleId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription());
+ final int messageId = mUsbPermissionMessageHandler.getMessageId();
+ String message = (messageId != Resources.ID_NULL)
+ ? getString(messageId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription()) : null;
+ setAlertParams(title, message);
+
// Only show the "always use" checkbox if there is no USB/Record warning
if (!useRecordWarning && mDialogHelper.canBeDefault()) {
addAlwaysUseCheckbox();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
index 3d554880ed58..b30c20db642d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
@@ -21,11 +21,16 @@ import android.hardware.usb.IUsbSerialReader
import android.hardware.usb.UsbAccessory
import android.hardware.usb.UsbManager
import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
+import androidx.test.runner.intercepting.SingleActivityFactory
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
+
+import javax.inject.Inject
+
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -37,14 +42,26 @@ import org.junit.runner.RunWith
*/
@RunWith(AndroidTestingRunner::class)
@SmallTest
+@TestableLooper.RunWithLooper
class UsbPermissionActivityTest : SysuiTestCase() {
- class UsbPermissionActivityTestable : UsbPermissionActivity()
+ private var mMessage: UsbAudioWarningDialogMessage = UsbAudioWarningDialogMessage()
+
+ open class UsbPermissionActivityTestable @Inject constructor (
+ val message: UsbAudioWarningDialogMessage
+ )
+ : UsbPermissionActivity(UsbAudioWarningDialogMessage())
@Rule
@JvmField
var activityRule = ActivityTestRule<UsbPermissionActivityTestable>(
- UsbPermissionActivityTestable::class.java, false, false)
+ object : SingleActivityFactory<UsbPermissionActivityTestable>(
+ UsbPermissionActivityTestable::class.java
+ ) {
+ override fun create(intent: Intent?): UsbPermissionActivityTestable {
+ return UsbPermissionActivityTestable(mMessage)
+ }
+ }, false, false)
private val activityIntent = Intent(mContext, UsbPermissionActivityTestable::class.java)
.apply {
@@ -72,6 +89,7 @@ class UsbPermissionActivityTest : SysuiTestCase() {
@Before
fun setUp() {
+ UsbPermissionActivityTestable(mMessage)
activityRule.launchActivity(activityIntent)
}