Merge "Remove blocking binder call to WifiManager" into udc-dev
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index c4e8b0e..a8b6c0b 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -105,6 +105,7 @@
static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
static const char CLOCK_ENABLED_PROP_NAME[] = "persist.sys.bootanim.clock.enabled";
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
+static const int MAX_CHECK_EXIT_INTERVAL_US = 50000;
static constexpr size_t TEXT_POS_LEN_MAX = 16;
static const int DYNAMIC_COLOR_COUNT = 4;
static const char U_TEXTURE[] = "uTexture";
@@ -1678,7 +1679,17 @@
checkExit();
}
- usleep(part.pause * ns2us(frameDuration));
+ int pauseDuration = part.pause * ns2us(frameDuration);
+ while(pauseDuration > 0 && !exitPending()){
+ if (pauseDuration > MAX_CHECK_EXIT_INTERVAL_US) {
+ usleep(MAX_CHECK_EXIT_INTERVAL_US);
+ pauseDuration -= MAX_CHECK_EXIT_INTERVAL_US;
+ } else {
+ usleep(pauseDuration);
+ break;
+ }
+ checkExit();
+ }
if (exitPending() && !part.count && mCurrentInset >= mTargetInset &&
!part.hasFadingPhase()) {
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index ac50d09..cd89a56 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -99,9 +99,16 @@
@Override
public ISurfaceSyncGroup getSurfaceSyncGroup() {
CompletableFuture<ISurfaceSyncGroup> surfaceSyncGroup = new CompletableFuture<>();
- mViewRoot.mHandler.post(
- () -> surfaceSyncGroup.complete(
- mViewRoot.getOrCreateSurfaceSyncGroup().mISurfaceSyncGroup));
+ // If the call came from in process and it's already running on the UI thread, return
+ // results immediately instead of posting to the main thread. If we post to the main
+ // thread, it will block itself and the return value will always be null.
+ if (Thread.currentThread() == mViewRoot.mThread) {
+ return mViewRoot.getOrCreateSurfaceSyncGroup().mISurfaceSyncGroup;
+ } else {
+ mViewRoot.mHandler.post(
+ () -> surfaceSyncGroup.complete(
+ mViewRoot.getOrCreateSurfaceSyncGroup().mISurfaceSyncGroup));
+ }
try {
return surfaceSyncGroup.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 18874f7..3165654 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1780,6 +1780,21 @@
Object value = getParameterValue(view);
try {
MethodHandle method = getMethod(view, this.methodName, param, true /* async */);
+ // Upload the bitmap to GPU if the parameter is of type Bitmap or Icon.
+ // Since bitmaps in framework are seldomly modified, this is supposed to accelerate
+ // the operations.
+ if (value instanceof Bitmap bitmap) {
+ bitmap.prepareToDraw();
+ }
+
+ if (value instanceof Icon icon
+ && (icon.getType() == Icon.TYPE_BITMAP
+ || icon.getType() == Icon.TYPE_ADAPTIVE_BITMAP)) {
+ Bitmap bitmap = icon.getBitmap();
+ if (bitmap != null) {
+ bitmap.prepareToDraw();
+ }
+ }
if (method != null) {
Runnable endAction = (Runnable) method.invoke(view, value);
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java b/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
index 316c70c..980211f 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
@@ -25,8 +25,7 @@
import android.app.Activity;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Bundle;
-import android.platform.test.annotations.IwTest;
-import android.platform.test.annotations.Postsubmit;
+import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.util.PollingCheck;
import android.view.View;
@@ -60,7 +59,7 @@
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
-@Postsubmit
+@Presubmit
public class FontScaleConverterActivityTest {
@Rule
public ActivityScenarioRule<TestActivity> rule = new ActivityScenarioRule<>(TestActivity.class);
@@ -85,7 +84,6 @@
}
}
- @IwTest(focusArea = "accessibility")
@Test
public void testFontsScaleNonLinearly() {
final ActivityScenario<TestActivity> scenario = rule.getScenario();
@@ -116,7 +114,6 @@
)));
}
- @IwTest(focusArea = "accessibility")
@Test
public void testOnConfigurationChanged_doesNotCrash() {
final ActivityScenario<TestActivity> scenario = rule.getScenario();
@@ -130,7 +127,6 @@
});
}
- @IwTest(focusArea = "accessibility")
@Test
public void testUpdateConfiguration_doesNotCrash() {
final ActivityScenario<TestActivity> scenario = rule.getScenario();
diff --git a/core/tests/coretests/src/android/content/res/TEST_MAPPING b/core/tests/coretests/src/android/content/res/TEST_MAPPING
index ab14950..4ea6e40 100644
--- a/core/tests/coretests/src/android/content/res/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/res/TEST_MAPPING
@@ -39,18 +39,5 @@
}
]
}
- ],
- "ironwood-postsubmit": [
- {
- "name": "FrameworksCoreTests",
- "options":[
- {
- "include-annotation": "android.platform.test.annotations.IwTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
- }
]
}
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index cc987bc..2a8cb42 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -104,7 +104,8 @@
GrBackendRenderTarget backendRT(frame.width(), frame.height(), 0, STENCIL_BUFFER_SIZE, fboInfo);
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+ SkSurfaceProps props(mColorMode == ColorMode::Default ? 0 : SkSurfaceProps::kAlwaysDither_Flag,
+ kUnknown_SkPixelGeometry);
SkASSERT(mRenderThread.getGrContext() != nullptr);
sk_sp<SkSurface> surface;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 1f92968..b020e96 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -28,7 +28,6 @@
#include <SkMultiPictureDocument.h>
#include <SkOverdrawCanvas.h>
#include <SkOverdrawColorFilter.h>
-#include <SkPaintFilterCanvas.h>
#include <SkPicture.h>
#include <SkPictureRecorder.h>
#include <SkRect.h>
@@ -450,23 +449,6 @@
}
}
-class ForceDitherCanvas : public SkPaintFilterCanvas {
-public:
- ForceDitherCanvas(SkCanvas* canvas) : SkPaintFilterCanvas(canvas) {}
-
-protected:
- bool onFilter(SkPaint& paint) const override {
- paint.setDither(true);
- return true;
- }
-
- void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
- // We unroll the drawable using "this" canvas, so that draw calls contained inside will
- // get dithering applied
- drawable->draw(this, matrix);
- }
-};
-
void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque,
const Rect& contentDrawBounds, sk_sp<SkSurface> surface,
@@ -521,12 +503,6 @@
canvas->clear(SK_ColorTRANSPARENT);
}
- std::optional<ForceDitherCanvas> forceDitherCanvas;
- if (shouldForceDither()) {
- forceDitherCanvas.emplace(canvas);
- canvas = &forceDitherCanvas.value();
- }
-
if (1 == nodes.size()) {
if (!nodes[0]->nothingToDraw()) {
RenderNodeDrawable root(nodes[0].get(), canvas);
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 0763b06..befee89 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -98,8 +98,6 @@
bool isCapturingSkp() const { return mCaptureMode != CaptureMode::None; }
- virtual bool shouldForceDither() const { return mColorMode != ColorMode::Default; }
-
private:
void renderFrameImpl(const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque,
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index f22652f..86096d5 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -203,11 +203,6 @@
return nullptr;
}
-bool SkiaVulkanPipeline::shouldForceDither() const {
- if (mVkSurface && mVkSurface->isBeyond8Bit()) return false;
- return SkiaPipeline::shouldForceDither();
-}
-
void SkiaVulkanPipeline::onContextDestroyed() {
if (mVkSurface) {
vulkanManager().destroySurface(mVkSurface);
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index cce5468e..284cde5 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -63,8 +63,6 @@
protected:
void onContextDestroyed() override;
- bool shouldForceDither() const override;
-
private:
renderthread::VulkanManager& vulkanManager();
renderthread::VulkanSurface* mVkSurface = nullptr;
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index 2b7fa04..10f4567 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -453,9 +453,15 @@
VulkanSurface::NativeBufferInfo* bufferInfo = &mNativeBuffers[idx];
if (bufferInfo->skSurface.get() == nullptr) {
+ SkSurfaceProps surfaceProps;
+ if (mWindowInfo.colorMode != ColorMode::Default) {
+ surfaceProps = SkSurfaceProps(SkSurfaceProps::kAlwaysDither_Flag | surfaceProps.flags(),
+ surfaceProps.pixelGeometry());
+ }
bufferInfo->skSurface = SkSurface::MakeFromAHardwareBuffer(
mGrContext, ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
- kTopLeft_GrSurfaceOrigin, mWindowInfo.colorspace, nullptr, /*from_window=*/true);
+ kTopLeft_GrSurfaceOrigin, mWindowInfo.colorspace, &surfaceProps,
+ /*from_window=*/true);
if (bufferInfo->skSurface.get() == nullptr) {
ALOGE("SkSurface::MakeFromAHardwareBuffer failed");
mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer,
@@ -545,16 +551,6 @@
}
}
-bool VulkanSurface::isBeyond8Bit() const {
- switch (mWindowInfo.bufferFormat) {
- case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
- case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
- return true;
- default:
- return false;
- }
-}
-
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index d3266af8..6f528010 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -49,8 +49,6 @@
void setColorSpace(sk_sp<SkColorSpace> colorSpace);
const SkM44& getPixelSnapMatrix() const { return mWindowInfo.pixelSnapMatrix; }
- bool isBeyond8Bit() const;
-
private:
/*
* All structs/methods in this private section are specifically for use by the VulkanManager
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index e9b2e10..3e65251 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -117,6 +117,8 @@
<string name="get_dialog_sign_in_type_username_separator" translatable="false">" • "</string>
<!-- This text is followed by a list of one or more options. [CHAR LIMIT=80] -->
<string name="get_dialog_title_sign_in_options">Sign-in options</string>
+ <!-- Button label for viewing the full information about an account. [CHAR LIMIT=80] -->
+ <string name="button_label_view_more">View more</string>
<!-- Column heading for displaying sign-ins for a specific username. [CHAR LIMIT=80] -->
<string name="get_dialog_heading_for_username">For <xliff:g id="username" example="becket@gmail.com">%1$s</xliff:g></string>
<!-- Column heading for displaying locked (that is, the user needs to first authenticate via pin, fingerprint, faceId, etc.) sign-ins. [CHAR LIMIT=80] -->
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 0623ff6..2dba2ab 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt
@@ -51,6 +51,7 @@
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
@@ -79,6 +80,7 @@
/** If true, draws a trailing lock icon. */
isLockedAuthEntry: Boolean = false,
enforceOneLine: Boolean = false,
+ onTextLayout: (TextLayoutResult) -> Unit = {},
) {
val iconPadding = Modifier.wrapContentSize().padding(
// Horizontal padding should be 16dp, but the suggestion chip itself
@@ -103,7 +105,11 @@
) {
// Apply weight so that the trailing icon can always show.
Column(modifier = Modifier.wrapContentHeight().fillMaxWidth().weight(1f)) {
- SmallTitleText(text = entryHeadlineText, enforceOneLine = enforceOneLine)
+ SmallTitleText(
+ text = entryHeadlineText,
+ enforceOneLine = enforceOneLine,
+ onTextLayout = onTextLayout,
+ )
if (passwordValue != null) {
Row(
modifier = Modifier.fillMaxWidth().padding(top = 4.dp),
@@ -141,10 +147,18 @@
)
}
} else if (entrySecondLineText != null) {
- BodySmallText(text = entrySecondLineText, enforceOneLine = enforceOneLine)
+ BodySmallText(
+ text = entrySecondLineText,
+ enforceOneLine = enforceOneLine,
+ onTextLayout = onTextLayout,
+ )
}
if (entryThirdLineText != null) {
- BodySmallText(text = entryThirdLineText, enforceOneLine = enforceOneLine)
+ BodySmallText(
+ text = entryThirdLineText,
+ enforceOneLine = enforceOneLine,
+ onTextLayout = onTextLayout,
+ )
}
}
if (isLockedAuthEntry) {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt
index 61c03b4..6b46636 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt
@@ -22,6 +22,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
@@ -59,14 +60,20 @@
* Body-small typography; on-surface-variant color.
*/
@Composable
-fun BodySmallText(text: String, modifier: Modifier = Modifier, enforceOneLine: Boolean = false) {
+fun BodySmallText(
+ text: String,
+ modifier: Modifier = Modifier,
+ enforceOneLine: Boolean = false,
+ onTextLayout: (TextLayoutResult) -> Unit = {},
+) {
Text(
modifier = modifier.wrapContentSize(),
text = text,
color = LocalAndroidColorScheme.current.colorOnSurfaceVariant,
style = MaterialTheme.typography.bodySmall,
overflow = TextOverflow.Ellipsis,
- maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE
+ maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE,
+ onTextLayout = onTextLayout,
)
}
@@ -87,14 +94,20 @@
* Title-small typography; on-surface color.
*/
@Composable
-fun SmallTitleText(text: String, modifier: Modifier = Modifier, enforceOneLine: Boolean = false) {
+fun SmallTitleText(
+ text: String,
+ modifier: Modifier = Modifier,
+ enforceOneLine: Boolean = false,
+ onTextLayout: (TextLayoutResult) -> Unit = {},
+) {
Text(
modifier = modifier.wrapContentSize(),
text = text,
color = LocalAndroidColorScheme.current.colorOnSurface,
style = MaterialTheme.typography.titleSmall,
overflow = TextOverflow.Ellipsis,
- maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE
+ maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE,
+ onTextLayout = onTextLayout,
)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 6d7ecd7..c1ea1d8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -34,11 +34,15 @@
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap
import com.android.credentialmanager.CredentialSelectorViewModel
@@ -158,6 +162,7 @@
onMoreOptionSelected: () -> Unit,
onLog: @Composable (UiEventEnum) -> Unit,
) {
+ val showMoreForTruncatedEntry = remember { mutableStateOf(false) }
val sortedUserNameToCredentialEntryList =
providerDisplayInfo.sortedUserNameToCredentialEntryList
val authenticationEntryList = providerDisplayInfo.authenticationEntryList
@@ -209,6 +214,8 @@
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
val usernameForCredentialSize = sortedUserNameToCredentialEntryList.size
val authenticationEntrySize = authenticationEntryList.size
+ // If true, render a view more button for the single truncated entry on the
+ // front page.
// Show max 4 entries in this primary page
if (usernameForCredentialSize + authenticationEntrySize <= 4) {
sortedUserNameToCredentialEntryList.forEach {
@@ -216,6 +223,9 @@
credentialEntryInfo = it.sortedCredentialEntryList.first(),
onEntrySelected = onEntrySelected,
enforceOneLine = true,
+ onTextLayout = {
+ showMoreForTruncatedEntry.value = it.hasVisualOverflow
+ }
)
}
authenticationEntryList.forEach {
@@ -269,6 +279,13 @@
onMoreOptionSelected
)
}
+ } else if (showMoreForTruncatedEntry.value) {
+ {
+ ActionButton(
+ stringResource(R.string.button_label_view_more),
+ onMoreOptionSelected
+ )
+ }
} else null,
rightButton = if (activeEntry != null) { // Only one sign-in options exist
{
@@ -438,6 +455,7 @@
credentialEntryInfo: CredentialEntryInfo,
onEntrySelected: (BaseEntry) -> Unit,
enforceOneLine: Boolean = false,
+ onTextLayout: (TextLayoutResult) -> Unit = {},
) {
Entry(
onClick = { onEntrySelected(credentialEntryInfo) },
@@ -463,6 +481,7 @@
)
},
enforceOneLine = enforceOneLine,
+ onTextLayout = onTextLayout,
)
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 36a0b5d..dabb578 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -347,15 +347,6 @@
<uses-permission android:name="android.permission.MONITOR_KEYBOARD_BACKLIGHT" />
- <!-- Intent Chooser -->
- <permission
- android:name="android.permission.ADD_CHOOSER_PINS"
- android:protectionLevel="signature" />
- <uses-permission android:name="android.permission.ADD_CHOOSER_PINS" />
- <permission
- android:name="android.permission.RECEIVE_CHOOSER_PIN_MIGRATION"
- android:protectionLevel="signature" />
-
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
index f71c137..52dfc55 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
@@ -4,7 +4,7 @@
import androidx.annotation.VisibleForTesting
class WeatherData
-constructor(
+private constructor(
val description: String,
val state: WeatherStateIcon,
val useCelsius: Boolean,
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index c0f7029..e9acf3f 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -64,20 +64,20 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="bottom"
+ android:layout_marginHorizontal="@dimen/keyguard_affordance_horizontal_offset"
+ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+ android:gravity="bottom"
>
<com.android.systemui.animation.view.LaunchableImageView
android:id="@+id/start_button"
android:layout_height="@dimen/keyguard_affordance_fixed_height"
android:layout_width="@dimen/keyguard_affordance_fixed_width"
- android:layout_gravity="bottom|start"
android:scaleType="fitCenter"
android:padding="@dimen/keyguard_affordance_fixed_padding"
android:tint="?android:attr/textColorPrimary"
android:background="@drawable/keyguard_bottom_affordance_bg"
android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
- android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
- android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
android:visibility="invisible" />
<FrameLayout
@@ -90,7 +90,7 @@
android:id="@+id/keyguard_settings_button"
layout="@layout/keyguard_settings_popup_menu"
android:layout_width="wrap_content"
- android:layout_height="@dimen/keyguard_affordance_fixed_height"
+ android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
/>
@@ -100,14 +100,11 @@
android:id="@+id/end_button"
android:layout_height="@dimen/keyguard_affordance_fixed_height"
android:layout_width="@dimen/keyguard_affordance_fixed_width"
- android:layout_gravity="bottom|end"
android:scaleType="fitCenter"
android:padding="@dimen/keyguard_affordance_fixed_padding"
android:tint="?android:attr/textColorPrimary"
android:background="@drawable/keyguard_bottom_affordance_bg"
android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
- android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
- android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
android:visibility="invisible" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml b/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
index 9d0d783..65ee8b3 100644
--- a/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
+++ b/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
@@ -20,7 +20,8 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
- android:layout_height="48dp"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/keyguard_affordance_fixed_height"
android:orientation="horizontal"
android:gravity="center_vertical"
android:background="@drawable/keyguard_settings_popup_menu_background"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index b7cf23b..350c4ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2867,7 +2867,7 @@
|| mGoingToSleep
|| shouldListenForFingerprintAssistant
|| (mKeyguardOccluded && mIsDreaming)
- || (mKeyguardOccluded && userDoesNotHaveTrust
+ || (mKeyguardOccluded && userDoesNotHaveTrust && mKeyguardShowing
&& (mOccludingAppRequestingFp || isUdfps || mAlternateBouncerShowing));
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
diff --git a/packages/SystemUI/src/com/android/systemui/ChooserPinMigration.kt b/packages/SystemUI/src/com/android/systemui/ChooserPinMigration.kt
deleted file mode 100644
index 2f03259..0000000
--- a/packages/SystemUI/src/com/android/systemui/ChooserPinMigration.kt
+++ /dev/null
@@ -1,140 +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
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.Context.MODE_PRIVATE
-import android.content.Intent
-import android.content.SharedPreferences
-import android.os.Bundle
-import android.os.Environment
-import android.os.storage.StorageManager
-import android.util.Log
-import androidx.core.util.Supplier
-import com.android.internal.R
-import com.android.systemui.broadcast.BroadcastSender
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import java.io.File
-import javax.inject.Inject
-
-/**
- * Performs a migration of pinned targets to the unbundled chooser if legacy data exists.
- *
- * Sends an explicit broadcast with the contents of the legacy pin preferences. The broadcast is
- * protected by the RECEIVE_CHOOSER_PIN_MIGRATION permission. This class requires the
- * ADD_CHOOSER_PINS permission in order to be able to send this broadcast.
- */
-class ChooserPinMigration
-@Inject
-constructor(
- private val context: Context,
- private val featureFlags: FeatureFlags,
- private val broadcastSender: BroadcastSender,
- legacyPinPrefsFileSupplier: LegacyPinPrefsFileSupplier,
-) : CoreStartable {
-
- private val legacyPinPrefsFile = legacyPinPrefsFileSupplier.get()
- private val chooserComponent =
- ComponentName.unflattenFromString(
- context.resources.getString(R.string.config_chooserActivity)
- )
-
- override fun start() {
- if (migrationIsRequired()) {
- doMigration()
- }
- }
-
- private fun migrationIsRequired(): Boolean {
- return featureFlags.isEnabled(Flags.CHOOSER_MIGRATION_ENABLED) &&
- legacyPinPrefsFile.exists() &&
- chooserComponent?.packageName != null
- }
-
- private fun doMigration() {
- Log.i(TAG, "Beginning migration")
-
- val legacyPinPrefs = context.getSharedPreferences(legacyPinPrefsFile, MODE_PRIVATE)
-
- if (legacyPinPrefs.all.isEmpty()) {
- Log.i(TAG, "No data to migrate, deleting legacy file")
- } else {
- sendSharedPreferences(legacyPinPrefs)
- Log.i(TAG, "Legacy data sent, deleting legacy preferences")
-
- val legacyPinPrefsEditor = legacyPinPrefs.edit()
- legacyPinPrefsEditor.clear()
- if (!legacyPinPrefsEditor.commit()) {
- Log.e(TAG, "Failed to delete legacy preferences")
- return
- }
- }
-
- if (!legacyPinPrefsFile.delete()) {
- Log.e(TAG, "Legacy preferences deleted, but failed to delete legacy preferences file")
- return
- }
-
- Log.i(TAG, "Legacy preference deletion complete")
- }
-
- private fun sendSharedPreferences(sharedPreferences: SharedPreferences) {
- val bundle = Bundle()
-
- sharedPreferences.all.entries.forEach { (key, value) ->
- when (value) {
- is Boolean -> bundle.putBoolean(key, value)
- else -> Log.e(TAG, "Unsupported preference type for $key: ${value?.javaClass}")
- }
- }
-
- sendBundle(bundle)
- }
-
- private fun sendBundle(bundle: Bundle) {
- val intent =
- Intent().apply {
- `package` = chooserComponent?.packageName!!
- action = BROADCAST_ACTION
- putExtras(bundle)
- }
- broadcastSender.sendBroadcast(intent, BROADCAST_PERMISSION)
- }
-
- companion object {
- private const val TAG = "PinnedShareTargetMigration"
- private const val BROADCAST_ACTION = "android.intent.action.CHOOSER_PIN_MIGRATION"
- private const val BROADCAST_PERMISSION = "android.permission.RECEIVE_CHOOSER_PIN_MIGRATION"
-
- class LegacyPinPrefsFileSupplier @Inject constructor(private val context: Context) :
- Supplier<File> {
-
- override fun get(): File {
- val packageDirectory =
- Environment.getDataUserCePackageDirectory(
- StorageManager.UUID_PRIVATE_INTERNAL,
- context.userId,
- context.packageName,
- )
- val sharedPrefsDirectory = File(packageDirectory, "shared_prefs")
- return File(sharedPrefsDirectory, "chooser_pin_settings.xml")
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 92344db..0999229 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -1005,9 +1005,11 @@
* not enrolled sfps. This may be false if called before onAllAuthenticatorsRegistered.
*/
public boolean isRearFpsSupported() {
- for (FingerprintSensorPropertiesInternal prop: mFpProps) {
- if (prop.sensorType == TYPE_REAR) {
- return true;
+ if (mFpProps != null) {
+ for (FingerprintSensorPropertiesInternal prop: mFpProps) {
+ if (prop.sensorType == TYPE_REAR) {
+ return true;
+ }
}
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt
index 26fc36d..81ed076 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/MotionEventExt.kt
@@ -19,10 +19,18 @@
import android.util.MathUtils
import android.view.MotionEvent
-/** Returns the distance from the position of this [MotionEvent] and the given coordinates. */
-fun MotionEvent.distanceFrom(
- x: Float,
- y: Float,
+/**
+ * Returns the distance from the raw position of this [MotionEvent] and the given coordinates.
+ * Because this is all expected to be in the coordinate space of the display and not the view,
+ * applying mutations to the view (such as scaling animations) does not affect the distance
+ * measured.
+ * @param xOnDisplay the x coordinate relative to the display
+ * @param yOnDisplay the y coordinate relative to the display
+ * @return distance from the raw position of this [MotionEvent] and the given coordinates
+ */
+fun MotionEvent.rawDistanceFrom(
+ xOnDisplay: Float,
+ yOnDisplay: Float,
): Float {
- return MathUtils.dist(this.x, this.y, x, y)
+ return MathUtils.dist(this.rawX, this.rawY, xOnDisplay, yOnDisplay)
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index df236e7..9bf6b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -17,7 +17,6 @@
package com.android.systemui.dagger
import com.android.keyguard.KeyguardBiometricLockoutLogger
-import com.android.systemui.ChooserPinMigration
import com.android.systemui.ChooserSelector
import com.android.systemui.CoreStartable
import com.android.systemui.LatencyTester
@@ -76,13 +75,6 @@
@ClassKey(AuthController::class)
abstract fun bindAuthController(service: AuthController): CoreStartable
- /** Inject into ChooserPinMigration. */
- @Binds
- @IntoMap
- @ClassKey(ChooserPinMigration::class)
- @PerUser
- abstract fun bindChooserPinMigration(sysui: ChooserPinMigration): CoreStartable
-
/** Inject into ChooserCoreStartable. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index bd9f766..69d7582 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -65,7 +65,7 @@
val FSI_ON_DND_UPDATE = releasedFlag(259130119, "fsi_on_dnd_update")
// TODO(b/254512538): Tracking Bug
- val INSTANT_VOICE_REPLY = releasedFlag(111, "instant_voice_reply")
+ val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply")
// TODO(b/254512425): Tracking Bug
val NOTIFICATION_MEMORY_MONITOR_ENABLED =
@@ -411,7 +411,7 @@
val MEDIA_RETAIN_RECOMMENDATIONS = releasedFlag(916, "media_retain_recommendations")
// TODO(b/270437894): Tracking Bug
- val MEDIA_REMOTE_RESUME = unreleasedFlag(917, "media_remote_resume")
+ val MEDIA_REMOTE_RESUME = unreleasedFlag(917, "media_remote_resume", teamfood = true)
// 1000 - dock
val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
@@ -621,9 +621,6 @@
val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW =
releasedFlag(1504, "sharesheet_scrollable_image_preview")
- // TODO(b/274137694) Tracking Bug
- val CHOOSER_MIGRATION_ENABLED = unreleasedFlag(1505, "chooser_migration_enabled")
-
// 1700 - clipboard
@JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
index 779095c..5745d6a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt
@@ -26,7 +26,7 @@
import androidx.core.animation.ObjectAnimator
import com.android.systemui.R
import com.android.systemui.animation.Expandable
-import com.android.systemui.common.ui.view.distanceFrom
+import com.android.systemui.common.ui.view.rawDistanceFrom
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
@@ -41,14 +41,14 @@
private val longPressDurationMs = ViewConfiguration.getLongPressTimeout().toLong()
private var longPressAnimator: ViewPropertyAnimator? = null
- private val down: PointF by lazy { PointF() }
+ private val downDisplayCoords: PointF by lazy { PointF() }
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View, event: MotionEvent): Boolean {
return when (event.actionMasked) {
MotionEvent.ACTION_DOWN ->
if (viewModel.configKey != null) {
- down.set(event.x, event.y)
+ downDisplayCoords.set(event.rawX, event.rawY)
if (isUsingAccurateTool(event)) {
// For accurate tool types (stylus, mouse, etc.), we don't require a
// long-press.
@@ -81,7 +81,13 @@
if (!isUsingAccurateTool(event)) {
// Moving too far while performing a long-press gesture cancels that
// gesture.
- if (event.distanceFrom(down.x, down.y) > ViewConfiguration.getTouchSlop()) {
+ if (
+ event
+ .rawDistanceFrom(
+ downDisplayCoords.x,
+ downDisplayCoords.y,
+ ) > ViewConfiguration.getTouchSlop()
+ ) {
cancel()
}
}
@@ -94,7 +100,7 @@
// the pointer performs a click.
if (
viewModel.configKey != null &&
- event.distanceFrom(down.x, down.y) <=
+ event.rawDistanceFrom(downDisplayCoords.x, downDisplayCoords.y) <=
ViewConfiguration.getTouchSlop() &&
falsingManager?.isFalseTap(FalsingManager.NO_PENALTY) == false
) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt
index ad3fb63..c54203c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsButtonOnTouchListener.kt
@@ -21,7 +21,7 @@
import android.view.View
import android.view.ViewConfiguration
import com.android.systemui.animation.view.LaunchableLinearLayout
-import com.android.systemui.common.ui.view.distanceFrom
+import com.android.systemui.common.ui.view.rawDistanceFrom
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
class KeyguardSettingsButtonOnTouchListener(
@@ -29,18 +29,20 @@
private val viewModel: KeyguardSettingsMenuViewModel,
) : View.OnTouchListener {
- private val downPosition = PointF()
+ private val downPositionDisplayCoords = PointF()
override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
when (motionEvent.actionMasked) {
MotionEvent.ACTION_DOWN -> {
view.isPressed = true
- downPosition.set(motionEvent.x, motionEvent.y)
+ downPositionDisplayCoords.set(motionEvent.rawX, motionEvent.rawY)
viewModel.onTouchGestureStarted()
}
MotionEvent.ACTION_UP -> {
view.isPressed = false
- val distanceMoved = motionEvent.distanceFrom(downPosition.x, downPosition.y)
+ val distanceMoved =
+ motionEvent
+ .rawDistanceFrom(downPositionDisplayCoords.x, downPositionDisplayCoords.y)
val isClick = distanceMoved < ViewConfiguration.getTouchSlop()
viewModel.onTouchGestureEnded(isClick)
if (isClick) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index b31ec33..7cb1cbe 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -17,6 +17,8 @@
package com.android.systemui.shade;
+import static android.view.WindowInsets.Type.ime;
+
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.shade.NotificationPanelViewController.COUNTER_PANEL_OPEN_QS;
@@ -463,9 +465,17 @@
return (mQs != null ? mQs.getHeader().getHeight() : 0) + mPeekHeight;
}
+ private boolean isRemoteInputActiveWithKeyboardUp() {
+ //TODO(b/227115380) remove the isVisible(ime()) check once isRemoteInputActive is fixed.
+ // The check for keyboard visibility is a temporary workaround that allows QS to expand
+ // even when isRemoteInputActive is mistakenly returning true.
+ return mRemoteInputManager.isRemoteInputActive()
+ && mPanelView.getRootWindowInsets().isVisible(ime());
+ }
+
public boolean isExpansionEnabled() {
return mExpansionEnabledPolicy && mExpansionEnabledAmbient
- && !mRemoteInputManager.isRemoteInputActive();
+ && !isRemoteInputActiveWithKeyboardUp();
}
public float getTransitioningToFullShadeProgress() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index de14892..3eb9590 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -1010,6 +1010,7 @@
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
verifyFingerprintAuthenticateNeverCalled();
// WHEN alternate bouncer is shown
+ mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
// THEN make sure FP listening begins
@@ -2731,6 +2732,21 @@
KeyguardUpdateMonitor.getCurrentUser())).isTrue();
}
+ @Test
+ public void testFingerprintListeningStateWhenOccluded() {
+ when(mAuthController.isUdfpsSupported()).thenReturn(true);
+
+ mKeyguardUpdateMonitor.setKeyguardShowing(false, false);
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_BIOMETRIC);
+ mKeyguardUpdateMonitor.setKeyguardShowing(false, true);
+
+ verifyFingerprintAuthenticateNeverCalled();
+
+ mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
+ mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
+
+ verifyFingerprintAuthenticateCall();
+ }
private void verifyFingerprintAuthenticateNeverCalled() {
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserPinMigrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserPinMigrationTest.kt
deleted file mode 100644
index 44da5f4..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/ChooserPinMigrationTest.kt
+++ /dev/null
@@ -1,255 +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
-
-import android.content.Context
-import android.content.Intent
-import android.content.SharedPreferences
-import android.content.res.Resources
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.broadcast.BroadcastSender
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.kotlinArgumentCaptor
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import java.io.File
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-class ChooserPinMigrationTest : SysuiTestCase() {
-
- private val fakeFeatureFlags = FakeFeatureFlags()
- private val fakePreferences =
- mutableMapOf(
- "TestPinnedPackage/TestPinnedClass" to true,
- "TestUnpinnedPackage/TestUnpinnedClass" to false,
- )
- private val intent = kotlinArgumentCaptor<Intent>()
- private val permission = kotlinArgumentCaptor<String>()
-
- private lateinit var chooserPinMigration: ChooserPinMigration
-
- @Mock private lateinit var mockContext: Context
- @Mock private lateinit var mockResources: Resources
- @Mock
- private lateinit var mockLegacyPinPrefsFileSupplier:
- ChooserPinMigration.Companion.LegacyPinPrefsFileSupplier
- @Mock private lateinit var mockFile: File
- @Mock private lateinit var mockSharedPreferences: SharedPreferences
- @Mock private lateinit var mockSharedPreferencesEditor: SharedPreferences.Editor
- @Mock private lateinit var mockBroadcastSender: BroadcastSender
-
- @Before
- fun setup() {
- MockitoAnnotations.initMocks(this)
-
- whenever(mockContext.resources).thenReturn(mockResources)
- whenever(mockContext.getSharedPreferences(any<File>(), anyInt()))
- .thenReturn(mockSharedPreferences)
- whenever(mockResources.getString(anyInt())).thenReturn("TestPackage/TestClass")
- whenever(mockSharedPreferences.all).thenReturn(fakePreferences)
- whenever(mockSharedPreferences.edit()).thenReturn(mockSharedPreferencesEditor)
- whenever(mockSharedPreferencesEditor.commit()).thenReturn(true)
- whenever(mockLegacyPinPrefsFileSupplier.get()).thenReturn(mockFile)
- whenever(mockFile.exists()).thenReturn(true)
- whenever(mockFile.delete()).thenReturn(true)
- fakeFeatureFlags.set(Flags.CHOOSER_MIGRATION_ENABLED, true)
- }
-
- @Test
- fun start_performsMigration() {
- // Arrange
- chooserPinMigration =
- ChooserPinMigration(
- mockContext,
- fakeFeatureFlags,
- mockBroadcastSender,
- mockLegacyPinPrefsFileSupplier,
- )
-
- // Act
- chooserPinMigration.start()
-
- // Assert
- verify(mockBroadcastSender).sendBroadcast(intent.capture(), permission.capture())
- assertThat(intent.value.action).isEqualTo("android.intent.action.CHOOSER_PIN_MIGRATION")
- assertThat(intent.value.`package`).isEqualTo("TestPackage")
- assertThat(intent.value.extras?.keySet()).hasSize(2)
- assertThat(intent.value.hasExtra("TestPinnedPackage/TestPinnedClass")).isTrue()
- assertThat(intent.value.getBooleanExtra("TestPinnedPackage/TestPinnedClass", false))
- .isTrue()
- assertThat(intent.value.hasExtra("TestUnpinnedPackage/TestUnpinnedClass")).isTrue()
- assertThat(intent.value.getBooleanExtra("TestUnpinnedPackage/TestUnpinnedClass", true))
- .isFalse()
- assertThat(permission.value).isEqualTo("android.permission.RECEIVE_CHOOSER_PIN_MIGRATION")
-
- // Assert
- verify(mockSharedPreferencesEditor).clear()
- verify(mockSharedPreferencesEditor).commit()
-
- // Assert
- verify(mockFile).delete()
- }
-
- @Test
- fun start_doesNotDeleteLegacyPreferencesFile_whenClearingItFails() {
- // Arrange
- whenever(mockSharedPreferencesEditor.commit()).thenReturn(false)
- chooserPinMigration =
- ChooserPinMigration(
- mockContext,
- fakeFeatureFlags,
- mockBroadcastSender,
- mockLegacyPinPrefsFileSupplier,
- )
-
- // Act
- chooserPinMigration.start()
-
- // Assert
- verify(mockBroadcastSender).sendBroadcast(intent.capture(), permission.capture())
- assertThat(intent.value.action).isEqualTo("android.intent.action.CHOOSER_PIN_MIGRATION")
- assertThat(intent.value.`package`).isEqualTo("TestPackage")
- assertThat(intent.value.extras?.keySet()).hasSize(2)
- assertThat(intent.value.hasExtra("TestPinnedPackage/TestPinnedClass")).isTrue()
- assertThat(intent.value.getBooleanExtra("TestPinnedPackage/TestPinnedClass", false))
- .isTrue()
- assertThat(intent.value.hasExtra("TestUnpinnedPackage/TestUnpinnedClass")).isTrue()
- assertThat(intent.value.getBooleanExtra("TestUnpinnedPackage/TestUnpinnedClass", true))
- .isFalse()
- assertThat(permission.value).isEqualTo("android.permission.RECEIVE_CHOOSER_PIN_MIGRATION")
-
- // Assert
- verify(mockSharedPreferencesEditor).clear()
- verify(mockSharedPreferencesEditor).commit()
-
- // Assert
- verify(mockFile, never()).delete()
- }
-
- @Test
- fun start_OnlyDeletesLegacyPreferencesFile_whenEmpty() {
- // Arrange
- whenever(mockSharedPreferences.all).thenReturn(emptyMap())
- chooserPinMigration =
- ChooserPinMigration(
- mockContext,
- fakeFeatureFlags,
- mockBroadcastSender,
- mockLegacyPinPrefsFileSupplier,
- )
-
- // Act
- chooserPinMigration.start()
-
- // Assert
- verifyZeroInteractions(mockBroadcastSender)
-
- // Assert
- verifyZeroInteractions(mockSharedPreferencesEditor)
-
- // Assert
- verify(mockFile).delete()
- }
-
- @Test
- fun start_DoesNotDoMigration_whenFlagIsDisabled() {
- // Arrange
- fakeFeatureFlags.set(Flags.CHOOSER_MIGRATION_ENABLED, false)
- chooserPinMigration =
- ChooserPinMigration(
- mockContext,
- fakeFeatureFlags,
- mockBroadcastSender,
- mockLegacyPinPrefsFileSupplier,
- )
-
- // Act
- chooserPinMigration.start()
-
- // Assert
- verifyZeroInteractions(mockBroadcastSender)
-
- // Assert
- verifyZeroInteractions(mockSharedPreferencesEditor)
-
- // Assert
- verify(mockFile, never()).delete()
- }
-
- @Test
- fun start_DoesNotDoMigration_whenLegacyPreferenceFileNotPresent() {
- // Arrange
- whenever(mockFile.exists()).thenReturn(false)
- chooserPinMigration =
- ChooserPinMigration(
- mockContext,
- fakeFeatureFlags,
- mockBroadcastSender,
- mockLegacyPinPrefsFileSupplier,
- )
-
- // Act
- chooserPinMigration.start()
-
- // Assert
- verifyZeroInteractions(mockBroadcastSender)
-
- // Assert
- verifyZeroInteractions(mockSharedPreferencesEditor)
-
- // Assert
- verify(mockFile, never()).delete()
- }
-
- @Test
- fun start_DoesNotDoMigration_whenConfiguredChooserComponentIsInvalid() {
- // Arrange
- whenever(mockResources.getString(anyInt())).thenReturn("InvalidComponent")
- chooserPinMigration =
- ChooserPinMigration(
- mockContext,
- fakeFeatureFlags,
- mockBroadcastSender,
- mockLegacyPinPrefsFileSupplier,
- )
-
- // Act
- chooserPinMigration.start()
-
- // Assert
- verifyZeroInteractions(mockBroadcastSender)
-
- // Assert
- verifyZeroInteractions(mockSharedPreferencesEditor)
-
- // Assert
- verify(mockFile, never()).delete()
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index aace566..1e465c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -24,6 +24,7 @@
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
+import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
@@ -42,6 +43,7 @@
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.animation.Interpolator
@@ -101,7 +103,6 @@
import junit.framework.Assert.assertTrue
import org.junit.After
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -2200,8 +2201,7 @@
}
@Test
- @Ignore("b/276920368")
- fun bindRecommendation_carouselNotFitThreeRecs() {
+ fun bindRecommendation_carouselNotFitThreeRecs_OrientationPortrait() {
useRealConstraintSets()
setupUpdatedRecommendationViewHolder()
val albumArt = getColorIcon(Color.RED)
@@ -2229,16 +2229,84 @@
// set the screen width less than the width of media controls.
player.context.resources.configuration.screenWidthDp = 350
+ player.context.resources.configuration.orientation = Configuration.ORIENTATION_PORTRAIT
player.attachRecommendation(recommendationViewHolder)
player.bindRecommendation(data)
- assertThat(player.numberOfFittedRecommendations).isEqualTo(2)
- assertThat(expandedSet.getVisibility(coverContainer1.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(collapsedSet.getVisibility(coverContainer1.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(expandedSet.getVisibility(coverContainer2.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(collapsedSet.getVisibility(coverContainer2.id)).isEqualTo(ConstraintSet.VISIBLE)
- assertThat(expandedSet.getVisibility(coverContainer3.id)).isEqualTo(ConstraintSet.GONE)
- assertThat(collapsedSet.getVisibility(coverContainer3.id)).isEqualTo(ConstraintSet.GONE)
+ val res = player.context.resources
+ val displayAvailableWidth =
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350f, res.displayMetrics).toInt()
+ val recCoverWidth: Int =
+ (res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width) +
+ res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2)
+ val numOfRecs = displayAvailableWidth / recCoverWidth
+
+ assertThat(player.numberOfFittedRecommendations).isEqualTo(numOfRecs)
+ recommendationViewHolder.mediaCoverContainers.forEachIndexed { index, container ->
+ if (index < numOfRecs) {
+ assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(collapsedSet.getVisibility(container.id))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ } else {
+ assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
+ }
+ }
+ }
+
+ @Test
+ fun bindRecommendation_carouselNotFitThreeRecs_OrientationLandscape() {
+ useRealConstraintSets()
+ setupUpdatedRecommendationViewHolder()
+ val albumArt = getColorIcon(Color.RED)
+ val data =
+ smartspaceData.copy(
+ recommendations =
+ listOf(
+ SmartspaceAction.Builder("id1", "title1")
+ .setSubtitle("subtitle1")
+ .setIcon(albumArt)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", "title2")
+ .setSubtitle("subtitle1")
+ .setIcon(albumArt)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", "title3")
+ .setSubtitle("subtitle1")
+ .setIcon(albumArt)
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+
+ // set the screen width less than the width of media controls.
+ // We should have dp width less than 378 to test. In landscape we should have 2x.
+ player.context.resources.configuration.screenWidthDp = 700
+ player.context.resources.configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ player.attachRecommendation(recommendationViewHolder)
+ player.bindRecommendation(data)
+
+ val res = player.context.resources
+ val displayAvailableWidth =
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350f, res.displayMetrics).toInt()
+ val recCoverWidth: Int =
+ (res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width) +
+ res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2)
+ val numOfRecs = displayAvailableWidth / recCoverWidth
+
+ assertThat(player.numberOfFittedRecommendations).isEqualTo(numOfRecs)
+ recommendationViewHolder.mediaCoverContainers.forEachIndexed { index, container ->
+ if (index < numOfRecs) {
+ assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(collapsedSet.getVisibility(container.id))
+ .isEqualTo(ConstraintSet.VISIBLE)
+ } else {
+ assertThat(expandedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(container.id)).isEqualTo(ConstraintSet.GONE)
+ }
+ }
}
@Test
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 8d039fc..2a964b8 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2073,15 +2073,14 @@
@Override
public void onSaveRequestSuccess(@NonNull String servicePackageName,
@Nullable IntentSender intentSender) {
- // Log onSaveRequest result.
- mSaveEventLogger.maybeSetIsSaved(true);
- final long saveRequestFinishTimestamp = SystemClock.elapsedRealtime() - mLatencyBaseTime;
- mSaveEventLogger.maybeSetLatencySaveFinishMillis(saveRequestFinishTimestamp);
- mSaveEventLogger.logAndEndEvent();
-
synchronized (mLock) {
mSessionFlags.mShowingSaveUi = false;
-
+ // Log onSaveRequest result.
+ mSaveEventLogger.maybeSetIsSaved(true);
+ final long saveRequestFinishTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mSaveEventLogger.maybeSetLatencySaveFinishMillis(saveRequestFinishTimestamp);
+ mSaveEventLogger.logAndEndEvent();
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onSaveRequestSuccess() rejected - session: "
+ id + " destroyed");
@@ -2108,14 +2107,13 @@
@NonNull String servicePackageName) {
boolean showMessage = !TextUtils.isEmpty(message);
- // Log onSaveRequest result.
- final long saveRequestFinishTimestamp = SystemClock.elapsedRealtime() - mLatencyBaseTime;
- mSaveEventLogger.maybeSetLatencySaveFinishMillis(saveRequestFinishTimestamp);
- mSaveEventLogger.logAndEndEvent();
-
synchronized (mLock) {
mSessionFlags.mShowingSaveUi = false;
-
+ // Log onSaveRequest result.
+ final long saveRequestFinishTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mSaveEventLogger.maybeSetLatencySaveFinishMillis(saveRequestFinishTimestamp);
+ mSaveEventLogger.logAndEndEvent();
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onSaveRequestFailure() rejected - session: "
+ id + " destroyed");
@@ -2228,8 +2226,8 @@
// AutoFillUiCallback
@Override
public void save() {
- mSaveEventLogger.maybeSetSaveButtonClicked(true);
synchronized (mLock) {
+ mSaveEventLogger.maybeSetSaveButtonClicked(true);
if (mDestroyed) {
Slog.w(TAG, "Call to Session#save() rejected - session: "
+ id + " destroyed");
@@ -2247,10 +2245,9 @@
// AutoFillUiCallback
@Override
public void cancelSave() {
- mSaveEventLogger.maybeSetDialogDismissed(true);
synchronized (mLock) {
mSessionFlags.mShowingSaveUi = false;
-
+ mSaveEventLogger.maybeSetDialogDismissed(true);
if (mDestroyed) {
Slog.w(TAG, "Call to Session#cancelSave() rejected - session: "
+ id + " destroyed");
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 542cc2f..5b320a8 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.MANAGE_COMPANION_DEVICES;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.SYSTEM_UID;
@@ -1066,6 +1067,10 @@
// No role was granted to for this association, there is nothing else we need to here.
return true;
}
+ // Do not need to remove the system role since it was pre-granted by the system.
+ if (deviceProfile.equals(DEVICE_PROFILE_AUTOMOTIVE_PROJECTION)) {
+ return true;
+ }
// Check if the applications is associated with another devices with the profile. If so,
// it should remain the role holder.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ef7d5ae..9752ade 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13713,7 +13713,7 @@
if (!sdkSandboxManagerLocal.canRegisterBroadcastReceiver(
/*IntentFilter=*/ filter, flags, onlyProtectedBroadcasts)) {
throw new SecurityException("SDK sandbox not allowed to register receiver"
- + " with the given IntentFilter: " + filter.toString());
+ + " with the given IntentFilter: " + filter.toLongString());
}
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 568997b..4328efe 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -1329,7 +1329,7 @@
}
try {
- traceAppFreeze(app.processName, pid, false);
+ traceAppFreeze(app.processName, pid, reason);
Process.setProcessFrozen(pid, app.uid, false);
opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
@@ -1341,7 +1341,7 @@
}
if (!opt.isFrozen()) {
- Slog.d(TAG_AM, "sync unfroze " + pid + " " + app.processName);
+ Slog.d(TAG_AM, "sync unfroze " + pid + " " + app.processName + " for " + reason);
mFreezeHandler.sendMessage(
mFreezeHandler.obtainMessage(REPORT_UNFREEZE_MSG,
@@ -1371,7 +1371,7 @@
if (app == null) {
return;
}
- Slog.d(TAG_AM, "quick sync unfreeze " + pid);
+ Slog.d(TAG_AM, "quick sync unfreeze " + pid + " for " + reason);
try {
freezeBinder(pid, false, FREEZE_BINDER_TIMEOUT_MS);
} catch (RuntimeException e) {
@@ -1380,7 +1380,7 @@
}
try {
- traceAppFreeze(app.processName, pid, false);
+ traceAppFreeze(app.processName, pid, reason);
Process.setProcessFrozen(pid, app.uid, false);
} catch (Exception e) {
Slog.e(TAG_AM, "Unable to quick unfreeze " + pid);
@@ -1388,9 +1388,15 @@
}
}
- private static void traceAppFreeze(String processName, int pid, boolean freeze) {
+ /**
+ * Trace app freeze status
+ * @param processName The name of the target process
+ * @param pid The pid of the target process
+ * @param reason UNFREEZE_REASON_XXX (>=0) for unfreezing and -1 for freezing
+ */
+ private static void traceAppFreeze(String processName, int pid, int reason) {
Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_FREEZER_TRACK,
- (freeze ? "Freeze " : "Unfreeze ") + processName + ":" + pid);
+ (reason < 0 ? "Freeze " : "Unfreeze ") + processName + ":" + pid + " " + reason);
}
/**
@@ -2063,7 +2069,7 @@
long unfreezeTime = opt.getFreezeUnfreezeTime();
try {
- traceAppFreeze(proc.processName, pid, true);
+ traceAppFreeze(proc.processName, pid, -1);
Process.setProcessFrozen(pid, proc.uid, true);
opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
@@ -2127,7 +2133,7 @@
private void reportUnfreeze(int pid, int frozenDuration, String processName,
@UnfreezeReason int reason) {
- EventLog.writeEvent(EventLogTags.AM_UNFREEZE, pid, processName);
+ EventLog.writeEvent(EventLogTags.AM_UNFREEZE, pid, processName, reason);
// See above for why we're not taking mPhenotypeFlagLock here
if (mRandom.nextFloat() < mFreezerStatsdSampleRate) {
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index f0e8ede..94d5aab 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -357,12 +357,16 @@
} catch (NameNotFoundException e) {
throw new IllegalArgumentException("No package matching :" + packageName);
}
-
- projection = new MediaProjection(type, uid, packageName, ai.targetSdkVersion,
- ai.isPrivilegedApp());
- if (isPermanentGrant) {
- mAppOps.setMode(AppOpsManager.OP_PROJECT_MEDIA,
- projection.uid, projection.packageName, AppOpsManager.MODE_ALLOWED);
+ final long callingToken = Binder.clearCallingIdentity();
+ try {
+ projection = new MediaProjection(type, uid, packageName, ai.targetSdkVersion,
+ ai.isPrivilegedApp());
+ if (isPermanentGrant) {
+ mAppOps.setMode(AppOpsManager.OP_PROJECT_MEDIA,
+ projection.uid, projection.packageName, AppOpsManager.MODE_ALLOWED);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingToken);
}
return projection;
}
@@ -418,16 +422,9 @@
if (packageName == null || packageName.isEmpty()) {
throw new IllegalArgumentException("package name must not be empty");
}
- MediaProjection projection;
final UserHandle callingUser = Binder.getCallingUserHandle();
- final long callingToken = Binder.clearCallingIdentity();
- try {
- projection = createProjectionInternal(uid, packageName, type, isPermanentGrant,
- callingUser, false);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- return projection;
+ return createProjectionInternal(uid, packageName, type, isPermanentGrant,
+ callingUser, false);
}
@Override // Binder call
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index e209ef9..714877f 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -918,6 +918,8 @@
final WindowContainer<?> participant = mParticipants.valueAt(i);
final ActivityRecord ar = participant.asActivityRecord();
if (ar != null) {
+ final Task task = ar.getTask();
+ if (task == null) continue;
boolean visibleAtTransitionEnd = mVisibleAtTransitionEndTokens.contains(ar);
// We need both the expected visibility AND current requested-visibility to be
// false. If it is expected-visible but not currently visible, it means that
@@ -936,9 +938,7 @@
if (commitVisibility) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
" Commit activity becoming invisible: %s", ar);
- final Task task = ar.getTask();
- if (task != null && !task.isVisibleRequested()
- && mTransientLaunches != null) {
+ if (mTransientLaunches != null && !task.isVisibleRequested()) {
// If transition is transient, then snapshots are taken at end of
// transition.
mController.mSnapshotController.mTaskSnapshotController
@@ -963,8 +963,9 @@
// Since transient launches don't automatically take focus, make sure we
// synchronize focus since we committed to the launch.
- if (ar.isTopRunningActivity()) {
- ar.moveFocusableActivityToTop("transitionFinished");
+ if (!task.isFocused() && ar.isTopRunningActivity()) {
+ mController.mAtm.setLastResumedActivityUncheckLocked(ar,
+ "transitionFinished");
}
}
continue;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index cbdf38ae..ee9d6c1 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2989,4 +2989,14 @@
* {@code false} otherwise.
*/
boolean setSatelliteServicePackageName(in String servicePackageName);
+
+ /**
+ * This API can be used by only CTS to update the timeout duration in milliseconds that
+ * satellite should stay at listening mode to wait for the next incoming page before disabling
+ * listening mode.
+ *
+ * @param timeoutMillis The timeout duration in millisecond.
+ * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+ */
+ boolean setSatelliteListeningTimeoutDuration(in long timeoutMillis);
}
diff --git a/tests/SilkFX/res/drawable-nodpi/dark_gradient.xml b/tests/SilkFX/res/drawable-nodpi/dark_gradient.xml
index d2653d0..f20dd42 100644
--- a/tests/SilkFX/res/drawable-nodpi/dark_gradient.xml
+++ b/tests/SilkFX/res/drawable-nodpi/dark_gradient.xml
@@ -18,6 +18,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#000000"
- android:endColor="#181818"
+ android:endColor="#222222"
android:angle="0"/>
</shape>
\ No newline at end of file