diff options
27 files changed, 325 insertions, 144 deletions
diff --git a/api/current.txt b/api/current.txt index eb244e4cd1eb..8ec7594773af 100644 --- a/api/current.txt +++ b/api/current.txt @@ -41758,7 +41758,7 @@ package android.service.voice { method public int getDisabledShowContext(); method public static boolean isActiveService(android.content.Context, android.content.ComponentName); method public android.os.IBinder onBind(android.content.Intent); - method @Nullable public java.util.Set<java.lang.String> onGetSupportedVoiceActions(@NonNull java.util.Set<java.lang.String>); + method @NonNull public java.util.Set<java.lang.String> onGetSupportedVoiceActions(@NonNull java.util.Set<java.lang.String>); method public void onLaunchVoiceAssistFromKeyguard(); method public void onReady(); method public void onShutdown(); diff --git a/api/system-current.txt b/api/system-current.txt index d15d00682817..c031429b6d8a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -604,7 +604,7 @@ package android.app { public final class Vr2dDisplayProperties implements android.os.Parcelable { ctor public Vr2dDisplayProperties(int, int, int); method public int describeContents(); - method public void dump(java.io.PrintWriter, String); + method public void dump(@NonNull java.io.PrintWriter, @NonNull String); method public int getAddedFlags(); method public int getDpi(); method public int getHeight(); @@ -615,26 +615,26 @@ package android.app { field public static final int FLAG_VIRTUAL_DISPLAY_ENABLED = 1; // 0x1 } - public static class Vr2dDisplayProperties.Builder { + public static final class Vr2dDisplayProperties.Builder { ctor public Vr2dDisplayProperties.Builder(); - method public android.app.Vr2dDisplayProperties.Builder addFlags(int); - method public android.app.Vr2dDisplayProperties build(); - method public android.app.Vr2dDisplayProperties.Builder removeFlags(int); - method public android.app.Vr2dDisplayProperties.Builder setDimensions(int, int, int); - method public android.app.Vr2dDisplayProperties.Builder setEnabled(boolean); + method @NonNull public android.app.Vr2dDisplayProperties.Builder addFlags(int); + method @NonNull public android.app.Vr2dDisplayProperties build(); + method @NonNull public android.app.Vr2dDisplayProperties.Builder removeFlags(int); + method @NonNull public android.app.Vr2dDisplayProperties.Builder setDimensions(int, int, int); + method @NonNull public android.app.Vr2dDisplayProperties.Builder setEnabled(boolean); } public class VrManager { method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public int getVr2dDisplayId(); method @RequiresPermission(anyOf={android.Manifest.permission.RESTRICTED_VR_ACCESS, "android.permission.ACCESS_VR_STATE"}) public boolean isPersistentVrModeEnabled(); method @RequiresPermission(anyOf={android.Manifest.permission.RESTRICTED_VR_ACCESS, "android.permission.ACCESS_VR_STATE"}) public boolean isVrModeEnabled(); - method @RequiresPermission(anyOf={android.Manifest.permission.RESTRICTED_VR_ACCESS, "android.permission.ACCESS_VR_STATE"}) public void registerVrStateCallback(@NonNull java.util.concurrent.Executor, android.app.VrStateCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.RESTRICTED_VR_ACCESS, "android.permission.ACCESS_VR_STATE"}) public void registerVrStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.app.VrStateCallback); method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setAndBindVrCompositor(android.content.ComponentName); method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setPersistentVrModeEnabled(boolean); method @RequiresPermission("android.permission.ACCESS_VR_MANAGER") public void setStandbyEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setVr2dDisplayProperties(android.app.Vr2dDisplayProperties); - method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setVrInputMethod(android.content.ComponentName); - method @RequiresPermission(anyOf={android.Manifest.permission.RESTRICTED_VR_ACCESS, "android.permission.ACCESS_VR_STATE"}) public void unregisterVrStateCallback(android.app.VrStateCallback); + method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setVr2dDisplayProperties(@NonNull android.app.Vr2dDisplayProperties); + method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setVrInputMethod(@Nullable android.content.ComponentName); + method @RequiresPermission(anyOf={android.Manifest.permission.RESTRICTED_VR_ACCESS, "android.permission.ACCESS_VR_STATE"}) public void unregisterVrStateCallback(@NonNull android.app.VrStateCallback); } public abstract class VrStateCallback { diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java index bcb8592183e9..fc200bf05253 100644 --- a/core/java/android/app/Vr2dDisplayProperties.java +++ b/core/java/android/app/Vr2dDisplayProperties.java @@ -17,6 +17,7 @@ package android.app; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -136,7 +137,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Prints out dump info. */ - public void dump(PrintWriter pw, String prefix) { + public void dump(@NonNull PrintWriter pw, @NonNull String prefix) { pw.println(prefix + toString()); } @@ -188,7 +189,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Convenience class for creating Vr2dDisplayProperties. */ - public static class Builder { + public static final class Builder { private int mAddedFlags = 0; private int mRemovedFlags = 0; @@ -203,6 +204,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Sets the dimensions to use for the virtual display. */ + @NonNull public Builder setDimensions(int width, int height, int dpi) { mWidth = width; mHeight = height; @@ -213,6 +215,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Toggles the virtual display functionality for 2D activities in VR. */ + @NonNull public Builder setEnabled(boolean enabled) { if (enabled) { addFlags(FLAG_VIRTUAL_DISPLAY_ENABLED); @@ -225,6 +228,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Adds property flags. */ + @NonNull public Builder addFlags(@Vr2dDisplayFlag int flags) { mAddedFlags |= flags; mRemovedFlags &= ~flags; @@ -234,6 +238,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Removes property flags. */ + @NonNull public Builder removeFlags(@Vr2dDisplayFlag int flags) { mRemovedFlags |= flags; mAddedFlags &= ~flags; @@ -243,6 +248,7 @@ public final class Vr2dDisplayProperties implements Parcelable { /** * Builds the Vr2dDisplayProperty instance. */ + @NonNull public Vr2dDisplayProperties build() { return new Vr2dDisplayProperties(mWidth, mHeight, mDpi, mAddedFlags, mRemovedFlags); } diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java index 5f1a94c835c3..c74f8c389c20 100644 --- a/core/java/android/app/VrManager.java +++ b/core/java/android/app/VrManager.java @@ -2,6 +2,7 @@ package android.app; import android.annotation.CallbackExecutor; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; @@ -71,7 +72,7 @@ public class VrManager { android.Manifest.permission.ACCESS_VR_STATE }) public void registerVrStateCallback(@NonNull @CallbackExecutor Executor executor, - VrStateCallback callback) { + @NonNull VrStateCallback callback) { if (callback == null || mCallbackMap.containsKey(callback)) { return; } @@ -99,7 +100,7 @@ public class VrManager { android.Manifest.permission.RESTRICTED_VR_ACCESS, android.Manifest.permission.ACCESS_VR_STATE }) - public void unregisterVrStateCallback(VrStateCallback callback) { + public void unregisterVrStateCallback(@NonNull VrStateCallback callback) { CallbackEntry entry = mCallbackMap.remove(callback); if (entry != null) { try { @@ -175,7 +176,7 @@ public class VrManager { */ @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setVr2dDisplayProperties( - Vr2dDisplayProperties vr2dDisplayProp) { + @NonNull Vr2dDisplayProperties vr2dDisplayProp) { try { mService.setVr2dDisplayProperties(vr2dDisplayProp); } catch (RemoteException e) { @@ -220,7 +221,7 @@ public class VrManager { * @param componentName not used */ @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) - public void setVrInputMethod(ComponentName componentName) { + public void setVrInputMethod(@Nullable ComponentName componentName) { } /** diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index cc39e56a556b..335ed212ae71 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1531,6 +1531,9 @@ public final class Settings { /** * Activity Action: Show More default apps settings. * <p> + * If a Settings activity handles this intent action, a "More defaults" entry will be shown in + * the Default apps settings, and clicking it will launch that activity. + * <p> * In some cases, a matching Activity may not exist, so ensure you safeguard against this. * <p> * Input: Nothing. diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index e3e63e539591..0de17ca3b960 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -17,7 +17,6 @@ package android.service.voice; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.UnsupportedAppUsage; import android.app.Service; @@ -41,6 +40,7 @@ import com.android.internal.util.function.pooled.PooledLambda; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Set; @@ -211,11 +211,11 @@ public class VoiceInteractionService extends Service { * * @param voiceActions A set of checked voice actions. * @return Returns a subset of checked voice actions. Additional voice actions in the - * returned set will be ignored. Returns null or empty set if no actions are supported. + * returned set will be ignored. Returns empty set if no actions are supported. */ - @Nullable + @NonNull public Set<String> onGetSupportedVoiceActions(@NonNull Set<String> voiceActions) { - return null; + return Collections.emptySet(); } @Override @@ -272,7 +272,7 @@ public class VoiceInteractionService extends Service { try { Set<String> voiceActionsSet = new ArraySet<>(voiceActions); Set<String> resultSet = onGetSupportedVoiceActions(voiceActionsSet); - callback.onComplete(resultSet == null ? null : new ArrayList<>(resultSet)); + callback.onComplete(new ArrayList<>(resultSet)); } catch (RemoteException e) { } } diff --git a/core/jni/android_nio_utils.cpp b/core/jni/android_nio_utils.cpp index 19a1c7212fae..a62dd7c4048f 100644 --- a/core/jni/android_nio_utils.cpp +++ b/core/jni/android_nio_utils.cpp @@ -18,42 +18,51 @@ #include "core_jni_helpers.h" -void* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) { - assert(array); +namespace { +void* getPointer(JNIEnv *_env, jobject buffer, jarray *array, void** elements) { + assert(array); jint position; jint limit; jint elementSizeShift; jlong pointer = jniGetNioBufferFields(_env, buffer, &position, &limit, &elementSizeShift); if (pointer != 0L) { + *array = nullptr; + *elements = nullptr; pointer += position << elementSizeShift; return reinterpret_cast<void*>(pointer); } - jint offset = jniGetNioBufferBaseArrayOffset(_env, buffer); *array = jniGetNioBufferBaseArray(_env, buffer); - void * data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - return reinterpret_cast<void*>(reinterpret_cast<char*>(data) + offset); + *elements = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); + return reinterpret_cast<void*>(reinterpret_cast<char*>(*elements) + offset); } +void releasePointer(JNIEnv *_env, jarray array, void *elements, jboolean commit) { + _env->ReleasePrimitiveArrayCritical(array, elements, commit ? 0 : JNI_ABORT); +} + +} // namespace + +void* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) { + void* elements; + return getPointer(_env, buffer, array, &elements); +} -void android::nio_releasePointer(JNIEnv *_env, jarray array, void *data, - jboolean commit) { - _env->ReleasePrimitiveArrayCritical(array, data, - commit ? 0 : JNI_ABORT); +void android::nio_releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit) { + releasePointer(_env, array, data, commit); } /////////////////////////////////////////////////////////////////////////////// -android::AutoBufferPointer::AutoBufferPointer(JNIEnv* env, jobject nioBuffer, - jboolean commit) { +android::AutoBufferPointer::AutoBufferPointer(JNIEnv* env, jobject nioBuffer, jboolean commit) { fEnv = env; fCommit = commit; - fPointer = android::nio_getPointer(env, nioBuffer, &fArray); + fPointer = getPointer(env, nioBuffer, &fArray, &fElements); } android::AutoBufferPointer::~AutoBufferPointer() { - if (NULL != fArray) { - android::nio_releasePointer(fEnv, fArray, fPointer, fCommit); + if (nullptr != fArray) { + releasePointer(fEnv, fArray, fElements, fCommit); } } diff --git a/core/jni/android_nio_utils.h b/core/jni/android_nio_utils.h index c634cb917719..7c9acd2638da 100644 --- a/core/jni/android_nio_utils.h +++ b/core/jni/android_nio_utils.h @@ -20,7 +20,7 @@ #include <android_runtime/AndroidRuntime.h> namespace android { - + /** * Given an nio.Buffer, return a pointer to it, beginning at its current * position. The returned pointer is only valid for the current JNI stack-frame. @@ -63,9 +63,10 @@ public: private: JNIEnv* fEnv; - void* fPointer; - jarray fArray; - jboolean fCommit; + void* fPointer; // pointer to current buffer position. + void* fElements; // pointer to array element 0 (may be directly in fArray or a copy). + jarray fArray; // pointer to array on managed heap. + jboolean fCommit; // commit data to source if required (when fElements is a copy of fArray). }; } /* namespace android */ diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml index 371bcfef7ec9..9fa7c5498ea6 100644 --- a/core/res/res/anim/activity_close_enter.xml +++ b/core/res/res/anim/activity_close_enter.xml @@ -19,15 +19,16 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <translate - android:fromYDelta="-2%" - android:toYDelta="0" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="425"/> - <alpha - android:fromAlpha="0.9" - android:toAlpha="1.0" - android:interpolator="@interpolator/activity_close_dim" - android:startOffset="0" - android:duration="425"/> + <scale + android:fromXScale="1.1" + android:toXScale="1" + android:fromYScale="1.1" + android:toYScale="1" + android:pivotX="50%" + android:pivotY="50%" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:duration="400"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml index d87f1003def5..1599ae8cb19f 100644 --- a/core/res/res/anim/activity_close_exit.xml +++ b/core/res/res/anim/activity_close_exit.xml @@ -20,25 +20,25 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false" android:zAdjustment="top"> - <translate - android:fromYDelta="0" - android:toYDelta="4.1%" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="425"/> - <cliprect - android:fromLeft="0%" - android:fromTop="0%" - android:fromRight="100%" - android:fromBottom="100%" - android:toLeft="0%" - android:toTop="95.9%" - android:toRight="100%" - android:toBottom="100%" - android:interpolator="@interpolator/fast_out_extra_slow_in" - android:duration="425"/> <alpha - android:fromAlpha="1.0" - android:toAlpha="1.0" - android:interpolator="@interpolator/fast_out_linear_in" - android:duration="425"/> + android:fromAlpha="1" + android:toAlpha="0.0" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" + android:interpolator="@interpolator/linear" + android:startOffset="33" + android:duration="50"/> + <scale + android:fromXScale="1" + android:toXScale="0.9" + android:fromYScale="1" + android:toYScale="0.9" + android:pivotX="50%" + android:pivotY="50%" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:duration="400"/> </set> diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml index cb0307026e2f..38d3e8ed06ce 100644 --- a/core/res/res/anim/activity_open_enter.xml +++ b/core/res/res/anim/activity_open_enter.xml @@ -18,20 +18,25 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <translate - android:fromYDelta="4.1%" - android:toYDelta="0" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="425"/> - <cliprect - android:fromLeft="0%" - android:fromTop="95.9%" - android:fromRight="100%" - android:fromBottom="100%" - android:toLeft="0%" - android:toTop="0%" - android:toRight="100%" - android:toBottom="100%" + <alpha + android:fromAlpha="0" + android:toAlpha="1.0" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" + android:interpolator="@interpolator/linear" + android:startOffset="50" + android:duration="50"/> + <scale + android:fromXScale="0.85" + android:toXScale="1" + android:fromYScale="0.85" + android:toYScale="1" + android:pivotX="50%" + android:pivotY="50%" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" android:interpolator="@interpolator/fast_out_extra_slow_in" - android:duration="425"/> + android:duration="400"/> </set> diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml index d52b150391fb..3865d2149f42 100644 --- a/core/res/res/anim/activity_open_exit.xml +++ b/core/res/res/anim/activity_open_exit.xml @@ -18,14 +18,28 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <translate - android:fromYDelta="0" - android:toYDelta="-2%" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="425"/> + + <!-- Fade out, over a black surface, which simulates a black scrim --> <alpha - android:fromAlpha="1.0" - android:toAlpha="0.9" + android:fromAlpha="1" + android:toAlpha="0.4" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" android:interpolator="@interpolator/linear" - android:duration="117"/> + android:startOffset="83" + android:duration="167"/> + + <scale + android:fromXScale="1" + android:toXScale="1.05" + android:fromYScale="1" + android:toYScale="1.05" + android:pivotX="50%" + android:pivotY="50%" + android:fillEnabled="true" + android:fillBefore="true" + android:fillAfter="true" + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:duration="400"/> </set>
\ No newline at end of file diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml index 3c9ffdb8e439..f3ca0af767b1 100644 --- a/core/res/res/layout/chooser_grid_preview_text.xml +++ b/core/res/res/layout/chooser_grid_preview_text.xml @@ -24,9 +24,9 @@ android:layout_height="wrap_content" android:orientation="vertical" android:paddingBottom="@dimen/chooser_view_spacing" - android:background="?attr/colorBackgroundFloating"> + android:background="?android:attr/colorBackgroundFloating"> - <LinearLayout + <RelativeLayout android:layout_width="@dimen/chooser_preview_width" android:layout_height="wrap_content" android:layout_gravity="center" @@ -35,28 +35,51 @@ android:paddingRight="@dimen/chooser_edge_margin_normal" android:layout_marginBottom="@dimen/chooser_view_spacing" android:id="@+id/content_preview_text_layout"> + <TextView android:id="@+id/content_preview_text" - android:layout_width="0dp" - android:layout_weight="1" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" + android:layout_alignParentStart="true" + android:layout_toStartOf="@id/copy_button" + android:layout_centerVertical="true" android:ellipsize="end" - android:gravity="start|top" - android:paddingRight="@dimen/chooser_view_spacing" + android:textColor="?android:attr/textColorPrimary" android:maxLines="2"/> - <ImageButton + + <LinearLayout android:id="@+id/copy_button" - android:layout_width="48dp" - android:layout_height="48dp" - android:padding="12dp" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_alignParentEnd="true" + android:layout_marginStart="@dimen/chooser_view_spacing" android:gravity="center" - android:layout_gravity="center_vertical" - android:src="@drawable/ic_content_copy_gm2" + android:minWidth="48dp" + android:minHeight="48dp" android:clickable="true" - android:contentDescription="@string/copy" - android:background="?attr/selectableItemBackgroundBorderless"/> - </LinearLayout> + android:background="?android:attr/selectableItemBackgroundBorderless"> + + <ImageView + android:layout_width="24dp" + android:layout_height="24dp" + android:gravity="top|center_horizontal" + android:src="@drawable/ic_content_copy_gm2" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:gravity="center_horizontal" + android:text="@string/copy" + android:textColor="?android:textColorSecondary" + android:textSize="12sp" + android:maxWidth="72dp" + android:maxLines="2" + android:ellipsize="end" /> + </LinearLayout> + </RelativeLayout> <!-- Required sub-layout so we can get the nice rounded corners--> <!-- around this section --> @@ -89,7 +112,8 @@ android:layout_gravity="center_vertical" android:ellipsize="end" android:maxLines="2" - android:textSize="20sp"/> + android:textSize="20sp" + android:textColor="?android:attr/textColorPrimary"/> </LinearLayout> </LinearLayout> diff --git a/core/tests/coretests/src/android/graphics/BitmapTest.java b/core/tests/coretests/src/android/graphics/BitmapTest.java index d2a1dd9a7b5c..4bee24385cc5 100644 --- a/core/tests/coretests/src/android/graphics/BitmapTest.java +++ b/core/tests/coretests/src/android/graphics/BitmapTest.java @@ -22,6 +22,8 @@ import androidx.test.filters.SmallTest; import junit.framework.TestCase; +import java.nio.ByteBuffer; + public class BitmapTest extends TestCase { @SmallTest @@ -262,4 +264,74 @@ public class BitmapTest extends TestCase { assertFalse(hardwareBitmap.isMutable()); assertEquals(ColorSpace.get(ColorSpace.Named.DISPLAY_P3), hardwareBitmap.getColorSpace()); } + + @SmallTest + public void testCopyWithDirectBuffer() { + // Initialize Bitmap + final int width = 2; + final int height = 2; + Bitmap bm1 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + bm1.setPixels(new int[] { 0xff, 0xeeee, 0xdddddd, 0xcccccccc }, 0, 2, 0, 0, 2, 2); + + // Copy bytes to direct buffer, buffer is padded by fixed amount (pad bytes) either side + // of bitmap. + final int pad = 1; + final byte padValue = 0x5a; + final int bufferSize = pad + width * height * 2 + pad; + ByteBuffer directBuffer = ByteBuffer.allocateDirect(bufferSize); + + // Write padding + directBuffer.put(0, padValue); + directBuffer.put(directBuffer.limit() - 1, padValue); + + // Copy bitmap + directBuffer.position(pad); + bm1.copyPixelsToBuffer(directBuffer); + assertEquals(directBuffer.position(), pad + width * height * 2); + + // Check padding + assertEquals(directBuffer.get(0), padValue); + assertEquals(directBuffer.get(directBuffer.limit() - 1), padValue); + + // Create bitmap from direct buffer and check match. + directBuffer.position(pad); + Bitmap bm2 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + bm2.copyPixelsFromBuffer(directBuffer); + assertTrue(bm2.sameAs(bm1)); + } + + @SmallTest + public void testCopyWithHeapBuffer() { + // Initialize Bitmap + final int width = 2; + final int height = 2; + Bitmap bm1 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + bm1.setPixels(new int[] { 0xff, 0xeeee, 0xdddddd, 0xcccccccc }, 0, 2, 0, 0, 2, 2); + + // Copy bytes to heap buffer, buffer is padded by fixed amount (pad bytes) either side + // of bitmap. + final int pad = 1; + final byte padValue = 0x5a; + final int bufferSize = pad + width * height * 2 + pad; + ByteBuffer heapBuffer = ByteBuffer.allocate(bufferSize); + + // Write padding + heapBuffer.put(0, padValue); + heapBuffer.put(heapBuffer.limit() - 1, padValue); + + // Copy bitmap + heapBuffer.position(pad); + bm1.copyPixelsToBuffer(heapBuffer); + assertEquals(heapBuffer.position(), pad + width * height * 2); + + // Check padding + assertEquals(heapBuffer.get(0), padValue); + assertEquals(heapBuffer.get(heapBuffer.limit() - 1), padValue); + + // Create bitmap from heap buffer and check match. + heapBuffer.position(pad); + Bitmap bm2 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + bm2.copyPixelsFromBuffer(heapBuffer); + assertTrue(bm2.sameAs(bm1)); + } } diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java index ebbbdec7d376..bdd3038cfee5 100644 --- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java +++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java @@ -39,11 +39,13 @@ import android.platform.test.annotations.Presubmit; import android.util.SparseArray; import android.view.SurfaceControl.Transaction; import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; +import android.view.test.InsetsModeSession; -import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -62,7 +64,6 @@ import java.util.List; * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}. */ @Presubmit -@FlakyTest(detail = "Promote once confirmed non-flaky") @RunWith(AndroidJUnit4.class) public class InsetsAnimationControlImplTest { @@ -72,15 +73,25 @@ public class InsetsAnimationControlImplTest { private SurfaceControl mTopLeash; private SurfaceControl mNavLeash; private InsetsState mInsetsState; + private static InsetsModeSession sInsetsModeSession; @Mock Transaction mMockTransaction; @Mock InsetsController mMockController; @Mock WindowInsetsAnimationControlListener mMockListener; @Mock SyncRtSurfaceTransactionApplier mMockTransactionApplier; + @BeforeClass + public static void setupOnce() { + sInsetsModeSession = new InsetsModeSession(NEW_INSETS_MODE_FULL); + } + + @AfterClass + public static void tearDownOnce() throws Exception { + sInsetsModeSession.close(); + } + @Before public void setup() { - ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL; MockitoAnnotations.initMocks(this); mTopLeash = new SurfaceControl.Builder(mSession) .setName("testSurface") diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index 4d8d3f68f875..1e558287e21b 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -43,7 +43,6 @@ import android.view.WindowManager.LayoutParams; import android.widget.TextView; import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; @@ -63,7 +62,6 @@ import java.util.concurrent.CountDownLatch; * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}. */ @Presubmit -@FlakyTest(detail = "Promote once confirmed non-flaky") @RunWith(AndroidJUnit4.class) public class InsetsControllerTest { diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java index a32fa778e736..971e143927b3 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java @@ -34,7 +34,6 @@ import android.view.WindowManager.LayoutParams; import android.widget.TextView; import androidx.test.InstrumentationRegistry; -import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; @@ -53,7 +52,6 @@ import org.mockito.MockitoAnnotations; * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}. */ @Presubmit -@FlakyTest(detail = "Promote once confirmed non-flaky") @RunWith(AndroidJUnit4.class) public class InsetsSourceConsumerTest { diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java index b55a9c600a61..533a58ef1dfb 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java @@ -24,7 +24,6 @@ import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; -import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; @@ -41,7 +40,6 @@ import org.junit.runner.RunWith; * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}. */ @Presubmit -@FlakyTest(detail = "Promote once confirmed non-flaky") @RunWith(AndroidJUnit4.class) public class InsetsSourceTest { diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java index 8e167da84e08..a73269a81b11 100644 --- a/core/tests/coretests/src/android/view/InsetsStateTest.java +++ b/core/tests/coretests/src/android/view/InsetsStateTest.java @@ -40,7 +40,6 @@ import android.util.SparseIntArray; import android.view.WindowInsets.Type; import android.view.test.InsetsModeSession; -import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; @@ -56,7 +55,6 @@ import org.junit.runner.RunWith; * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}. */ @Presubmit -@FlakyTest(detail = "Promote once confirmed non-flaky") @RunWith(AndroidJUnit4.class) public class InsetsStateTest { diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java index 1544adb23175..b2baff5db75b 100644 --- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java +++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java @@ -272,6 +272,9 @@ public class Assistant extends NotificationAssistantService { final int importance = entry.getImportance() < IMPORTANCE_LOW ? entry.getImportance() : IMPORTANCE_LOW; signals.putInt(KEY_IMPORTANCE, importance); + } else { + // Even if no change is made, send an identity adjustment for metric logging. + signals.putInt(KEY_IMPORTANCE, entry.getImportance()); } } diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml index f34161e285da..81d44cfa49dd 100644 --- a/packages/SystemUI/res/layout/qs_tile_label.xml +++ b/packages/SystemUI/res/layout/qs_tile_label.xml @@ -44,8 +44,7 @@ android:padding="0dp" android:gravity="center" android:ellipsize="marquee" - android:textAppearance="@style/TextAppearance.QS.TileLabel" - android:textColor="?android:attr/textColorPrimary"/> + android:textAppearance="@style/TextAppearance.QS.TileLabel"/> <ImageView android:id="@+id/restricted_padlock" android:layout_width="@dimen/qs_tile_text_size" diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java index 91cd65259d73..8a360ee2e4eb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java @@ -15,11 +15,10 @@ package com.android.systemui.qs.tileimpl; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.Configuration; import android.service.quicksettings.Tile; -import android.text.SpannableStringBuilder; import android.text.TextUtils; -import android.text.style.ForegroundColorSpan; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -27,6 +26,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import com.android.settingslib.Utils; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSIconView; @@ -46,6 +46,8 @@ public class QSTileView extends QSTileBaseView { private ViewGroup mLabelContainer; private View mExpandIndicator; private View mExpandSpace; + private ColorStateList mColorLabelDefault; + private ColorStateList mColorLabelUnavailable; public QSTileView(Context context, QSIconView icon) { this(context, icon, false); @@ -62,6 +64,11 @@ public class QSTileView extends QSTileBaseView { createLabel(); setOrientation(VERTICAL); setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); + mColorLabelDefault = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary); + // The text color for unavailable tiles is textColorSecondary, same as secondaryLabel for + // contrast purposes + mColorLabelUnavailable = Utils.getColorAttr(getContext(), + android.R.attr.textColorSecondary); } TextView getLabel() { @@ -111,12 +118,8 @@ public class QSTileView extends QSTileBaseView { protected void handleStateChanged(QSTile.State state) { super.handleStateChanged(state); if (!Objects.equals(mLabel.getText(), state.label) || mState != state.state) { - if (state.state == Tile.STATE_UNAVAILABLE) { - int color = QSTileImpl.getColorForState(getContext(), state.state); - state.label = new SpannableStringBuilder().append(state.label, - new ForegroundColorSpan(color), - SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE); - } + mLabel.setTextColor(state.state == Tile.STATE_UNAVAILABLE ? mColorLabelUnavailable + : mColorLabelDefault); mState = state.state; mLabel.setText(state.label); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index d2b1e8f7151d..c12ee03fb86d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20032,7 +20032,7 @@ public class PackageManagerService extends IPackageManager.Stub PreferredActivity pa = removed.get(j); pir.removeFilter(pa); } - outUserChanged.setValueAt(thisUserId, true); + outUserChanged.put(thisUserId, true); } } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 1934e2508c9b..bd874ba786ed 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -28,6 +28,7 @@ import static android.content.res.Configuration.UI_MODE_TYPE_MASK; import static android.view.InsetsState.TYPE_TOP_BAR; import static android.view.InsetsState.TYPE_TOP_GESTURES; import static android.view.InsetsState.TYPE_TOP_TAPPABLE_ELEMENT; +import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; @@ -1230,7 +1231,7 @@ public class DisplayPolicy { final boolean screenDecor = (pfl & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0; if (layoutInScreenAndInsetDecor && !screenDecor) { - if ((sysUiVis & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { + if ((sysUiVis & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { outFrame.set(displayFrames.mUnrestricted); } else { outFrame.set(displayFrames.mRestricted); @@ -1290,7 +1291,7 @@ public class DisplayPolicy { && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT; if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 || forceWindowDrawsBarBackgrounds) { - impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + impliedFlags |= SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; } return impliedFlags; @@ -1722,6 +1723,22 @@ public class DisplayPolicy { of.set(displayFrames.mDock); df.set(displayFrames.mDock); } else { + + // In case we forced the window to draw behind the navigation bar, restrict df/of to + // DF.RestrictedOverscan to simulate old compat behavior. + Rect parentDisplayFrame = attached.getDisplayFrameLw(); + Rect parentOverscan = attached.getOverscanFrameLw(); + final WindowManager.LayoutParams attachedAttrs = attached.mAttrs; + if ((attachedAttrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0 + && (attachedAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0 + && (attachedAttrs.systemUiVisibility + & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0) { + parentOverscan = new Rect(parentOverscan); + parentOverscan.intersect(displayFrames.mRestrictedOverscan); + parentDisplayFrame = new Rect(parentDisplayFrame); + parentDisplayFrame.intersect(displayFrames.mRestrictedOverscan); + } + // The effective display frame of the attached window depends on whether it is taking // care of insetting its content. If not, we need to use the parent's content frame so // that the entire window is positioned within that content. Otherwise we can use the @@ -1733,7 +1750,7 @@ public class DisplayPolicy { // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag. // Otherwise, use the overscan frame. cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0 - ? attached.getContentFrameLw() : attached.getOverscanFrameLw()); + ? attached.getContentFrameLw() : parentOverscan); } else { // If the window is resizing, then we want to base the content frame on our attached // content frame to resize...however, things can be tricky if the attached window is @@ -1747,8 +1764,8 @@ public class DisplayPolicy { cf.intersectUnchecked(displayFrames.mContent); } } - df.set(insetDecors ? attached.getDisplayFrameLw() : cf); - of.set(insetDecors ? attached.getOverscanFrameLw() : cf); + df.set(insetDecors ? parentDisplayFrame : cf); + of.set(insetDecors ? parentOverscan : cf); vf.set(attached.getVisibleFrameLw()); } // The LAYOUT_IN_SCREEN flag is used to determine whether the attached window should be @@ -1956,7 +1973,7 @@ public class DisplayPolicy { of.set(displayFrames.mOverscan); df.set(displayFrames.mOverscan); pf.set(displayFrames.mOverscan); - } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 + } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW || type == TYPE_VOLUME_OVERLAY)) { // Asking for layout as if the nav bar is hidden, lets the application @@ -2006,7 +2023,7 @@ public class DisplayPolicy { } } else if (layoutInScreen || (sysUiFl & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) { + | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) { if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN"); // A window that has requested to fill the entire screen just @@ -2051,7 +2068,7 @@ public class DisplayPolicy { of.set(displayFrames.mOverscan); df.set(displayFrames.mOverscan); pf.set(displayFrames.mOverscan); - } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 + } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && (type == TYPE_STATUS_BAR || type == TYPE_TOAST || type == TYPE_DOCK_DIVIDER diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d990e6c6c24b..8e18683d3e76 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1305,7 +1305,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void onDisplayChanged(DisplayContent dc) { super.onDisplayChanged(dc); // Window was not laid out for this display yet, so make sure mLayoutSeq does not match. - if (dc != null) { + if (dc != null && mInputWindowHandle.displayId != dc.getDisplayId()) { mLayoutSeq = dc.mLayoutSeq - 1; mInputWindowHandle.displayId = dc.getDisplayId(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 4f8fe5b10f19..715353e5d980 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -397,7 +397,9 @@ public class WindowStateTests extends WindowTestsBase { app.mLayoutSeq = 1; mDisplayContent.mLayoutSeq = 1; - app.onDisplayChanged(mDisplayContent); + DisplayContent newDisplay = createNewDisplay(); + + app.onDisplayChanged(newDisplay); assertThat(app.mLayoutSeq, not(is(mDisplayContent.mLayoutSeq))); } diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java index 71a28b575394..eb568e04ebf3 100644 --- a/telecomm/java/android/telecom/PhoneAccountHandle.java +++ b/telecomm/java/android/telecom/PhoneAccountHandle.java @@ -17,6 +17,7 @@ package android.telecom; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.os.Build; @@ -174,4 +175,21 @@ public final class PhoneAccountHandle implements Parcelable { in.readString(), UserHandle.CREATOR.createFromParcel(in)); } + + /** + * Determines if two {@link PhoneAccountHandle}s are from the same package. + * + * @param a Phone account handle to check for same {@link ConnectionService} package. + * @param b Other phone account handle to check for same {@link ConnectionService} package. + * @return {@code true} if the two {@link PhoneAccountHandle}s passed in belong to the same + * {@link ConnectionService} / package, {@code false} otherwise. Note: {@code null} phone + * account handles are considered equivalent to other {@code null} phone account handles. + * @hide + */ + public static boolean areFromSamePackage(@Nullable PhoneAccountHandle a, + @Nullable PhoneAccountHandle b) { + String aPackageName = a != null ? a.getComponentName().getPackageName() : null; + String bPackageName = b != null ? b.getComponentName().getPackageName() : null; + return Objects.equals(aPackageName, bPackageName); + } } |