summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/chipbar.xml4
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt28
7 files changed, 80 insertions, 18 deletions
diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml
index 8fa975be43d2..e1b8ab469765 100644
--- a/packages/SystemUI/res/layout/chipbar.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -49,7 +49,7 @@
android:alpha="0.0"
/>
- <!-- LINT.IfChange textColor -->
+ <!-- LINT.IfChange -->
<TextView
android:id="@+id/text"
android:layout_width="0dp"
@@ -78,7 +78,7 @@
android:layout_height="@dimen/chipbar_end_icon_size"
android:layout_marginStart="@dimen/chipbar_end_item_start_margin"
android:src="@drawable/ic_warning"
- android:tint="@color/GM2_red_600"
+ android:tint="@color/GM2_red_800"
android:alpha="0.0"
/>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 0350cd7dab98..8cf0fb2537cc 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -160,8 +160,8 @@
<color name="GM2_red_300">#F28B82</color>
<color name="GM2_red_500">#EA4335</color>
- <color name="GM2_red_600">#B3261E</color>
<color name="GM2_red_700">#C5221F</color>
+ <color name="GM2_red_800">#B3261E</color>
<color name="GM2_blue_300">#8AB4F8</color>
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index cbb61b37b7a4..117035422c51 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -181,7 +181,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_START);
} else {
updateState(false);
- createErrorNotification();
+ createErrorStartingNotification();
stopForeground(STOP_FOREGROUND_DETACH);
stopSelf();
return Service.START_NOT_STICKY;
@@ -272,17 +272,30 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
}
/**
- * Simple error notification, needed since startForeground must be called to avoid errors
+ * Simple "error starting" notification, needed since startForeground must be called to avoid
+ * errors.
*/
@VisibleForTesting
- protected void createErrorNotification() {
+ protected void createErrorStartingNotification() {
+ createErrorNotification(strings().getStartError());
+ }
+
+ /**
+ * Simple "error saving" notification, needed since startForeground must be called to avoid
+ * errors.
+ */
+ @VisibleForTesting
+ protected void createErrorSavingNotification() {
+ createErrorNotification(strings().getSaveError());
+ }
+
+ private void createErrorNotification(String notificationContentTitle) {
Bundle extras = new Bundle();
extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, strings().getTitle());
- String notificationTitle = strings().getStartError();
Notification.Builder builder = new Notification.Builder(this, getChannelId())
.setSmallIcon(R.drawable.ic_screenrecord)
- .setContentTitle(notificationTitle)
+ .setContentTitle(notificationContentTitle)
.addExtras(extras);
startForeground(mNotificationId, builder.build());
}
@@ -427,11 +440,11 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
// let's release the recorder and delete all temporary files in this case
getRecorder().release();
}
- showErrorToast(R.string.screenrecord_start_error);
+ showErrorToast(R.string.screenrecord_save_error);
Log.e(getTag(), "stopRecording called, but there was an error when ending"
+ "recording");
exception.printStackTrace();
- createErrorNotification();
+ createErrorSavingNotification();
} catch (Throwable throwable) {
if (getRecorder() != null) {
// Something unexpected happen, SystemUI will crash but let's delete
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index 6ba4fefd6f3c..9e6cacb8b9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -41,6 +41,7 @@ import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.ChipTransitionHelper
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
+import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -64,7 +65,8 @@ constructor(
@StatusBarChipsLog private val logger: LogBuffer,
) : OngoingActivityChipViewModel {
- private val internalChip =
+ /** A direct mapping from [ScreenRecordChipModel] to [OngoingActivityChipModel]. */
+ private val simpleChip =
interactor.screenRecordState
.map { state ->
when (state) {
@@ -105,10 +107,31 @@ constructor(
// See b/347726238 for [SharingStarted.Lazily] reasoning.
.stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden())
+ /**
+ * The screen record chip to show that also ensures that the start time doesn't change once we
+ * enter the recording state. If we change the start time while we're recording, the chronometer
+ * could skip a second. See b/349620526.
+ */
+ private val chipWithConsistentTimer: StateFlow<OngoingActivityChipModel> =
+ simpleChip
+ .pairwise(initialValue = OngoingActivityChipModel.Hidden())
+ .map { (old, new) ->
+ if (
+ old is OngoingActivityChipModel.Shown.Timer &&
+ new is OngoingActivityChipModel.Shown.Timer
+ ) {
+ new.copy(startTimeMs = old.startTimeMs)
+ } else {
+ new
+ }
+ }
+ // See b/347726238 for [SharingStarted.Lazily] reasoning.
+ .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden())
+
private val chipTransitionHelper = ChipTransitionHelper(scope)
override val chip: StateFlow<OngoingActivityChipModel> =
- chipTransitionHelper.createChipFlow(internalChip)
+ chipTransitionHelper.createChipFlow(chipWithConsistentTimer)
private fun createDelegate(
recordedTask: ActivityManager.RunningTaskInfo?
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
index 130b1170c9f1..8a5165d8df7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.chips.ui.model
import android.content.Context
import android.content.res.ColorStateList
-import android.view.ContextThemeWrapper
import androidx.annotation.ColorInt
import com.android.settingslib.Utils
import com.android.systemui.res.R
@@ -43,9 +42,7 @@ sealed interface ColorsModel {
/** The chip should have a red background with white text. */
data object Red : ColorsModel {
override fun background(context: Context): ColorStateList {
- val themedContext =
- ContextThemeWrapper(context, com.android.internal.R.style.Theme_DeviceDefault_Light)
- return Utils.getColorAttr(themedContext, com.android.internal.R.attr.materialColorError)
+ return ColorStateList.valueOf(context.getColor(R.color.GM2_red_700))
}
override fun text(context: Context) = context.getColor(android.R.color.white)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index f866f740345e..79c206c1a838 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -126,7 +126,8 @@ public class RecordingServiceTest extends SysuiTestCase {
doNothing().when(mRecordingService).createRecordingNotification();
doReturn(mNotification).when(mRecordingService).createProcessingNotification();
doReturn(mNotification).when(mRecordingService).createSaveNotification(any());
- doNothing().when(mRecordingService).createErrorNotification();
+ doNothing().when(mRecordingService).createErrorStartingNotification();
+ doNothing().when(mRecordingService).createErrorSavingNotification();
doNothing().when(mRecordingService).showErrorToast(anyInt());
doNothing().when(mRecordingService).stopForeground(anyInt());
@@ -234,7 +235,7 @@ public class RecordingServiceTest extends SysuiTestCase {
mRecordingService.onStopped();
- verify(mRecordingService).createErrorNotification();
+ verify(mRecordingService).createErrorSavingNotification();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index e68fa0bc6eb3..804eb5cf597c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -231,6 +231,34 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(5678)
}
+ /** Regression test for b/349620526. */
+ @Test
+ fun chip_recordingState_thenGetsTaskInfo_startTimeDoesNotChange() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ // Start recording, but without any task info
+ systemClock.setElapsedRealtime(1234)
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
+
+ // WHEN we receive the recording task info a few milliseconds later
+ systemClock.setElapsedRealtime(1240)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ "host.package",
+ hostDeviceName = null,
+ FakeActivityTaskManager.createTask(taskId = 1)
+ )
+
+ // THEN the start time is still the old start time
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
+ }
+
@Test
fun chip_notProjecting_clickListenerShowsDialog() =
testScope.runTest {