Merge "Do not show the satellite icon when wifi is connected" into main
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index c95d6ff..a23df79 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -951,7 +951,7 @@
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
boolean creating, boolean sizeChanged, boolean hintChanged, boolean relativeZChanged,
- Transaction surfaceUpdateTransaction) {
+ boolean hdrHeadroomChanged, Transaction surfaceUpdateTransaction) {
boolean realSizeChanged = false;
mSurfaceLock.lock();
@@ -986,7 +986,7 @@
updateBackgroundVisibility(surfaceUpdateTransaction);
updateBackgroundColor(surfaceUpdateTransaction);
- if (mLimitedHdrEnabled) {
+ if (mLimitedHdrEnabled && hdrHeadroomChanged) {
surfaceUpdateTransaction.setDesiredHdrHeadroom(
mBlastSurfaceControl, mHdrHeadroom);
}
@@ -1203,7 +1203,7 @@
}
final boolean realSizeChanged = performSurfaceTransaction(viewRoot, translator,
- creating, sizeChanged, hintChanged, relativeZChanged,
+ creating, sizeChanged, hintChanged, relativeZChanged, hdrHeadroomChanged,
surfaceUpdateTransaction);
try {
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp
index 4bd2d72..01920de 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.cpp
+++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp
@@ -42,7 +42,11 @@
bool punchHoles(const char *filePath, const uint64_t offset,
const std::vector<Elf64_Phdr> &programHeaders) {
struct stat64 beforePunch;
- lstat64(filePath, &beforePunch);
+ if (int result = lstat64(filePath, &beforePunch); result != 0) {
+ ALOGE("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ return false;
+ }
+
uint64_t blockSize = beforePunch.st_blksize;
IF_ALOGD() {
ALOGD("Total number of LOAD segments %zu", programHeaders.size());
@@ -152,7 +156,10 @@
IF_ALOGD() {
struct stat64 afterPunch;
- lstat64(filePath, &afterPunch);
+ if (int result = lstat64(filePath, &afterPunch); result != 0) {
+ ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ return false;
+ }
ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %ld, st_size: %" PRIu64
"",
afterPunch.st_blocks, afterPunch.st_blksize,
@@ -177,7 +184,7 @@
// only consider elf64 for punching holes
if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) {
- ALOGE("Provided file is not ELF64");
+ ALOGW("Provided file is not ELF64");
return false;
}
@@ -215,4 +222,108 @@
return punchHoles(filePath, offset, programHeaders);
}
+bool punchHolesInZip(const char *filePath, uint64_t offset, uint16_t extraFieldLen) {
+ android::base::unique_fd fd(open(filePath, O_RDWR | O_CLOEXEC));
+ if (!fd.ok()) {
+ ALOGE("Can't open file to punch %s", filePath);
+ return false;
+ }
+
+ struct stat64 beforePunch;
+ if (int result = lstat64(filePath, &beforePunch); result != 0) {
+ ALOGE("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ return false;
+ }
+
+ uint64_t blockSize = beforePunch.st_blksize;
+ IF_ALOGD() {
+ ALOGD("Extra field length: %hu, Size before punching holes st_blocks: %" PRIu64
+ ", st_blksize: %ld, st_size: %" PRIu64 "",
+ extraFieldLen, beforePunch.st_blocks, beforePunch.st_blksize,
+ static_cast<uint64_t>(beforePunch.st_size));
+ }
+
+ if (extraFieldLen < blockSize) {
+ ALOGD("Skipping punching apk as extra field length is less than block size");
+ return false;
+ }
+
+ // content is preceded by extra field. Zip offset is offset of exact content.
+ // move back by extraFieldLen so that scan can be started at start of extra field.
+ uint64_t extraFieldStart;
+ if (__builtin_sub_overflow(offset, extraFieldLen, &extraFieldStart)) {
+ ALOGE("Overflow occurred when calculating start of extra field");
+ return false;
+ }
+
+ constexpr uint64_t kMaxSize = 64 * 1024;
+ // Use malloc to gracefully handle any oom conditions
+ std::unique_ptr<uint8_t, decltype(&free)> buffer(static_cast<uint8_t *>(malloc(kMaxSize)),
+ &free);
+ if (buffer == nullptr) {
+ ALOGE("Failed to allocate read buffer");
+ return false;
+ }
+
+ // Read the entire extra fields at once and punch file according to zero stretches.
+ if (!ReadFullyAtOffset(fd, buffer.get(), extraFieldLen, extraFieldStart)) {
+ ALOGE("Failed to read extra field content");
+ return false;
+ }
+
+ IF_ALOGD() {
+ ALOGD("Extra field length: %hu content near offset: %s", extraFieldLen,
+ HexString(buffer.get(), extraFieldLen).c_str());
+ }
+
+ uint64_t currentSize = 0;
+ while (currentSize < extraFieldLen) {
+ uint64_t end = currentSize;
+ // find zero ranges
+ while (end < extraFieldLen && *(buffer.get() + end) == 0) {
+ ++end;
+ }
+
+ uint64_t punchLen;
+ if (__builtin_sub_overflow(end, currentSize, &punchLen)) {
+ ALOGW("Overflow occurred when calculating punching length");
+ return false;
+ }
+
+ // Don't punch for every stretch of zero which is found
+ if (punchLen > blockSize) {
+ uint64_t punchOffset;
+ if (__builtin_add_overflow(extraFieldStart, currentSize, &punchOffset)) {
+ ALOGW("Overflow occurred when calculating punch start offset");
+ return false;
+ }
+
+ ALOGD("Punching hole in apk start: %" PRIu64 " len:%" PRIu64 "", punchOffset, punchLen);
+
+ // Punch hole for this entire stretch.
+ int result = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, punchOffset,
+ punchLen);
+ if (result < 0) {
+ ALOGE("fallocate failed to punch hole inside apk, error:%d", errno);
+ return false;
+ }
+ }
+ currentSize = end;
+ ++currentSize;
+ }
+
+ IF_ALOGD() {
+ struct stat64 afterPunch;
+ if (int result = lstat64(filePath, &afterPunch); result != 0) {
+ ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ return false;
+ }
+ ALOGD("punchHolesInApk:: Size after punching holes st_blocks: %" PRIu64
+ ", st_blksize: %ld, st_size: %" PRIu64 "",
+ afterPunch.st_blocks, afterPunch.st_blksize,
+ static_cast<uint64_t>(afterPunch.st_size));
+ }
+ return true;
+}
+
}; // namespace android
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.h b/core/jni/com_android_internal_content_FileSystemUtils.h
index a6b145c..52445e2 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.h
+++ b/core/jni/com_android_internal_content_FileSystemUtils.h
@@ -28,4 +28,11 @@
*/
bool punchHolesInElf64(const char* filePath, uint64_t offset);
+/*
+ * This function punches holes in zero segments of Apk file which are introduced during the
+ * alignment. Alignment tools add padding inside of extra field in local file header. punch holes in
+ * extra field for zero stretches till the actual file content.
+ */
+bool punchHolesInZip(const char* filePath, uint64_t offset, uint16_t extraFieldLen);
+
} // namespace android
\ No newline at end of file
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index faa83f8..9b8dab7 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/statfs.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@@ -145,8 +146,9 @@
uint16_t method;
off64_t offset;
-
- if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, nullptr, &offset, &when, &crc)) {
+ uint16_t extraFieldLength;
+ if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, nullptr, &offset, &when, &crc,
+ &extraFieldLength)) {
ALOGE("Couldn't read zip entry info\n");
return INSTALL_FAILED_INVALID_APK;
}
@@ -177,6 +179,12 @@
"%" PRIu64 "",
fileName, zipFile->getZipFileName(), offset);
}
+
+ // if extra field for this zip file is present with some length, possibility is that it is
+ // padding added for zip alignment. Punch holes there too.
+ if (!punchHolesInZip(zipFile->getZipFileName(), offset, extraFieldLength)) {
+ ALOGW("Failed to punch apk : %s at extra field", zipFile->getZipFileName());
+ }
#endif // ENABLE_PUNCH_HOLES
return INSTALL_SUCCEEDED;
@@ -279,6 +287,25 @@
return INSTALL_FAILED_CONTAINER_ERROR;
}
+#ifdef ENABLE_PUNCH_HOLES
+ // punch extracted elf files as well. This will fail where compression is on (like f2fs) but it
+ // will be useful for ext4 based systems
+ struct statfs64 fsInfo;
+ int result = statfs64(localFileName, &fsInfo);
+ if (result < 0) {
+ ALOGW("Failed to stat file :%s", localFileName);
+ }
+
+ if (result == 0 && fsInfo.f_type == EXT4_SUPER_MAGIC) {
+ ALOGD("Punching extracted elf file %s on fs:%" PRIu64 "", fileName,
+ static_cast<uint64_t>(fsInfo.f_type));
+ if (!punchHolesInElf64(localFileName, 0)) {
+ ALOGW("Failed to punch extracted elf file :%s from apk : %s", fileName,
+ zipFile->getZipFileName());
+ }
+ }
+#endif // ENABLE_PUNCH_HOLES
+
ALOGV("Successfully moved %s to %s\n", localTmpFileName, localFileName);
return INSTALL_SUCCEEDED;
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 34a6bc2..839c7b6 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -119,30 +119,41 @@
* appear to be bogus.
*/
bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
+ uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
+ uint32_t* pModWhen, uint32_t* pCrc32) const
+{
+ return getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset, pModWhen,
+ pCrc32, nullptr);
+}
+
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
- uint32_t* pModWhen, uint32_t* pCrc32) const
+ uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const
{
const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
const ZipEntry& ze = zipEntry->entry;
- if (pMethod != NULL) {
+ if (pMethod != nullptr) {
*pMethod = ze.method;
}
- if (pUncompLen != NULL) {
+ if (pUncompLen != nullptr) {
*pUncompLen = ze.uncompressed_length;
}
- if (pCompLen != NULL) {
+ if (pCompLen != nullptr) {
*pCompLen = ze.compressed_length;
}
- if (pOffset != NULL) {
+ if (pOffset != nullptr) {
*pOffset = ze.offset;
}
- if (pModWhen != NULL) {
+ if (pModWhen != nullptr) {
*pModWhen = ze.mod_time;
}
- if (pCrc32 != NULL) {
+ if (pCrc32 != nullptr) {
*pCrc32 = ze.crc32;
}
+ if (pExtraFieldSize != nullptr) {
+ *pExtraFieldSize = ze.extra_field_size;
+ }
return true;
}
diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
index 031d2e8..f7c5007 100644
--- a/libs/androidfw/include/androidfw/ZipFileRO.h
+++ b/libs/androidfw/include/androidfw/ZipFileRO.h
@@ -151,6 +151,10 @@
uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,
uint32_t* pCrc32) const;
+ bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
+ uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
+ uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const;
+
/*
* Create a new FileMap object that maps a subset of the archive. For
* an uncompressed entry this effectively provides a pointer to the
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 34932b1..dc669a5 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -24,7 +24,6 @@
#include <SkImageAndroid.h>
#include <SkImageInfo.h>
#include <SkMatrix.h>
-#include <SkMultiPictureDocument.h>
#include <SkOverdrawCanvas.h>
#include <SkOverdrawColorFilter.h>
#include <SkPicture.h>
@@ -38,6 +37,7 @@
#include <android-base/properties.h>
#include <gui/TraceUtils.h>
#include <include/android/SkSurfaceAndroid.h>
+#include <include/docs/SkMultiPictureDocument.h>
#include <include/encode/SkPngEncoder.h>
#include <include/gpu/ganesh/SkSurfaceGanesh.h>
#include <unistd.h>
@@ -185,7 +185,7 @@
// we need to keep it until after mMultiPic.close()
// procs is passed as a pointer, but just as a method of having an optional default.
// procs doesn't need to outlive this Make call.
- mMultiPic = SkMakeMultiPictureDocument(mOpenMultiPicStream.get(), &procs,
+ mMultiPic = SkMultiPictureDocument::Make(mOpenMultiPicStream.get(), &procs,
[sharingCtx = mSerialContext.get()](const SkPicture* pic) {
SkSharingSerialContext::collectNonTextureImagesFromPicture(pic, sharingCtx);
});
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index cf14b1f..823b209 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -18,7 +18,6 @@
#include <SkColorSpace.h>
#include <SkDocument.h>
-#include <SkMultiPictureDocument.h>
#include <SkSurface.h>
#include "Lighting.h"
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index b62711f..21fe6ff 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -16,10 +16,10 @@
#include "VkFunctorDrawable.h"
-#include <GrBackendDrawableInfo.h>
#include <SkAndroidFrameworkUtils.h>
#include <SkImage.h>
#include <SkM44.h>
+#include <include/gpu/ganesh/vk/GrBackendDrawableInfo.h>
#include <gui/TraceUtils.h>
#include <private/hwui/DrawVkInfo.h>
#include <utils/Color.h>
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 36f6ad2..429bdbf 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -270,6 +270,15 @@
)
}
+ fun getFlowOnMoreOptionOnlySelected() {
+ Log.d(Constants.LOG_TAG, "More Option Only selected")
+ uiState = uiState.copy(
+ getCredentialUiState = uiState.getCredentialUiState?.copy(
+ currentScreenState = GetScreenState.ALL_SIGN_IN_OPTIONS_ONLY
+ )
+ )
+ }
+
fun getFlowOnMoreOptionOnSnackBarSelected(isNoAccount: Boolean) {
Log.d(Constants.LOG_TAG, "More Option on snackBar selected")
uiState = uiState.copy(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
index e088d3a..aa721c9 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
@@ -20,6 +20,7 @@
import android.graphics.Bitmap
import android.hardware.biometrics.BiometricManager
import android.hardware.biometrics.BiometricPrompt
+import android.hardware.biometrics.CryptoObject
import android.os.CancellationSignal
import android.util.Log
import androidx.core.content.ContextCompat.getMainExecutor
@@ -221,13 +222,24 @@
val executor = getMainExecutor(context)
try {
- biometricPrompt.authenticate(cancellationSignal, executor, callback)
+ val cryptoOpId = getCryptoOpId(biometricDisplayInfo)
+ if (cryptoOpId != null) {
+ biometricPrompt.authenticate(
+ BiometricPrompt.CryptoObject(cryptoOpId.toLong()),
+ cancellationSignal, executor, callback)
+ } else {
+ biometricPrompt.authenticate(cancellationSignal, executor, callback)
+ }
} catch (e: IllegalArgumentException) {
Log.w(TAG, "Calling the biometric prompt API failed with: /n${e.localizedMessage}\n")
onBiometricFailureFallback(biometricFlowType)
}
}
+private fun getCryptoOpId(biometricDisplayInfo: BiometricDisplayInfo): Int? {
+ return biometricDisplayInfo.biometricRequestInfo.opId
+}
+
/**
* Sets up the biometric prompt with the UI specific bits.
* // TODO(b/333445112) : Pass in opId once dependency is confirmed via CryptoObject
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
index d13d86f..149c14a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
@@ -349,6 +349,38 @@
}
}
+@Composable
+fun MoreOptionTopAppBarWithCustomNavigation(
+ text: String,
+ onNavigationIconClicked: () -> Unit,
+ navigationIcon: ImageVector,
+ navigationIconContentDescription: String,
+ bottomPadding: Dp,
+) {
+ Row(
+ modifier = Modifier.padding(top = 12.dp, bottom = bottomPadding),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ IconButton(
+ modifier = Modifier.padding(top = 8.dp, bottom = 8.dp, start = 4.dp).size(48.dp),
+ onClick = onNavigationIconClicked
+ ) {
+ Box(
+ modifier = Modifier.size(48.dp),
+ contentAlignment = Alignment.Center,
+ ) {
+ Icon(
+ imageVector = navigationIcon,
+ contentDescription = navigationIconContentDescription,
+ modifier = Modifier.size(24.dp).autoMirrored(),
+ tint = LocalAndroidColorScheme.current.onSurfaceVariant,
+ )
+ }
+ }
+ LargeTitleText(text = text, modifier = Modifier.padding(horizontal = 4.dp))
+ }
+}
+
private fun Modifier.autoMirrored() = composed {
when (LocalLayoutDirection.current) {
LayoutDirection.Rtl -> graphicsLayer(scaleX = -1f)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index c1120bb3..e68baf4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -32,6 +32,7 @@
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.outlined.QrCodeScanner
import androidx.compose.material3.Divider
import androidx.compose.material3.TextButton
@@ -70,6 +71,7 @@
import com.android.credentialmanager.common.ui.LargeLabelTextOnSurfaceVariant
import com.android.credentialmanager.common.ui.ModalBottomSheet
import com.android.credentialmanager.common.ui.MoreOptionTopAppBar
+import com.android.credentialmanager.common.ui.MoreOptionTopAppBarWithCustomNavigation
import com.android.credentialmanager.common.ui.SheetContainerCard
import com.android.credentialmanager.common.ui.Snackbar
import com.android.credentialmanager.common.ui.SnackbarActionText
@@ -148,7 +150,7 @@
.currentScreenState == GetScreenState.BIOMETRIC_SELECTION) {
BiometricSelectionPage(
biometricEntry = getCredentialUiState.activeEntry,
- onMoreOptionSelected = viewModel::getFlowOnMoreOptionSelected,
+ onMoreOptionSelected = viewModel::getFlowOnMoreOptionOnlySelected,
onCancelFlowAndFinish = viewModel::onUserCancel,
onIllegalStateAndFinish = viewModel::onIllegalUiState,
requestDisplayInfo = getCredentialUiState.requestDisplayInfo,
@@ -163,6 +165,28 @@
onBiometricPromptStateChange =
viewModel::onBiometricPromptStateChange
)
+ } else if (credmanBiometricApiEnabled() &&
+ getCredentialUiState.currentScreenState
+ == GetScreenState.ALL_SIGN_IN_OPTIONS_ONLY) {
+ AllSignInOptionCard(
+ providerInfoList = getCredentialUiState.providerInfoList,
+ providerDisplayInfo = getCredentialUiState.providerDisplayInfo,
+ onEntrySelected = viewModel::getFlowOnEntrySelected,
+ onBackButtonClicked = viewModel::onUserCancel,
+ onCancel = viewModel::onUserCancel,
+ onLog = { viewModel.logUiEvent(it) },
+ customTopBar = { MoreOptionTopAppBarWithCustomNavigation(
+ text = stringResource(
+ R.string.get_dialog_title_sign_in_options),
+ onNavigationIconClicked = viewModel::onUserCancel,
+ navigationIcon = Icons.Filled.Close,
+ navigationIconContentDescription =
+ stringResource(R.string.accessibility_close_button),
+ bottomPadding = 0.dp
+ ) }
+ )
+ viewModel.uiMetrics.log(GetCredentialEvent
+ .CREDMAN_GET_CRED_SCREEN_ALL_SIGN_IN_OPTIONS)
} else {
AllSignInOptionCard(
providerInfoList = getCredentialUiState.providerInfoList,
@@ -642,7 +666,13 @@
return providerId
}
-/** Draws the secondary credential selection page, where all sign-in options are listed. */
+/**
+ * Draws the secondary credential selection page, where all sign-in options are listed.
+ *
+ * By default, this card has 'back' navigation whereby user can navigate back to invoke
+ * [onBackButtonClicked]. However if a different top bar with possibly a different navigation
+ * is required, then the caller of this Composable can set a [customTopBar].
+ */
@Composable
fun AllSignInOptionCard(
providerInfoList: List<ProviderInfo>,
@@ -651,16 +681,21 @@
onBackButtonClicked: () -> Unit,
onCancel: () -> Unit,
onLog: @Composable (UiEventEnum) -> Unit,
+ customTopBar: (@Composable() () -> Unit)? = null
) {
val sortedUserNameToCredentialEntryList =
providerDisplayInfo.sortedUserNameToCredentialEntryList
val authenticationEntryList = providerDisplayInfo.authenticationEntryList
SheetContainerCard(topAppBar = {
- MoreOptionTopAppBar(
- text = stringResource(R.string.get_dialog_title_sign_in_options),
- onNavigationIconClicked = onBackButtonClicked,
- bottomPadding = 0.dp,
- )
+ if (customTopBar != null) {
+ customTopBar()
+ } else {
+ MoreOptionTopAppBar(
+ text = stringResource(R.string.get_dialog_title_sign_in_options),
+ onNavigationIconClicked = onBackButtonClicked,
+ bottomPadding = 0.dp,
+ )
+ }
}) {
var isFirstSection = true
// For username
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index b03407b..8e78861 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -163,7 +163,11 @@
/** The single tap biometric selection page. */
BIOMETRIC_SELECTION,
- /** The secondary credential selection page, where all sign-in options are listed. */
+ /**
+ * The secondary credential selection page, where all sign-in options are listed.
+ *
+ * This state is expected to go back to PRIMARY_SELECTION on back navigation
+ */
ALL_SIGN_IN_OPTIONS,
/** The snackbar only page when there's no account but only a remoteEntry. */
@@ -171,6 +175,14 @@
/** The snackbar when there are only auth entries and all of them turn out to be empty. */
UNLOCKED_AUTH_ENTRIES_ONLY,
+
+ /**
+ * The secondary credential selection page, where all sign-in options are listed.
+ *
+ * This state has no option for the user to navigate back to PRIMARY_SELECTION, and
+ * instead can be terminated independently.
+ */
+ ALL_SIGN_IN_OPTIONS_ONLY,
}
@@ -285,7 +297,7 @@
providerDisplayInfo.remoteEntry != null)
GetScreenState.REMOTE_ONLY
else if (isRequestForAllOptions)
- GetScreenState.ALL_SIGN_IN_OPTIONS
+ GetScreenState.ALL_SIGN_IN_OPTIONS_ONLY
else if (isBiometricFlow(providerDisplayInfo, isFlowAutoSelectable(providerDisplayInfo)))
GetScreenState.BIOMETRIC_SELECTION
else GetScreenState.PRIMARY_SELECTION
diff --git a/packages/PrintSpooler/res/values-night/themes.xml b/packages/PrintSpooler/res/values-night/themes.xml
index 4428dbb..3cc64a6 100644
--- a/packages/PrintSpooler/res/values-night/themes.xml
+++ b/packages/PrintSpooler/res/values-night/themes.xml
@@ -30,6 +30,7 @@
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
+ <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
index 4dcad10..bd96025 100644
--- a/packages/PrintSpooler/res/values/themes.xml
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -31,6 +31,7 @@
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowLightStatusBar">true</item>
+ <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index ad3eb92..e77cf2f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -531,13 +531,22 @@
pw.println(" put NAMESPACE KEY VALUE [default]");
pw.println(" Change the contents of KEY to VALUE for the given NAMESPACE.");
pw.println(" {default} to set as the default value.");
+ pw.println(" override NAMESPACE KEY VALUE");
+ pw.println(" Set flag NAMESPACE/KEY to the given VALUE, and ignores "
+ + "server-updates for");
+ pw.println(" this flag. This can still be called even if there is no underlying "
+ + "value set.");
pw.println(" delete NAMESPACE KEY");
pw.println(" Delete the entry for KEY for the given NAMESPACE.");
+ pw.println(" clear_override NAMESPACE KEY");
+ pw.println(" Clear local sticky flag override for KEY in the given NAMESPACE.");
pw.println(" list_namespaces [--public]");
pw.println(" Prints the name of all (or just the public) namespaces.");
pw.println(" list [NAMESPACE]");
pw.println(" Print all keys and values defined, optionally for the given "
+ "NAMESPACE.");
+ pw.println(" list_local_overrides");
+ pw.println(" Print all flags that have been overridden.");
pw.println(" reset RESET_MODE [NAMESPACE]");
pw.println(" Reset all flag values, optionally for a NAMESPACE, according to "
+ "RESET_MODE.");
@@ -547,8 +556,9 @@
+ "flags are reset");
pw.println(" set_sync_disabled_for_tests SYNC_DISABLED_MODE");
pw.println(" Modifies bulk property setting behavior for tests. When in one of the"
- + " disabled modes this ensures that config isn't overwritten.");
- pw.println(" SYNC_DISABLED_MODE is one of:");
+ + " disabled modes");
+ pw.println(" this ensures that config isn't overwritten. SYNC_DISABLED_MODE is "
+ + "one of:");
pw.println(" none: Sync is not disabled. A reboot may be required to restart"
+ " syncing.");
pw.println(" persistent: Sync is disabled, this state will survive a reboot.");
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/fold/ui/composable/UnfoldModifiers.kt b/packages/SystemUI/compose/features/src/com/android/systemui/fold/ui/composable/UnfoldModifiers.kt
new file mode 100644
index 0000000..c2a2696
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/fold/ui/composable/UnfoldModifiers.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 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.fold.ui.composable
+
+import androidx.annotation.FloatRange
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.LayoutDirection
+import com.android.compose.modifiers.padding
+import kotlin.math.roundToInt
+
+/**
+ * Applies a translation that feeds off of the unfold transition that's active while the device is
+ * being folded or unfolded, effectively shifting the element towards the fold hinge.
+ *
+ * @param startSide `true` if the affected element is on the start side (left-hand side in
+ * left-to-right layouts), `false` otherwise.
+ * @param fullTranslation The maximum translation to apply when the element is the most shifted. The
+ * modifier will never apply more than this much translation on the element.
+ * @param unfoldProgress A provider for the amount of progress of the unfold transition. This should
+ * be sourced from the `UnfoldTransitionInteractor`, ideally through a view-model.
+ */
+@Composable
+fun Modifier.unfoldTranslation(
+ startSide: Boolean,
+ fullTranslation: Dp,
+ @FloatRange(from = 0.0, to = 1.0) unfoldProgress: () -> Float,
+): Modifier {
+ val translateToTheRight = startSide && LocalLayoutDirection.current == LayoutDirection.Ltr
+ return this.graphicsLayer {
+ translationX =
+ fullTranslation.toPx() *
+ if (translateToTheRight) {
+ 1 - unfoldProgress()
+ } else {
+ unfoldProgress() - 1
+ }
+ }
+}
+
+/**
+ * Applies horizontal padding that feeds off of the unfold transition that's active while the device
+ * is being folded or unfolded, effectively "squishing" the element on both sides.
+ *
+ * This is horizontal padding so it's applied on both the start and end sides of the element.
+ *
+ * @param fullPadding The maximum padding to apply when the element is the most padded. The modifier
+ * will never apply more than this much horizontal padding on the element.
+ * @param unfoldProgress A provider for the amount of progress of the unfold transition. This should
+ * be sourced from the `UnfoldTransitionInteractor`, ideally through a view-model.
+ */
+@Composable
+fun Modifier.unfoldHorizontalPadding(
+ fullPadding: Dp,
+ @FloatRange(from = 0.0, to = 1.0) unfoldProgress: () -> Float,
+): Modifier {
+ return this.padding(
+ horizontal = { (fullPadding.toPx() * (1 - unfoldProgress())).roundToInt() },
+ )
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 9bd6f81..01c27a4d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -65,6 +65,8 @@
import com.android.compose.modifiers.thenIf
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.fold.ui.composable.unfoldHorizontalPadding
+import com.android.systemui.fold.ui.composable.unfoldTranslation
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
@@ -289,6 +291,7 @@
remember(lifecycleOwner, viewModel) { viewModel.getFooterActionsViewModel(lifecycleOwner) }
val tileSquishiness by
animateSceneFloatAsState(value = 1f, key = QuickSettings.SharedValues.TilesSquishiness)
+ val unfoldTransitionProgress by viewModel.unfoldTransitionProgress.collectAsState()
val navBarBottomHeight = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
val density = LocalDensity.current
@@ -337,10 +340,23 @@
modifier =
Modifier.padding(horizontal = Shade.Dimensions.HorizontalPadding)
.then(brightnessMirrorShowingModifier)
+ .unfoldHorizontalPadding(
+ fullPadding = dimensionResource(R.dimen.notification_side_paddings),
+ ) {
+ unfoldTransitionProgress
+ }
)
Row(modifier = Modifier.fillMaxWidth().weight(1f)) {
- Box(modifier = Modifier.weight(1f)) {
+ Box(
+ modifier =
+ Modifier.weight(1f).unfoldTranslation(
+ startSide = true,
+ fullTranslation = dimensionResource(R.dimen.notification_side_paddings),
+ ) {
+ unfoldTransitionProgress
+ },
+ ) {
BrightnessMirror(
viewModel = viewModel.brightnessMirrorViewModel,
qsSceneAdapter = viewModel.qsSceneAdapter,
@@ -407,7 +423,16 @@
Modifier.weight(1f)
.fillMaxHeight()
.padding(bottom = navBarBottomHeight)
- .then(brightnessMirrorShowingModifier),
+ .then(brightnessMirrorShowingModifier)
+ .unfoldTranslation(
+ startSide = false,
+ fullTranslation =
+ dimensionResource(
+ R.dimen.notification_side_paddings,
+ ),
+ ) {
+ unfoldTransitionProgress
+ },
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 2d4b63e..ae9794a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -50,6 +50,7 @@
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
@@ -65,8 +66,6 @@
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.scene.shared.model.FakeSceneDataSource
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
@@ -87,7 +86,6 @@
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.GlobalSettings
import com.google.common.truth.Truth
-import dagger.Lazy
import java.util.Optional
import junit.framework.Assert
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -171,7 +169,7 @@
private lateinit var sceneInteractor: SceneInteractor
private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
private lateinit var deviceEntryInteractor: DeviceEntryInteractor
- @Mock private lateinit var primaryBouncerInteractor: Lazy<PrimaryBouncerInteractor>
+ @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
private lateinit var sceneTransitionStateFlow: MutableStateFlow<ObservableTransitionState>
private lateinit var fakeSceneDataSource: FakeSceneDataSource
@@ -217,9 +215,13 @@
)
mSetFlagsRule.disableFlags(
FLAG_SIDEFPS_CONTROLLER_REFACTOR,
- AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
- AConfigFlags.FLAG_REFACTOR_KEYGUARD_DISMISS_INTENT,
)
+ if (!com.android.systemui.Flags.sceneContainer()) {
+ mSetFlagsRule.disableFlags(
+ AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR,
+ AConfigFlags.FLAG_REFACTOR_KEYGUARD_DISMISS_INTENT,
+ )
+ }
keyguardPasswordViewController =
KeyguardPasswordViewController(
@@ -268,7 +270,6 @@
falsingManager,
userSwitcherController,
featureFlags,
- kosmos.sceneContainerFlags,
globalSettings,
sessionTracker,
Optional.of(sideFpsController),
@@ -283,7 +284,7 @@
deviceProvisionedController,
faceAuthAccessibilityDelegate,
keyguardTransitionInteractor,
- primaryBouncerInteractor,
+ { primaryBouncerInteractor },
) {
deviceEntryInteractor
}
@@ -804,17 +805,17 @@
}
@Test
+ @EnableSceneContainer
fun dismissesKeyguard_whenSceneChangesToGone() =
kosmos.testScope.runTest {
- kosmos.fakeSceneContainerFlags.enabled = true
// Upon init, we have never dismisses the keyguard.
underTest.onInit()
runCurrent()
- verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor, never())
+ .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
// Once the view is attached, we start listening but simply going to the bouncer scene
- // is
- // not enough to trigger a dismissal of the keyguard.
+ // is not enough to trigger a dismissal of the keyguard.
underTest.onViewAttached()
fakeSceneDataSource.pause()
sceneInteractor.changeScene(Scenes.Bouncer, "reason")
@@ -830,7 +831,8 @@
fakeSceneDataSource.unpause(expectedScene = Scenes.Bouncer)
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Bouncer)
runCurrent()
- verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor, never())
+ .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
// While listening, going from the bouncer scene to the gone scene, does dismiss the
// keyguard.
@@ -852,11 +854,11 @@
fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
runCurrent()
- verify(viewMediatorCallback).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor).notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
// While listening, moving back to the bouncer scene does not dismiss the keyguard
// again.
- clearInvocations(viewMediatorCallback)
+ clearInvocations(primaryBouncerInteractor)
fakeSceneDataSource.pause()
sceneInteractor.changeScene(Scenes.Bouncer, "reason")
sceneTransitionStateFlow.value =
@@ -871,7 +873,8 @@
fakeSceneDataSource.unpause(expectedScene = Scenes.Bouncer)
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Bouncer)
runCurrent()
- verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor, never())
+ .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
// Detaching the view stops listening, so moving from the bouncer scene to the gone
// scene
@@ -891,7 +894,8 @@
fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
runCurrent()
- verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor, never())
+ .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
// While not listening, moving to the lockscreen does not dismiss the keyguard.
fakeSceneDataSource.pause()
@@ -908,7 +912,8 @@
fakeSceneDataSource.unpause(expectedScene = Scenes.Lockscreen)
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Lockscreen)
runCurrent()
- verify(viewMediatorCallback, never()).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor, never())
+ .notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
// Reattaching the view starts listening again so moving from the bouncer scene to the
// gone scene now does dismiss the keyguard again, this time from lockscreen.
@@ -927,7 +932,7 @@
fakeSceneDataSource.unpause(expectedScene = Scenes.Gone)
sceneTransitionStateFlow.value = ObservableTransitionState.Idle(Scenes.Gone)
runCurrent()
- verify(viewMediatorCallback).keyguardDone(anyInt())
+ verify(primaryBouncerInteractor).notifyKeyguardAuthenticatedPrimaryAuth(anyInt())
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
index caf9219..1cd9d76 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
@@ -32,7 +32,6 @@
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.testKosmos
@@ -86,7 +85,6 @@
AuthenticationRepositoryImpl(
applicationScope = testScope.backgroundScope,
backgroundDispatcher = kosmos.testDispatcher,
- flags = kosmos.sceneContainerFlags,
clock = clock,
getSecurityMode = getSecurityMode,
userRepository = userRepository,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 85774c6..60b48f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -571,7 +571,7 @@
// THEN the view layout is never updated
verify(windowManager, never()).updateViewLayout(any(), any())
- // CLEANUPL we hide to end the job that listens for the finishedGoingToSleep signal
+ // CLEANUP we hide to end the job that listens for the finishedGoingToSleep signal
controllerOverlay.hide()
}
}
@@ -595,7 +595,7 @@
controllerOverlay.updateOverlayParams(overlayParams)
// THEN the view layout is updated
- verify(windowManager, never()).updateViewLayout(any(), any())
+ verify(windowManager).updateViewLayout(any(), any())
}
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
index 741cde8..d850f17 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
@@ -29,10 +29,10 @@
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags.REFACTOR_GETCURRENTUSER
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
import com.android.systemui.telephony.data.repository.fakeTelephonyRepository
@@ -56,6 +56,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class BouncerActionButtonInteractorTest : SysuiTestCase() {
@Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
@@ -75,7 +76,6 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- kosmos.fakeSceneContainerFlags.enabled = true
mobileConnectionsRepository = kosmos.fakeMobileConnectionsRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index cbdb71b..361b078 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -30,11 +30,11 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration.Companion.seconds
@@ -50,9 +50,10 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class BouncerInteractorTest : SysuiTestCase() {
- private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+ private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val authenticationInteractor = kosmos.authenticationInteractor
private val uiEventLoggerFake = kosmos.uiEventLoggerFake
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index 0db0e07..b83c0ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -34,10 +34,10 @@
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel.Sim
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
@@ -60,6 +60,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class BouncerViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -70,7 +71,6 @@
@Before
fun setUp() {
- kosmos.fakeSceneContainerFlags.enabled = true
underTest = kosmos.bouncerViewModel
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index f21e969..497180b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -52,6 +52,7 @@
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -61,7 +62,6 @@
import com.android.systemui.plugins.activityStarter
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.fakeUserTracker
@@ -698,10 +698,9 @@
}
@Test
+ @EnableSceneContainer
fun isCommunalShowing_whenSceneContainerEnabled() =
testScope.runTest {
- kosmos.fakeSceneContainerFlags.enabled = true
-
// Verify default is false
val isCommunalShowing by collectLastValue(underTest.isCommunalShowing)
runCurrent()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 5caf35b..37a6ac6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.TrustAgentDisabled
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UnattendedUpdate
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UserLockdown
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.fakeSystemPropertiesHelper
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
@@ -47,7 +48,6 @@
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -62,6 +62,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class DeviceEntryInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -74,7 +75,6 @@
@Before
fun setUp() {
- kosmos.fakeSceneContainerFlags.enabled = true
underTest = kosmos.deviceEntryInteractor
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index 1dd5d07..12f8918 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -37,8 +38,6 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -76,7 +75,6 @@
repository = repository,
commandQueue = commandQueue,
powerInteractor = PowerInteractorFactory.create().powerInteractor,
- sceneContainerFlags = kosmos.sceneContainerFlags,
bouncerRepository = bouncerRepository,
configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()),
shadeRepository = shadeRepository,
@@ -249,9 +247,9 @@
}
@Test
+ @EnableSceneContainer
fun animationDozingTransitions() =
testScope.runTest {
- kosmos.fakeSceneContainerFlags.enabled = true
val isAnimate by collectLastValue(underTest.animateDozingTransitions)
underTest.setAnimateDozingTransitions(true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index a277fe0..65fd101 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -51,6 +51,7 @@
import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
@@ -69,7 +70,6 @@
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.SceneContainerStartable
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
@@ -85,6 +85,7 @@
import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
import com.android.systemui.telephony.data.repository.fakeTelephonyRepository
import com.android.systemui.testKosmos
+import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -128,9 +129,10 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWithLooper
+@EnableSceneContainer
class SceneFrameworkIntegrationTest : SysuiTestCase() {
- private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+ private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val sceneContainerConfig by lazy { kosmos.sceneContainerConfig }
private val sceneInteractor by lazy { kosmos.sceneInteractor }
@@ -227,6 +229,7 @@
footerActionsController = kosmos.footerActionsController,
footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
sceneInteractor = sceneInteractor,
+ unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor,
)
val displayTracker = FakeDisplayTracker(context)
@@ -236,15 +239,15 @@
applicationScope = testScope.backgroundScope,
sceneInteractor = sceneInteractor,
deviceEntryInteractor = deviceEntryInteractor,
+ deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
+ bouncerInteractor = bouncerInteractor,
keyguardInteractor = keyguardInteractor,
- flags = kosmos.fakeSceneContainerFlags,
sysUiState = sysUiState,
displayId = displayTracker.defaultDisplayId,
sceneLogger = mock(),
falsingCollector = kosmos.falsingCollector,
falsingManager = kosmos.falsingManager,
powerInteractor = powerInteractor,
- bouncerInteractor = bouncerInteractor,
simBouncerInteractor = dagger.Lazy { kosmos.simBouncerInteractor },
authenticationInteractor = dagger.Lazy { kosmos.authenticationInteractor },
windowController = mock(),
@@ -253,7 +256,6 @@
headsUpInteractor = kosmos.headsUpNotificationInteractor,
occlusionInteractor = kosmos.sceneContainerOcclusionInteractor,
faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor,
- deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
shadeInteractor = kosmos.shadeInteractor,
)
startable.start()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 7f7c24e..8e2eea1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -23,10 +23,10 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -39,9 +39,10 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class SceneContainerRepositoryTest : SysuiTestCase() {
- private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+ private val kosmos = testKosmos()
private val testScope = kosmos.testScope
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index b179c30..63f4816 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -23,13 +23,13 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
@@ -45,6 +45,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class SceneInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -55,7 +56,6 @@
@Before
fun setUp() {
- kosmos.fakeSceneContainerFlags.enabled = true
underTest = kosmos.sceneInteractor
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
index d5e43f4..bfe5ef7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
@@ -31,7 +31,6 @@
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.statusbar.NotificationPresenter
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
@@ -82,7 +81,6 @@
headsUpManager,
powerInteractor,
activeNotificationsInteractor,
- kosmos.sceneContainerFlags,
kosmos::sceneInteractor,
)
.apply { setUp(notificationPresenter, notificationsController) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 61adcd2..1472a4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -54,7 +54,6 @@
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -102,7 +101,6 @@
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val sceneInteractor by lazy { kosmos.sceneInteractor }
- private val sceneContainerFlags by lazy { kosmos.fakeSceneContainerFlags }
private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
private val bouncerInteractor by lazy { kosmos.bouncerInteractor }
private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository }
@@ -124,15 +122,15 @@
applicationScope = testScope.backgroundScope,
sceneInteractor = sceneInteractor,
deviceEntryInteractor = deviceEntryInteractor,
+ deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
+ bouncerInteractor = bouncerInteractor,
keyguardInteractor = keyguardInteractor,
- flags = sceneContainerFlags,
sysUiState = sysUiState,
displayId = Display.DEFAULT_DISPLAY,
sceneLogger = mock(),
falsingCollector = falsingCollector,
falsingManager = kosmos.falsingManager,
powerInteractor = powerInteractor,
- bouncerInteractor = bouncerInteractor,
simBouncerInteractor = { kosmos.simBouncerInteractor },
authenticationInteractor = { authenticationInteractor },
windowController = windowController,
@@ -141,7 +139,6 @@
headsUpInteractor = kosmos.headsUpNotificationInteractor,
occlusionInteractor = kosmos.sceneContainerOcclusionInteractor,
faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor,
- deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
shadeInteractor = kosmos.shadeInteractor,
)
}
@@ -1245,7 +1242,6 @@
"Cannot start on the Gone scene and have the device be locked at the same time."
}
- sceneContainerFlags.enabled = true
kosmos.fakeDeviceEntryRepository.setBypassEnabled(isBypassEnabled)
authenticationMethod?.let {
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(authenticationMethod)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
index 2938acf..ae5bf07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
@@ -21,7 +21,6 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
-import com.android.systemui.kosmos.Kosmos
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
@@ -34,15 +33,11 @@
@DisableSceneContainer
fun isNotEnabled_withoutAconfigFlags() {
Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(false)
- Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(false)
- Truth.assertThat(Kosmos().sceneContainerFlags.isEnabled()).isEqualTo(false)
}
@Test
@EnableSceneContainer
fun isEnabled_withAconfigFlags() {
Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(true)
- Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(true)
- Truth.assertThat(Kosmos().sceneContainerFlags.isEnabled()).isEqualTo(true)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index 7b0127e..427b66b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -23,13 +23,13 @@
import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.classifier.fakeFalsingManager
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
@@ -45,6 +45,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class SceneContainerViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -58,7 +59,6 @@
@Before
fun setUp() {
- kosmos.fakeSceneContainerFlags.enabled = true
underTest =
SceneContainerViewModel(
sceneInteractor = sceneInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
index cbbcce9..420418b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
@@ -22,6 +22,7 @@
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
@@ -30,7 +31,6 @@
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -52,6 +52,7 @@
@ExperimentalCoroutinesApi
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class ShadeControllerSceneImplTest : SysuiTestCase() {
private val kosmos = Kosmos()
private val testScope = kosmos.testScope
@@ -64,7 +65,6 @@
@Before
fun setup() {
kosmos.testCase = this
- kosmos.fakeSceneContainerFlags.enabled = true
kosmos.fakeFeatureFlagsClassic.apply {
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
set(Flags.NSSL_DEBUG_LINES, false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
index e759b50..26f342a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
@@ -22,9 +22,9 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shared.recents.utilities.Utilities
import com.android.systemui.testKosmos
@@ -43,8 +43,9 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
@Ignore("b/328827631")
+@EnableSceneContainer
class ShadeBackActionInteractorImplTest : SysuiTestCase() {
- val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
+ val kosmos = testKosmos()
val testScope = kosmos.testScope
val sceneInteractor = kosmos.sceneInteractor
val underTest = kosmos.shadeBackActionInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index ab95e2c..2727af6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -44,6 +44,8 @@
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
import com.android.systemui.testKosmos
+import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
+import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
@@ -91,6 +93,7 @@
footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
footerActionsController = kosmos.footerActionsController,
sceneInteractor = kosmos.sceneInteractor,
+ unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor,
)
}
@@ -254,4 +257,26 @@
shadeRepository.setShadeMode(ShadeMode.Split)
assertThat(shadeMode).isEqualTo(ShadeMode.Split)
}
+
+ @Test
+ fun unfoldTransitionProgress() =
+ testScope.runTest {
+ val unfoldProvider = kosmos.fakeUnfoldTransitionProgressProvider
+ val progress by collectLastValue(underTest.unfoldTransitionProgress)
+
+ unfoldProvider.onTransitionStarted()
+ assertThat(progress).isEqualTo(1f)
+
+ repeat(10) { repetition ->
+ val transitionProgress = 0.1f * (repetition + 1)
+ unfoldProvider.onTransitionProgress(transitionProgress)
+ assertThat(progress).isEqualTo(transitionProgress)
+ }
+
+ unfoldProvider.onTransitionFinishing()
+ assertThat(progress).isEqualTo(1f)
+
+ unfoldProvider.onTransitionFinished()
+ assertThat(progress).isEqualTo(1f)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index a3cf929..01e1aa59 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -23,11 +23,11 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
@@ -46,11 +46,11 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
private val kosmos =
testKosmos().apply {
- fakeSceneContainerFlags.enabled = true
fakeFeatureFlagsClassic.apply {
set(Flags.FULL_SCREEN_USER_SWITCHER, false)
set(Flags.NSSL_DEBUG_LINES, false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 8f7a56d..a023033 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -52,7 +52,6 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.mockLargeScreenHeaderHelper
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -128,7 +127,7 @@
@Before
fun setUp() {
- assertThat(kosmos.sceneContainerFlags.isEnabled()).isEqualTo(SceneContainerFlag.isEnabled)
+ assertThat(SceneContainerFlag.isEnabled).isEqualTo(SceneContainerFlag.isEnabled)
overrideResource(R.bool.config_use_split_notification_shade, false)
movementFlow = MutableStateFlow(BurnInModel())
whenever(aodBurnInViewModel.movement(any())).thenReturn(movementFlow)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
similarity index 60%
rename from packages/SystemUI/tests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
index 6a801e0..3b4cce4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
@@ -15,42 +15,31 @@
*/
package com.android.systemui.unfold.domain.interactor
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
-import com.android.systemui.unfold.data.repository.UnfoldTransitionRepositoryImpl
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
import com.google.common.truth.Truth.assertThat
-import java.util.Optional
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidTestingRunner::class)
-open class UnfoldTransitionInteractorTest : SysuiTestCase() {
+@RunWith(AndroidJUnit4::class)
+class UnfoldTransitionInteractorTest : SysuiTestCase() {
- private val testScope = TestScope()
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val unfoldTransitionProgressProvider = kosmos.fakeUnfoldTransitionProgressProvider
- private val unfoldTransitionProgressProvider = TestUnfoldTransitionProvider()
- private val unfoldTransitionRepository =
- UnfoldTransitionRepositoryImpl(Optional.of(unfoldTransitionProgressProvider))
-
- private lateinit var underTest: UnfoldTransitionInteractor
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
-
- underTest = UnfoldTransitionInteractorImpl(unfoldTransitionRepository)
- }
+ private val underTest: UnfoldTransitionInteractor = kosmos.unfoldTransitionInteractor
@Test
fun waitForTransitionFinish_noEvents_doesNotComplete() =
@@ -88,4 +77,26 @@
assertThat(deferred.isCompleted).isFalse()
deferred.cancel()
}
+
+ @Test
+ fun unfoldProgress() =
+ testScope.runTest {
+ val progress by collectLastValue(underTest.unfoldProgress)
+ runCurrent()
+
+ unfoldTransitionProgressProvider.onTransitionStarted()
+ assertThat(progress).isEqualTo(1f)
+
+ repeat(10) { repetition ->
+ val transitionProgress = 0.1f * (repetition + 1)
+ unfoldTransitionProgressProvider.onTransitionProgress(transitionProgress)
+ assertThat(progress).isEqualTo(transitionProgress)
+ }
+
+ unfoldTransitionProgressProvider.onTransitionFinishing()
+ assertThat(progress).isEqualTo(1f)
+
+ unfoldTransitionProgressProvider.onTransitionFinished()
+ assertThat(progress).isEqualTo(1f)
+ }
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
index 8e2bd9b..79bf5f1 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
@@ -267,6 +267,9 @@
/** True if the clock will react to tone changes in the seed color. */
val isReactiveToTone: Boolean = true,
+
+ /** True if the clock is large frame clock, which will use weather in compose. */
+ val useCustomClockScene: Boolean = false,
)
/** Render configuration options for a clock face. Modifies the way SystemUI behaves. */
@@ -283,6 +286,9 @@
* animation will be used (e.g. a simple translation).
*/
val hasCustomPositionUpdatedAnimation: Boolean = false,
+
+ /** True if the clock is large frame clock, which will use weatherBlueprint in compose. */
+ val useCustomClockScene: Boolean = false,
)
/** Structure for keeping clock-specific settings */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index c509356..e8e1cab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -90,7 +90,7 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -134,7 +134,6 @@
private final UserSwitcherController mUserSwitcherController;
private final GlobalSettings mGlobalSettings;
private final FeatureFlags mFeatureFlags;
- private final SceneContainerFlags mSceneContainerFlags;
private final SessionTracker mSessionTracker;
private final Optional<SideFpsController> mSideFpsController;
private final FalsingA11yDelegate mFalsingA11yDelegate;
@@ -456,7 +455,6 @@
FalsingManager falsingManager,
UserSwitcherController userSwitcherController,
FeatureFlags featureFlags,
- SceneContainerFlags sceneContainerFlags,
GlobalSettings globalSettings,
SessionTracker sessionTracker,
Optional<SideFpsController> sideFpsController,
@@ -491,7 +489,6 @@
mFalsingManager = falsingManager;
mUserSwitcherController = userSwitcherController;
mFeatureFlags = featureFlags;
- mSceneContainerFlags = sceneContainerFlags;
mGlobalSettings = globalSettings;
mSessionTracker = sessionTracker;
if (SideFpsControllerRefactor.isEnabled()) {
@@ -534,7 +531,7 @@
showPrimarySecurityScreen(false);
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
// When the scene framework says that the lockscreen has been dismissed, dismiss the
// keyguard here, revealing the underlying app or launcher:
mSceneTransitionCollectionJob = mJavaAdapter.get().alwaysCollectFlow(
diff --git a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
index 4e5df35..cf2675b 100644
--- a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
@@ -74,7 +74,7 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -131,7 +131,6 @@
@NonNull private final KeyguardInteractor mKeyguardInteractor;
@NonNull private final View.AccessibilityDelegate mAccessibilityDelegate;
@NonNull private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractor;
- @NonNull private final SceneContainerFlags mSceneContainerFlags;
// Tracks the velocity of a touch to help filter out the touches that move too fast.
private VelocityTracker mVelocityTracker;
@@ -208,8 +207,7 @@
@NonNull FeatureFlags featureFlags,
PrimaryBouncerInteractor primaryBouncerInteractor,
Context context,
- Lazy<DeviceEntryInteractor> deviceEntryInteractor,
- SceneContainerFlags sceneContainerFlags
+ Lazy<DeviceEntryInteractor> deviceEntryInteractor
) {
mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -236,7 +234,6 @@
mResources = resources;
mContext = context;
mDeviceEntryInteractor = deviceEntryInteractor;
- mSceneContainerFlags = sceneContainerFlags;
mAccessibilityDelegate = new View.AccessibilityDelegate() {
private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint =
@@ -746,7 +743,7 @@
// play device entry haptic (consistent with UDFPS controller longpress)
vibrateOnLongPress();
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
mDeviceEntryInteractor.get().attemptDeviceEntry();
} else {
mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index 454ed27..a9f985f 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -36,7 +36,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.onSubscriberAdded
@@ -186,7 +186,6 @@
constructor(
@Application private val applicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
- flags: SceneContainerFlags,
private val clock: SystemClock,
private val getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode>,
private val userRepository: UserRepository,
@@ -255,7 +254,7 @@
override val hasLockoutOccurred: StateFlow<Boolean> = _hasLockoutOccurred.asStateFlow()
init {
- if (flags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
// Hydrate failedAuthenticationAttempts initially and whenever the selected user
// changes.
applicationScope.launch {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 61d1c71..4a60d19 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -323,7 +323,7 @@
overlayParams = updatedOverlayParams
sensorBounds = updatedOverlayParams.sensorBounds
getTouchOverlay()?.let {
- if (addViewRunnable != null) {
+ if (addViewRunnable == null) {
// Only updateViewLayout if there's no pending view to add to WM.
// If there is a pending view, that means the view hasn't been added yet so there's
// no need to update any layouts. Instead the correct params will be used when the
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
index e789475..62ef365 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
@@ -18,7 +18,7 @@
import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import dagger.Module
import dagger.Provides
@@ -42,11 +42,10 @@
fun isOnlyComposeBouncerEnabled(): Boolean
}
-class ComposeBouncerFlagsImpl(private val sceneContainerFlags: SceneContainerFlags) :
- ComposeBouncerFlags {
+class ComposeBouncerFlagsImpl() : ComposeBouncerFlags {
override fun isComposeBouncerOrSceneContainerEnabled(): Boolean {
- return sceneContainerFlags.isEnabled() || Flags.composeBouncer()
+ return SceneContainerFlag.isEnabled || Flags.composeBouncer()
}
@Deprecated(
@@ -55,7 +54,7 @@
replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()")
)
override fun isOnlyComposeBouncerEnabled(): Boolean {
- return !sceneContainerFlags.isEnabled() && Flags.composeBouncer()
+ return !SceneContainerFlag.isEnabled && Flags.composeBouncer()
}
}
@@ -63,7 +62,7 @@
object ComposeBouncerFlagsModule {
@Provides
@SysUISingleton
- fun impl(sceneContainerFlags: SceneContainerFlags): ComposeBouncerFlags {
- return ComposeBouncerFlagsImpl(sceneContainerFlags)
+ fun impl(): ComposeBouncerFlags {
+ return ComposeBouncerFlagsImpl()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
index af467ef..613280c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
@@ -22,7 +22,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.phone.NotificationTapHelper;
import dagger.Binds;
@@ -51,9 +51,8 @@
@SysUISingleton
static FalsingCollector providesFalsingCollectorLegacy(
FalsingCollectorImpl impl,
- FalsingCollectorNoOp noOp,
- SceneContainerFlags flags) {
- return flags.isEnabled() ? noOp : impl;
+ FalsingCollectorNoOp noOp) {
+ return SceneContainerFlag.isEnabled() ? noOp : impl;
}
/** Provides the actual {@link FalsingCollector}. */
diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt b/packages/SystemUI/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt
index d4a1f74..c08babb 100644
--- a/packages/SystemUI/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt
@@ -16,14 +16,14 @@
package com.android.systemui.common.coroutine
-import kotlin.experimental.ExperimentalTypeInference
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
+import kotlin.experimental.ExperimentalTypeInference
+import com.android.systemui.common.coroutine.conflatedCallbackFlow as wrapped
+@Deprecated("Use com.android.systemui.common.coroutine.conflatedCallbackFlow instead")
object ConflatedCallbackFlow {
/**
@@ -32,9 +32,9 @@
* consumer(s) of the values in the flow), the values are buffered and, if the buffer fills up,
* we drop the oldest values automatically instead of suspending the producer.
*/
- @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
- @OptIn(ExperimentalTypeInference::class, ExperimentalCoroutinesApi::class)
+ @Deprecated("Use com.android.systemui.common.coroutine.conflatedCallbackFlow instead")
+ @OptIn(ExperimentalTypeInference::class)
fun <T> conflatedCallbackFlow(
@BuilderInference block: suspend ProducerScope<T>.() -> Unit,
- ): Flow<T> = callbackFlow(block).buffer(capacity = Channel.CONFLATED)
+ ): Flow<T> = wrapped(block)
}
diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/FlowConflated.kt b/packages/SystemUI/src/com/android/systemui/common/coroutine/FlowConflated.kt
new file mode 100644
index 0000000..c7d2bb8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/coroutine/FlowConflated.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+@file:OptIn(ExperimentalTypeInference::class)
+
+package com.android.systemui.common.coroutine
+
+import kotlin.experimental.ExperimentalTypeInference
+import kotlinx.coroutines.channels.ProducerScope
+import kotlinx.coroutines.channels.SendChannel
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.buffer
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.channelFlow
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.produceIn
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+/**
+ * Creates an instance of a _cold_ [Flow] with elements that are sent to a [SendChannel] provided to
+ * the builder's [block] of code via [ProducerScope]. It allows elements to be produced by code that
+ * is running in a different context or concurrently.
+ *
+ * The resulting flow is _cold_, which means that [block] is called every time a terminal operator
+ * is applied to the resulting flow.
+ *
+ * This builder ensures thread-safety and context preservation, thus the provided [ProducerScope]
+ * can be used from any context, e.g. from a callback-based API. The resulting flow completes as
+ * soon as the code in the [block] completes. [awaitClose] should be used to keep the flow running,
+ * otherwise the channel will be closed immediately when block completes. [awaitClose] argument is
+ * called either when a flow consumer cancels the flow collection or when a callback-based API
+ * invokes [SendChannel.close] manually and is typically used to cleanup the resources after the
+ * completion, e.g. unregister a callback. Using [awaitClose] is mandatory in order to prevent
+ * memory leaks when the flow collection is cancelled, otherwise the callback may keep running even
+ * when the flow collector is already completed. To avoid such leaks, this method throws
+ * [IllegalStateException] if block returns, but the channel is not closed yet.
+ *
+ * A [conflated][conflate] channel is used. Use the [buffer] operator on the resulting flow to
+ * specify a user-defined value and to control what happens when data is produced faster than
+ * consumed, i.e. to control the back-pressure behavior.
+ *
+ * Adjacent applications of [callbackFlow], [flowOn], [buffer], and [produceIn] are always fused so
+ * that only one properly configured channel is used for execution.
+ *
+ * Example of usage that converts a multi-shot callback API to a flow. For single-shot callbacks use
+ * [suspendCancellableCoroutine].
+ *
+ * ```
+ * fun flowFrom(api: CallbackBasedApi): Flow<T> = callbackFlow {
+ * val callback = object : Callback { // Implementation of some callback interface
+ * override fun onNextValue(value: T) {
+ * // To avoid blocking you can configure channel capacity using
+ * // either buffer(Channel.CONFLATED) or buffer(Channel.UNLIMITED) to avoid overfill
+ * trySendBlocking(value)
+ * .onFailure { throwable ->
+ * // Downstream has been cancelled or failed, can log here
+ * }
+ * }
+ * override fun onApiError(cause: Throwable) {
+ * cancel(CancellationException("API Error", cause))
+ * }
+ * override fun onCompleted() = channel.close()
+ * }
+ * api.register(callback)
+ * /*
+ * * Suspends until either 'onCompleted'/'onApiError' from the callback is invoked
+ * * or flow collector is cancelled (e.g. by 'take(1)' or because a collector's coroutine was cancelled).
+ * * In both cases, callback will be properly unregistered.
+ * */
+ * awaitClose { api.unregister(callback) }
+ * }
+ * ```
+ * > The callback `register`/`unregister` methods provided by an external API must be thread-safe,
+ * > because `awaitClose` block can be called at any time due to asynchronous nature of
+ * > cancellation, even concurrently with the call of the callback.
+ *
+ * This builder is to be preferred over [callbackFlow], due to the latter's default configuration of
+ * using an internal buffer, negatively impacting system health.
+ *
+ * @see callbackFlow
+ */
+fun <T> conflatedCallbackFlow(
+ @BuilderInference block: suspend ProducerScope<T>.() -> Unit,
+): Flow<T> = callbackFlow(block).conflate()
+
+/**
+ * Creates an instance of a _cold_ [Flow] with elements that are sent to a [SendChannel] provided to
+ * the builder's [block] of code via [ProducerScope]. It allows elements to be produced by code that
+ * is running in a different context or concurrently. The resulting flow is _cold_, which means that
+ * [block] is called every time a terminal operator is applied to the resulting flow.
+ *
+ * This builder ensures thread-safety and context preservation, thus the provided [ProducerScope]
+ * can be used concurrently from different contexts. The resulting flow completes as soon as the
+ * code in the [block] and all its children completes. Use [awaitClose] as the last statement to
+ * keep it running. A more detailed example is provided in the documentation of [callbackFlow].
+ *
+ * A [conflated][conflate] channel is used. Use the [buffer] operator on the resulting flow to
+ * specify a user-defined value and to control what happens when data is produced faster than
+ * consumed, i.e. to control the back-pressure behavior.
+ *
+ * Adjacent applications of [channelFlow], [flowOn], [buffer], and [produceIn] are always fused so
+ * that only one properly configured channel is used for execution.
+ *
+ * Examples of usage:
+ * ```
+ * fun <T> Flow<T>.merge(other: Flow<T>): Flow<T> = channelFlow {
+ * // collect from one coroutine and send it
+ * launch {
+ * collect { send(it) }
+ * }
+ * // collect and send from this coroutine, too, concurrently
+ * other.collect { send(it) }
+ * }
+ *
+ * fun <T> contextualFlow(): Flow<T> = channelFlow {
+ * // send from one coroutine
+ * launch(Dispatchers.IO) {
+ * send(computeIoValue())
+ * }
+ * // send from another coroutine, concurrently
+ * launch(Dispatchers.Default) {
+ * send(computeCpuValue())
+ * }
+ * }
+ * ```
+ *
+ * This builder is to be preferred over [channelFlow], due to the latter's default configuration of
+ * using an internal buffer, negatively impacting system health.
+ *
+ * @see channelFlow
+ */
+fun <T> conflatedChannelFlow(
+ @BuilderInference block: suspend ProducerScope<T>.() -> Unit,
+): Flow<T> = channelFlow(block).conflate()
diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/LatestConflated.kt b/packages/SystemUI/src/com/android/systemui/common/coroutine/LatestConflated.kt
new file mode 100644
index 0000000..247fcf7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/coroutine/LatestConflated.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class, ExperimentalTypeInference::class)
+
+package com.android.systemui.common.coroutine
+
+import kotlin.experimental.ExperimentalTypeInference
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.FlowCollector
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.transformLatest
+
+/**
+ * Returns a flow that emits elements from the original flow transformed by [transform] function.
+ * When the original flow emits a new value, computation of the [transform] block for previous value
+ * is cancelled.
+ *
+ * For example, the following flow:
+ * ```
+ * flow {
+ * emit("a")
+ * delay(100)
+ * emit("b")
+ * }.mapLatest { value ->
+ * println("Started computing $value")
+ * delay(200)
+ * "Computed $value"
+ * }
+ * ```
+ *
+ * will print "Started computing a" and "Started computing b", but the resulting flow will contain
+ * only "Computed b" value.
+ *
+ * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
+ * [mapLatest], due to the latter's default configuration of using an internal buffer, negatively
+ * impacting system health.
+ *
+ * @see mapLatest
+ */
+fun <T, R> Flow<T>.mapLatestConflated(@BuilderInference transform: suspend (T) -> R): Flow<R> =
+ mapLatest(transform).conflate()
+
+/**
+ * Returns a flow that switches to a new flow produced by [transform] function every time the
+ * original flow emits a value. When the original flow emits a new value, the previous flow produced
+ * by `transform` block is cancelled.
+ *
+ * For example, the following flow:
+ * ```
+ * flow {
+ * emit("a")
+ * delay(100)
+ * emit("b")
+ * }.flatMapLatest { value ->
+ * flow {
+ * emit(value)
+ * delay(200)
+ * emit(value + "_last")
+ * }
+ * }
+ * ```
+ *
+ * produces `a b b_last`
+ *
+ * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
+ * [flatMapLatest], due to the latter's default configuration of using an internal buffer,
+ * negatively impacting system health.
+ *
+ * @see flatMapLatest
+ */
+fun <T, R> Flow<T>.flatMapLatestConflated(
+ @BuilderInference transform: suspend (T) -> Flow<R>,
+): Flow<R> = flatMapLatest(transform).conflate()
+
+/**
+ * Returns a flow that produces element by [transform] function every time the original flow emits a
+ * value. When the original flow emits a new value, the previous `transform` block is cancelled,
+ * thus the name `transformLatest`.
+ *
+ * For example, the following flow:
+ * ```
+ * flow {
+ * emit("a")
+ * delay(100)
+ * emit("b")
+ * }.transformLatest { value ->
+ * emit(value)
+ * delay(200)
+ * emit(value + "_last")
+ * }
+ * ```
+ *
+ * produces `a b b_last`.
+ *
+ * This operator is [conflated][conflate] by default, and as such should be preferred over usage of
+ * [transformLatest], due to the latter's default configuration of using an internal buffer,
+ * negatively impacting system health.
+ *
+ * @see transformLatest
+ */
+fun <T, R> Flow<T>.transformLatestConflated(
+ @BuilderInference transform: suspend FlowCollector<R>.(T) -> Unit,
+): Flow<R> = transformLatest(transform).conflate()
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 373e1c9..619e052 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -55,7 +55,7 @@
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.UserTracker
import com.android.systemui.smartspace.data.repository.SmartspaceRepository
@@ -107,7 +107,6 @@
private val userManager: UserManager,
private val dockManager: DockManager,
sceneInteractor: SceneInteractor,
- sceneContainerFlags: SceneContainerFlags,
@CommunalLog logBuffer: LogBuffer,
@CommunalTableLog tableLogBuffer: TableLogBuffer,
) {
@@ -216,7 +215,7 @@
*/
// TODO(b/323215860): rename to something more appropriate after cleaning up usages
val isCommunalShowing: Flow<Boolean> =
- flow { emit(sceneContainerFlags.isEnabled()) }
+ flow { emit(SceneContainerFlag.isEnabled) }
.flatMapLatest { sceneContainerEnabled ->
if (sceneContainerEnabled) {
sceneInteractor.currentScene.map { it == Scenes.Communal }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
index bf1f074..eef4b97 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
@@ -27,7 +27,7 @@
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -52,7 +52,6 @@
@Application private val applicationScope: CoroutineScope,
@Application private val context: Context,
deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
- private val sceneContainerFlags: SceneContainerFlags,
private val sceneInteractor: SceneInteractor,
private val primaryBouncerInteractor: PrimaryBouncerInteractor,
alternateBouncerInteractor: AlternateBouncerInteractor,
@@ -75,7 +74,7 @@
get() = context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
private val isBouncerSceneActive: Flow<Boolean> =
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
sceneInteractor.currentScene.map { it == Scenes.Bouncer }.distinctUntilChanged()
} else {
flowOf(false)
@@ -115,7 +114,7 @@
.distinctUntilChanged()
private fun isBouncerActive(): Boolean {
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
return sceneInteractor.currentScene.value == Scenes.Bouncer
}
return primaryBouncerInteractor.isBouncerShowing() &&
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index c476948..7224536 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -44,7 +44,7 @@
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.statusbar.CommandQueue
@@ -84,7 +84,6 @@
private val repository: KeyguardRepository,
private val commandQueue: CommandQueue,
powerInteractor: PowerInteractor,
- sceneContainerFlags: SceneContainerFlags,
bouncerRepository: KeyguardBouncerRepository,
configurationInteractor: ConfigurationInteractor,
shadeRepository: ShadeRepository,
@@ -331,7 +330,7 @@
/** Whether to animate the next doze mode transition. */
val animateDozingTransitions: Flow<Boolean> by lazy {
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
sceneInteractorProvider
.get()
.transitioningTo
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
index 80e94a2..20b7b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
@@ -23,12 +23,14 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
+import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.kotlin.toPx
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
/**
* Distance over which the surface behind the keyguard is animated in during a Y-translation
@@ -96,13 +98,21 @@
.distinctUntilChanged()
/**
+ * Whether a notification launch animation is running when we're not already in the GONE state.
+ */
+ private val isNotificationLaunchAnimationRunningOnKeyguard =
+ notificationLaunchInteractor.isLaunchAnimationRunning
+ .sample(transitionInteractor.finishedKeyguardState)
+ .map { it != KeyguardState.GONE }
+
+ /**
* Whether we're animating the surface, or a notification launch animation is running (which
* means we're going to animate the surface, even if animators aren't yet running).
*/
val isAnimatingSurface =
combine(
repository.isAnimatingSurface,
- notificationLaunchInteractor.isLaunchAnimationRunning
+ isNotificationLaunchAnimationRunningOnKeyguard,
) { animatingSurface, animatingLaunch ->
animatingSurface || animatingLaunch
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
index 6255f0d..7178e1b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
@@ -36,7 +36,6 @@
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.ClockController
-import com.android.systemui.shared.clocks.DEFAULT_CLOCK_ID
import kotlinx.coroutines.launch
object KeyguardClockViewBinder {
@@ -76,13 +75,13 @@
}
launch {
if (!MigrateClocksToBlueprint.isEnabled) return@launch
- viewModel.clockShouldBeCentered.collect { clockShouldBeCentered ->
+ viewModel.clockShouldBeCentered.collect {
viewModel.currentClock.value?.let {
- // Weather clock also has hasCustomPositionUpdatedAnimation as true
- // TODO(b/323020908): remove ID check
+ // TODO(b/301502635): remove "!it.config.useCustomClockScene" when
+ // migrate clocks to blueprint is fully rolled out
if (
it.largeClock.config.hasCustomPositionUpdatedAnimation &&
- it.config.id == DEFAULT_CLOCK_ID
+ !it.config.useCustomClockScene
) {
blueprintInteractor.refreshBlueprint(Type.DefaultClockStepping)
} else {
@@ -93,12 +92,9 @@
}
launch {
if (!MigrateClocksToBlueprint.isEnabled) return@launch
- viewModel.isAodIconsVisible.collect { isAodIconsVisible ->
+ viewModel.isAodIconsVisible.collect {
viewModel.currentClock.value?.let {
- // Weather clock also has hasCustomPositionUpdatedAnimation as true
- if (
- viewModel.useLargeClock && it.config.id == "DIGITAL_CLOCK_WEATHER"
- ) {
+ if (viewModel.useLargeClock && it.config.useCustomClockScene) {
blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 5ee35e4f..cc54920 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -30,6 +30,9 @@
import android.view.ViewGroup.OnHierarchyChangeListener
import android.view.ViewPropertyAnimator
import android.view.WindowInsets
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.OnBackPressedDispatcherOwner
+import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
@@ -49,6 +52,7 @@
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.MigrateClocksToBlueprint
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.shared.ComposeLockscreen
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
@@ -125,6 +129,21 @@
disposables +=
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
+ if (ComposeLockscreen.isEnabled) {
+ view.setViewTreeOnBackPressedDispatcherOwner(
+ object : OnBackPressedDispatcherOwner {
+ override val onBackPressedDispatcher =
+ OnBackPressedDispatcher().apply {
+ setOnBackInvokedDispatcher(
+ view.viewRootImpl.onBackInvokedDispatcher
+ )
+ }
+
+ override val lifecycle: Lifecycle =
+ this@repeatWhenAttached.lifecycle
+ }
+ )
+ }
launch {
occludingAppDeviceEntryMessageViewModel.message.collect { biometricMessage
->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index 49fffdd..45dca99 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -30,7 +30,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.util.kotlin.sample
import dagger.Lazy
@@ -64,7 +64,6 @@
transitionInteractor: KeyguardTransitionInteractor,
val keyguardInteractor: KeyguardInteractor,
val viewModel: AodToLockscreenTransitionViewModel,
- private val sceneContainerFlags: SceneContainerFlags,
private val keyguardViewController: Lazy<KeyguardViewController>,
private val deviceEntryInteractor: DeviceEntryInteractor,
private val deviceEntrySourceInteractor: DeviceEntrySourceInteractor,
@@ -242,7 +241,7 @@
}
suspend fun onLongPress() {
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
deviceEntryInteractor.attemptDeviceEntry()
} else {
keyguardViewController.get().showPrimaryBouncer(/* scrim */ true)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index f6da033..a6d3312 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -118,8 +118,7 @@
currentClock
) { isLargeClockVisible, clockShouldBeCentered, shadeMode, currentClock ->
val shouldUseSplitShade = shadeMode == ShadeMode.Split
- // TODO(b/326098079): make id a constant field in config
- if (currentClock?.config?.id == "DIGITAL_CLOCK_WEATHER") {
+ if (currentClock?.config?.useCustomClockScene == true) {
val weatherClockLayout =
when {
shouldUseSplitShade && clockShouldBeCentered ->
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
index e8d3274..5bdc67f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
@@ -69,7 +69,7 @@
private val mediaFlags: MediaFlags,
private val mediaFilterRepository: MediaFilterRepository,
) : MediaDataManager.Listener {
- lateinit var mediaDataManager: MediaDataManager
+ lateinit var mediaDataProcessor: MediaDataProcessor
// Ensure the field (and associated reference) isn't removed during optimization.
@KeepForWeakReference
@@ -279,7 +279,7 @@
mediaEntries.forEach { (key, data) ->
if (mediaFilterRepository.selectedUserEntries.value.containsKey(data.instanceId)) {
// Force updates to listeners, needed for re-activated card
- mediaDataManager.setInactive(key, timedOut = true, forceUpdate = true)
+ mediaDataProcessor.setInactive(key, timedOut = true, forceUpdate = true)
}
}
val smartspaceMediaData = mediaFilterRepository.smartspaceMediaData.value
@@ -301,7 +301,7 @@
if (mediaFlags.isPersistentSsCardEnabled()) {
mediaFilterRepository.setRecommendation(smartspaceMediaData.copy(isActive = false))
- mediaDataManager.setRecommendationInactive(smartspaceMediaData.targetId)
+ mediaDataProcessor.setRecommendationInactive(smartspaceMediaData.targetId)
} else {
mediaFilterRepository.setRecommendation(
EMPTY_SMARTSPACE_MEDIA_DATA.copy(
@@ -309,7 +309,7 @@
instanceId = smartspaceMediaData.instanceId,
)
)
- mediaDataManager.dismissSmartspaceRecommendation(
+ mediaDataProcessor.dismissSmartspaceRecommendation(
smartspaceMediaData.targetId,
delay = 0L,
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
index c3ba913..33d407c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
@@ -37,6 +37,7 @@
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.media.controls.util.MediaControlsRefactorFlag
import com.android.systemui.media.controls.util.MediaFlags
import java.io.PrintWriter
import javax.inject.Inject
@@ -156,12 +157,10 @@
mediaDataProcessor.onSessionDestroyed(key)
}
mediaResumeListener.setManager(this)
- mediaDataFilter.mediaDataManager = this
+ mediaDataFilter.mediaDataProcessor = mediaDataProcessor
}
- override fun setInactive(key: String, timedOut: Boolean, forceUpdate: Boolean) {
- mediaDataProcessor.setInactive(key, timedOut, forceUpdate)
- }
+ override fun setInactive(key: String, timedOut: Boolean, forceUpdate: Boolean) = unsupported
override fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
mediaDataProcessor.onNotificationAdded(key, sbn)
@@ -207,9 +206,7 @@
return mediaDataProcessor.dismissSmartspaceRecommendation(key, delay)
}
- override fun setRecommendationInactive(key: String) {
- mediaDataProcessor.setRecommendationInactive(key)
- }
+ override fun setRecommendationInactive(key: String) = unsupported
override fun onNotificationRemoved(key: String) {
mediaDataProcessor.onNotificationRemoved(key)
@@ -240,4 +237,12 @@
override fun dump(pw: PrintWriter, args: Array<out String>) {
mediaDeviceManager.dump(pw)
}
+
+ companion object {
+ val unsupported: Nothing
+ get() =
+ error(
+ "Code path not supported when ${MediaControlsRefactorFlag.FLAG_NAME} is enabled"
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
new file mode 100644
index 0000000..14a9179
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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.controls.ui.binder
+
+import android.widget.ImageButton
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.res.R
+
+object MediaControlViewBinder {
+
+ fun setVisibleAndAlpha(set: ConstraintSet, resId: Int, visible: Boolean) {
+ setVisibleAndAlpha(set, resId, visible, ConstraintSet.GONE)
+ }
+
+ private fun setVisibleAndAlpha(
+ set: ConstraintSet,
+ resId: Int,
+ visible: Boolean,
+ notVisibleValue: Int
+ ) {
+ set.setVisibility(resId, if (visible) ConstraintSet.VISIBLE else notVisibleValue)
+ set.setAlpha(resId, if (visible) 1.0f else 0.0f)
+ }
+
+ fun updateSeekBarVisibility(constraintSet: ConstraintSet, isSeekBarEnabled: Boolean) {
+ if (isSeekBarEnabled) {
+ constraintSet.setVisibility(R.id.media_progress_bar, ConstraintSet.VISIBLE)
+ constraintSet.setAlpha(R.id.media_progress_bar, 1.0f)
+ } else {
+ constraintSet.setVisibility(R.id.media_progress_bar, ConstraintSet.INVISIBLE)
+ constraintSet.setAlpha(R.id.media_progress_bar, 0.0f)
+ }
+ }
+
+ fun setSemanticButtonVisibleAndAlpha(
+ button: ImageButton,
+ expandedSet: ConstraintSet,
+ collapsedSet: ConstraintSet,
+ visible: Boolean,
+ notVisibleValue: Int,
+ showInCollapsed: Boolean
+ ) {
+ if (notVisibleValue == ConstraintSet.INVISIBLE) {
+ // Since time views should appear instead of buttons.
+ button.isFocusable = visible
+ button.isClickable = visible
+ }
+ setVisibleAndAlpha(expandedSet, button.id, visible, notVisibleValue)
+ setVisibleAndAlpha(collapsedSet, button.id, visible = visible && showInCollapsed)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
index b315cac..7fced5f8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
@@ -16,41 +16,73 @@
package com.android.systemui.media.controls.ui.controller
+import android.animation.Animator
+import android.animation.AnimatorInflater
+import android.animation.AnimatorSet
import android.content.Context
import android.content.res.Configuration
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.drawable.Drawable
+import android.provider.Settings
+import android.view.View
+import android.view.animation.Interpolator
import androidx.annotation.VisibleForTesting
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT
+import com.android.app.animation.Interpolators
import com.android.app.tracing.traceSection
+import com.android.systemui.Flags
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.controls.ui.animation.ColorSchemeTransition
+import com.android.systemui.media.controls.ui.animation.MetadataAnimationHandler
+import com.android.systemui.media.controls.ui.binder.MediaControlViewBinder
+import com.android.systemui.media.controls.ui.binder.SeekBarObserver
import com.android.systemui.media.controls.ui.controller.MediaCarouselController.Companion.calculateAlpha
import com.android.systemui.media.controls.ui.view.GutsViewHolder
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
+import com.android.systemui.media.controls.ui.viewmodel.MediaControlViewModel
+import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.surfaceeffects.PaintDrawCallback
+import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffect
+import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView
+import com.android.systemui.surfaceeffects.ripple.MultiRippleController
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseAnimationConfig
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseShader
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView
import com.android.systemui.util.animation.MeasurementInput
import com.android.systemui.util.animation.MeasurementOutput
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.animation.TransitionLayoutController
import com.android.systemui.util.animation.TransitionViewState
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.settings.GlobalSettings
import java.lang.Float.max
import java.lang.Float.min
+import java.util.Random
import javax.inject.Inject
/**
* A class responsible for controlling a single instance of a media player handling interactions
* with the view instance and keeping the media view states up to date.
*/
-class MediaViewController
+open class MediaViewController
@Inject
constructor(
private val context: Context,
private val configurationController: ConfigurationController,
private val mediaHostStatesManager: MediaHostStatesManager,
private val logger: MediaViewLogger,
+ private val seekBarViewModel: SeekBarViewModel,
+ @Main private val mainExecutor: DelayableExecutor,
private val mediaFlags: MediaFlags,
+ private val globalSettings: GlobalSettings,
) {
/**
@@ -131,6 +163,72 @@
return transitionLayout?.translationY ?: 0.0f
}
+ /** Whether artwork is bound. */
+ var isArtworkBound: Boolean = false
+
+ /** previous background artwork */
+ var prevArtwork: Drawable? = null
+
+ /** Whether scrubbing time can show */
+ var canShowScrubbingTime: Boolean = false
+
+ /** Whether user is touching the seek bar to change the position */
+ var isScrubbing: Boolean = false
+
+ var isSeekBarEnabled: Boolean = false
+
+ /** Not visible value for previous button when scrubbing */
+ private var prevNotVisibleValue = ConstraintSet.GONE
+ private var isPrevButtonAvailable = false
+
+ /** Not visible value for next button when scrubbing */
+ private var nextNotVisibleValue = ConstraintSet.GONE
+ private var isNextButtonAvailable = false
+
+ private lateinit var mediaViewHolder: MediaViewHolder
+ private lateinit var seekBarObserver: SeekBarObserver
+ private lateinit var turbulenceNoiseController: TurbulenceNoiseController
+ private lateinit var loadingEffect: LoadingEffect
+ private lateinit var turbulenceNoiseAnimationConfig: TurbulenceNoiseAnimationConfig
+ private lateinit var noiseDrawCallback: PaintDrawCallback
+ private lateinit var stateChangedCallback: LoadingEffect.AnimationStateChangedCallback
+ internal lateinit var metadataAnimationHandler: MetadataAnimationHandler
+ internal lateinit var colorSchemeTransition: ColorSchemeTransition
+ internal lateinit var multiRippleController: MultiRippleController
+
+ private val scrubbingChangeListener =
+ object : SeekBarViewModel.ScrubbingChangeListener {
+ override fun onScrubbingChanged(scrubbing: Boolean) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ if (isScrubbing == scrubbing) return
+ isScrubbing = scrubbing
+ updateDisplayForScrubbingChange()
+ }
+ }
+
+ private val enabledChangeListener =
+ object : SeekBarViewModel.EnabledChangeListener {
+ override fun onEnabledChanged(enabled: Boolean) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ if (isSeekBarEnabled == enabled) return
+ isSeekBarEnabled = enabled
+ MediaControlViewBinder.updateSeekBarVisibility(expandedLayout, isSeekBarEnabled)
+ }
+ }
+
+ /**
+ * Sets the listening state of the player.
+ *
+ * Should be set to true when the QS panel is open. Otherwise, false. This is a signal to avoid
+ * unnecessary work when the QS panel is closed.
+ *
+ * @param listening True when player should be active. Otherwise, false.
+ */
+ fun setListening(listening: Boolean) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ seekBarViewModel.listening = listening
+ }
+
/** A callback for config changes */
private val configurationListener =
object : ConfigurationController.ConfigurationListener {
@@ -232,6 +330,14 @@
* Notify this controller that the view has been removed and all listeners should be destroyed
*/
fun onDestroy() {
+ if (mediaFlags.isMediaControlsRefactorEnabled()) {
+ if (this::seekBarObserver.isInitialized) {
+ seekBarViewModel.progress.removeObserver(seekBarObserver)
+ }
+ seekBarViewModel.removeScrubbingChangeListener(scrubbingChangeListener)
+ seekBarViewModel.removeEnabledChangeListener(enabledChangeListener)
+ seekBarViewModel.onDestroy()
+ }
mediaHostStatesManager.removeController(this)
configurationController.removeCallback(configurationListener)
}
@@ -546,6 +652,178 @@
)
}
+ fun attachPlayer(mediaViewHolder: MediaViewHolder) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ this.mediaViewHolder = mediaViewHolder
+
+ // Setting up seek bar.
+ seekBarObserver = SeekBarObserver(mediaViewHolder)
+ seekBarViewModel.progress.observeForever(seekBarObserver)
+ seekBarViewModel.attachTouchHandlers(mediaViewHolder.seekBar)
+ seekBarViewModel.setScrubbingChangeListener(scrubbingChangeListener)
+ seekBarViewModel.setEnabledChangeListener(enabledChangeListener)
+
+ val mediaCard = mediaViewHolder.player
+ attach(mediaViewHolder.player, TYPE.PLAYER)
+
+ val turbulenceNoiseView = mediaViewHolder.turbulenceNoiseView
+ turbulenceNoiseController = TurbulenceNoiseController(turbulenceNoiseView)
+
+ multiRippleController = MultiRippleController(mediaViewHolder.multiRippleView)
+
+ // Metadata Animation
+ val titleText = mediaViewHolder.titleText
+ val artistText = mediaViewHolder.artistText
+ val explicitIndicator = mediaViewHolder.explicitIndicator
+ val enter =
+ loadAnimator(
+ mediaCard.context,
+ R.anim.media_metadata_enter,
+ Interpolators.EMPHASIZED_DECELERATE,
+ titleText,
+ artistText,
+ explicitIndicator
+ )
+ val exit =
+ loadAnimator(
+ mediaCard.context,
+ R.anim.media_metadata_exit,
+ Interpolators.EMPHASIZED_ACCELERATE,
+ titleText,
+ artistText,
+ explicitIndicator
+ )
+ metadataAnimationHandler = MetadataAnimationHandler(exit, enter)
+
+ colorSchemeTransition =
+ ColorSchemeTransition(
+ mediaCard.context,
+ mediaViewHolder,
+ multiRippleController,
+ turbulenceNoiseController
+ )
+
+ // For Turbulence noise.
+ val loadingEffectView = mediaViewHolder.loadingEffectView
+ turbulenceNoiseAnimationConfig =
+ createTurbulenceNoiseConfig(
+ loadingEffectView,
+ turbulenceNoiseView,
+ colorSchemeTransition
+ )
+ noiseDrawCallback =
+ object : PaintDrawCallback {
+ override fun onDraw(paint: Paint) {
+ loadingEffectView.draw(paint)
+ }
+ }
+ stateChangedCallback =
+ object : LoadingEffect.AnimationStateChangedCallback {
+ override fun onStateChanged(
+ oldState: LoadingEffect.AnimationState,
+ newState: LoadingEffect.AnimationState
+ ) {
+ if (newState === LoadingEffect.AnimationState.NOT_PLAYING) {
+ loadingEffectView.visibility = View.INVISIBLE
+ } else {
+ loadingEffectView.visibility = View.VISIBLE
+ }
+ }
+ }
+ }
+
+ fun updateAnimatorDurationScale() {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ if (this::seekBarObserver.isInitialized) {
+ seekBarObserver.animationEnabled =
+ globalSettings.getFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 1f) > 0f
+ }
+ }
+
+ /** update view with the needed UI changes when user touches seekbar. */
+ private fun updateDisplayForScrubbingChange() {
+ mainExecutor.execute {
+ val isTimeVisible = canShowScrubbingTime && isScrubbing
+ MediaControlViewBinder.setVisibleAndAlpha(
+ expandedLayout,
+ mediaViewHolder.scrubbingTotalTimeView.id,
+ isTimeVisible
+ )
+ MediaControlViewBinder.setVisibleAndAlpha(
+ expandedLayout,
+ mediaViewHolder.scrubbingElapsedTimeView.id,
+ isTimeVisible
+ )
+
+ MediaControlViewModel.SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.forEach { id ->
+ val isButtonVisible: Boolean
+ val notVisibleValue: Int
+ when (id) {
+ R.id.actionPrev -> {
+ isButtonVisible = isPrevButtonAvailable && !isTimeVisible
+ notVisibleValue = prevNotVisibleValue
+ }
+ R.id.actionNext -> {
+ isButtonVisible = isNextButtonAvailable && !isTimeVisible
+ notVisibleValue = nextNotVisibleValue
+ }
+ else -> {
+ isButtonVisible = !isTimeVisible
+ notVisibleValue = ConstraintSet.GONE
+ }
+ }
+ MediaControlViewBinder.setSemanticButtonVisibleAndAlpha(
+ mediaViewHolder.getAction(id),
+ expandedLayout,
+ collapsedLayout,
+ isButtonVisible,
+ notVisibleValue,
+ showInCollapsed = true
+ )
+ }
+
+ if (!metadataAnimationHandler.isRunning) {
+ refreshState()
+ }
+ }
+ }
+
+ fun bindSeekBar(onSeek: () -> Unit, onBindSeekBar: (SeekBarViewModel) -> Unit) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ seekBarViewModel.logSeek = onSeek
+ onBindSeekBar.invoke(seekBarViewModel)
+ }
+
+ fun setUpTurbulenceNoise() {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ if (Flags.shaderlibLoadingEffectRefactor()) {
+ if (!this::loadingEffect.isInitialized) {
+ loadingEffect =
+ LoadingEffect(
+ TurbulenceNoiseShader.Companion.Type.SIMPLEX_NOISE,
+ turbulenceNoiseAnimationConfig,
+ noiseDrawCallback,
+ stateChangedCallback
+ )
+ }
+ colorSchemeTransition.loadingEffect = loadingEffect
+ loadingEffect.play()
+ mainExecutor.executeDelayed(
+ loadingEffect::finish,
+ MediaControlViewModel.TURBULENCE_NOISE_PLAY_MS_DURATION
+ )
+ } else {
+ turbulenceNoiseController.play(
+ TurbulenceNoiseShader.Companion.Type.SIMPLEX_NOISE,
+ turbulenceNoiseAnimationConfig
+ )
+ mainExecutor.executeDelayed(
+ turbulenceNoiseController::finish,
+ MediaControlViewModel.TURBULENCE_NOISE_PLAY_MS_DURATION
+ )
+ }
+ }
+
/**
* Obtain a measurement for a given location. This makes sure that the state is up to date and
* all widgets know their location. Calling this method may create a measurement if we don't
@@ -801,6 +1079,75 @@
applyImmediately = true
)
}
+
+ @VisibleForTesting
+ protected open fun loadAnimator(
+ context: Context,
+ animId: Int,
+ motionInterpolator: Interpolator?,
+ vararg targets: View?
+ ): AnimatorSet {
+ val animators = ArrayList<Animator>()
+ for (target in targets) {
+ val animator = AnimatorInflater.loadAnimator(context, animId) as AnimatorSet
+ animator.childAnimations[0].interpolator = motionInterpolator
+ animator.setTarget(target)
+ animators.add(animator)
+ }
+ val result = AnimatorSet()
+ result.playTogether(animators)
+ return result
+ }
+
+ private fun createTurbulenceNoiseConfig(
+ loadingEffectView: LoadingEffectView,
+ turbulenceNoiseView: TurbulenceNoiseView,
+ colorSchemeTransition: ColorSchemeTransition
+ ): TurbulenceNoiseAnimationConfig {
+ val targetView: View =
+ if (Flags.shaderlibLoadingEffectRefactor()) {
+ loadingEffectView
+ } else {
+ turbulenceNoiseView
+ }
+ val width = targetView.width
+ val height = targetView.height
+ val random = Random()
+ return TurbulenceNoiseAnimationConfig(
+ gridCount = 2.14f,
+ TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER,
+ random.nextFloat(),
+ random.nextFloat(),
+ random.nextFloat(),
+ noiseMoveSpeedX = 0.42f,
+ noiseMoveSpeedY = 0f,
+ TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z,
+ // Color will be correctly updated in ColorSchemeTransition.
+ colorSchemeTransition.accentPrimary.currentColor,
+ screenColor = Color.BLACK,
+ width.toFloat(),
+ height.toFloat(),
+ TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS,
+ easeInDuration = 1350f,
+ easeOutDuration = 1350f,
+ targetView.context.resources.displayMetrics.density,
+ lumaMatteBlendFactor = 0.26f,
+ lumaMatteOverallBrightness = 0.09f,
+ shouldInverseNoiseLuminosity = false
+ )
+ }
+
+ fun setUpPrevButtonInfo(isAvailable: Boolean, notVisibleValue: Int = ConstraintSet.GONE) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ isPrevButtonAvailable = isAvailable
+ prevNotVisibleValue = notVisibleValue
+ }
+
+ fun setUpNextButtonInfo(isAvailable: Boolean, notVisibleValue: Int = ConstraintSet.GONE) {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return
+ isNextButtonAvailable = isAvailable
+ nextNotVisibleValue = notVisibleValue
+ }
}
/** An internal key for the cache of mediaViewStates. This is a subset of the full host state. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaActionViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaActionViewModel.kt
index 1e67a77..82099e6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaActionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaActionViewModel.kt
@@ -24,7 +24,8 @@
val icon: Drawable?,
val contentDescription: CharSequence?,
val background: Drawable?,
- val isVisible: Boolean = true,
+ /** whether action is visible if user is touching seekbar to change position. */
+ val isVisibleWhenScrubbing: Boolean = true,
val notVisibleValue: Int = ConstraintSet.GONE,
val showInCollapsed: Boolean,
val rebindId: Int? = null,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
index 7c59995..d74506d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
@@ -18,6 +18,7 @@
import android.content.Context
import android.content.pm.PackageManager
+import android.media.session.MediaController
import android.media.session.MediaSession.Token
import android.text.TextUtils
import android.util.Log
@@ -40,6 +41,7 @@
import com.android.systemui.monet.Style
import com.android.systemui.res.R
import com.android.systemui.util.kotlin.sample
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -51,6 +53,7 @@
class MediaControlViewModel(
@Application private val applicationContext: Context,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ @Background private val backgroundExecutor: Executor,
private val interactor: MediaControlInteractor,
private val logger: MediaUiEventLogger,
) {
@@ -124,13 +127,15 @@
}
},
backgroundCover = model.artwork,
- appIcon = getAppIcon(model.appIcon, model.isResume, model.packageName),
+ appIcon = model.appIcon,
+ launcherIcon = getIconFromApp(model.packageName),
useGrayColorFilter = model.appIcon == null || model.isResume,
artistName = model.artistName ?: "",
titleName = model.songName ?: "",
isExplicitVisible = model.showExplicit,
+ shouldAddGradient = wallpaperColors != null,
colorScheme = scheme,
- isTimeVisible = canShowScrubbingTimeViews(model.semanticActionButtons),
+ canShowTime = canShowScrubbingTimeViews(model.semanticActionButtons),
playTurbulenceNoise = playTurbulenceNoise,
useSemanticActions = model.semanticActionButtons != null,
actionButtons = toActionViewModels(model),
@@ -146,6 +151,21 @@
onLongClicked = {
logger.logLongPressOpen(model.uid, model.packageName, model.instanceId)
},
+ onSeek = {
+ logger.logSeek(model.uid, model.packageName, model.instanceId)
+ // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT)
+ },
+ onBindSeekbar = { seekBarViewModel ->
+ if (model.isResume && model.resumeProgress != null) {
+ seekBarViewModel.updateStaticProgress(model.resumeProgress)
+ } else {
+ backgroundExecutor.execute {
+ seekBarViewModel.updateController(
+ model.token?.let { MediaController(applicationContext, it) }
+ )
+ }
+ }
+ }
)
}
@@ -278,16 +298,16 @@
model: MediaControlModel,
mediaAction: MediaAction,
buttonId: Int,
- isScrubbingTimeEnabled: Boolean
+ canShowScrubbingTimeViews: Boolean
): MediaActionViewModel {
val showInCollapsed = SEMANTIC_ACTIONS_COMPACT.contains(buttonId)
val hideWhenScrubbing = SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.contains(buttonId)
- val shouldHideDueToScrubbing = isScrubbingTimeEnabled && hideWhenScrubbing
+ val shouldHideWhenScrubbing = canShowScrubbingTimeViews && hideWhenScrubbing
return MediaActionViewModel(
icon = mediaAction.icon,
contentDescription = mediaAction.contentDescription,
background = mediaAction.background,
- isVisible = !shouldHideDueToScrubbing,
+ isVisibleWhenScrubbing = !shouldHideWhenScrubbing,
notVisibleValue =
if (
(buttonId == R.id.actionPrev && model.semanticActionButtons!!.reservePrev) ||
@@ -342,19 +362,6 @@
action.run()
}
- private fun getAppIcon(
- icon: android.graphics.drawable.Icon?,
- isResume: Boolean,
- packageName: String
- ): Icon {
- if (icon != null && !isResume) {
- icon.loadDrawable(applicationContext)?.let { drawable ->
- return Icon.Loaded(drawable, null)
- }
- }
- return getIconFromApp(packageName)
- }
-
private fun getIconFromApp(packageName: String): Icon {
return try {
Icon.Loaded(applicationContext.packageManager.getApplicationIcon(packageName), null)
@@ -381,17 +388,17 @@
private const val DISABLED_ALPHA = 0.38f
/** Buttons to show in small player when using semantic actions */
- private val SEMANTIC_ACTIONS_COMPACT =
+ val SEMANTIC_ACTIONS_COMPACT =
listOf(R.id.actionPlayPause, R.id.actionPrev, R.id.actionNext)
/**
* Buttons that should get hidden when we are scrubbing (they will be replaced with the
* views showing scrubbing time)
*/
- private val SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING = listOf(R.id.actionPrev, R.id.actionNext)
+ val SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING = listOf(R.id.actionPrev, R.id.actionNext)
/** Buttons to show in player when using semantic actions. */
- private val SEMANTIC_ACTIONS_ALL =
+ val SEMANTIC_ACTIONS_ALL =
listOf(
R.id.actionPlayPause,
R.id.actionPrev,
@@ -399,5 +406,9 @@
R.id.action0,
R.id.action1
)
+
+ const val TURBULENCE_NOISE_PLAY_MS_DURATION = 7500L
+ const val MEDIA_PLAYER_SCRIM_START_ALPHA = 0.25f
+ const val MEDIA_PLAYER_SCRIM_END_ALPHA = 1.0f
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
index 9029a65..d1014e8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
@@ -24,13 +24,15 @@
data class MediaPlayerViewModel(
val contentDescription: (Boolean) -> CharSequence,
val backgroundCover: android.graphics.drawable.Icon?,
- val appIcon: Icon,
+ val appIcon: android.graphics.drawable.Icon?,
+ val launcherIcon: Icon,
val useGrayColorFilter: Boolean,
val artistName: CharSequence,
val titleName: CharSequence,
val isExplicitVisible: Boolean,
+ val shouldAddGradient: Boolean,
val colorScheme: ColorScheme,
- val isTimeVisible: Boolean,
+ val canShowTime: Boolean,
val playTurbulenceNoise: Boolean,
val useSemanticActions: Boolean,
val actionButtons: List<MediaActionViewModel?>,
@@ -38,4 +40,6 @@
val gutsMenu: GutsViewModel,
val onClicked: (Expandable) -> Unit,
val onLongClicked: () -> Unit,
+ val onSeek: () -> Unit,
+ val onBindSeekbar: (SeekBarViewModel) -> Unit,
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index d4bd6da..4e77d13 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -21,16 +21,11 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import javax.inject.Inject
@SysUISingleton
-class MediaFlags
-@Inject
-constructor(
- private val featureFlags: FeatureFlagsClassic,
- private val sceneContainerFlags: SceneContainerFlags
-) {
+class MediaFlags @Inject constructor(private val featureFlags: FeatureFlagsClassic) {
/**
* Check whether media control actions should be based on PlaybackState instead of notification
*/
@@ -57,7 +52,7 @@
/** Check whether to use scene framework */
fun isSceneContainerEnabled() =
- sceneContainerFlags.isEnabled() && MediaInSceneContainerFlag.isEnabled
+ SceneContainerFlag.isEnabled && MediaInSceneContainerFlag.isEnabled
/** Check whether to use media refactor code */
fun isMediaControlsRefactorEnabled() = MediaControlsRefactorFlag.isEnabled
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index ffbc560..7ccdf0a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -24,7 +24,7 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.ViewController;
@@ -66,15 +66,14 @@
QSPanelController qsPanelController,
QuickStatusBarHeaderController quickStatusBarHeaderController,
ConfigurationController configurationController,
- FalsingManager falsingManager,
- SceneContainerFlags sceneContainerFlags) {
+ FalsingManager falsingManager) {
super(view);
mQsPanelController = qsPanelController;
mQuickStatusBarHeaderController = quickStatusBarHeaderController;
mConfigurationController = configurationController;
mFalsingManager = falsingManager;
mQSPanelContainer = mView.getQSPanelContainer();
- mSceneContainerEnabled = sceneContainerFlags.isEnabled();
+ mSceneContainerEnabled = SceneContainerFlag.isEnabled();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
index a0607e9..1f4838e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
@@ -60,7 +60,7 @@
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.brightness.MirrorController;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.CommandQueue;
@@ -174,8 +174,6 @@
@Nullable
private View mFooterActionsView;
- private final SceneContainerFlags mSceneContainerFlags;
-
@Inject
public QSImpl(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
SysuiStatusBarStateController statusBarStateController, CommandQueue commandQueue,
@@ -188,8 +186,7 @@
FooterActionsViewModel.Factory footerActionsViewModelFactory,
FooterActionsViewBinder footerActionsViewBinder,
LargeScreenShadeInterpolator largeScreenShadeInterpolator,
- FeatureFlags featureFlags,
- SceneContainerFlags sceneContainerFlags) {
+ FeatureFlags featureFlags) {
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
mQsMediaHost = qsMediaHost;
mQqsMediaHost = qqsMediaHost;
@@ -205,8 +202,7 @@
mFooterActionsViewModelFactory = footerActionsViewModelFactory;
mFooterActionsViewBinder = footerActionsViewBinder;
mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
- mSceneContainerFlags = sceneContainerFlags;
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
mStatusBarState = StatusBarState.SHADE;
}
}
@@ -224,7 +220,7 @@
mQSPanelController.init();
mQuickQSPanelController.init();
- if (!mSceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled()) {
mQSFooterActionsViewModel = mFooterActionsViewModelFactory
.create(mListeningAndVisibilityLifecycleOwner);
bindFooterActionsView(mRootView);
@@ -249,7 +245,7 @@
mScrollListener.onQsPanelScrollChanged(scrollY);
}
});
- mQSPanelScrollView.setScrollingEnabled(!mSceneContainerFlags.isEnabled());
+ mQSPanelScrollView.setScrollingEnabled(!SceneContainerFlag.isEnabled());
mHeader = mRootView.findViewById(R.id.header);
mFooter = qsComponent.getQSFooter();
@@ -509,7 +505,7 @@
@VisibleForTesting
boolean isKeyguardState() {
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
return false;
} else {
// We want the freshest state here since otherwise we'll have some weirdness if earlier
@@ -573,7 +569,7 @@
}
private void setKeyguardShowing(boolean keyguardShowing) {
- if (!mSceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled()) {
if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
mLastQSExpansion = -1;
@@ -651,7 +647,7 @@
@Override
public int getHeightDiff() {
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
return mQSPanelController.getViewBottom() - mHeader.getBottom()
+ mHeader.getPaddingBottom();
} else {
@@ -720,7 +716,7 @@
mQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
mQuickQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
- if (!mSceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled()) {
float qsScrollViewTranslation =
onKeyguard && !mShowCollapsedOnKeyguard ? panelTranslationY : 0;
mQSPanelScrollView.setTranslationY(qsScrollViewTranslation);
@@ -824,7 +820,7 @@
mQsBounds.set(-sideMargin, 0, mQSPanelScrollView.getWidth() + sideMargin,
mQSPanelScrollView.getHeight());
}
- if (!mSceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled()) {
mQSPanelScrollView.setClipBounds(mQsBounds);
mQSPanelScrollView.getLocationOnScreen(mLocationTemp);
@@ -907,7 +903,7 @@
// The customize state changed, so our height changed.
mContainer.updateExpansion();
boolean customizing = isCustomizing();
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
mQSPanelController.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
} else {
mQSPanelScrollView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
@@ -984,7 +980,7 @@
@Override
public void onStateChanged(int newState) {
- if (mSceneContainerFlags.isEnabled() || newState == mStatusBarState) {
+ if (SceneContainerFlag.isEnabled() || newState == mStatusBarState) {
return;
}
mStatusBarState = newState;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index b8c3c1a..e24caf1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -37,7 +37,7 @@
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.brightness.BrightnessController;
import com.android.systemui.settings.brightness.BrightnessMirrorHandler;
import com.android.systemui.settings.brightness.BrightnessSliderController;
@@ -94,7 +94,6 @@
FalsingManager falsingManager,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
SplitShadeStateController splitShadeStateController,
- SceneContainerFlags sceneContainerFlags,
Provider<QSLongPressEffect> longPRessEffectProvider) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager, splitShadeStateController,
@@ -113,7 +112,7 @@
mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mLastDensity = view.getResources().getConfiguration().densityDpi;
- mSceneContainerEnabled = sceneContainerFlags.isEnabled();
+ mSceneContainerEnabled = SceneContainerFlag.isEnabled();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index 1d92d78..bb40d3e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -17,7 +17,7 @@
package com.android.systemui.qs;
import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
@@ -34,12 +34,11 @@
@Inject
QuickStatusBarHeaderController(QuickStatusBarHeader view,
- QuickQSPanelController quickQSPanelController,
- SceneContainerFlags sceneContainerFlags
+ QuickQSPanelController quickQSPanelController
) {
super(view);
mQuickQSPanelController = quickQSPanelController;
- mSceneContainerEnabled = sceneContainerFlags.isEnabled();
+ mSceneContainerEnabled = SceneContainerFlag.isEnabled();
}
@Override
protected void onViewAttached() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
index 34b1b2d..a222b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
@@ -42,7 +42,7 @@
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -107,8 +107,7 @@
protected QSCustomizerController(QSCustomizer view, TileQueryHelper tileQueryHelper,
QSHost qsHost, TileAdapter tileAdapter, ScreenLifecycle screenLifecycle,
KeyguardStateController keyguardStateController, LightBarController lightBarController,
- ConfigurationController configurationController, UiEventLogger uiEventLogger,
- SceneContainerFlags sceneContainerFlags) {
+ ConfigurationController configurationController, UiEventLogger uiEventLogger) {
super(view);
mTileQueryHelper = tileQueryHelper;
mQsHost = qsHost;
@@ -118,7 +117,7 @@
mLightBarController = lightBarController;
mConfigurationController = configurationController;
mUiEventLogger = uiEventLogger;
- view.setSceneContainerEnabled(sceneContainerFlags.isEnabled());
+ view.setSceneContainerEnabled(SceneContainerFlag.isEnabled());
mToolbar = mView.findViewById(com.android.internal.R.id.action_bar);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 4ece7b6..1ddc094 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -98,7 +98,7 @@
import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.scene.shared.model.Scenes;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
@@ -146,7 +146,6 @@
private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
private final Context mContext;
- private final SceneContainerFlags mSceneContainerFlags;
private final Executor mMainExecutor;
private final ShellInterface mShellInterface;
private final Lazy<ShadeViewController> mShadeViewControllerLazy;
@@ -208,7 +207,7 @@
@Override
public void onStatusBarTouchEvent(MotionEvent event) {
verifyCallerAndClearCallingIdentity("onStatusBarTouchEvent", () -> {
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
//TODO(b/329863123) implement latency tracking for shade scene
Log.i(TAG_OPS, "Scene container enabled. Latency tracking not started.");
} else if (event.getActionMasked() == ACTION_DOWN) {
@@ -223,7 +222,7 @@
// If scene framework is enabled, set the scene container window to
// visible and let the touch "slip" into that window.
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
mSceneInteractor.get().onRemoteUserInteractionStarted("launcher swipe");
} else {
mShadeViewControllerLazy.get().startInputFocusTransfer();
@@ -232,7 +231,7 @@
if (action == ACTION_UP || action == ACTION_CANCEL) {
mInputFocusTransferStarted = false;
- if (!mSceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled()) {
float velocity = (event.getY() - mInputFocusTransferStartY)
/ (event.getEventTime() - mInputFocusTransferStartMillis);
if (action == ACTION_CANCEL) {
@@ -612,7 +611,6 @@
KeyguardUnlockAnimationController sysuiUnlockAnimationController,
InWindowLauncherUnlockAnimationManager inWindowLauncherUnlockAnimationManager,
AssistUtils assistUtils,
- SceneContainerFlags sceneContainerFlags,
DumpManager dumpManager,
Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
BroadcastDispatcher broadcastDispatcher
@@ -624,7 +622,6 @@
}
mContext = context;
- mSceneContainerFlags = sceneContainerFlags;
mMainExecutor = mainExecutor;
mShellInterface = shellInterface;
mShadeViewControllerLazy = shadeViewControllerLazy;
diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
index afd0746..8277c73 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
@@ -16,7 +16,6 @@
package com.android.systemui.scene
-import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import dagger.Module
@@ -29,7 +28,6 @@
EmptySceneModule::class,
GoneSceneModule::class,
QuickSettingsSceneModule::class,
- SceneContainerFlagsModule::class,
ShadeSceneModule::class,
],
)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 62b0914..69f9443 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -20,7 +20,6 @@
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlagsModule
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.startable.SceneContainerStartable
-import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import dagger.Binds
@@ -40,7 +39,6 @@
GoneSceneModule::class,
LockscreenSceneModule::class,
QuickSettingsSceneModule::class,
- SceneContainerFlagsModule::class,
ShadeSceneModule::class,
],
)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
index 0665c9e..d202c24 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
@@ -16,7 +16,6 @@
package com.android.systemui.scene
-import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import dagger.Module
@@ -30,7 +29,6 @@
EmptySceneModule::class,
GoneSceneModule::class,
LockscreenSceneModule::class,
- SceneContainerFlagsModule::class,
],
)
object ShadelessSceneContainerFrameworkModule {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
index c736707..1cf1c18 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractor.kt
@@ -24,7 +24,7 @@
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.NotificationPresenter
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -53,7 +53,6 @@
private val headsUpManager: HeadsUpManager,
private val powerInteractor: PowerInteractor,
private val activeNotificationsInteractor: ActiveNotificationsInteractor,
- sceneContainerFlags: SceneContainerFlags,
sceneInteractorProvider: Provider<SceneInteractor>,
) : CoreStartable {
@@ -68,7 +67,7 @@
* false if the bouncer is visible.
*/
val isLockscreenOrShadeVisible: StateFlow<Boolean> =
- if (!sceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled) {
windowRootViewVisibilityRepository.isLockscreenOrShadeVisible
} else {
sceneInteractorProvider
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 0e66c28..4774eb3 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -44,7 +44,7 @@
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.logger.SceneLogger
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -92,7 +92,6 @@
private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
private val bouncerInteractor: BouncerInteractor,
private val keyguardInteractor: KeyguardInteractor,
- private val flags: SceneContainerFlags,
private val sysUiState: SysUiState,
@DisplayId private val displayId: Int,
private val sceneLogger: SceneLogger,
@@ -111,7 +110,7 @@
) : CoreStartable {
override fun start() {
- if (flags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
sceneLogger.logFrameworkEnabled(isEnabled = true)
hydrateVisibility()
automaticallySwitchScenes()
@@ -124,16 +123,18 @@
} else {
sceneLogger.logFrameworkEnabled(
isEnabled = false,
- reason = flags.requirementDescription(),
+ reason = SceneContainerFlag.requirementDescription(),
)
}
}
override fun dump(pw: PrintWriter, args: Array<out String>) =
pw.asIndenting().run {
- printSection("SceneContainerFlags") {
- println("isEnabled", flags.isEnabled())
- printSection("requirementDescription") { println(flags.requirementDescription()) }
+ printSection("SceneContainerFlag") {
+ println("isEnabled", SceneContainerFlag.isEnabled)
+ printSection("requirementDescription") {
+ println(SceneContainerFlag.requirementDescription())
+ }
}
}
@@ -288,7 +289,8 @@
Scenes.Gone to "device was unlocked in Bouncer scene"
} else {
val prevScene = previousScene.value
- (prevScene ?: Scenes.Gone) to
+ (prevScene
+ ?: Scenes.Gone) to
"device was unlocked in Bouncer scene, from sceneKey=$prevScene"
}
isOnLockscreen ->
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
rename to packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
index cff11a7..234eda8 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
@@ -20,7 +20,6 @@
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.Flags.sceneContainer
-import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
import com.android.systemui.flags.FlagToken
import com.android.systemui.flags.RefactorFlagUtils
@@ -32,8 +31,6 @@
import com.android.systemui.media.controls.util.MediaInSceneContainerFlag
import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
import com.android.systemui.statusbar.phone.PredictiveBackSysUiFlag
-import dagger.Module
-import dagger.Provides
/** Helper for reading or using the scene container flag state. */
object SceneContainerFlag {
@@ -99,30 +96,12 @@
*/
@JvmStatic
inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, DESCRIPTION)
-}
-
-/**
- * Defines interface for classes that can check whether the scene container framework feature is
- * enabled.
- */
-interface SceneContainerFlags {
-
- /** Returns `true` if the Scene Container Framework is enabled; `false` otherwise. */
- fun isEnabled(): Boolean
/** Returns a developer-readable string that describes the current requirement list. */
- fun requirementDescription(): String
-}
-
-class SceneContainerFlagsImpl : SceneContainerFlags {
-
- override fun isEnabled(): Boolean {
- return SceneContainerFlag.isEnabled
- }
-
- override fun requirementDescription(): String {
+ @JvmStatic
+ fun requirementDescription(): String {
return buildString {
- SceneContainerFlag.getAllRequirements().forEach { requirement ->
+ getAllRequirements().forEach { requirement ->
append('\n')
append(if (requirement.isEnabled) " [MET]" else "[NOT MET]")
append(" ${requirement.name}")
@@ -130,9 +109,3 @@
}
}
}
-
-@Module
-object SceneContainerFlagsModule {
-
- @Provides @SysUISingleton fun impl(): SceneContainerFlags = SceneContainerFlagsImpl()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
index 67dc0cc..259a8bf 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
@@ -4,7 +4,6 @@
import android.util.AttributeSet
import android.view.View
import android.view.WindowInsets
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -31,7 +30,6 @@
viewModel: SceneContainerViewModel,
containerConfig: SceneContainerConfig,
sharedNotificationContainer: SharedNotificationContainer,
- flags: SceneContainerFlags,
scenes: Set<Scene>,
layoutInsetController: LayoutInsetsController,
sceneDataSourceDelegator: SceneDataSourceDelegator,
@@ -44,7 +42,6 @@
windowInsets = windowInsets,
containerConfig = containerConfig,
sharedNotificationContainer = sharedNotificationContainer,
- flags = flags,
scenes = scenes,
onVisibilityChangedInternal = { isVisible ->
super.setVisibility(if (isVisible) View.VISIBLE else View.INVISIBLE)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index 809ac2e..2ef9b73 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -39,7 +39,7 @@
import com.android.systemui.common.ui.compose.windowinsets.ScreenDecorProvider
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -63,7 +63,6 @@
windowInsets: StateFlow<WindowInsets?>,
containerConfig: SceneContainerConfig,
sharedNotificationContainer: SharedNotificationContainer,
- flags: SceneContainerFlags,
scenes: Set<Scene>,
onVisibilityChangedInternal: (isVisible: Boolean) -> Unit,
dataSourceDelegator: SceneDataSourceDelegator,
@@ -115,7 +114,7 @@
// the SceneContainerView. This SharedNotificationContainer should contain NSSL
// due to the NotificationStackScrollLayoutSection (legacy) or
// NotificationSection (scene container) moving it there.
- if (flags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
(sharedNotificationContainer.parent as? ViewGroup)?.removeView(
sharedNotificationContainer
)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/scroll/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/scroll/LongScreenshotActivity.java
index 706ac9c..b43a1d2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/scroll/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/scroll/LongScreenshotActivity.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.HardwareRenderer;
+import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
@@ -38,9 +39,11 @@
import android.view.Display;
import android.view.ScrollCaptureResponse;
import android.view.View;
+import android.view.WindowInsets;
import android.widget.ImageView;
import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.core.view.WindowCompat;
import com.android.internal.app.ChooserActivity;
import com.android.internal.logging.UiEventLogger;
@@ -127,6 +130,10 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ // Enable edge-to-edge explicitly.
+ WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
+
setContentView(R.layout.long_screenshot);
mPreview = requireViewById(R.id.preview);
@@ -149,6 +156,13 @@
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
updateImageDimensions());
+ requireViewById(R.id.root).setOnApplyWindowInsetsListener(
+ (view, windowInsets) -> {
+ Insets insets = windowInsets.getInsets(WindowInsets.Type.systemBars());
+ view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
+ return WindowInsets.CONSUMED;
+ });
+
Intent intent = getIntent();
mScrollCaptureResponse = intent.getParcelableExtra(EXTRA_CAPTURE_RESPONSE);
mScreenshotUserHandle = intent.getParcelableExtra(EXTRA_SCREENSHOT_USER_HANDLE,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index fb32b9f..adcb14a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -59,7 +59,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.scene.ui.view.WindowRootViewComponent;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
@@ -117,7 +117,6 @@
private final AuthController mAuthController;
private final Lazy<SelectedUserInteractor> mUserInteractor;
private final Lazy<ShadeInteractor> mShadeInteractorLazy;
- private final SceneContainerFlags mSceneContainerFlags;
private final Lazy<CommunalInteractor> mCommunalInteractor;
private ViewGroup mWindowRootView;
private LayoutParams mLp;
@@ -166,7 +165,6 @@
ShadeWindowLogger logger,
Lazy<SelectedUserInteractor> userInteractor,
UserTracker userTracker,
- SceneContainerFlags sceneContainerFlags,
Lazy<CommunalInteractor> communalInteractor) {
mContext = context;
mWindowRootViewComponentFactory = windowRootViewComponentFactory;
@@ -186,7 +184,6 @@
dumpManager.registerCriticalDumpable("{slow}NotificationShadeWindowControllerImpl", this);
mAuthController = authController;
mUserInteractor = userInteractor;
- mSceneContainerFlags = sceneContainerFlags;
mCommunalInteractor = communalInteractor;
mLastKeyguardRotationAllowed = mKeyguardStateController.isKeyguardScreenRotationAllowed();
mLockScreenDisplayTimeout = context.getResources()
@@ -289,7 +286,7 @@
mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mLp.privateFlags |= PRIVATE_FLAG_OPTIMIZE_MEASURE;
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
// This prevents the appearance and disappearance of the software keyboard (also known
// as the "IME") from scrolling/panning the window to make room for the keyboard.
//
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index 648d4b5..a0c9391 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -19,7 +19,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.qs.QSContainerController
import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.data.repository.PrivacyChipRepository
import com.android.systemui.shade.data.repository.PrivacyChipRepositoryImpl
import com.android.systemui.shade.data.repository.ShadeRepository
@@ -50,11 +50,10 @@
@Provides
@SysUISingleton
fun provideBaseShadeInteractor(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<ShadeInteractorSceneContainerImpl>,
sceneContainerOff: Provider<ShadeInteractorLegacyImpl>
): BaseShadeInteractor {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
@@ -64,11 +63,10 @@
@Provides
@SysUISingleton
fun provideShadeController(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<ShadeControllerSceneImpl>,
sceneContainerOff: Provider<ShadeControllerImpl>
): ShadeController {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
@@ -78,11 +76,10 @@
@Provides
@SysUISingleton
fun provideShadeAnimationInteractor(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<ShadeAnimationInteractorSceneContainerImpl>,
sceneContainerOff: Provider<ShadeAnimationInteractorLegacyImpl>
): ShadeAnimationInteractor {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
@@ -92,11 +89,10 @@
@Provides
@SysUISingleton
fun provideShadeBackActionInteractor(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<ShadeBackActionInteractorImpl>,
sceneContainerOff: Provider<NotificationPanelViewController>
): ShadeBackActionInteractor {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
@@ -106,11 +102,10 @@
@Provides
@SysUISingleton
fun provideShadeLockscreenInteractor(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<ShadeLockscreenInteractorImpl>,
sceneContainerOff: Provider<NotificationPanelViewController>
): ShadeLockscreenInteractor {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
@@ -120,11 +115,10 @@
@Provides
@SysUISingleton
fun providePanelExpansionInteractor(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<PanelExpansionInteractorImpl>,
sceneContainerOff: Provider<NotificationPanelViewController>
): PanelExpansionInteractor {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
@@ -134,11 +128,10 @@
@Provides
@SysUISingleton
fun provideQuickSettingsController(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<QuickSettingsControllerSceneImpl>,
sceneContainerOff: Provider<QuickSettingsControllerImpl>,
): QuickSettingsController {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index f5dd5e4..bc23778 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -33,7 +33,7 @@
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.privacy.OngoingPrivacyChip
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -78,15 +78,13 @@
@SysUISingleton
fun providesWindowRootView(
layoutInflater: LayoutInflater,
- sceneContainerFlags: SceneContainerFlags,
viewModelProvider: Provider<SceneContainerViewModel>,
containerConfigProvider: Provider<SceneContainerConfig>,
- flagsProvider: Provider<SceneContainerFlags>,
scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
layoutInsetController: NotificationInsetsController,
sceneDataSourceDelegator: Provider<SceneDataSourceDelegator>,
): WindowRootView {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
checkNoSceneDuplicates(scenesProvider.get())
val sceneWindowRootView =
layoutInflater.inflate(R.layout.scene_window_root, null) as SceneWindowRootView
@@ -95,7 +93,6 @@
containerConfig = containerConfigProvider.get(),
sharedNotificationContainer =
sceneWindowRootView.requireViewById(R.id.shared_notification_container),
- flags = flagsProvider.get(),
scenes = scenesProvider.get(),
layoutInsetController = layoutInsetController,
sceneDataSourceDelegator = sceneDataSourceDelegator.get(),
@@ -115,9 +112,8 @@
@SysUISingleton
fun providesNotificationShadeWindowView(
root: WindowRootView,
- sceneContainerFlags: SceneContainerFlags,
): NotificationShadeWindowView {
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
return root.requireViewById(R.id.legacy_window_root)
}
return root as NotificationShadeWindowView?
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index 980f665a..6800c61 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -37,6 +37,7 @@
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
+import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -64,6 +65,7 @@
private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
private val footerActionsController: FooterActionsController,
private val sceneInteractor: SceneInteractor,
+ unfoldTransitionInteractor: UnfoldTransitionInteractor,
) {
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
combine(
@@ -106,6 +108,16 @@
val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode
+ /**
+ * The unfold transition progress. When fully-unfolded, this is `1` and fully folded, it's `0`.
+ */
+ val unfoldTransitionProgress: StateFlow<Float> =
+ unfoldTransitionInteractor.unfoldProgress.stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = 1f
+ )
+
/** Notifies that some content in the shade was clicked. */
fun onContentClicked() {
if (!isClickable.value) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index e5b6497..594c191 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -35,7 +35,7 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager;
import com.android.systemui.power.domain.interactor.PowerInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.ShadeSurface;
@@ -61,8 +61,6 @@
import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import javax.inject.Provider;
-
import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
@@ -70,6 +68,8 @@
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
+import javax.inject.Provider;
+
/**
* This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to
* this separate from {@link CentralSurfacesModule} module so that components that wish to build
@@ -185,10 +185,9 @@
@Provides
@SysUISingleton
static ShadeSurface provideShadeSurface(
- SceneContainerFlags sceneContainerFlags,
Provider<ShadeSurfaceImpl> sceneContainerOn,
Provider<NotificationPanelViewController> sceneContainerOff) {
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
return sceneContainerOn.get();
} else {
return sceneContainerOff.get();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 741102b..cf5366b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -29,7 +29,6 @@
import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
@@ -49,7 +48,6 @@
class SharedNotificationContainerBinder
@Inject
constructor(
- private val sceneContainerFlags: SceneContainerFlags,
private val controller: NotificationStackScrollLayoutController,
private val notificationStackSizeCalculator: NotificationStackSizeCalculator,
private val notificationScrollViewBinder: NotificationScrollViewBinder,
@@ -130,7 +128,7 @@
.collect { controller.setMaxDisplayedNotifications(it) }
}
- if (!sceneContainerFlags.isEnabled()) {
+ if (!SceneContainerFlag.isEnabled) {
launch {
viewModel.bounds.collect {
val animate =
@@ -166,7 +164,7 @@
}
}
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
disposables += notificationScrollViewBinder.bindWhileAttached()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index b284179..ca19da5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -22,7 +22,7 @@
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
@@ -43,7 +43,6 @@
dumpManager: DumpManager,
private val interactor: NotificationStackAppearanceInteractor,
shadeInteractor: ShadeInteractor,
- flags: SceneContainerFlags,
featureFlags: FeatureFlagsClassic,
private val keyguardInteractor: KeyguardInteractor,
) : FlowDumperImpl(dumpManager) {
@@ -51,7 +50,7 @@
val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES)
/** DEBUG: whether the debug logging should be output. */
- val isDebugLoggingEnabled: Boolean = flags.isEnabled()
+ val isDebugLoggingEnabled: Boolean = SceneContainerFlag.isEnabled
/** Notifies that the bounds of the notification scrim have changed. */
fun onScrimBoundsChanged(bounds: ShadeScrimBounds?) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 08b65e3..cb3c03e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -164,7 +164,6 @@
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.settings.brightness.BrightnessSliderController;
@@ -592,9 +591,6 @@
private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
(extractor, which) -> updateTheme();
-
- private final SceneContainerFlags mSceneContainerFlags;
-
private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor;
/**
@@ -708,7 +704,6 @@
UserTracker userTracker,
Provider<FingerprintManager> fingerprintManager,
ActivityStarter activityStarter,
- SceneContainerFlags sceneContainerFlags,
BrightnessMirrorShowingInteractor brightnessMirrorShowingInteractor
) {
mContext = context;
@@ -804,7 +799,6 @@
mUserTracker = userTracker;
mFingerprintManager = fingerprintManager;
mActivityStarter = activityStarter;
- mSceneContainerFlags = sceneContainerFlags;
mBrightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
@@ -1088,7 +1082,7 @@
mJavaAdapter.alwaysCollectFlow(
mCommunalInteractor.isIdleOnCommunal(),
mIdleOnCommunalConsumer);
- if (mSceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
mJavaAdapter.alwaysCollectFlow(
mBrightnessMirrorShowingInteractor.isShowing(),
this::setBrightnessMirrorShowing
@@ -1277,7 +1271,7 @@
// Set up the quick settings tile panel
final View container = getNotificationShadeWindowView().findViewById(R.id.qs_frame);
- if (container != null && !mSceneContainerFlags.isEnabled()) {
+ if (container != null && !SceneContainerFlag.isEnabled()) {
FragmentHostManager fragmentHostManager =
mFragmentService.getFragmentHostManager(container);
ExtensionFragmentListener.attachExtensonToFragment(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 92fd90a..5206e46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -24,10 +24,10 @@
import android.view.ViewGroup
import android.view.ViewTreeObserver
import com.android.systemui.Gefingerpoken
-import com.android.systemui.res.R
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.ShadeLogger
@@ -65,7 +65,6 @@
private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
private val userChipViewModel: StatusBarUserChipViewModel,
private val viewUtil: ViewUtil,
- private val sceneContainerFlags: SceneContainerFlags,
private val configurationController: ConfigurationController,
private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
) : ViewController<PhoneStatusBarView>(view) {
@@ -205,7 +204,7 @@
// If scene framework is enabled, route the touch to it and
// ignore the rest of the gesture.
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled) {
windowRootView.get().dispatchTouchEvent(event)
return true
}
@@ -267,7 +266,6 @@
@Named(UNFOLD_STATUS_BAR)
private val progressProvider: Optional<ScopedUnfoldTransitionProgressProvider>,
private val featureFlags: FeatureFlags,
- private val sceneContainerFlags: SceneContainerFlags,
private val userChipViewModel: StatusBarUserChipViewModel,
private val centralSurfaces: CentralSurfaces,
private val statusBarWindowStateController: StatusBarWindowStateController,
@@ -301,7 +299,6 @@
statusBarMoveFromCenterAnimationController,
userChipViewModel,
viewUtil,
- sceneContainerFlags,
configurationController,
statusOverlayHoverListenerFactory,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 8e8de46..d1189e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -37,7 +37,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -91,7 +91,6 @@
ShadeInteractor shadeInteractor,
Provider<SceneInteractor> sceneInteractor,
JavaAdapter javaAdapter,
- SceneContainerFlags sceneContainerFlags,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
PrimaryBouncerInteractor primaryBouncerInteractor,
AlternateBouncerInteractor alternateBouncerInteractor
@@ -130,7 +129,7 @@
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
- if (sceneContainerFlags.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
javaAdapter.alwaysCollectFlow(
sceneInteractor.get().isVisible(),
this::onSceneContainerVisibilityChanged);
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/data/repository/UnfoldTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/unfold/data/repository/UnfoldTransitionRepository.kt
index 0d3682c..fbbd2b9 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/data/repository/UnfoldTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/data/repository/UnfoldTransitionRepository.kt
@@ -15,9 +15,11 @@
*/
package com.android.systemui.unfold.data.repository
+import androidx.annotation.FloatRange
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionFinished
+import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionInProgress
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionStarted
import com.android.systemui.util.kotlin.getOrNull
import java.util.Optional
@@ -42,6 +44,10 @@
sealed class UnfoldTransitionStatus {
/** Status that is sent when fold or unfold transition is in started state */
data object TransitionStarted : UnfoldTransitionStatus()
+ /** Status that is sent while fold or unfold transition is in progress */
+ data class TransitionInProgress(
+ @FloatRange(from = 0.0, to = 1.0) val progress: Float,
+ ) : UnfoldTransitionStatus()
/** Status that is sent when fold or unfold transition is finished */
data object TransitionFinished : UnfoldTransitionStatus()
}
@@ -66,6 +72,10 @@
trySend(TransitionStarted)
}
+ override fun onTransitionProgress(progress: Float) {
+ trySend(TransitionInProgress(progress))
+ }
+
override fun onTransitionFinished() {
trySend(TransitionFinished)
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt
index 3e2e564..a8e4496 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt
@@ -17,10 +17,14 @@
import com.android.systemui.unfold.data.repository.UnfoldTransitionRepository
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionFinished
+import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionInProgress
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionStarted
import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
/**
* Contains business-logic related to fold-unfold transitions while interacting with
@@ -30,6 +34,8 @@
/** Returns availability of fold/unfold transitions on the device */
val isAvailable: Boolean
+ val unfoldProgress: Flow<Float>
+
/** Suspends and waits for a fold/unfold transition to finish */
suspend fun waitForTransitionFinish()
@@ -44,6 +50,11 @@
override val isAvailable: Boolean
get() = repository.isAvailable
+ override val unfoldProgress: Flow<Float> =
+ repository.transitionStatus
+ .map { (it as? TransitionInProgress)?.progress ?: 1f }
+ .distinctUntilChanged()
+
override suspend fun waitForTransitionFinish() {
repository.transitionStatus.filter { it is TransitionFinished }.first()
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
index a249961..319b615 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
@@ -205,9 +205,9 @@
when(mClockRegistry.createCurrentClock()).thenReturn(mClockController);
when(mClockEventController.getClock()).thenReturn(mClockController);
when(mSmallClockController.getConfig())
- .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
+ .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false, false));
when(mLargeClockController.getConfig())
- .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
+ .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false, false));
mSliceView = new View(getContext());
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 9d81b96..99b5a4b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -272,9 +272,9 @@
assertEquals(View.VISIBLE, mFakeDateView.getVisibility());
when(mSmallClockController.getConfig())
- .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, true, false));
+ .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, true, false, true));
when(mLargeClockController.getConfig())
- .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, true, false));
+ .thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, true, false, true));
verify(mClockRegistry).registerClockChangeListener(listenerArgumentCaptor.capture());
listenerArgumentCaptor.getValue().onCurrentClockChanged();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 11fe862..b2828a4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -98,7 +98,7 @@
public void updatePosition_primaryClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", false, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", false, true, false));
mController.updatePosition(10, 15, 20f, true);
@@ -113,7 +113,7 @@
public void updatePosition_alternateClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", true, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", true, true, false));
mController.updatePosition(10, 15, 20f, true);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
index f924ab4..bcea411 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
@@ -36,6 +36,7 @@
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageView;
import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
@@ -78,6 +79,7 @@
protected final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
protected @Mock DeviceEntryInteractor mDeviceEntryInteractor;
protected @Mock LockIconView mLockIconView;
+ protected @Mock ImageView mLockIcon;
protected @Mock AnimatedStateListDrawable mIconDrawable;
protected @Mock Context mContext;
protected @Mock Resources mResources;
@@ -146,8 +148,10 @@
when(mStatusBarStateController.isDozing()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR);
- mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT);
+ if (!Flags.sceneContainer()) {
+ mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR);
+ mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT);
+ }
mFeatureFlags = new FakeFeatureFlags();
mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
@@ -172,8 +176,7 @@
mFeatureFlags,
mPrimaryBouncerInteractor,
mContext,
- () -> mDeviceEntryInteractor,
- mKosmos.getFakeSceneContainerFlags()
+ () -> mDeviceEntryInteractor
);
}
@@ -225,6 +228,7 @@
protected void setupLockIconViewMocks() {
when(mLockIconView.getResources()).thenReturn(mResources);
when(mLockIconView.getContext()).thenReturn(mContext);
+ when(mLockIconView.getLockIcon()).thenReturn(mLockIcon);
}
protected void resetLockIconView() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
index 8689842..255c7d9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
@@ -43,6 +43,7 @@
import com.android.systemui.biometrics.UdfpsController;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
import com.android.systemui.doze.util.BurnInHelperKt;
+import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.statusbar.StatusBarState;
import org.junit.Test;
@@ -373,7 +374,6 @@
@Test
public void longPress_showBouncer_sceneContainerNotEnabled() {
init(/* useMigrationFlag= */ false);
- mKosmos.getFakeSceneContainerFlags().setEnabled(false);
when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
// WHEN longPress
@@ -385,9 +385,9 @@
}
@Test
+ @EnableSceneContainer
public void longPress_showBouncer() {
init(/* useMigrationFlag= */ false);
- mKosmos.getFakeSceneContainerFlags().setEnabled(true);
when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
// WHEN longPress
@@ -399,9 +399,9 @@
}
@Test
+ @EnableSceneContainer
public void longPress_falsingTriggered_doesNotShowBouncer() {
init(/* useMigrationFlag= */ false);
- mKosmos.getFakeSceneContainerFlags().setEnabled(true);
when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(true);
// WHEN longPress
diff --git a/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
index f490f3c..cbad133 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
@@ -41,7 +41,6 @@
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.QuickSettingsController
import com.android.systemui.shade.ShadeController
@@ -109,7 +108,6 @@
headsUpManager,
powerInteractor,
activeNotificationsInteractor,
- kosmos.sceneContainerFlags,
kosmos::sceneInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index 30c5e6e..d3cc232 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -78,7 +78,6 @@
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
import com.android.systemui.statusbar.phone.dozeServiceHost
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -239,7 +238,6 @@
testScope.backgroundScope,
mContext,
deviceEntryFingerprintAuthRepository,
- kosmos.fakeSceneContainerFlags,
kosmos.sceneInteractor,
primaryBouncerInteractor,
alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index 238a76e..415da02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -77,7 +77,6 @@
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
import com.android.systemui.statusbar.phone.dozeServiceHost
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -236,7 +235,6 @@
testScope.backgroundScope,
mContext,
deviceEntryFingerprintAuthRepository,
- kosmos.fakeSceneContainerFlags,
kosmos.sceneInteractor,
primaryBouncerInteractor,
alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index a46f755..709f779 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -25,8 +25,8 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
-import static com.android.systemui.Flags.FLAG_REFACTOR_GET_CURRENT_USER;
import static com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR;
+import static com.android.systemui.Flags.FLAG_REFACTOR_GET_CURRENT_USER;
import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION;
import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT;
import static com.android.systemui.keyguard.KeyguardViewMediator.REBOOT_MAINLINE_UPDATE;
@@ -102,7 +102,6 @@
import com.android.systemui.log.SessionTracker;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.scene.FakeWindowRootViewComponent;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.scene.ui.view.WindowRootView;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
@@ -222,7 +221,6 @@
private @Mock DreamViewModel mDreamViewModel;
private @Mock CommunalTransitionViewModel mCommunalTransitionViewModel;
private @Mock SystemPropertiesHelper mSystemPropertiesHelper;
- private @Mock SceneContainerFlags mSceneContainerFlags;
private FakeFeatureFlags mFeatureFlags;
private final int mDefaultUserId = 100;
@@ -270,7 +268,6 @@
mShadeWindowLogger,
() -> mSelectedUserInteractor,
mUserTracker,
- mSceneContainerFlags,
mKosmos::getCommunalInteractor);
mFeatureFlags = new FakeFeatureFlags();
mSetFlagsRule.enableFlags(FLAG_REFACTOR_GET_CURRENT_USER);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index b0aace6..b50d248 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -23,7 +23,6 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.utils.GlobalWindowManager
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -63,8 +62,8 @@
val withDeps =
KeyguardInteractorFactory.create(
- repository = keyguardRepository,
featureFlags = featureFlags,
+ repository = keyguardRepository,
)
val keyguardInteractor = withDeps.keyguardInteractor
resourceTrimmer =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
index 9266af4..dc7f372 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
@@ -32,6 +32,7 @@
import com.android.systemui.coroutines.collectValues
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFingerprintAuthInteractor
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
@@ -40,7 +41,6 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -87,7 +87,6 @@
@Before
fun setup() {
mSetFlagsRule.enableFlags(FLAG_SIDEFPS_CONTROLLER_REFACTOR)
- kosmos.fakeSceneContainerFlags.enabled = false
primaryBouncerInteractor =
PrimaryBouncerInteractor(
@@ -127,7 +126,6 @@
testScope.backgroundScope,
mContext,
deviceEntryFingerprintAuthRepository,
- kosmos.fakeSceneContainerFlags,
kosmos.sceneInteractor,
primaryBouncerInteractor,
alternateBouncerInteractor,
@@ -168,15 +166,14 @@
}
@Test
+ @EnableSceneContainer
fun updatesShowIndicatorForDeviceEntry_onBouncerSceneActive() =
testScope.runTest {
- kosmos.fakeSceneContainerFlags.enabled = true
underTest =
DeviceEntrySideFpsOverlayInteractor(
testScope.backgroundScope,
mContext,
deviceEntryFingerprintAuthRepository,
- kosmos.fakeSceneContainerFlags,
kosmos.sceneInteractor,
primaryBouncerInteractor,
alternateBouncerInteractor,
@@ -196,15 +193,14 @@
}
@Test
+ @EnableSceneContainer
fun updatesShowIndicatorForDeviceEntry_onBouncerSceneInactive() =
testScope.runTest {
- kosmos.fakeSceneContainerFlags.enabled = true
underTest =
DeviceEntrySideFpsOverlayInteractor(
testScope.backgroundScope,
mContext,
deviceEntryFingerprintAuthRepository,
- kosmos.fakeSceneContainerFlags,
kosmos.sceneInteractor,
primaryBouncerInteractor,
alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
index 3f05bfa..9ccf212 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
@@ -19,6 +19,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -227,4 +228,50 @@
{ it == KeyguardSurfaceBehindModel(alpha = 0f) },
)
}
+
+ @Test
+ fun notificationLaunchFromLockscreen_isAnimatingSurfaceTrue() =
+ testScope.runTest {
+ val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+ transitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ transitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ transitionState = TransitionState.FINISHED,
+ )
+ )
+ kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+ runCurrent()
+ assertThat(isAnimatingSurface).isTrue()
+ }
+
+ @Test
+ fun notificationLaunchFromGone_isAnimatingSurfaceFalse() =
+ testScope.runTest {
+ val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+ transitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.STARTED,
+ )
+ )
+ transitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.FINISHED,
+ )
+ )
+ kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+ runCurrent()
+ assertThat(isAnimatingSurface).isFalse()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
index 66aa572..5e3a142 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
@@ -113,7 +113,8 @@
id = "WEATHER_CLOCK",
name = "",
description = "",
- useAlternateSmartspaceAODTransition = true
+ useAlternateSmartspaceAODTransition = true,
+ useCustomClockScene = true
)
whenever(clock.config).thenReturn(clockConfig)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index 4d20f55..31658e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -78,7 +78,7 @@
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var broadcastSender: BroadcastSender
- @Mock private lateinit var mediaDataManager: MediaDataManager
+ @Mock private lateinit var mediaDataProcessor: MediaDataProcessor
@Mock private lateinit var lockscreenUserManager: NotificationLockscreenUserManager
@Mock private lateinit var executor: Executor
@Mock private lateinit var smartspaceData: SmartspaceMediaData
@@ -114,7 +114,7 @@
mediaFlags,
repository,
)
- mediaDataFilter.mediaDataManager = mediaDataManager
+ mediaDataFilter.mediaDataProcessor = mediaDataProcessor
// Start all tests as main user
setUser(USER_MAIN)
@@ -481,7 +481,7 @@
mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
mediaDataFilter.onSwipeToDismiss()
- verify(mediaDataManager).setInactive(eq(KEY), eq(true), eq(true))
+ verify(mediaDataProcessor).setInactive(eq(KEY), eq(true), eq(true))
}
@Test
@@ -846,8 +846,8 @@
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, data)
mediaDataFilter.onSwipeToDismiss()
- verify(mediaDataManager).setRecommendationInactive(eq(SMARTSPACE_KEY))
- verify(mediaDataManager, never())
+ verify(mediaDataProcessor).setRecommendationInactive(eq(SMARTSPACE_KEY))
+ verify(mediaDataProcessor, never())
.dismissSmartspaceRecommendation(eq(SMARTSPACE_KEY), anyLong())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt
index a73bb2c..e5d3082 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaViewControllerTest.kt
@@ -16,29 +16,54 @@
package com.android.systemui.media.controls.ui.controller
+import android.animation.AnimatorSet
+import android.content.Context
import android.content.res.Configuration
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.RippleDrawable
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
+import android.view.ViewGroup
+import android.view.animation.Interpolator
+import android.widget.FrameLayout
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.SeekBar
+import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintSet
+import androidx.lifecycle.LiveData
import androidx.test.filters.SmallTest
+import com.android.internal.widget.CachingIconView
import com.android.systemui.SysuiTestCase
+import com.android.systemui.media.controls.ui.view.GutsViewHolder
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
+import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.res.R
+import com.android.systemui.surfaceeffects.loadingeffect.LoadingEffectView
+import com.android.systemui.surfaceeffects.ripple.MultiRippleView
+import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView
import com.android.systemui.util.animation.MeasurementInput
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.animation.TransitionViewState
import com.android.systemui.util.animation.WidgetState
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.settings.GlobalSettings
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.floatThat
import org.mockito.Mock
+import org.mockito.Mockito
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@@ -55,6 +80,31 @@
com.android.systemui.statusbar.phone.ConfigurationControllerImpl(context)
private var player = TransitionLayout(context, /* attrs */ null, /* defStyleAttr */ 0)
private var recommendation = TransitionLayout(context, /* attrs */ null, /* defStyleAttr */ 0)
+ private val clock = FakeSystemClock()
+ private lateinit var mainExecutor: FakeExecutor
+ private lateinit var seekBar: SeekBar
+ private lateinit var multiRippleView: MultiRippleView
+ private lateinit var turbulenceNoiseView: TurbulenceNoiseView
+ private lateinit var loadingEffectView: LoadingEffectView
+ private lateinit var settings: ImageButton
+ private lateinit var cancel: View
+ private lateinit var cancelText: TextView
+ private lateinit var dismiss: FrameLayout
+ private lateinit var dismissText: TextView
+ private lateinit var titleText: TextView
+ private lateinit var artistText: TextView
+ private lateinit var explicitIndicator: CachingIconView
+ private lateinit var seamless: ViewGroup
+ private lateinit var seamlessButton: View
+ private lateinit var seamlessIcon: ImageView
+ private lateinit var seamlessText: TextView
+ private lateinit var scrubbingElapsedTimeView: TextView
+ private lateinit var scrubbingTotalTimeView: TextView
+ private lateinit var actionPlayPause: ImageButton
+ private lateinit var actionNext: ImageButton
+ private lateinit var actionPrev: ImageButton
+ @Mock private lateinit var seamlessBackground: RippleDrawable
+ @Mock private lateinit var albumView: ImageView
@Mock lateinit var logger: MediaViewLogger
@Mock private lateinit var mockViewState: TransitionViewState
@Mock private lateinit var mockCopiedState: TransitionViewState
@@ -64,6 +114,14 @@
@Mock private lateinit var mediaSubTitleWidgetState: WidgetState
@Mock private lateinit var mediaContainerWidgetState: WidgetState
@Mock private lateinit var mediaFlags: MediaFlags
+ @Mock private lateinit var seekBarViewModel: SeekBarViewModel
+ @Mock private lateinit var seekBarData: LiveData<SeekBarViewModel.Progress>
+ @Mock private lateinit var globalSettings: GlobalSettings
+ @Mock private lateinit var viewHolder: MediaViewHolder
+ @Mock private lateinit var view: TransitionLayout
+ @Mock private lateinit var mockAnimator: AnimatorSet
+ @Mock private lateinit var gutsViewHolder: GutsViewHolder
+ @Mock private lateinit var gutsText: TextView
private val delta = 0.1F
@@ -72,14 +130,30 @@
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ mainExecutor = FakeExecutor(clock)
mediaViewController =
- MediaViewController(
- context,
- configurationController,
- mediaHostStatesManager,
- logger,
- mediaFlags,
- )
+ object :
+ MediaViewController(
+ context,
+ configurationController,
+ mediaHostStatesManager,
+ logger,
+ seekBarViewModel,
+ mainExecutor,
+ mediaFlags,
+ globalSettings,
+ ) {
+ override fun loadAnimator(
+ context: Context,
+ animId: Int,
+ motionInterpolator: Interpolator?,
+ vararg targets: View?
+ ): AnimatorSet {
+ return mockAnimator
+ }
+ }
+ initGutsViewHolderMocks()
+ initMediaViewHolderMocks()
}
@Test
@@ -299,4 +373,270 @@
verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
}
+
+ @Test
+ fun attachPlayer_seekBarDisabled_seekBarVisibilityIsSetToInvisible() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ getEnabledChangeListener().onEnabledChanged(enabled = true)
+ getEnabledChangeListener().onEnabledChanged(enabled = false)
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.media_progress_bar))
+ .isEqualTo(ConstraintSet.INVISIBLE)
+ }
+
+ @Test
+ fun attachPlayer_seekBarEnabled_seekBarVisible() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ getEnabledChangeListener().onEnabledChanged(enabled = true)
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.media_progress_bar))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ }
+
+ @Test
+ fun attachPlayer_seekBarStatusUpdate_seekBarVisibilityChanges() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ getEnabledChangeListener().onEnabledChanged(enabled = true)
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.media_progress_bar))
+ .isEqualTo(ConstraintSet.VISIBLE)
+
+ getEnabledChangeListener().onEnabledChanged(enabled = false)
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.media_progress_bar))
+ .isEqualTo(ConstraintSet.INVISIBLE)
+ }
+
+ @Test
+ fun attachPlayer_notScrubbing_scrubbingViewsGone() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ mediaViewController.canShowScrubbingTime = true
+ getScrubbingChangeListener().onScrubbingChanged(true)
+ getScrubbingChangeListener().onScrubbingChanged(false)
+ mainExecutor.runAllReady()
+
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ }
+
+ @Test
+ fun setIsScrubbing_noSemanticActions_scrubbingViewsGone() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ mediaViewController.canShowScrubbingTime = false
+ getScrubbingChangeListener().onScrubbingChanged(true)
+ mainExecutor.runAllReady()
+
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ }
+
+ @Test
+ fun setIsScrubbing_noPrevButton_scrubbingTimesNotShown() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ mediaViewController.setUpNextButtonInfo(true)
+ mediaViewController.setUpPrevButtonInfo(false)
+ getScrubbingChangeListener().onScrubbingChanged(true)
+ mainExecutor.runAllReady()
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionNext))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ }
+
+ @Test
+ fun setIsScrubbing_noNextButton_scrubbingTimesNotShown() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ mediaViewController.setUpNextButtonInfo(false)
+ mediaViewController.setUpPrevButtonInfo(true)
+ getScrubbingChangeListener().onScrubbingChanged(true)
+ mainExecutor.runAllReady()
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionPrev))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ }
+
+ @Test
+ fun setIsScrubbing_scrubbingViewsShownAndPrevNextHiddenOnlyInExpanded() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ mediaViewController.setUpNextButtonInfo(true)
+ mediaViewController.setUpPrevButtonInfo(true)
+ mediaViewController.canShowScrubbingTime = true
+ getScrubbingChangeListener().onScrubbingChanged(true)
+ mainExecutor.runAllReady()
+
+ // Only in expanded, we should show the scrubbing times and hide prev+next
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionPrev))
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionNext))
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.VISIBLE)
+ }
+
+ @Test
+ fun setIsScrubbing_trueThenFalse_reservePrevAndNextButtons() {
+ whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(true)
+
+ mediaViewController.attachPlayer(viewHolder)
+ mediaViewController.setUpNextButtonInfo(true, ConstraintSet.INVISIBLE)
+ mediaViewController.setUpPrevButtonInfo(true, ConstraintSet.INVISIBLE)
+ mediaViewController.canShowScrubbingTime = true
+
+ getScrubbingChangeListener().onScrubbingChanged(true)
+ mainExecutor.runAllReady()
+
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionPrev))
+ .isEqualTo(ConstraintSet.INVISIBLE)
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionNext))
+ .isEqualTo(ConstraintSet.INVISIBLE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.VISIBLE)
+
+ getScrubbingChangeListener().onScrubbingChanged(false)
+ mainExecutor.runAllReady()
+
+ // Only in expanded, we should hide the scrubbing times and show prev+next
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionPrev))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(mediaViewController.expandedLayout.getVisibility(R.id.actionNext))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_elapsed_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ assertThat(
+ mediaViewController.expandedLayout.getVisibility(R.id.media_scrubbing_total_time)
+ )
+ .isEqualTo(ConstraintSet.GONE)
+ }
+
+ private fun initGutsViewHolderMocks() {
+ settings = ImageButton(context)
+ cancel = View(context)
+ cancelText = TextView(context)
+ dismiss = FrameLayout(context)
+ dismissText = TextView(context)
+ whenever(gutsViewHolder.gutsText).thenReturn(gutsText)
+ whenever(gutsViewHolder.settings).thenReturn(settings)
+ whenever(gutsViewHolder.cancel).thenReturn(cancel)
+ whenever(gutsViewHolder.cancelText).thenReturn(cancelText)
+ whenever(gutsViewHolder.dismiss).thenReturn(dismiss)
+ whenever(gutsViewHolder.dismissText).thenReturn(dismissText)
+ }
+
+ private fun initMediaViewHolderMocks() {
+ titleText = TextView(context)
+ artistText = TextView(context)
+ explicitIndicator = CachingIconView(context).also { it.id = R.id.media_explicit_indicator }
+ seamless = FrameLayout(context)
+ seamless.foreground = seamlessBackground
+ seamlessButton = View(context)
+ seamlessIcon = ImageView(context)
+ seamlessText = TextView(context)
+ seekBar = SeekBar(context).also { it.id = R.id.media_progress_bar }
+
+ actionPlayPause = ImageButton(context).also { it.id = R.id.actionPlayPause }
+ actionPrev = ImageButton(context).also { it.id = R.id.actionPrev }
+ actionNext = ImageButton(context).also { it.id = R.id.actionNext }
+ scrubbingElapsedTimeView =
+ TextView(context).also { it.id = R.id.media_scrubbing_elapsed_time }
+ scrubbingTotalTimeView = TextView(context).also { it.id = R.id.media_scrubbing_total_time }
+
+ multiRippleView = MultiRippleView(context, null)
+ turbulenceNoiseView = TurbulenceNoiseView(context, null)
+ loadingEffectView = LoadingEffectView(context, null)
+
+ whenever(viewHolder.player).thenReturn(view)
+ whenever(view.context).thenReturn(context)
+ whenever(viewHolder.albumView).thenReturn(albumView)
+ whenever(albumView.foreground).thenReturn(Mockito.mock(Drawable::class.java))
+ whenever(viewHolder.titleText).thenReturn(titleText)
+ whenever(viewHolder.artistText).thenReturn(artistText)
+ whenever(viewHolder.explicitIndicator).thenReturn(explicitIndicator)
+ whenever(seamlessBackground.getDrawable(0))
+ .thenReturn(Mockito.mock(GradientDrawable::class.java))
+ whenever(viewHolder.seamless).thenReturn(seamless)
+ whenever(viewHolder.seamlessButton).thenReturn(seamlessButton)
+ whenever(viewHolder.seamlessIcon).thenReturn(seamlessIcon)
+ whenever(viewHolder.seamlessText).thenReturn(seamlessText)
+ whenever(viewHolder.seekBar).thenReturn(seekBar)
+ whenever(viewHolder.scrubbingElapsedTimeView).thenReturn(scrubbingElapsedTimeView)
+ whenever(viewHolder.scrubbingTotalTimeView).thenReturn(scrubbingTotalTimeView)
+ whenever(viewHolder.gutsViewHolder).thenReturn(gutsViewHolder)
+ whenever(seekBarViewModel.progress).thenReturn(seekBarData)
+
+ // Action buttons
+ whenever(viewHolder.actionPlayPause).thenReturn(actionPlayPause)
+ whenever(viewHolder.getAction(R.id.actionNext)).thenReturn(actionNext)
+ whenever(viewHolder.getAction(R.id.actionPrev)).thenReturn(actionPrev)
+ whenever(viewHolder.getAction(R.id.actionPlayPause)).thenReturn(actionPlayPause)
+
+ whenever(viewHolder.multiRippleView).thenReturn(multiRippleView)
+ whenever(viewHolder.turbulenceNoiseView).thenReturn(turbulenceNoiseView)
+ whenever(viewHolder.loadingEffectView).thenReturn(loadingEffectView)
+ }
+
+ private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
+ withArgCaptor {
+ verify(seekBarViewModel).setScrubbingChangeListener(capture())
+ }
+
+ private fun getEnabledChangeListener(): SeekBarViewModel.EnabledChangeListener = withArgCaptor {
+ verify(seekBarViewModel).setEnabledChangeListener(capture())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
index e4a4836..6956bea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
@@ -57,6 +57,7 @@
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.flags.FeatureFlagsClassic;
import com.android.systemui.media.controls.ui.view.MediaHost;
import com.android.systemui.qs.customize.QSCustomizerController;
@@ -66,7 +67,6 @@
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.CommandQueue;
@@ -115,7 +115,6 @@
@Mock private FooterActionsViewBinder mFooterActionsViewBinder;
@Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
@Mock private FeatureFlagsClassic mFeatureFlags;
- @Mock private SceneContainerFlags mSceneContainerFlags;
private ViewGroup mQsView;
private final CommandQueue mCommandQueue =
@@ -127,7 +126,6 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- when(mSceneContainerFlags.isEnabled()).thenReturn(false);
mUnderTest = instantiate();
@@ -496,8 +494,8 @@
}
@Test
+ @EnableSceneContainer
public void testSceneContainerFlagsEnabled_FooterActionsRemoved_controllerNotStarted() {
- when(mSceneContainerFlags.isEnabled()).thenReturn(true);
clearInvocations(
mFooterActionsViewBinder, mFooterActionsViewModel, mFooterActionsViewModelFactory);
QSImpl other = instantiate();
@@ -513,9 +511,8 @@
}
@Test
+ @EnableSceneContainer
public void testSceneContainerFlagsEnabled_statusBarStateIsShade() {
- when(mSceneContainerFlags.isEnabled()).thenReturn(true);
-
mUnderTest.onStateChanged(KEYGUARD);
assertThat(mUnderTest.getStatusBarState()).isEqualTo(SHADE);
@@ -524,9 +521,8 @@
}
@Test
+ @EnableSceneContainer
public void testSceneContainerFlagsEnabled_isKeyguardState_alwaysFalse() {
- when(mSceneContainerFlags.isEnabled()).thenReturn(true);
-
mUnderTest.onStateChanged(KEYGUARD);
assertThat(mUnderTest.isKeyguardState()).isFalse();
@@ -559,8 +555,8 @@
mFooterActionsViewModelFactory,
mFooterActionsViewBinder,
mLargeScreenShadeInterpolator,
- mFeatureFlags,
- mSceneContainerFlags);
+ mFeatureFlags
+ );
}
private void setUpOther() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index a60494f..0275643 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -17,13 +17,13 @@
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
import com.android.systemui.settings.brightness.BrightnessController
import com.android.systemui.settings.brightness.BrightnessSliderController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.tuner.TunerService
import com.google.common.truth.Truth.assertThat
+import javax.inject.Provider
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -36,7 +36,6 @@
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import javax.inject.Provider
import org.mockito.Mockito.`when` as whenever
@SmallTest
@@ -65,8 +64,6 @@
@Mock private lateinit var pagedTileLayout: PagedTileLayout
@Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect>
- private val sceneContainerFlags = FakeSceneContainerFlags()
-
private lateinit var controller: QSPanelController
private val testableResources: TestableResources = mContext.orCreateTestableResources
@@ -103,7 +100,6 @@
falsingManager,
statusBarKeyguardViewManager,
ResourcesSplitShadeStateController(),
- sceneContainerFlags,
longPressEffectProvider,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index 8acde36..4915e55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -20,15 +20,14 @@
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Answers
import org.mockito.Mock
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@@ -43,8 +42,6 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private lateinit var context: Context
- private val sceneContainerFlags = FakeSceneContainerFlags()
-
private lateinit var controller: QuickStatusBarHeaderController
@Before
@@ -55,9 +52,8 @@
`when`(view.context).thenReturn(context)
controller = QuickStatusBarHeaderController(
- view,
- quickQSPanelController,
- sceneContainerFlags,
+ view,
+ quickQSPanelController,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
index 1313227..387f27d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
@@ -42,7 +42,6 @@
import com.android.systemui.navigationbar.NavigationBarController
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.recents.OverviewProxyService.ACTION_QUICKSTEP
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
import com.android.systemui.settings.FakeDisplayTracker
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.ShadeViewController
@@ -249,7 +248,6 @@
sysuiUnlockAnimationController,
inWindowLauncherUnlockAnimationManager,
assistUtils,
- FakeSceneContainerFlags(),
dumpManager,
unfoldTransitionProgressForwarder,
broadcastDispatcher
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index cf7c6f4..b89ccef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -75,8 +75,6 @@
import com.android.systemui.scene.FakeWindowRootViewComponent;
import com.android.systemui.scene.data.repository.SceneContainerRepository;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.scene.shared.logger.SceneLogger;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.data.repository.FakeShadeRepository;
@@ -136,7 +134,6 @@
@Mock private ShadeWindowLogger mShadeWindowLogger;
@Mock private SelectedUserInteractor mSelectedUserInteractor;
@Mock private UserTracker mUserTracker;
- @Mock private SceneContainerFlags mSceneContainerFlags;
@Mock private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
@Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
@Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListener;
@@ -185,14 +182,12 @@
mKosmos.getDeviceUnlockedInteractor());
FakeConfigurationRepository configurationRepository = new FakeConfigurationRepository();
- FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags();
KeyguardTransitionInteractor keyguardTransitionInteractor =
mKosmos.getKeyguardTransitionInteractor();
KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
keyguardRepository,
new FakeCommandQueue(),
powerInteractor,
- sceneContainerFlags,
new FakeKeyguardBouncerRepository(),
new ConfigurationInteractor(configurationRepository),
shadeRepository,
@@ -256,7 +251,6 @@
mShadeWindowLogger,
() -> mSelectedUserInteractor,
mUserTracker,
- mSceneContainerFlags,
() -> communalInteractor) {
@Override
protected boolean isDebuggable() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index 20d877e..77ad17a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -62,7 +62,6 @@
import com.android.systemui.res.R;
import com.android.systemui.scene.data.repository.SceneContainerRepository;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
import com.android.systemui.scene.shared.logger.SceneLogger;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shade.data.repository.FakeShadeRepository;
@@ -208,14 +207,12 @@
mock(SceneLogger.class),
mKosmos.getDeviceUnlockedInteractor());
- FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags();
KeyguardTransitionInteractor keyguardTransitionInteractor =
mKosmos.getKeyguardTransitionInteractor();
KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
mKeyguardRepository,
new FakeCommandQueue(),
powerInteractor,
- sceneContainerFlags,
new FakeKeyguardBouncerRepository(),
new ConfigurationInteractor(configurationRepository),
mShadeRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index 433c95a..6bdd3ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
@@ -33,7 +33,6 @@
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
@@ -95,7 +94,6 @@
headsUpManager,
PowerInteractorFactory.create().powerInteractor,
ActiveNotificationsInteractor(activeNotificationsRepository, testDispatcher),
- kosmos.sceneContainerFlags,
kosmos::sceneInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
index 56fc0c7..a05a23b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
@@ -21,7 +21,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction
import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.ViewIdToTranslate
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
@@ -34,21 +34,19 @@
@RunWith(AndroidTestingRunner::class)
class UnfoldConstantTranslateAnimatorTest : SysuiTestCase() {
- private val progressProvider = TestUnfoldTransitionProvider()
+ private val progressProvider = FakeUnfoldTransitionProvider()
- @Mock
- private lateinit var parent: ViewGroup
+ @Mock private lateinit var parent: ViewGroup
- @Mock
- private lateinit var shouldBeAnimated: () -> Boolean
+ @Mock private lateinit var shouldBeAnimated: () -> Boolean
private lateinit var animator: UnfoldConstantTranslateAnimator
private val viewsIdToRegister
get() =
setOf(
- ViewIdToTranslate(START_VIEW_ID, Direction.START, shouldBeAnimated),
- ViewIdToTranslate(END_VIEW_ID, Direction.END, shouldBeAnimated)
+ ViewIdToTranslate(START_VIEW_ID, Direction.START, shouldBeAnimated),
+ ViewIdToTranslate(END_VIEW_ID, Direction.END, shouldBeAnimated)
)
@Before
@@ -122,11 +120,12 @@
progressProvider.onTransitionStarted()
progressProvider.onTransitionProgress(0f)
- val rtlMultiplier = if (layoutDirection == View.LAYOUT_DIRECTION_LTR) {
- 1
- } else {
- -1
- }
+ val rtlMultiplier =
+ if (layoutDirection == View.LAYOUT_DIRECTION_LTR) {
+ 1
+ } else {
+ -1
+ }
list.forEach { (view, direction) ->
assertEquals(
(-MAX_TRANSLATION * direction * rtlMultiplier).toInt(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index d2fc087..be5af88 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -55,7 +55,6 @@
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.data.repository.FakeShadeRepository
@@ -87,8 +86,8 @@
import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -135,7 +134,6 @@
val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
val featureFlags = FakeFeatureFlagsClassic()
val shadeRepository = FakeShadeRepository()
- val sceneContainerFlags = FakeSceneContainerFlags()
val configurationRepository = FakeConfigurationRepository()
val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
fromLockscreenTransitionInteractor = kosmos.fromLockscreenTransitionInteractor
@@ -146,7 +144,6 @@
keyguardRepository,
FakeCommandQueue(),
powerInteractor,
- sceneContainerFlags,
FakeKeyguardBouncerRepository(),
ConfigurationInteractor(configurationRepository),
shadeRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index 54a6523..bb68ec5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -138,7 +138,6 @@
mHeadsUpManager,
mPowerInteractor,
mActiveNotificationsInteractor,
- mKosmos.getSceneContainerFlags(),
() -> mKosmos.getSceneInteractor());
mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index db053d8..9e2856d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -180,7 +180,6 @@
mHeadsUpManager,
PowerInteractorFactory.create().getPowerInteractor(),
mActiveNotificationsInteractor,
- mKosmos.getSceneContainerFlags(),
() -> mKosmos.getSceneInteractor()
);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 65a960b..1b85dfa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -45,6 +45,7 @@
import com.android.internal.statusbar.statusBarService
import com.android.systemui.SysuiTestCase
import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.people.widget.PeopleSpaceWidgetManager
@@ -55,7 +56,6 @@
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.UserContextProvider
import com.android.systemui.shade.shadeControllerSceneImpl
@@ -93,6 +93,7 @@
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
+@EnableSceneContainer
class NotificationGutsManagerWithScenesTest : SysuiTestCase() {
private val testNotificationChannel =
NotificationChannel(
@@ -143,8 +144,6 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- val sceneContainerFlags = kosmos.fakeSceneContainerFlags
- sceneContainerFlags.enabled = true
allowTestableLooperAsMainThread()
helper = NotificationTestHelper(mContext, mDependency)
Mockito.`when`(accessibilityManager.isTouchExplorationEnabled).thenReturn(false)
@@ -156,9 +155,9 @@
headsUpManager,
create().powerInteractor,
activeNotificationsInteractor,
- sceneContainerFlags,
- { sceneInteractor },
- )
+ ) {
+ sceneInteractor
+ }
gutsManager =
NotificationGutsManager(
mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
index 4bfd7e3..df82df8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
@@ -31,7 +31,7 @@
import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_ON
import com.android.systemui.power.shared.model.WakefulnessState.STARTING_TO_SLEEP
import com.android.systemui.statusbar.policy.FakeConfigurationController
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.unfold.data.repository.UnfoldTransitionRepositoryImpl
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractorImpl
import com.android.systemui.util.animation.data.repository.FakeAnimationStatusRepository
@@ -59,7 +59,7 @@
private val animationStatus = FakeAnimationStatusRepository()
private val configurationController = FakeConfigurationController()
- private val unfoldTransitionProgressProvider = TestUnfoldTransitionProvider()
+ private val unfoldTransitionProgressProvider = FakeUnfoldTransitionProvider()
private val powerRepository = FakePowerRepository()
private val powerInteractor =
PowerInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 783bf80..5c65103 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -31,6 +31,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -101,6 +102,7 @@
import com.android.systemui.communal.shared.model.CommunalScenes;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.EnableSceneContainer;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.fragments.FragmentService;
@@ -120,7 +122,6 @@
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.settings.brightness.BrightnessSliderController;
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor;
@@ -336,8 +337,6 @@
private final DumpManager mDumpManager = new DumpManager();
private final ScreenLifecycle mScreenLifecycle = new ScreenLifecycle(mDumpManager);
- private final FakeSceneContainerFlags mSceneContainerFlags = new FakeSceneContainerFlags();
-
private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor =
mKosmos.getBrightnessMirrorShowingInteractor();
@@ -351,7 +350,9 @@
// Turn AOD on and toggle feature flag for jank fixes
mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true);
when(mDozeParameters.getAlwaysOn()).thenReturn(true);
- mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
+ if (!com.android.systemui.Flags.sceneContainer()) {
+ mSetFlagsRule.disableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
+ }
IThermalService thermalService = mock(IThermalService.class);
mPowerManager = new PowerManager(mContext, mPowerManagerService, thermalService,
@@ -426,22 +427,25 @@
((Runnable) invocation.getArgument(0)).run();
return null;
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
-
- mShadeController = spy(new ShadeControllerImpl(
- mCommandQueue,
- mMainExecutor,
- mock(WindowRootViewVisibilityInteractor.class),
- mKeyguardStateController,
- mStatusBarStateController,
- mStatusBarKeyguardViewManager,
- mStatusBarWindowController,
- mDeviceProvisionedController,
- mNotificationShadeWindowController,
- 0,
- () -> mNotificationPanelViewController,
- () -> mAssistManager,
- () -> mNotificationGutsManager
- ));
+ if (com.android.systemui.Flags.sceneContainer()) {
+ mShadeController = spy(mKosmos.getShadeController());
+ } else {
+ mShadeController = spy(new ShadeControllerImpl(
+ mCommandQueue,
+ mMainExecutor,
+ mock(WindowRootViewVisibilityInteractor.class),
+ mKeyguardStateController,
+ mStatusBarStateController,
+ mStatusBarKeyguardViewManager,
+ mStatusBarWindowController,
+ mDeviceProvisionedController,
+ mNotificationShadeWindowController,
+ 0,
+ () -> mNotificationPanelViewController,
+ () -> mAssistManager,
+ () -> mNotificationGutsManager
+ ));
+ }
mShadeController.setNotificationShadeWindowViewController(
mNotificationShadeWindowViewController);
mShadeController.setNotificationPresenter(mNotificationPresenter);
@@ -562,7 +566,6 @@
mUserTracker,
() -> mFingerprintManager,
mActivityStarter,
- mSceneContainerFlags,
mBrightnessMirrorShowingInteractor
);
mScreenLifecycle.addObserver(mCentralSurfaces.mScreenObserver);
@@ -1094,25 +1097,24 @@
}
@Test
+ @EnableSceneContainer
public void brightnesShowingChanged_flagEnabled_ScrimControllerNotified() {
- mSceneContainerFlags.setEnabled(true);
mCentralSurfaces.registerCallbacks();
mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
mTestScope.getTestScheduler().runCurrent();
- verify(mScrimController).transitionTo(ScrimState.BRIGHTNESS_MIRROR);
+ verify(mScrimController, atLeastOnce()).transitionTo(ScrimState.BRIGHTNESS_MIRROR);
mBrightnessMirrorShowingInteractor.setMirrorShowing(false);
mTestScope.getTestScheduler().runCurrent();
ArgumentCaptor<ScrimState> captor = ArgumentCaptor.forClass(ScrimState.class);
// The default is to call the one with the callback argument
- verify(mScrimController).transitionTo(captor.capture(), any());
+ verify(mScrimController, atLeastOnce()).transitionTo(captor.capture(), any());
assertThat(captor.getValue()).isNotEqualTo(ScrimState.BRIGHTNESS_MIRROR);
}
@Test
public void brightnesShowingChanged_flagDisabled_ScrimControllerNotified() {
- mSceneContainerFlags.setEnabled(false);
mCentralSurfaces.registerCallbacks();
mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index dc3db4c..a6a4f24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -20,9 +20,9 @@
import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS;
import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
+import static com.android.systemui.Flags.FLAG_UPDATE_USER_SWITCHER_BACKGROUND;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
-import static com.android.systemui.Flags.FLAG_UPDATE_USER_SWITCHER_BACKGROUND;
import static com.google.common.truth.Truth.assertThat;
@@ -172,7 +172,6 @@
mKeyguardRepository,
mCommandQueue,
PowerInteractorFactory.create().getPowerInteractor(),
- mKosmos.getSceneContainerFlags(),
new FakeKeyguardBouncerRepository(),
new ConfigurationInteractor(new FakeConfigurationRepository()),
new FakeShadeRepository(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 1463680..d365663 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -33,7 +33,6 @@
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.ShadeControllerImpl
import com.android.systemui.shade.ShadeLogger
@@ -51,6 +50,8 @@
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.view.ViewUtil
import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import javax.inject.Provider
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentCaptor
@@ -61,8 +62,6 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
-import java.util.Optional
-import javax.inject.Provider
@SmallTest
class PhoneStatusBarViewControllerTest : SysuiTestCase() {
@@ -296,7 +295,6 @@
Optional.of(sysuiUnfoldComponent),
Optional.of(progressProvider),
featureFlags,
- FakeSceneContainerFlags(),
userChipViewModel,
centralSurfacesImpl,
statusBarWindowStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
index feff046..1ec1765 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
@@ -8,7 +8,7 @@
import android.view.WindowManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.unfold.util.CurrentActivityTypeProvider
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.util.mockito.whenever
@@ -23,17 +23,14 @@
@TestableLooper.RunWithLooper
class StatusBarMoveFromCenterAnimationControllerTest : SysuiTestCase() {
- @Mock
- private lateinit var windowManager: WindowManager
+ @Mock private lateinit var windowManager: WindowManager
- @Mock
- private lateinit var display: Display
+ @Mock private lateinit var display: Display
- @Mock
- private lateinit var currentActivityTypeProvider: CurrentActivityTypeProvider
+ @Mock private lateinit var currentActivityTypeProvider: CurrentActivityTypeProvider
private val view: View = View(context)
- private val progressProvider = TestUnfoldTransitionProvider()
+ private val progressProvider = FakeUnfoldTransitionProvider()
private val scopedProvider = ScopedUnfoldTransitionProgressProvider(progressProvider)
private lateinit var controller: StatusBarMoveFromCenterAnimationController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index 69536c5..bdd3d18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -30,7 +30,6 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository
@@ -60,7 +59,6 @@
keyguardRepository,
mock<CommandQueue>(),
PowerInteractorFactory.create().powerInteractor,
- kosmos.sceneContainerFlags,
FakeKeyguardBouncerRepository(),
ConfigurationInteractor(FakeConfigurationRepository()),
FakeShadeRepository(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
index 28adbce..383f4a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
@@ -86,7 +86,7 @@
private val areAnimationEnabled = MutableStateFlow(true)
private val lastWakefulnessEvent = MutableStateFlow(WakefulnessModel())
private val systemClock = FakeSystemClock()
- private val unfoldTransitionProgressProvider = TestUnfoldTransitionProvider()
+ private val unfoldTransitionProgressProvider = FakeUnfoldTransitionProvider()
private val unfoldTransitionRepository =
UnfoldTransitionRepositoryImpl(Optional.of(unfoldTransitionProgressProvider))
private val unfoldTransitionInteractor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
index b9c7e61..fd513c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
@@ -35,7 +35,7 @@
@SmallTest
class UnfoldHapticsPlayerTest : SysuiTestCase() {
- private val progressProvider = TestUnfoldTransitionProvider()
+ private val progressProvider = FakeUnfoldTransitionProvider()
private val vibrator: Vibrator = mock()
private val testFoldProvider = TestFoldProvider()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
index ba72716..2955384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
@@ -27,6 +27,7 @@
import com.android.systemui.unfold.util.FoldableDeviceStates
import com.android.systemui.unfold.util.FoldableTestUtils
import com.android.systemui.util.mockito.any
+import java.util.Optional
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -37,45 +38,41 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
-import java.util.Optional
@RunWith(AndroidTestingRunner::class)
@SmallTest
class UnfoldLatencyTrackerTest : SysuiTestCase() {
- @Mock
- lateinit var latencyTracker: LatencyTracker
+ @Mock lateinit var latencyTracker: LatencyTracker
- @Mock
- lateinit var deviceStateManager: DeviceStateManager
+ @Mock lateinit var deviceStateManager: DeviceStateManager
- @Mock
- lateinit var screenLifecycle: ScreenLifecycle
+ @Mock lateinit var screenLifecycle: ScreenLifecycle
- @Captor
- private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
+ @Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
- @Captor
- private lateinit var screenLifecycleCaptor: ArgumentCaptor<ScreenLifecycle.Observer>
+ @Captor private lateinit var screenLifecycleCaptor: ArgumentCaptor<ScreenLifecycle.Observer>
private lateinit var deviceStates: FoldableDeviceStates
private lateinit var unfoldLatencyTracker: UnfoldLatencyTracker
- private val transitionProgressProvider = TestUnfoldTransitionProvider()
+ private val transitionProgressProvider = FakeUnfoldTransitionProvider()
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- unfoldLatencyTracker = UnfoldLatencyTracker(
- latencyTracker,
- deviceStateManager,
- Optional.of(transitionProgressProvider),
- context.mainExecutor,
- context,
- context.contentResolver,
- screenLifecycle
- ).apply { init() }
+ unfoldLatencyTracker =
+ UnfoldLatencyTracker(
+ latencyTracker,
+ deviceStateManager,
+ Optional.of(transitionProgressProvider),
+ context.mainExecutor,
+ context,
+ context.contentResolver,
+ screenLifecycle
+ )
+ .apply { init() }
deviceStates = FoldableTestUtils.findDeviceStates(context)
verify(deviceStateManager).registerCallback(any(), foldStateListenerCaptor.capture())
@@ -107,7 +104,7 @@
}
@Test
- fun unfold_firstFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventNotPropagated() {
+ fun firstFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventNotPropagated() {
setAnimationsEnabled(true)
sendFoldEvent(folded = false)
@@ -118,7 +115,7 @@
}
@Test
- fun unfold_secondFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
+ fun secondFoldEventAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
setAnimationsEnabled(true)
sendFoldEvent(folded = true)
sendFoldEvent(folded = false)
@@ -131,7 +128,7 @@
}
@Test
- fun unfold_unfoldFoldUnfoldAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
+ fun unfoldFoldUnfoldAnimationsEnabledOnScreenTurnedOnAndTransitionStarted_eventPropagated() {
setAnimationsEnabled(true)
sendFoldEvent(folded = false)
sendFoldEvent(folded = true)
@@ -196,4 +193,4 @@
durationScale.toString()
)
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
index 6ec0251..0c452eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
@@ -17,21 +17,18 @@
@SmallTest
class UnfoldTransitionWallpaperControllerTest : SysuiTestCase() {
- @Mock
- private lateinit var wallpaperController: WallpaperController
+ @Mock private lateinit var wallpaperController: WallpaperController
- private val progressProvider = TestUnfoldTransitionProvider()
+ private val progressProvider = FakeUnfoldTransitionProvider()
- @JvmField
- @Rule
- val mockitoRule = MockitoJUnit.rule()
+ @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
private lateinit var unfoldWallpaperController: UnfoldTransitionWallpaperController
@Before
fun setup() {
- unfoldWallpaperController = UnfoldTransitionWallpaperController(progressProvider,
- wallpaperController)
+ unfoldWallpaperController =
+ UnfoldTransitionWallpaperController(progressProvider, wallpaperController)
unfoldWallpaperController.init()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
index 2bc05fc..e5f619b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
@@ -23,7 +23,7 @@
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.utils.os.FakeHandler
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
@@ -34,7 +34,7 @@
@RunWithLooper(setAsMainLooper = true)
class MainThreadUnfoldTransitionProgressProviderTest : SysuiTestCase() {
- private val wrappedProgressProvider = TestUnfoldTransitionProvider()
+ private val wrappedProgressProvider = FakeUnfoldTransitionProvider()
private val fakeHandler = FakeHandler(Looper.getMainLooper())
private val listener = TestUnfoldProgressListener()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
index d864d53..70ec050 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
@@ -20,7 +20,7 @@
import android.view.Surface
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.updates.RotationChangeProvider
import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListener
@@ -43,14 +43,14 @@
@Mock lateinit var rotationChangeProvider: RotationChangeProvider
- private val sourceProvider = TestUnfoldTransitionProvider()
+ private val sourceProvider = FakeUnfoldTransitionProvider()
@Mock lateinit var transitionListener: TransitionProgressListener
@Captor private lateinit var rotationListenerCaptor: ArgumentCaptor<RotationListener>
lateinit var progressProvider: NaturalRotationUnfoldProgressProvider
- private lateinit var testableLooper : TestableLooper
+ private lateinit var testableLooper: TestableLooper
@Before
fun setUp() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
index 2f29b3b..451bd24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
@@ -22,7 +22,7 @@
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.util.mockito.any
import org.junit.Before
@@ -42,7 +42,7 @@
@Mock lateinit var sinkProvider: TransitionProgressListener
- private val sourceProvider = TestUnfoldTransitionProvider()
+ private val sourceProvider = FakeUnfoldTransitionProvider()
private lateinit var contentResolver: ContentResolver
private lateinit var progressProvider: ScaleAwareTransitionProgressProvider
@@ -132,6 +132,6 @@
durationScale.toString()
)
- animatorDurationScaleListenerCaptor.value.dispatchChange(/* selfChange= */false)
+ animatorDurationScaleListenerCaptor.value.dispatchChange(/* selfChange= */ false)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt
index 95c934e..4486402 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt
@@ -23,7 +23,7 @@
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.unfold.progress.TestUnfoldProgressListener
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration.Companion.seconds
@@ -43,7 +43,7 @@
@RunWithLooper
class ScopedUnfoldTransitionProgressProviderTest : SysuiTestCase() {
- private val rootProvider = TestUnfoldTransitionProvider()
+ private val rootProvider = FakeUnfoldTransitionProvider()
private val listener = TestUnfoldProgressListener()
private val testScope = TestScope(UnconfinedTestDispatcher())
private val bgThread =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
index f484ea0..cd4d7b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
@@ -19,7 +19,7 @@
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.FakeUnfoldTransitionProvider
import com.android.systemui.unfold.progress.TestUnfoldProgressListener
import com.google.common.util.concurrent.MoreExecutors
import org.junit.Before
@@ -32,7 +32,7 @@
class UnfoldOnlyProgressProviderTest : SysuiTestCase() {
private val listener = TestUnfoldProgressListener()
- private val sourceProvider = TestUnfoldTransitionProvider()
+ private val sourceProvider = FakeUnfoldTransitionProvider()
private val foldProvider = TestFoldProvider()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index c24c86c..d9a0c4b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -121,8 +121,6 @@
import com.android.systemui.scene.FakeWindowRootViewComponent;
import com.android.systemui.scene.data.repository.SceneContainerRepository;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.scene.shared.logger.SceneLogger;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.settings.UserTracker;
@@ -360,8 +358,6 @@
@Mock
private Display mDefaultDisplay;
@Mock
- private SceneContainerFlags mSceneContainerFlags;
- @Mock
private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
@@ -430,14 +426,12 @@
mock(SceneLogger.class),
mKosmos.getDeviceUnlockedInteractor());
- FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags();
KeyguardTransitionInteractor keyguardTransitionInteractor =
mKosmos.getKeyguardTransitionInteractor();
KeyguardInteractor keyguardInteractor = new KeyguardInteractor(
keyguardRepository,
new FakeCommandQueue(),
powerInteractor,
- sceneContainerFlags,
new FakeKeyguardBouncerRepository(),
new ConfigurationInteractor(configurationRepository),
shadeRepository,
@@ -503,7 +497,6 @@
mShadeWindowLogger,
() -> mSelectedUserInteractor,
mUserTracker,
- mSceneContainerFlags,
mKosmos::getCommunalInteractor
);
mNotificationShadeWindowController.fetchWindowRootView();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
index de7b14d..0682361 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysUITestModule.kt
@@ -31,7 +31,7 @@
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
import com.android.systemui.deviceentry.domain.interactor.SystemUIDeviceEntryFaceAuthInteractor
import com.android.systemui.scene.SceneContainerFrameworkModule
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneDataSource
import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -104,11 +104,10 @@
@Provides
fun provideBaseShadeInteractor(
- sceneContainerFlags: SceneContainerFlags,
sceneContainerOn: Provider<ShadeInteractorSceneContainerImpl>,
sceneContainerOff: Provider<ShadeInteractorLegacyImpl>
): BaseShadeInteractor {
- return if (sceneContainerFlags.isEnabled()) {
+ return if (SceneContainerFlag.isEnabled) {
sceneContainerOn.get()
} else {
sceneContainerOff.get()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
index 5c3e1f4..60d97d1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
@@ -17,8 +17,6 @@
package com.android.systemui.bouncer.shared.flag
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-var Kosmos.fakeComposeBouncerFlags by
- Kosmos.Fixture { FakeComposeBouncerFlags(fakeSceneContainerFlags) }
+var Kosmos.fakeComposeBouncerFlags by Kosmos.Fixture { FakeComposeBouncerFlags() }
val Kosmos.composeBouncerFlags by Kosmos.Fixture<ComposeBouncerFlags> { fakeComposeBouncerFlags }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
index c116bbd..7482c0f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
@@ -16,14 +16,11 @@
package com.android.systemui.bouncer.shared.flag
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
-class FakeComposeBouncerFlags(
- private val sceneContainerFlags: SceneContainerFlags,
- var composeBouncerEnabled: Boolean = false
-) : ComposeBouncerFlags {
+class FakeComposeBouncerFlags(var composeBouncerEnabled: Boolean = false) : ComposeBouncerFlags {
override fun isComposeBouncerOrSceneContainerEnabled(): Boolean {
- return sceneContainerFlags.isEnabled() || composeBouncerEnabled
+ return SceneContainerFlag.isEnabled || composeBouncerEnabled
}
@Deprecated(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index 4b6ef37..3dd382f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -34,7 +34,6 @@
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.activityStarter
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.settings.userTracker
import com.android.systemui.smartspace.data.repository.smartspaceRepository
import com.android.systemui.user.data.repository.fakeUserRepository
@@ -46,21 +45,20 @@
broadcastDispatcher = broadcastDispatcher,
communalRepository = communalRepository,
widgetRepository = communalWidgetRepository,
- mediaRepository = communalMediaRepository,
communalPrefsRepository = communalPrefsRepository,
+ mediaRepository = communalMediaRepository,
smartspaceRepository = smartspaceRepository,
- appWidgetHost = mock(),
keyguardInteractor = keyguardInteractor,
+ communalSettingsInteractor = communalSettingsInteractor,
+ appWidgetHost = mock(),
editWidgetsActivityStarter = editWidgetsActivityStarter,
userTracker = userTracker,
activityStarter = activityStarter,
userManager = userManager,
dockManager = fakeDockManager,
+ sceneInteractor = sceneInteractor,
logBuffer = logcatLogBuffer("CommunalInteractor"),
tableLogBuffer = mock(),
- communalSettingsInteractor = communalSettingsInteractor,
- sceneInteractor = sceneInteractor,
- sceneContainerFlags = sceneContainerFlags,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
index e21c766..2e751cc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
@@ -24,12 +24,9 @@
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor.ConfigurationBasedDimensions
@@ -49,7 +46,6 @@
@JvmStatic
fun create(
featureFlags: FakeFeatureFlags = FakeFeatureFlags(),
- sceneContainerFlags: SceneContainerFlags = FakeSceneContainerFlags(),
repository: FakeKeyguardRepository = FakeKeyguardRepository(),
commandQueue: FakeCommandQueue = FakeCommandQueue(),
bouncerRepository: FakeKeyguardBouncerRepository = FakeKeyguardBouncerRepository(),
@@ -88,7 +84,6 @@
repository = repository,
commandQueue = commandQueue,
featureFlags = featureFlags,
- sceneContainerFlags = sceneContainerFlags,
bouncerRepository = bouncerRepository,
configurationRepository = configurationRepository,
shadeRepository = shadeRepository,
@@ -96,13 +91,12 @@
KeyguardInteractor(
repository = repository,
commandQueue = commandQueue,
- sceneContainerFlags = sceneContainerFlags,
+ powerInteractor = powerInteractor,
bouncerRepository = bouncerRepository,
configurationInteractor = ConfigurationInteractor(configurationRepository),
shadeRepository = shadeRepository,
- sceneInteractorProvider = { sceneInteractor },
keyguardTransitionInteractor = keyguardTransitionInteractor,
- powerInteractor = powerInteractor,
+ sceneInteractorProvider = { sceneInteractor },
fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
sharedNotificationContainerInteractor = { sncInteractor },
applicationScope = testScope,
@@ -114,7 +108,6 @@
val repository: FakeKeyguardRepository,
val commandQueue: FakeCommandQueue,
val featureFlags: FakeFeatureFlags,
- val sceneContainerFlags: SceneContainerFlags,
val bouncerRepository: FakeKeyguardBouncerRepository,
val configurationRepository: FakeConfigurationRepository,
val shadeRepository: FakeShadeRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
index 2a0c01c..9426718 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
@@ -23,7 +23,6 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.statusbar.commandQueue
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -34,7 +33,6 @@
repository = keyguardRepository,
commandQueue = commandQueue,
powerInteractor = powerInteractor,
- sceneContainerFlags = sceneContainerFlags,
bouncerRepository = keyguardBouncerRepository,
configurationInteractor = configurationInteractor,
shadeRepository = shadeRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
index 709f864..58b0ff8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelKosmos.kt
@@ -26,7 +26,6 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,7 +46,6 @@
transitionInteractor = keyguardTransitionInteractor,
keyguardInteractor = keyguardInteractor,
viewModel = aodToLockscreenTransitionViewModel,
- sceneContainerFlags = sceneContainerFlags,
keyguardViewController = { statusBarKeyguardViewManager },
deviceEntryInteractor = deviceEntryInteractor,
deviceEntrySourceInteractor = deviceEntrySourceInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index fdc3e0a..162f278 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -48,10 +48,9 @@
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.sceneContainerConfig
-import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.scene.shared.model.sceneDataSource
import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
+import com.android.systemui.shade.shadeController
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.statusbar.phone.screenOffAnimationController
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
@@ -71,8 +70,6 @@
val testDispatcher by lazy { kosmos.testDispatcher }
val testScope by lazy { kosmos.testScope }
val fakeFeatureFlags by lazy { kosmos.fakeFeatureFlagsClassic }
- val fakeSceneContainerFlags by lazy { kosmos.fakeSceneContainerFlags }
- val sceneContainerFlags by lazy { kosmos.sceneContainerFlags }
val fakeExecutor by lazy { kosmos.fakeExecutor }
val fakeExecutorHandler by lazy { kosmos.fakeExecutorHandler }
val configurationRepository by lazy { kosmos.fakeConfigurationRepository }
@@ -112,6 +109,7 @@
}
val brightnessMirrorShowingInteractor by lazy { kosmos.brightnessMirrorShowingInteractor }
val qsLongPressEffect by lazy { kosmos.qsLongPressEffect }
+ val shadeController by lazy { kosmos.shadeController }
init {
kosmos.applicationContext = testCase.context
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
index da2170c..2f3d3c3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
@@ -17,6 +17,7 @@
package com.android.systemui.media.controls.ui.viewmodel
import android.content.applicationContext
+import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaControlInteractor
@@ -27,6 +28,7 @@
MediaControlViewModel(
applicationContext = applicationContext,
backgroundDispatcher = testDispatcher,
+ backgroundExecutor = fakeExecutor,
interactor = mediaControlInteractor,
logger = mediaUiEventLogger,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt
index 6f652f2..e88d22a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaFlagsKosmos.kt
@@ -18,9 +18,5 @@
import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
-val Kosmos.mediaFlags by
- Kosmos.Fixture {
- MediaFlags(featureFlags = featureFlagsClassic, sceneContainerFlags = sceneContainerFlags)
- }
+val Kosmos.mediaFlags by Kosmos.Fixture { MediaFlags(featureFlags = featureFlagsClassic) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/FakeSceneContainerFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/FakeSceneContainerFlags.kt
deleted file mode 100644
index ded7256..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/FakeSceneContainerFlags.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2023 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.scene.shared.flag
-
-import dagger.Binds
-import dagger.Module
-import dagger.Provides
-
-class FakeSceneContainerFlags(
- var enabled: Boolean = SceneContainerFlag.isEnabled,
-) : SceneContainerFlags {
-
- override fun isEnabled(): Boolean {
- return enabled
- }
-
- override fun requirementDescription(): String {
- return ""
- }
-}
-
-@Module(includes = [FakeSceneContainerFlagsModule.Bindings::class])
-class FakeSceneContainerFlagsModule(
- @get:Provides val sceneContainerFlags: FakeSceneContainerFlags = FakeSceneContainerFlags(),
-) {
- @Module
- interface Bindings {
- @Binds fun bindFake(fake: FakeSceneContainerFlags): SceneContainerFlags
- }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsKosmos.kt
deleted file mode 100644
index 979d8e7..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsKosmos.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2023 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.scene.shared.flag
-
-import com.android.systemui.kosmos.Kosmos
-
-var Kosmos.fakeSceneContainerFlags by Kosmos.Fixture { FakeSceneContainerFlags() }
-val Kosmos.sceneContainerFlags by Kosmos.Fixture<SceneContainerFlags> { fakeSceneContainerFlags }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
index 07e2d6b..543d5b6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
@@ -23,7 +23,6 @@
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.shade.ShadeModule
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.statusbar.disableflags.data.repository.disableFlagsRepository
@@ -36,7 +35,6 @@
var Kosmos.baseShadeInteractor: BaseShadeInteractor by
Kosmos.Fixture {
ShadeModule.provideBaseShadeInteractor(
- sceneContainerFlags = sceneContainerFlags,
sceneContainerOn = { shadeInteractorSceneContainerImpl },
sceneContainerOff = { shadeInteractorLegacyImpl },
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
index b249211..f0eea38 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
@@ -21,7 +21,6 @@
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
@@ -30,7 +29,6 @@
dumpManager = dumpManager,
interactor = notificationStackAppearanceInteractor,
shadeInteractor = shadeInteractor,
- flags = sceneContainerFlags,
featureFlags = featureFlagsClassic,
keyguardInteractor = keyguardInteractor,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
index cf800d0..9c3f510 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
@@ -24,7 +24,6 @@
import com.android.systemui.scene.data.repository.windowRootViewVisibilityRepository
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.policy.headsUpManager
@@ -36,7 +35,7 @@
headsUpManager = headsUpManager,
powerInteractor = powerInteractor,
activeNotificationsInteractor = activeNotificationsInteractor,
- sceneInteractorProvider = { sceneInteractor },
- sceneContainerFlags = sceneContainerFlags,
- )
+ ) {
+ sceneInteractor
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/FakeUnfoldTransitionProvider.kt
similarity index 93%
rename from packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/unfold/FakeUnfoldTransitionProvider.kt
index 56c6245..94f0c44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/FakeUnfoldTransitionProvider.kt
@@ -2,7 +2,7 @@
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-class TestUnfoldTransitionProvider : UnfoldTransitionProgressProvider, TransitionProgressListener {
+class FakeUnfoldTransitionProvider : UnfoldTransitionProgressProvider, TransitionProgressListener {
private val listeners = mutableListOf<TransitionProgressListener>()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/UnfoldTransitionProgressProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/UnfoldTransitionProgressProviderKosmos.kt
index 7c54a57..a0f5b58 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/UnfoldTransitionProgressProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/UnfoldTransitionProgressProviderKosmos.kt
@@ -18,6 +18,8 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
-var Kosmos.unfoldTransitionProgressProvider by Fixture { mock<UnfoldTransitionProgressProvider>() }
+val Kosmos.fakeUnfoldTransitionProgressProvider by Fixture { FakeUnfoldTransitionProvider() }
+
+val Kosmos.unfoldTransitionProgressProvider by
+ Fixture<UnfoldTransitionProgressProvider> { fakeUnfoldTransitionProgressProvider }
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 23e269a..cbbce1a 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -19,6 +19,7 @@
import static android.app.WallpaperManager.FLAG_LOCK;
import static android.app.WallpaperManager.FLAG_SYSTEM;
import static android.app.WallpaperManager.ORIENTATION_UNKNOWN;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE;
import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA;
@@ -39,6 +40,7 @@
import android.content.SharedPreferences;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
+import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
@@ -109,22 +111,16 @@
static final String LOCK_WALLPAPER_STAGE = "wallpaper-lock-stage";
@VisibleForTesting
static final String WALLPAPER_INFO_STAGE = "wallpaper-info-stage";
-
@VisibleForTesting
static final String WALLPAPER_BACKUP_DEVICE_INFO_STAGE = "wallpaper-backup-device-info-stage";
-
static final String EMPTY_SENTINEL = "empty";
static final String QUOTA_SENTINEL = "quota";
-
// Shared preferences constants.
static final String PREFS_NAME = "wbprefs.xml";
static final String SYSTEM_GENERATION = "system_gen";
static final String LOCK_GENERATION = "lock_gen";
- /**
- * An approximate area threshold to compare device dimension similarity
- */
- static final int AREA_THRESHOLD = 50; // TODO (b/327637867): determine appropriate threshold
+ static final float DEFAULT_ACCEPTABLE_PARALLAX = 0.2f;
// If this file exists, it means we exceeded our quota last time
private File mQuotaFile;
@@ -336,7 +332,6 @@
mEventLogger.onSystemImageWallpaperBackupFailed(error);
}
-
private void backupLockWallpaperFileIfItExists(SharedPreferences sharedPrefs,
boolean lockChanged, int lockGeneration, FullBackupDataOutput data) throws IOException {
final File lockImageStage = new File(getFilesDir(), LOCK_WALLPAPER_STAGE);
@@ -409,6 +404,16 @@
}
}
+ private static String readText(TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ String result = "";
+ if (parser.next() == XmlPullParser.TEXT) {
+ result = parser.getText();
+ parser.nextTag();
+ }
+ return result;
+ }
+
@VisibleForTesting
// fullBackupFile is final, so we intercept backups here in tests.
protected void backupFile(File file, FullBackupDataOutput data) {
@@ -438,18 +443,10 @@
boolean lockImageStageExists = lockImageStage.exists();
try {
- // Parse the device dimensions of the source device and compare with target to
- // to identify whether we need to skip the remainder of the restore process
+ // Parse the device dimensions of the source device
Pair<Point, Point> sourceDeviceDimensions = parseDeviceDimensions(
deviceDimensionsStage);
- Point targetDeviceDimensions = getScreenDimensions();
- if (sourceDeviceDimensions != null && targetDeviceDimensions != null
- && isSourceDeviceSignificantlySmallerThanTarget(sourceDeviceDimensions.first,
- targetDeviceDimensions)) {
- Slog.d(TAG, "The source device is significantly smaller than target");
- }
-
// First parse the live component name so that we know for logging if we care about
// logging errors with the image restore.
ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
@@ -466,9 +463,10 @@
// to back up the original image on the source device, or there was no user-supplied
// wallpaper image present.
if (lockImageStageExists) {
- restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK);
+ restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK,
+ sourceDeviceDimensions);
}
- restoreFromStage(imageStage, infoStage, "wp", sysWhich);
+ restoreFromStage(imageStage, infoStage, "wp", sysWhich, sourceDeviceDimensions);
// And reset to the wallpaper service we should be using
if (mLockHasLiveComponent) {
@@ -543,16 +541,6 @@
}
}
- private static String readText(TypedXmlPullParser parser)
- throws IOException, XmlPullParserException {
- String result = "";
- if (parser.next() == XmlPullParser.TEXT) {
- result = parser.getText();
- parser.nextTag();
- }
- return result;
- }
-
@VisibleForTesting
void updateWallpaperComponent(ComponentName wpService, int which)
throws IOException {
@@ -578,10 +566,13 @@
}
}
- private void restoreFromStage(File stage, File info, String hintTag, int which)
+ private void restoreFromStage(File stage, File info, String hintTag, int which,
+ Pair<Point, Point> sourceDeviceDimensions)
throws IOException {
if (stage.exists()) {
if (multiCrop()) {
+ // TODO(b/332937943): implement offset adjustment by manually adjusting crop to
+ // adhere to device aspect ratio
SparseArray<Rect> cropHints = parseCropHints(info, hintTag);
if (cropHints != null) {
Slog.i(TAG, "Got restored wallpaper; applying which=" + which
@@ -601,7 +592,6 @@
}
return;
}
-
// Parse the restored info file to find the crop hint. Note that this currently
// relies on a priori knowledge of the wallpaper info file schema.
Rect cropHint = parseCropHint(info, hintTag);
@@ -609,8 +599,33 @@
Slog.i(TAG, "Got restored wallpaper; applying which=" + which
+ "; cropHint = " + cropHint);
try (FileInputStream in = new FileInputStream(stage)) {
- mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint, true,
- which);
+
+ if (sourceDeviceDimensions != null && sourceDeviceDimensions.first != null) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ ParcelFileDescriptor pdf = ParcelFileDescriptor.open(stage, MODE_READ_ONLY);
+ BitmapFactory.decodeFileDescriptor(pdf.getFileDescriptor(),
+ null, options);
+ Point bitmapSize = new Point(options.outWidth, options.outHeight);
+ Point sourceDeviceSize = new Point(sourceDeviceDimensions.first.x,
+ sourceDeviceDimensions.first.y);
+ Point targetDeviceDimensions = getScreenDimensions();
+
+ // TODO: for now we handle only the case where the target device has smaller
+ // aspect ratio than the source device i.e. the target device is more narrow
+ // than the source device
+ if (isTargetMoreNarrowThanSource(targetDeviceDimensions,
+ sourceDeviceSize)) {
+ Rect adjustedCrop = findNewCropfromOldCrop(cropHint,
+ sourceDeviceDimensions.first, true, targetDeviceDimensions,
+ bitmapSize, true);
+
+ cropHint.set(adjustedCrop);
+ }
+ }
+
+ mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint,
+ true, which);
// And log the success
if ((which & FLAG_SYSTEM) > 0) {
@@ -629,6 +644,209 @@
}
}
+ /**
+ * This method computes the crop of the stored wallpaper to preserve its center point as the
+ * user had set it in the previous device.
+ *
+ * The algorithm involves first computing the original crop of the user (without parallax). Then
+ * manually adjusting the user's original crop to respect the current device's aspect ratio
+ * (thereby preserving the center point). Then finally, adding any leftover image real-estate
+ * (i.e. space left over on the horizontal axis) to add parallax effect. Parallax is only added
+ * if was present in the old device's settings.
+ *
+ */
+ private Rect findNewCropfromOldCrop(Rect oldCrop, Point oldDisplaySize, boolean oldRtl,
+ Point newDisplaySize, Point bitmapSize, boolean newRtl) {
+ Rect cropWithoutParallax = withoutParallax(oldCrop, oldDisplaySize, oldRtl, bitmapSize);
+ oldCrop = oldCrop.isEmpty() ? new Rect(0, 0, bitmapSize.x, bitmapSize.y) : oldCrop;
+ float oldParallaxAmount = ((float) oldCrop.width() / cropWithoutParallax.width()) - 1;
+
+ Rect newCropWithSameCenterWithoutParallax = sameCenter(newDisplaySize, bitmapSize,
+ cropWithoutParallax);
+
+ Rect newCrop = newCropWithSameCenterWithoutParallax;
+
+ // calculate the amount of left-over space there is in the image after adjusting the crop
+ // from the above operation i.e. in a rtl configuration, this is the remaining space in the
+ // image after subtracting the new crop's right edge coordinate from the image itself, and
+ // for ltr, its just the new crop's left edge coordinate (as it's the distance from the
+ // beginning of the image)
+ int widthAvailableForParallaxOnTheNewDevice =
+ (newRtl) ? newCrop.left : bitmapSize.x - newCrop.right;
+
+ // calculate relatively how much this available space is as a fraction of the total cropped
+ // image
+ float availableParallaxAmount =
+ (float) widthAvailableForParallaxOnTheNewDevice / newCrop.width();
+
+ float minAcceptableParallax = Math.min(DEFAULT_ACCEPTABLE_PARALLAX, oldParallaxAmount);
+
+ if (DEBUG) {
+ Slog.d(TAG, "- cropWithoutParallax: " + cropWithoutParallax);
+ Slog.d(TAG, "- oldParallaxAmount: " + oldParallaxAmount);
+ Slog.d(TAG, "- newCropWithSameCenterWithoutParallax: "
+ + newCropWithSameCenterWithoutParallax);
+ Slog.d(TAG, "- widthAvailableForParallaxOnTheNewDevice: "
+ + widthAvailableForParallaxOnTheNewDevice);
+ Slog.d(TAG, "- availableParallaxAmount: " + availableParallaxAmount);
+ Slog.d(TAG, "- minAcceptableParallax: " + minAcceptableParallax);
+ Slog.d(TAG, "- oldCrop: " + oldCrop);
+ Slog.d(TAG, "- oldDisplaySize: " + oldDisplaySize);
+ Slog.d(TAG, "- oldRtl: " + oldRtl);
+ Slog.d(TAG, "- newDisplaySize: " + newDisplaySize);
+ Slog.d(TAG, "- bitmapSize: " + bitmapSize);
+ Slog.d(TAG, "- newRtl: " + newRtl);
+ }
+ if (availableParallaxAmount >= minAcceptableParallax) {
+ // but in any case, don't put more parallax than the amount of the old device
+ float parallaxToAdd = Math.min(availableParallaxAmount, oldParallaxAmount);
+
+ int widthToAddForParallax = (int) (newCrop.width() * parallaxToAdd);
+ if (DEBUG) {
+ Slog.d(TAG, "- parallaxToAdd: " + parallaxToAdd);
+ Slog.d(TAG, "- widthToAddForParallax: " + widthToAddForParallax);
+ }
+ if (newRtl) {
+ newCrop.left -= widthToAddForParallax;
+ } else {
+ newCrop.right += widthToAddForParallax;
+ }
+ }
+ return newCrop;
+ }
+
+ /**
+ * This method computes the original crop of the user without parallax.
+ *
+ * NOTE: When the user sets the wallpaper with a specific crop, there may additional image added
+ * to the crop to support parallax. In order to determine the user's actual crop the parallax
+ * must be removed if it exists.
+ */
+ Rect withoutParallax(Rect crop, Point displaySize, boolean rtl, Point bitmapSize) {
+ // in the case an image's crop is not set, we assume the image itself is cropped
+ if (crop.isEmpty()) {
+ crop = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
+ }
+
+ if (DEBUG) {
+ Slog.w(TAG, "- crop: " + crop);
+ }
+
+ Rect adjustedCrop = new Rect(crop);
+ float suggestedDisplayRatio = (float) displaySize.x / displaySize.y;
+
+ // here we calculate the width of the wallpaper image such that it has the same aspect ratio
+ // as the given display i.e. the width of the image on a single page of the device without
+ // parallax (i.e. displaySize will correspond to the display the crop was originally set on)
+ int wallpaperWidthWithoutParallax = (int) (0.5f + (float) displaySize.x * crop.height()
+ / displaySize.y);
+ // subtracting wallpaperWidthWithoutParallax from the wallpaper crop gives the amount of
+ // parallax added
+ int widthToRemove = Math.max(0, crop.width() - wallpaperWidthWithoutParallax);
+
+ if (DEBUG) {
+ Slog.d(TAG, "- adjustedCrop: " + adjustedCrop);
+ Slog.d(TAG, "- suggestedDisplayRatio: " + suggestedDisplayRatio);
+ Slog.d(TAG, "- wallpaperWidthWithoutParallax: " + wallpaperWidthWithoutParallax);
+ Slog.d(TAG, "- widthToRemove: " + widthToRemove);
+ }
+ if (rtl) {
+ adjustedCrop.left += widthToRemove;
+ } else {
+ adjustedCrop.right -= widthToRemove;
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG, "- adjustedCrop: " + crop);
+ }
+ return adjustedCrop;
+ }
+
+ /**
+ * This method computes a new crop based on the given crop in order to preserve the center point
+ * of the given crop on the provided displaySize. This is only for the case where the device
+ * displaySize has a smaller aspect ratio than the cropped image.
+ *
+ * NOTE: If the width to height ratio is less in the device display than cropped image
+ * this means the aspect ratios are off and there will be distortions in the image
+ * if the image is applied to the current display (i.e. the image will be skewed ->
+ * pixels in the image will not align correctly with the same pixels in the image that are
+ * above them)
+ */
+ Rect sameCenter(Point displaySize, Point bitmapSize, Rect crop) {
+
+ // in the case an image's crop is not set, we assume the image itself is cropped
+ if (crop.isEmpty()) {
+ crop = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
+ }
+
+ float screenRatio = (float) displaySize.x / displaySize.y;
+ float cropRatio = (float) crop.width() / crop.height();
+
+ Rect adjustedCrop = new Rect(crop);
+
+ if (screenRatio < cropRatio) {
+ // the screen is more narrow than the image, and as such, the image will need to be
+ // zoomed in till it fits in the vertical axis. Due to this, we need to manually adjust
+ // the image's crop in order for it to fit into the screen without having the framework
+ // do it (since the framework left aligns the image after zooming)
+
+ // Calculate the height of the adjusted wallpaper crop so it respects the aspect ratio
+ // of the device. To calculate the height, we will use the width of the current crop.
+ // This is so we find the largest height possible which also respects the device aspect
+ // ratio.
+ int heightToAdd = (int) (0.5f + crop.width() / screenRatio - crop.height());
+
+ // Calculate how much extra image space available that can be used to adjust
+ // the crop. If this amount is less than heightToAdd, from above, then that means we
+ // can't use heightToAdd. Instead we will need to use the maximum possible height, which
+ // is the height of the original bitmap. NOTE: the bitmap height may be different than
+ // the crop.
+ // since there is no guarantee to have height available on both sides
+ // (e.g. the available height might be fully at the bottom), grab the minimum
+ int availableHeight = 2 * Math.min(crop.top, bitmapSize.y - crop.bottom);
+ int actualHeightToAdd = Math.min(heightToAdd, availableHeight);
+
+ // half of the additional height is added to the top and bottom of the crop
+ adjustedCrop.top -= actualHeightToAdd / 2 + actualHeightToAdd % 2;
+ adjustedCrop.bottom += actualHeightToAdd / 2;
+
+ // Calculate the width of the adjusted crop. Initially we used the fixed width of the
+ // crop to calculate the heightToAdd, but since this height may be invalid (based on
+ // the calculation above) we calculate the width again instead of using the fixed width,
+ // using the adjustedCrop's updated height.
+ int widthToRemove = (int) (0.5f + crop.width() - adjustedCrop.height() * screenRatio);
+
+ // half of the additional width is subtracted from the left and right side of the crop
+ int widthToRemoveLeft = widthToRemove / 2;
+ int widthToRemoveRight = widthToRemove / 2 + widthToRemove % 2;
+
+ adjustedCrop.left += widthToRemoveLeft;
+ adjustedCrop.right -= widthToRemoveRight;
+
+ if (DEBUG) {
+ Slog.d(TAG, "cropRatio: " + cropRatio);
+ Slog.d(TAG, "screenRatio: " + screenRatio);
+ Slog.d(TAG, "heightToAdd: " + heightToAdd);
+ Slog.d(TAG, "actualHeightToAdd: " + actualHeightToAdd);
+ Slog.d(TAG, "availableHeight: " + availableHeight);
+ Slog.d(TAG, "widthToRemove: " + widthToRemove);
+ Slog.d(TAG, "adjustedCrop: " + adjustedCrop);
+ }
+
+ return adjustedCrop;
+ }
+
+ return adjustedCrop;
+ }
+
+ private boolean isTargetMoreNarrowThanSource(Point targetDisplaySize, Point srcDisplaySize) {
+ float targetScreenRatio = (float) targetDisplaySize.x / targetDisplaySize.y;
+ float srcScreenRatio = (float) srcDisplaySize.x / srcDisplaySize.y;
+
+ return (targetScreenRatio < srcScreenRatio);
+ }
+
private void logRestoreErrorIfNoLiveComponent(int which, String error) {
if (mSystemHasLiveComponent) {
return;
@@ -644,6 +862,7 @@
mEventLogger.onLockImageWallpaperRestoreFailed(error);
}
}
+
private Rect parseCropHint(File wallpaperInfo, String sectionTag) {
Rect cropHint = new Rect();
try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
@@ -681,7 +900,7 @@
if (type != XmlPullParser.START_TAG) continue;
String tag = parser.getName();
if (!sectionTag.equals(tag)) continue;
- for (Pair<Integer, String> pair: List.of(
+ for (Pair<Integer, String> pair : List.of(
new Pair<>(WallpaperManager.PORTRAIT, "Portrait"),
new Pair<>(WallpaperManager.LANDSCAPE, "Landscape"),
new Pair<>(WallpaperManager.SQUARE_PORTRAIT, "SquarePortrait"),
@@ -907,22 +1126,6 @@
return internalDisplays;
}
- /**
- * This method compares the source and target dimensions, and returns true if there is a
- * significant difference in area between them and the source dimensions are smaller than the
- * target dimensions.
- *
- * @param sourceDimensions is the dimensions of the source device
- * @param targetDimensions is the dimensions of the target device
- */
- @VisibleForTesting
- boolean isSourceDeviceSignificantlySmallerThanTarget(Point sourceDimensions,
- Point targetDimensions) {
- int rawAreaDelta = (targetDimensions.x * targetDimensions.y)
- - (sourceDimensions.x * sourceDimensions.y);
- return rawAreaDelta > AREA_THRESHOLD;
- }
-
@VisibleForTesting
boolean isDeviceInRestore() {
try {
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index ec9223c..3ecdf3f 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -59,7 +59,6 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.graphics.Point;
import android.graphics.Rect;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
@@ -841,26 +840,6 @@
testParseCropHints(testMap);
}
- @Test
- public void test_sourceDimensionsAreLargerThanTarget() {
- // source device is larger than target, expecting to get false
- Point sourceDimensions = new Point(2208, 1840);
- Point targetDimensions = new Point(1080, 2092);
- boolean isSourceSmaller = mWallpaperBackupAgent
- .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
- assertThat(isSourceSmaller).isEqualTo(false);
- }
-
- @Test
- public void test_sourceDimensionsMuchSmallerThanTarget() {
- // source device is smaller than target, expecting to get true
- Point sourceDimensions = new Point(1080, 2092);
- Point targetDimensions = new Point(2208, 1840);
- boolean isSourceSmaller = mWallpaperBackupAgent
- .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
- assertThat(isSourceSmaller).isEqualTo(true);
- }
-
private void testParseCropHints(Map<Integer, Rect> testMap) throws Exception {
assumeTrue(multiCrop());
mockRestoredStaticWallpaperFile(testMap);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 3f3ff4a..3a38406 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -5188,11 +5188,13 @@
String[] exception = resultData.getStringArray(
CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION);
if (exception != null && exception.length >= 2) {
+ String errType = exception[0];
+ String errMsg = exception[1];
Slog.w(TAG, "Credman bottom sheet from pinned "
- + "entry failed with: + " + exception[0] + " , "
- + exception[1]);
+ + "entry failed with: + " + errType + " , "
+ + errMsg);
sendCredentialManagerResponseToApp(/*response=*/ null,
- new GetCredentialException(exception[0], exception[1]),
+ new GetCredentialException(errType, errMsg),
mAutofillId);
}
} else {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6b33199..96f525a 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1135,8 +1135,7 @@
if (!isCurrentUser) {
return;
}
- mSettings = queryInputMethodServicesInternal(mContext, userId,
- newAdditionalSubtypeMap, DirectBootAwareness.AUTO);
+ mSettings = newSettings;
postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
boolean changed = false;
@@ -1540,9 +1539,7 @@
// and user switch would not happen at that time.
resetCurrentMethodAndClientLocked(UnbindReason.SWITCH_USER);
- final InputMethodSettings newSettings = queryInputMethodServicesInternal(mContext,
- newUserId, AdditionalSubtypeMapRepository.get(newUserId), DirectBootAwareness.AUTO);
- InputMethodSettingsRepository.put(newUserId, newSettings);
+ final InputMethodSettings newSettings = InputMethodSettingsRepository.get(newUserId);
mSettings = newSettings;
postInputMethodSettingUpdatedLocked(initialUserSwitch /* resetDefaultEnabledIme */);
if (TextUtils.isEmpty(mSettings.getSelectedInputMethod())) {
diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
index bd73cb6..1938642 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
@@ -23,9 +23,15 @@
import android.app.Notification;
import android.app.NotificationChannel;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.LoggingOnly;
import android.content.Context;
import android.media.AudioAttributes;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Slog;
+import com.android.internal.compat.IPlatformCompat;
/**
* Stores the latest notification channel information for this notification
@@ -34,14 +40,26 @@
private static final String TAG = "ChannelExtractor";
private static final boolean DBG = false;
+ /**
+ * Corrects audio attributes for notifications based on characteristics of the notifications.
+ */
+ @ChangeId
+ @LoggingOnly
+ static final long RESTRICT_AUDIO_ATTRIBUTES = 331793339L;
+
private RankingConfig mConfig;
private Context mContext;
+ private IPlatformCompat mPlatformCompat;
public void initialize(Context ctx, NotificationUsageStats usageStats) {
mContext = ctx;
if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
}
+ public void setCompatChangeLogger(IPlatformCompat platformCompat) {
+ mPlatformCompat = platformCompat;
+ }
+
public RankingReconsideration process(NotificationRecord record) {
if (record == null || record.getNotification() == null) {
if (DBG) Slog.d(TAG, "skipping empty notification");
@@ -80,6 +98,7 @@
}
if (updateAttributes) {
+ reportAudioAttributesChanged(record.getUid());
NotificationChannel clone = record.getChannel().copy();
clone.setSound(clone.getSound(), new AudioAttributes.Builder(attributes)
.setUsage(USAGE_NOTIFICATION)
@@ -91,6 +110,17 @@
return null;
}
+ private void reportAudioAttributesChanged(int uid) {
+ final long id = Binder.clearCallingIdentity();
+ try {
+ mPlatformCompat.reportChangeByUid(RESTRICT_AUDIO_ATTRIBUTES, uid);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unexpected exception while reporting to changecompat", e);
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ }
+
@Override
public void setConfig(RankingConfig config) {
mConfig = config;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8075ae0..6f27f6b 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2508,12 +2508,8 @@
mAppOps,
mUserProfiles,
mShowReviewPermissionsNotification);
- mRankingHelper = new RankingHelper(getContext(),
- mRankingHandler,
- mPreferencesHelper,
- mZenModeHelper,
- mUsageStats,
- extractorNames);
+ mRankingHelper = new RankingHelper(getContext(), mRankingHandler, mPreferencesHelper,
+ mZenModeHelper, mUsageStats, extractorNames, mPlatformCompat);
mSnoozeHelper = snoozeHelper;
mGroupHelper = groupHelper;
mHistoryManager = historyManager;
diff --git a/services/core/java/com/android/server/notification/NotificationSignalExtractor.java b/services/core/java/com/android/server/notification/NotificationSignalExtractor.java
index 24c1d59..f0358d1 100644
--- a/services/core/java/com/android/server/notification/NotificationSignalExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationSignalExtractor.java
@@ -17,6 +17,7 @@
package com.android.server.notification;
import android.content.Context;
+import com.android.internal.compat.IPlatformCompat;
/**
* Extracts signals that will be useful to the {@link NotificationComparator} and caches them
@@ -52,4 +53,6 @@
* DND.
*/
void setZenHelper(ZenModeHelper helper);
+
+ default void setCompatChangeLogger(IPlatformCompat platformCompat){};
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 50ca984..461bd9c 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1387,8 +1387,7 @@
public void updateFixedImportance(List<UserInfo> users) {
for (UserInfo user : users) {
List<PackageInfo> packages = mPm.getInstalledPackagesAsUser(
- PackageManager.PackageInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY),
- user.getUserHandle().getIdentifier());
+ 0, user.getUserHandle().getIdentifier());
for (PackageInfo pi : packages) {
boolean fixed = mPermissionHelper.isPermissionFixed(
pi.packageName, user.getUserHandle().getIdentifier());
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 68e0eaa..7756801 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -15,6 +15,9 @@
*/
package com.android.server.notification;
+import static android.app.Flags.restrictAudioAttributesAlarm;
+import static android.app.Flags.restrictAudioAttributesCall;
+import static android.app.Flags.restrictAudioAttributesMedia;
import static android.app.Flags.sortSectionByTime;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.text.TextUtils.formatSimple;
@@ -27,6 +30,7 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.compat.IPlatformCompat;
import com.android.tools.r8.keepanno.annotations.KeepItemKind;
import com.android.tools.r8.keepanno.annotations.KeepTarget;
import com.android.tools.r8.keepanno.annotations.UsesReflection;
@@ -56,7 +60,8 @@
methodName = "<init>")
})
public RankingHelper(Context context, RankingHandler rankingHandler, RankingConfig config,
- ZenModeHelper zenHelper, NotificationUsageStats usageStats, String[] extractorNames) {
+ ZenModeHelper zenHelper, NotificationUsageStats usageStats, String[] extractorNames,
+ IPlatformCompat platformCompat) {
mContext = context;
mRankingHandler = rankingHandler;
if (sortSectionByTime()) {
@@ -75,6 +80,10 @@
extractor.initialize(mContext, usageStats);
extractor.setConfig(config);
extractor.setZenHelper(zenHelper);
+ if (restrictAudioAttributesAlarm() || restrictAudioAttributesMedia()
+ || restrictAudioAttributesCall()) {
+ extractor.setCompatChangeLogger(platformCompat);
+ }
mSignalExtractors[i] = extractor;
} catch (ClassNotFoundException e) {
Slog.w(TAG, "Couldn't find extractor " + extractorNames[i] + ".", e);
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index d060c7c..54cb9c9 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -4885,7 +4885,6 @@
if (type == WAKE_TYPE_PARTIAL) {
// Only care about partial wake locks, since full wake locks
// will be canceled when the user puts the screen to sleep.
- aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
if (historyName == null) {
historyName = name;
}
@@ -5205,20 +5204,14 @@
}
@GuardedBy("this")
- void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) {
+ public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
if (mLastWakeupReason != null) {
long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs;
SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds
mFrameworkStatsLogger.kernelWakeupReported(deltaUptimeMs * 1000, mLastWakeupReason,
mLastWakeupElapsedTimeMs);
- mLastWakeupReason = null;
}
- }
-
- @GuardedBy("this")
- public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) {
- aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs);
mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason);
mLastWakeupReason = reason;
mLastWakeupUptimeMs = uptimeMs;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ed88b5a..143605a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2446,6 +2446,9 @@
ProtoLog.i(WM_DEBUG_SCREEN_ON,
"Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
viewVisibility, new RuntimeException().fillInStackTrace());
+ if (becameVisible) {
+ onWindowVisible(win);
+ }
win.setDisplayLayoutNeeded();
win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
@@ -10168,7 +10171,7 @@
* Called to notify WMS that the specified window has become visible. This shows a Toast if the
* window is deemed to hold sensitive content.
*/
- void onWindowVisible(@NonNull WindowState w) {
+ private void onWindowVisible(@NonNull WindowState w) {
showToastIfBlockingScreenCapture(w);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d3baedc..2fcee50 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -28,7 +28,6 @@
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.permission.flags.Flags.sensitiveContentImprovements;
import static android.view.SurfaceControl.Transaction;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
@@ -2139,9 +2138,6 @@
}
}
setDisplayLayoutNeeded();
- if (sensitiveContentImprovements() && visible) {
- mWmService.onWindowVisible(this);
- }
}
}
diff --git a/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java b/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java
index dedb687..b1673e2 100644
--- a/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetCandidateRequestSession.java
@@ -26,6 +26,7 @@
import android.credentials.CredentialProviderInfo;
import android.credentials.GetCandidateCredentialsException;
import android.credentials.GetCandidateCredentialsResponse;
+import android.credentials.GetCredentialException;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialResponse;
import android.credentials.IGetCandidateCredentialsCallback;
@@ -159,24 +160,26 @@
public void onFinalErrorReceived(ComponentName componentName, String errorType,
String message) {
Slog.d(TAG, "onFinalErrorReceived");
+ if (GetCredentialException.TYPE_USER_CANCELED.equals(errorType)) {
+ Slog.d(TAG, "User canceled but session is not being terminated");
+ return;
+ }
respondToFinalReceiverWithFailureAndFinish(errorType, message);
}
@Override
public void onUiCancellation(boolean isUserCancellation) {
- String exception = GetCandidateCredentialsException.TYPE_USER_CANCELED;
- String message = "User cancelled the selector";
- if (!isUserCancellation) {
- exception = GetCandidateCredentialsException.TYPE_INTERRUPTED;
- message = "The UI was interrupted - please try again.";
- }
- mRequestSessionMetric.collectFrameworkException(exception);
- respondToFinalReceiverWithFailureAndFinish(exception, message);
+ Slog.d(TAG, "User canceled but session is not being terminated");
}
private void respondToFinalReceiverWithFailureAndFinish(
String exception, String message
) {
+ if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
+ Slog.w(TAG, "Request has already been completed. This is strange.");
+ return;
+ }
+
if (mAutofillCallback != null) {
Bundle resultData = new Bundle();
resultData.putStringArray(
@@ -221,6 +224,19 @@
public void onFinalResponseReceived(ComponentName componentName,
GetCredentialResponse response) {
Slog.d(TAG, "onFinalResponseReceived");
+ if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
+ Slog.w(TAG, "Request has already been completed. This is strange.");
+ return;
+ }
+ respondToFinalReceiverWithResponseAndFinish(response);
+ }
+
+ private void respondToFinalReceiverWithResponseAndFinish(GetCredentialResponse response) {
+ if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
+ Slog.w(TAG, "Request has already been completed. This is strange.");
+ return;
+ }
+
if (this.mAutofillCallback != null) {
Slog.d(TAG, "onFinalResponseReceived sending through final receiver");
Bundle resultData = new Bundle();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
index ad25d76..770712a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
@@ -26,14 +26,18 @@
import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
import static android.media.AudioAttributes.USAGE_UNKNOWN;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static com.android.server.notification.NotificationChannelExtractor.RESTRICT_AUDIO_ATTRIBUTES;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Flags;
@@ -43,12 +47,14 @@
import android.app.Person;
import android.media.AudioAttributes;
import android.net.Uri;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
+import com.android.internal.compat.IPlatformCompat;
import com.android.server.UiServiceTestCase;
import org.junit.Before;
@@ -60,6 +66,8 @@
public class NotificationChannelExtractorTest extends UiServiceTestCase {
@Mock RankingConfig mConfig;
+ @Mock
+ IPlatformCompat mPlatformCompat;
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@@ -73,6 +81,7 @@
mExtractor = new NotificationChannelExtractor();
mExtractor.setConfig(mConfig);
mExtractor.initialize(mContext, null);
+ mExtractor.setCompatChangeLogger(mPlatformCompat);
}
private NotificationRecord getRecord(NotificationChannel channel, Notification n) {
@@ -82,7 +91,7 @@
}
@Test
- public void testExtractsUpdatedConversationChannel() {
+ public void testExtractsUpdatedConversationChannel() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
final Notification n = new Notification.Builder(getContext())
.setContentTitle("foo")
@@ -101,7 +110,7 @@
}
@Test
- public void testInvalidShortcutFlagEnabled_looksUpCorrectNonChannel() {
+ public void testInvalidShortcutFlagEnabled_looksUpCorrectNonChannel() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
final Notification n = new Notification.Builder(getContext())
.setContentTitle("foo")
@@ -122,7 +131,7 @@
}
@Test
- public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() {
+ public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
final Notification n = new Notification.Builder(getContext())
.setContentTitle("foo")
@@ -143,7 +152,7 @@
@Test
@EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL)
- public void testAudioAttributes_callStyleCanUseCallUsage() {
+ public void testAudioAttributes_callStyleCanUseCallUsage() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
.setUsage(USAGE_NOTIFICATION_RINGTONE)
@@ -162,11 +171,12 @@
assertThat(mExtractor.process(r)).isNull();
assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION_RINGTONE);
assertThat(r.getChannel()).isEqualTo(channel);
+ verify(mPlatformCompat, never()).reportChangeByUid(anyLong(), anyInt());
}
@Test
@EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL)
- public void testAudioAttributes_nonCallStyleCannotUseCallUsage() {
+ public void testAudioAttributes_nonCallStyleCannotUseCallUsage() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
.setUsage(USAGE_NOTIFICATION_RINGTONE)
@@ -180,13 +190,14 @@
assertThat(mExtractor.process(r)).isNull();
// instance updated
assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+ verify(mPlatformCompat).reportChangeByUid(RESTRICT_AUDIO_ATTRIBUTES, r.getUid());
// in-memory channel unchanged
assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION_RINGTONE);
}
@Test
@EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM)
- public void testAudioAttributes_alarmCategoryCanUseAlarmUsage() {
+ public void testAudioAttributes_alarmCategoryCanUseAlarmUsage() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
.setUsage(USAGE_ALARM)
@@ -201,11 +212,12 @@
assertThat(mExtractor.process(r)).isNull();
assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_ALARM);
assertThat(r.getChannel()).isEqualTo(channel);
+ verify(mPlatformCompat, never()).reportChangeByUid(anyLong(), anyInt());
}
@Test
@EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM)
- public void testAudioAttributes_nonAlarmCategoryCannotUseAlarmUsage() {
+ public void testAudioAttributes_nonAlarmCategoryCannotUseAlarmUsage() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
.setUsage(USAGE_ALARM)
@@ -219,13 +231,14 @@
assertThat(mExtractor.process(r)).isNull();
// instance updated
assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+ verify(mPlatformCompat).reportChangeByUid(RESTRICT_AUDIO_ATTRIBUTES, r.getUid());
// in-memory channel unchanged
assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_ALARM);
}
@Test
@EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA)
- public void testAudioAttributes_noMediaUsage() {
+ public void testAudioAttributes_noMediaUsage() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
.setUsage(USAGE_MEDIA)
@@ -239,13 +252,14 @@
assertThat(mExtractor.process(r)).isNull();
// instance updated
assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+ verify(mPlatformCompat).reportChangeByUid(RESTRICT_AUDIO_ATTRIBUTES, r.getUid());
// in-memory channel unchanged
assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_MEDIA);
}
@Test
@EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA)
- public void testAudioAttributes_noUnknownUsage() {
+ public void testAudioAttributes_noUnknownUsage() throws RemoteException {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
.setUsage(USAGE_UNKNOWN)
@@ -259,6 +273,7 @@
assertThat(mExtractor.process(r)).isNull();
// instance updated
assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+ verify(mPlatformCompat).reportChangeByUid(RESTRICT_AUDIO_ATTRIBUTES, r.getUid());
// in-memory channel unchanged
assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_UNKNOWN);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index aeeca2ae..5033a380 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -3981,7 +3981,7 @@
pm.applicationInfo = new ApplicationInfo();
pm.applicationInfo.uid = UID_O;
List<PackageInfo> packages = ImmutableList.of(pm);
- when(mPm.getInstalledPackagesAsUser(any(), anyInt())).thenReturn(packages);
+ when(mPm.getInstalledPackagesAsUser(eq(0), anyInt())).thenReturn(packages);
mHelper.updateFixedImportance(users);
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
@@ -4097,7 +4097,7 @@
pm.applicationInfo = new ApplicationInfo();
pm.applicationInfo.uid = UID_O;
List<PackageInfo> packages = ImmutableList.of(pm);
- when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
+ when(mPm.getInstalledPackagesAsUser(0, 0)).thenReturn(packages);
mHelper.updateFixedImportance(users);
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -4120,7 +4120,7 @@
pm.applicationInfo = new ApplicationInfo();
pm.applicationInfo.uid = UID_O;
List<PackageInfo> packages = ImmutableList.of(pm);
- when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
+ when(mPm.getInstalledPackagesAsUser(0, 0)).thenReturn(packages);
mHelper.updateFixedImportance(users);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
@@ -4309,7 +4309,7 @@
pm.applicationInfo = new ApplicationInfo();
pm.applicationInfo.uid = UID_O;
List<PackageInfo> packages = ImmutableList.of(pm);
- when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
+ when(mPm.getInstalledPackagesAsUser(0, 0)).thenReturn(packages);
mHelper.updateFixedImportance(users);
ArraySet<String> toRemove = new ArraySet<>();
@@ -4341,7 +4341,7 @@
pm.applicationInfo = new ApplicationInfo();
pm.applicationInfo.uid = UID_O;
List<PackageInfo> packages = ImmutableList.of(pm);
- when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
+ when(mPm.getInstalledPackagesAsUser(0, 0)).thenReturn(packages);
mHelper.updateFixedImportance(users);
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index ad420f6..527001d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -55,6 +55,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.compat.IPlatformCompat;
import com.android.server.UiServiceTestCase;
import org.junit.Before;
@@ -155,7 +156,8 @@
NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
mHelper = new RankingHelper(getContext(), mHandler, mConfig, mMockZenModeHelper,
- mUsageStats, new String[] {ImportanceExtractor.class.getName()});
+ mUsageStats, new String[] {ImportanceExtractor.class.getName()},
+ mock(IPlatformCompat.class));
mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
.setContentTitle("A")