summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Caitlin Cassidy <ccassidy@google.com> 2021-12-21 20:54:35 +0000
committer Caitlin Cassidy <ccassidy@google.com> 2021-12-22 16:45:35 +0000
commit5fae789837f7dc4335a355074ea237cd3e2c8f67 (patch)
tree31f01c3780edbee68a39d40264b7111a0cdfa18b
parente087e12997ae4b4d0d22c4aad0824b56d66d8d37 (diff)
[Media TTT] Define a common controller that will be used for both the
sender device chip and the receiver device chip. Code for the receiver device chip will be added in future CLs. Bug: 203800646 Test: manual (verify sender chip still works) Test: MediaTttChipControllerSenderTest, MediaTttCommandLineHelperTest Change-Id: I72c7e089c5b587fcdf5827f4e95f9032d96bbfd7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md11
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt104
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt (renamed from packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttChipState.kt)28
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt (renamed from packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttChipController.kt)69
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt94
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttChipControllerTest.kt)84
11 files changed, 322 insertions, 152 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index af0697996f43..1e96809b413b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -23,8 +23,8 @@ import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
-import com.android.systemui.media.taptotransfer.MediaTttChipController;
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
+import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
import com.android.systemui.people.PeopleProvider;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
@@ -134,7 +134,7 @@ public interface SysUIComponent {
});
getNaturalRotationUnfoldProgressProvider().ifPresent(o -> o.init());
// No init method needed, just needs to be gotten so that it's created.
- getMediaTttChipController();
+ getMediaTttChipControllerSender();
getMediaTttCommandLineHelper();
getUnfoldLatencyTracker().init();
}
@@ -190,7 +190,7 @@ public interface SysUIComponent {
Optional<NaturalRotationUnfoldProgressProvider> getNaturalRotationUnfoldProgressProvider();
/** */
- Optional<MediaTttChipController> getMediaTttChipController();
+ Optional<MediaTttChipControllerSender> getMediaTttChipControllerSender();
/** */
Optional<MediaTttCommandLineHelper> getMediaTttCommandLineHelper();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index a398a7fa4575..d76d17910dc2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -26,9 +26,9 @@ import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.media.MediaHostStatesManager;
-import com.android.systemui.media.taptotransfer.MediaTttChipController;
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.media.taptotransfer.MediaTttFlags;
+import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
import com.android.systemui.statusbar.commandline.CommandRegistry;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -80,7 +80,7 @@ public interface MediaModule {
/** */
@Provides
@SysUISingleton
- static Optional<MediaTttChipController> providesMediaTttChipController(
+ static Optional<MediaTttChipControllerSender> providesMediaTttChipControllerSender(
MediaTttFlags mediaTttFlags,
Context context,
WindowManager windowManager,
@@ -89,7 +89,7 @@ public interface MediaModule {
if (!mediaTttFlags.isMediaTttEnabled()) {
return Optional.empty();
}
- return Optional.of(new MediaTttChipController(
+ return Optional.of(new MediaTttChipControllerSender(
context, windowManager, mainExecutor, backgroundExecutor));
}
@@ -100,12 +100,12 @@ public interface MediaModule {
MediaTttFlags mediaTttFlags,
CommandRegistry commandRegistry,
Context context,
- MediaTttChipController mediaTttChipController,
+ MediaTttChipControllerSender mediaTttChipControllerSender,
@Main DelayableExecutor mainExecutor) {
if (!mediaTttFlags.isMediaTttEnabled()) {
return Optional.empty();
}
return Optional.of(new MediaTttCommandLineHelper(
- commandRegistry, context, mediaTttChipController, mainExecutor));
+ commandRegistry, context, mediaTttChipControllerSender, mainExecutor));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
index 74983e5bfe03..93f7b7dff96c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
@@ -23,6 +23,10 @@ import androidx.annotation.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender
+import com.android.systemui.media.taptotransfer.sender.MoveCloserToTransfer
+import com.android.systemui.media.taptotransfer.sender.TransferInitiated
+import com.android.systemui.media.taptotransfer.sender.TransferSucceeded
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -38,7 +42,7 @@ import javax.inject.Inject
class MediaTttCommandLineHelper @Inject constructor(
commandRegistry: CommandRegistry,
context: Context,
- private val mediaTttChipController: MediaTttChipController,
+ private val mediaTttChipControllerSender: MediaTttChipControllerSender,
@Main private val mainExecutor: DelayableExecutor,
) {
private val appIconDrawable =
@@ -54,21 +58,21 @@ class MediaTttCommandLineHelper @Inject constructor(
val otherDeviceName = args[0]
when (args[1]) {
MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME -> {
- mediaTttChipController.displayChip(
- MoveCloserToTransfer(otherDeviceName, appIconDrawable)
+ mediaTttChipControllerSender.displayChip(
+ MoveCloserToTransfer(appIconDrawable, otherDeviceName)
)
}
TRANSFER_INITIATED_COMMAND_NAME -> {
val futureTask = FutureTask { fakeUndoRunnable }
- mediaTttChipController.displayChip(
- TransferInitiated(otherDeviceName, appIconDrawable, futureTask)
+ mediaTttChipControllerSender.displayChip(
+ TransferInitiated(appIconDrawable, otherDeviceName, futureTask)
)
mainExecutor.executeDelayed({ futureTask.run() }, FUTURE_WAIT_TIME)
}
TRANSFER_SUCCEEDED_COMMAND_NAME -> {
- mediaTttChipController.displayChip(
- TransferSucceeded(otherDeviceName, appIconDrawable, fakeUndoRunnable)
+ mediaTttChipControllerSender.displayChip(
+ TransferSucceeded(appIconDrawable, otherDeviceName, fakeUndoRunnable)
)
}
else -> {
@@ -90,7 +94,7 @@ class MediaTttCommandLineHelper @Inject constructor(
inner class RemoveChipCommand : Command {
override fun execute(pw: PrintWriter, args: List<String>) {
- mediaTttChipController.removeChip()
+ mediaTttChipControllerSender.removeChip()
}
override fun help(pw: PrintWriter) {
pw.println("Usage: adb shell cmd statusbar $REMOVE_CHIP_COMMAND_TAG")
@@ -114,3 +118,4 @@ val TRANSFER_INITIATED_COMMAND_NAME = TransferInitiated::class.simpleName!!
val TRANSFER_SUCCEEDED_COMMAND_NAME = TransferSucceeded::class.simpleName!!
private const val FUTURE_WAIT_TIME = 2000L
+private const val TAG = "MediaTapToTransferCli"
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
new file mode 100644
index 000000000000..114589119cea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
@@ -0,0 +1,11 @@
+# Media Tap-To-Transfer
+
+This package (and child packages) include code for the media tap-to-transfer feature, which
+allows users to easily transfer playing media between devices.
+
+In media transfer, there are two devices: the *sender* and the *receiver*. The sender device will
+start and stop media casts to the receiver device. On both devices, System UI will display a chip
+informing the user about the media cast occurring.
+
+This package is structured so that the sender code is in the sender package, the receiver code is
+in the receiver package, and code that's shared between them is in the common package.
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
new file mode 100644
index 000000000000..3b429c887796
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.media.taptotransfer.common
+
+import android.annotation.LayoutRes
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.PixelFormat
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.view.WindowManager
+import com.android.internal.widget.CachingIconView
+import com.android.systemui.R
+
+/**
+ * A superclass controller that provides common functionality for showing chips on the sender device
+ * and the receiver device.
+ *
+ * Subclasses need to override and implement [updateChipView], which is where they can control what
+ * gets displayed to the user.
+ */
+abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
+ private val context: Context,
+ private val windowManager: WindowManager,
+ @LayoutRes private val chipLayoutRes: Int
+) {
+ /** The window layout parameters we'll use when attaching the view to a window. */
+ @SuppressLint("WrongConstant") // We're allowed to use TYPE_VOLUME_OVERLAY
+ private val windowLayoutParams = WindowManager.LayoutParams().apply {
+ width = WindowManager.LayoutParams.WRAP_CONTENT
+ height = WindowManager.LayoutParams.WRAP_CONTENT
+ gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
+ type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY
+ flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ title = "Media Tap-To-Transfer Chip View"
+ format = PixelFormat.TRANSLUCENT
+ setTrustedOverlay()
+ }
+
+ /** The chip view currently being displayed. Null if the chip is not being displayed. */
+ var chipView: ViewGroup? = null
+
+ /**
+ * Displays the chip with the current state.
+ *
+ * This method handles inflating and attaching the view, then delegates to [updateChipView] to
+ * display the correct information in the chip.
+ */
+ fun displayChip(chipState: T) {
+ val oldChipView = chipView
+ if (chipView == null) {
+ chipView = LayoutInflater
+ .from(context)
+ .inflate(chipLayoutRes, null) as ViewGroup
+ }
+ val currentChipView = chipView!!
+
+ updateChipView(chipState, currentChipView)
+
+ // Add view if necessary
+ if (oldChipView == null) {
+ windowManager.addView(chipView, windowLayoutParams)
+ }
+ }
+
+
+ /** Hides the chip. */
+ fun removeChip() {
+ if (chipView == null) { return }
+ windowManager.removeView(chipView)
+ chipView = null
+ }
+
+ /**
+ * A method implemented by subclasses to update [currentChipView] based on [chipState].
+ */
+ abstract fun updateChipView(chipState: T, currentChipView: ViewGroup)
+
+ /**
+ * An internal method to set the icon on the view.
+ *
+ * This is in the common superclass since both the sender and the receiver show an icon.
+ */
+ internal fun setIcon(chipState: T, currentChipView: ViewGroup) {
+ currentChipView.findViewById<CachingIconView>(R.id.app_icon).apply {
+ this.setImageDrawable(chipState.appIconDrawable)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
new file mode 100644
index 000000000000..1e475a5e7c82
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.media.taptotransfer.common
+
+import android.graphics.drawable.Drawable
+
+/**
+ * A superclass chip state that will be subclassed by the sender chip and receiver chip.
+ *
+ * @property appIconDrawable a drawable representing the icon of the app playing the media.
+ */
+open class MediaTttChipState(
+ internal val appIconDrawable: Drawable
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttChipState.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index 62e3b1ac8d5c..24943b9e2a1e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttChipState.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -14,52 +14,52 @@
* limitations under the License.
*/
-package com.android.systemui.media.taptotransfer
+package com.android.systemui.media.taptotransfer.sender
import android.graphics.drawable.Drawable
import androidx.annotation.StringRes
import com.android.systemui.R
+import com.android.systemui.media.taptotransfer.common.MediaTttChipState
import java.util.concurrent.Future
/**
- * A class that stores all the information necessary to display the media tap-to-transfer chip in
- * certain states.
+ * A class that stores all the information necessary to display the media tap-to-transfer chip on
+ * the sender device.
*
* This is a sealed class where each subclass represents a specific chip state. Each subclass can
* contain additional information that is necessary for only that state.
*
* @property chipText a string resource for the text that the chip should display.
* @property otherDeviceName the name of the other device involved in the transfer.
- * @property appIconDrawable a drawable representing the icon of the app playing the media.
*/
-sealed class MediaTttChipState(
+sealed class ChipStateSender(
+ appIconDrawable: Drawable,
@StringRes internal val chipText: Int,
internal val otherDeviceName: String,
- internal val appIconDrawable: Drawable,
-)
+) : MediaTttChipState(appIconDrawable)
/**
* A state representing that the two devices are close but not close enough to initiate a transfer.
* The chip will instruct the user to move closer in order to initiate the transfer.
*/
class MoveCloserToTransfer(
+ appIconDrawable: Drawable,
otherDeviceName: String,
- appIconDrawable: Drawable
-) : MediaTttChipState(R.string.media_move_closer_to_transfer, otherDeviceName, appIconDrawable)
+) : ChipStateSender(appIconDrawable, R.string.media_move_closer_to_transfer, otherDeviceName)
/**
* A state representing that a transfer has been initiated (but not completed).
*
* @property future a future that will be resolved when the transfer has either succeeded or failed.
* If the transfer succeeded, the future can optionally return an undo runnable (see
- * [TransferSucceeded.undoRunnable]). [MediaTttChipController] is responsible for transitioning
+ * [TransferSucceeded.undoRunnable]). [MediaTttChipControllerSender] is responsible for transitioning
* the chip to the [TransferSucceeded] state if the future resolves successfully.
*/
class TransferInitiated(
- otherDeviceName: String,
appIconDrawable: Drawable,
+ otherDeviceName: String,
val future: Future<Runnable?>
-) : MediaTttChipState(R.string.media_transfer_playing, otherDeviceName, appIconDrawable)
+) : ChipStateSender(appIconDrawable, R.string.media_transfer_playing, otherDeviceName)
/**
* A state representing that a transfer has been successfully completed.
@@ -68,7 +68,7 @@ class TransferInitiated(
* show an Undo button on the chip if this runnable is present.
*/
class TransferSucceeded(
- otherDeviceName: String,
appIconDrawable: Drawable,
+ otherDeviceName: String,
val undoRunnable: Runnable? = null
-) : MediaTttChipState(R.string.media_transfer_playing, otherDeviceName, appIconDrawable)
+) : ChipStateSender(appIconDrawable, R.string.media_transfer_playing, otherDeviceName)
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttChipController.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index 2b55d634b382..fce4b98f9abe 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttChipController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -14,71 +14,40 @@
* limitations under the License.
*/
-package com.android.systemui.media.taptotransfer
+package com.android.systemui.media.taptotransfer.sender
-import android.annotation.SuppressLint
import android.content.Context
-import android.graphics.PixelFormat
-import android.view.Gravity
-import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
import android.view.WindowManager
-import android.widget.LinearLayout
import android.widget.TextView
-import com.android.internal.widget.CachingIconView
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
import javax.inject.Inject
-const val TAG = "MediaTapToTransfer"
-
/**
- * A controller to display and hide the Media Tap-To-Transfer chip. This chip is shown when a user
- * is currently playing media on a local "media cast sender" device (e.g. a phone) and gets close
- * enough to a "media cast receiver" device (e.g. a tablet). This chip encourages the user to
- * transfer the media from the sender device to the receiver device.
+ * A controller to display and hide the Media Tap-To-Transfer chip on the **sending** device. This
+ * chip is shown when a user is transferring media to/from this device and a receiver device.
*/
@SysUISingleton
-class MediaTttChipController @Inject constructor(
- private val context: Context,
- private val windowManager: WindowManager,
+class MediaTttChipControllerSender @Inject constructor(
+ context: Context,
+ windowManager: WindowManager,
@Main private val mainExecutor: Executor,
@Background private val backgroundExecutor: Executor,
+) : MediaTttChipControllerCommon<ChipStateSender>(
+ context, windowManager, R.layout.media_ttt_chip
) {
- @SuppressLint("WrongConstant") // We're allowed to use TYPE_VOLUME_OVERLAY
- private val windowLayoutParams = WindowManager.LayoutParams().apply {
- width = WindowManager.LayoutParams.WRAP_CONTENT
- height = WindowManager.LayoutParams.WRAP_CONTENT
- gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
- type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY
- flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- title = "Media Tap-To-Transfer Chip View"
- format = PixelFormat.TRANSLUCENT
- setTrustedOverlay()
- }
-
- /** The chip view currently being displayed. Null if the chip is not being displayed. */
- private var chipView: LinearLayout? = null
-
/** Displays the chip view for the given state. */
- fun displayChip(chipState: MediaTttChipState) {
- val oldChipView = chipView
- if (chipView == null) {
- chipView = LayoutInflater
- .from(context)
- .inflate(R.layout.media_ttt_chip, null) as LinearLayout
- }
- val currentChipView = chipView!!
-
+ override fun updateChipView(chipState: ChipStateSender, currentChipView: ViewGroup) {
// App icon
- currentChipView.findViewById<CachingIconView>(R.id.app_icon).apply {
- this.setImageDrawable(chipState.appIconDrawable)
- }
+ setIcon(chipState, currentChipView)
// Text
currentChipView.requireViewById<TextView>(R.id.text).apply {
@@ -108,18 +77,6 @@ class MediaTttChipController @Inject constructor(
if (chipState is TransferInitiated) {
addFutureCallback(chipState)
}
-
- // Add view if necessary
- if (oldChipView == null) {
- windowManager.addView(chipView, windowLayoutParams)
- }
- }
-
- /** Hides the chip. */
- fun removeChip() {
- if (chipView == null) { return }
- windowManager.removeView(chipView)
- chipView = null
}
/**
@@ -136,7 +93,7 @@ class MediaTttChipController @Inject constructor(
mainExecutor.execute {
displayChip(
TransferSucceeded(
- chipState.otherDeviceName, chipState.appIconDrawable, undoRunnable
+ chipState.appIconDrawable, chipState.otherDeviceName, undoRunnable
)
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
index 91b529875654..b29e4b85f81c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
@@ -18,6 +18,10 @@ package com.android.systemui.media.taptotransfer
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender
+import com.android.systemui.media.taptotransfer.sender.MoveCloserToTransfer
+import com.android.systemui.media.taptotransfer.sender.TransferInitiated
+import com.android.systemui.media.taptotransfer.sender.TransferSucceeded
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.concurrency.FakeExecutor
@@ -42,14 +46,17 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
private lateinit var mediaTttCommandLineHelper: MediaTttCommandLineHelper
@Mock
- private lateinit var mediaTttChipController: MediaTttChipController
+ private lateinit var mediaTttChipControllerSender: MediaTttChipControllerSender
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
mediaTttCommandLineHelper =
MediaTttCommandLineHelper(
- commandRegistry, context, mediaTttChipController, FakeExecutor(FakeSystemClock())
+ commandRegistry,
+ context,
+ mediaTttChipControllerSender,
+ FakeExecutor(FakeSystemClock())
)
}
@@ -75,28 +82,28 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
fun moveCloserToTransfer_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(pw, getMoveCloserToTransferCommand())
- verify(mediaTttChipController).displayChip(any(MoveCloserToTransfer::class.java))
+ verify(mediaTttChipControllerSender).displayChip(any(MoveCloserToTransfer::class.java))
}
@Test
fun transferInitiated_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(pw, getTransferInitiatedCommand())
- verify(mediaTttChipController).displayChip(any(TransferInitiated::class.java))
+ verify(mediaTttChipControllerSender).displayChip(any(TransferInitiated::class.java))
}
@Test
fun transferSucceeded_chipDisplayWithCorrectState() {
commandRegistry.onShellCommand(pw, getTransferSucceededCommand())
- verify(mediaTttChipController).displayChip(any(TransferSucceeded::class.java))
+ verify(mediaTttChipControllerSender).displayChip(any(TransferSucceeded::class.java))
}
@Test
fun removeCommand_chipRemoved() {
commandRegistry.onShellCommand(pw, arrayOf(REMOVE_CHIP_COMMAND_TAG))
- verify(mediaTttChipController).removeChip()
+ verify(mediaTttChipControllerSender).removeChip()
}
private fun getMoveCloserToTransferCommand(): Array<String> =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
new file mode 100644
index 000000000000..b74ba2646ba3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.media.taptotransfer.common
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
+import android.view.ViewGroup
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+class MediaTttChipControllerCommonTest : SysuiTestCase() {
+ private lateinit var controllerCommon: MediaTttChipControllerCommon<MediaTttChipState>
+
+ private lateinit var appIconDrawable: Drawable
+ @Mock
+ private lateinit var windowManager: WindowManager
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ appIconDrawable = Icon.createWithResource(context, R.drawable.ic_cake).loadDrawable(context)
+ controllerCommon = TestControllerCommon(context, windowManager)
+ }
+
+ @Test
+ fun displayChip_chipAdded() {
+ controllerCommon.displayChip(MediaTttChipState(appIconDrawable))
+
+ verify(windowManager).addView(any(), any())
+ }
+
+ @Test
+ fun displayChip_twice_chipNotAddedTwice() {
+ controllerCommon.displayChip(MediaTttChipState(appIconDrawable))
+ reset(windowManager)
+
+ controllerCommon.displayChip(MediaTttChipState(appIconDrawable))
+ verify(windowManager, never()).addView(any(), any())
+ }
+
+ @Test
+ fun removeChip_chipRemoved() {
+ // First, add the chip
+ controllerCommon.displayChip(MediaTttChipState(appIconDrawable))
+
+ // Then, remove it
+ controllerCommon.removeChip()
+
+ verify(windowManager).removeView(any())
+ }
+
+ @Test
+ fun removeChip_noAdd_viewNotRemoved() {
+ controllerCommon.removeChip()
+
+ verify(windowManager, never()).removeView(any())
+ }
+
+ inner class TestControllerCommon(
+ context: Context,
+ windowManager: WindowManager
+ ) : MediaTttChipControllerCommon<MediaTttChipState>(
+ context, windowManager, R.layout.media_ttt_chip
+ ) {
+ override fun updateChipView(chipState: MediaTttChipState, currentChipView: ViewGroup) {
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttChipControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index de6525a2e750..028ec55ce28e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttChipControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.media.taptotransfer
+package com.android.systemui.media.taptotransfer.sender
import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
@@ -35,21 +35,19 @@ import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.concurrent.Future
@SmallTest
-class MediaTttChipControllerTest : SysuiTestCase() {
+class MediaTttChipControllerSenderTest : SysuiTestCase() {
private lateinit var appIconDrawable: Drawable
private lateinit var fakeMainClock: FakeSystemClock
private lateinit var fakeMainExecutor: FakeExecutor
private lateinit var fakeBackgroundClock: FakeSystemClock
private lateinit var fakeBackgroundExecutor: FakeExecutor
- private lateinit var mediaTttChipController: MediaTttChipController
+ private lateinit var controllerSender: MediaTttChipControllerSender
@Mock
private lateinit var windowManager: WindowManager
@@ -62,48 +60,14 @@ class MediaTttChipControllerTest : SysuiTestCase() {
fakeMainExecutor = FakeExecutor(fakeMainClock)
fakeBackgroundClock = FakeSystemClock()
fakeBackgroundExecutor = FakeExecutor(fakeBackgroundClock)
- mediaTttChipController = MediaTttChipController(
+ controllerSender = MediaTttChipControllerSender(
context, windowManager, fakeMainExecutor, fakeBackgroundExecutor
)
}
@Test
- fun displayChip_chipAdded() {
- mediaTttChipController.displayChip(moveCloserToTransfer())
-
- verify(windowManager).addView(any(), any())
- }
-
- @Test
- fun displayChip_twice_chipNotAddedTwice() {
- mediaTttChipController.displayChip(moveCloserToTransfer())
- reset(windowManager)
-
- mediaTttChipController.displayChip(moveCloserToTransfer())
- verify(windowManager, never()).addView(any(), any())
- }
-
- @Test
- fun removeChip_chipRemoved() {
- // First, add the chip
- mediaTttChipController.displayChip(moveCloserToTransfer())
-
- // Then, remove it
- mediaTttChipController.removeChip()
-
- verify(windowManager).removeView(any())
- }
-
- @Test
- fun removeChip_noAdd_viewNotRemoved() {
- mediaTttChipController.removeChip()
-
- verify(windowManager, never()).removeView(any())
- }
-
- @Test
fun moveCloserToTransfer_appIcon_chipTextContainsDeviceName_noLoadingIcon_noUndo() {
- mediaTttChipController.displayChip(moveCloserToTransfer())
+ controllerSender.displayChip(moveCloserToTransfer())
val chipView = getChipView()
assertThat(chipView.getAppIconDrawable()).isEqualTo(appIconDrawable)
@@ -115,7 +79,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
@Test
fun transferInitiated_futureNotResolvedYet_appIcon_loadingIcon_noUndo() {
val future: SettableFuture<Runnable?> = SettableFuture.create()
- mediaTttChipController.displayChip(transferInitiated(future))
+ controllerSender.displayChip(transferInitiated(future))
// Don't resolve the future in any way and don't run our executors
@@ -132,7 +96,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
val future: SettableFuture<Runnable?> = SettableFuture.create()
val undoRunnable = Runnable { }
- mediaTttChipController.displayChip(transferInitiated(future))
+ controllerSender.displayChip(transferInitiated(future))
future.set(undoRunnable)
fakeBackgroundExecutor.advanceClockToLast()
@@ -153,7 +117,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
fun transferInitiated_futureCancelled_chipRemoved() {
val future: SettableFuture<Runnable?> = SettableFuture.create()
- mediaTttChipController.displayChip(transferInitiated(future))
+ controllerSender.displayChip(transferInitiated(future))
future.cancel(true)
fakeBackgroundExecutor.advanceClockToLast()
@@ -170,7 +134,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
@Test
fun transferInitiated_futureNotResolvedAfterTimeout_chipRemoved() {
val future: SettableFuture<Runnable?> = SettableFuture.create()
- mediaTttChipController.displayChip(transferInitiated(future))
+ controllerSender.displayChip(transferInitiated(future))
// We won't set anything on the future, but we will still run the executors so that we're
// waiting on the future resolving. If we have a bug in our code, then this test will time
@@ -188,7 +152,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
@Test
fun transferSucceeded_appIcon_chipTextContainsDeviceName_noLoadingIcon() {
- mediaTttChipController.displayChip(transferSucceeded())
+ controllerSender.displayChip(transferSucceeded())
val chipView = getChipView()
assertThat(chipView.getAppIconDrawable()).isEqualTo(appIconDrawable)
@@ -198,7 +162,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
@Test
fun transferSucceededNullUndoRunnable_noUndo() {
- mediaTttChipController.displayChip(transferSucceeded(undoRunnable = null))
+ controllerSender.displayChip(transferSucceeded(undoRunnable = null))
val chipView = getChipView()
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
@@ -206,7 +170,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
@Test
fun transferSucceededWithUndoRunnable_undoWithClick() {
- mediaTttChipController.displayChip(transferSucceeded { })
+ controllerSender.displayChip(transferSucceeded { })
val chipView = getChipView()
assertThat(chipView.getUndoButton().visibility).isEqualTo(View.VISIBLE)
@@ -218,7 +182,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
var runnableRun = false
val runnable = Runnable { runnableRun = true }
- mediaTttChipController.displayChip(transferSucceeded(undoRunnable = runnable))
+ controllerSender.displayChip(transferSucceeded(undoRunnable = runnable))
getChipView().getUndoButton().performClick()
assertThat(runnableRun).isTrue()
@@ -226,32 +190,32 @@ class MediaTttChipControllerTest : SysuiTestCase() {
@Test
fun changeFromCloserToTransferToTransferInitiated_loadingIconAppears() {
- mediaTttChipController.displayChip(moveCloserToTransfer())
- mediaTttChipController.displayChip(transferInitiated())
+ controllerSender.displayChip(moveCloserToTransfer())
+ controllerSender.displayChip(transferInitiated())
assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
}
@Test
fun changeFromTransferInitiatedToTransferSucceeded_loadingIconDisappears() {
- mediaTttChipController.displayChip(transferInitiated())
- mediaTttChipController.displayChip(transferSucceeded())
+ controllerSender.displayChip(transferInitiated())
+ controllerSender.displayChip(transferSucceeded())
assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.GONE)
}
@Test
fun changeFromTransferInitiatedToTransferSucceeded_undoButtonAppears() {
- mediaTttChipController.displayChip(transferInitiated())
- mediaTttChipController.displayChip(transferSucceeded { })
+ controllerSender.displayChip(transferInitiated())
+ controllerSender.displayChip(transferSucceeded { })
assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.VISIBLE)
}
@Test
fun changeFromTransferSucceededToMoveCloser_undoButtonDisappears() {
- mediaTttChipController.displayChip(transferSucceeded())
- mediaTttChipController.displayChip(moveCloserToTransfer())
+ controllerSender.displayChip(transferSucceeded())
+ controllerSender.displayChip(moveCloserToTransfer())
assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.GONE)
}
@@ -274,17 +238,17 @@ class MediaTttChipControllerTest : SysuiTestCase() {
}
/** Helper method providing default parameters to not clutter up the tests. */
- private fun moveCloserToTransfer() = MoveCloserToTransfer(DEVICE_NAME, appIconDrawable)
+ private fun moveCloserToTransfer() = MoveCloserToTransfer(appIconDrawable, DEVICE_NAME)
/** Helper method providing default parameters to not clutter up the tests. */
private fun transferInitiated(
future: Future<Runnable?> = TEST_FUTURE
- ) = TransferInitiated(DEVICE_NAME, appIconDrawable, future)
+ ) = TransferInitiated(appIconDrawable, DEVICE_NAME, future)
/** Helper method providing default parameters to not clutter up the tests. */
private fun transferSucceeded(
undoRunnable: Runnable? = null
- ) = TransferSucceeded(DEVICE_NAME, appIconDrawable, undoRunnable)
+ ) = TransferSucceeded(appIconDrawable, DEVICE_NAME, undoRunnable)
}
private const val DEVICE_NAME = "My Tablet"