summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java2
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/util/proto/ProtoOutputStream.java11
-rw-r--r--core/java/android/util/proto/ProtoStream.java76
-rw-r--r--core/java/android/view/InsetsAnimationControlImpl.java5
-rw-r--r--core/java/android/view/View.java49
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java204
-rw-r--r--core/java/com/android/internal/widget/ObservableTextView.java66
-rw-r--r--core/proto/android/app/settings_enums.proto12
-rw-r--r--core/res/res/layout/conversation_face_pile_layout.xml22
-rw-r--r--core/res/res/layout/notification_template_material_conversation.xml3
-rw-r--r--core/res/res/values/dimens.xml29
-rw-r--r--core/res/res/values/symbols.xml16
-rw-r--r--data/etc/privapp-permissions-platform.xml5
-rw-r--r--media/java/android/media/tv/tuner/filter/Filter.java23
-rw-r--r--media/jni/android_media_tv_Tuner.cpp131
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java5
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java6
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/Shell/AndroidManifest.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt20
-rw-r--r--packages/Tethering/AndroidManifest.xml2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java27
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java2
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java4
-rwxr-xr-xwifi/java/android/net/wifi/WifiMigration.java11
29 files changed, 579 insertions, 175 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c2ee21d5115d..7c34ddcb9287 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -878,7 +878,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
private void notifyImeHidden() {
- doHideWindow();
+ requestHideSelf(0);
}
private void removeImeSurface() {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a28ea899694c..ccc3132c535d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10338,6 +10338,14 @@ public final class Settings {
public static final String WIFI_WAKEUP_ENABLED = "wifi_wakeup_enabled";
/**
+ * Value to specify if wifi settings migration is complete or not.
+ *
+ * Type: int (0 for false, 1 for true)
+ * @hide
+ */
+ public static final String WIFI_MIGRATION_COMPLETED = "wifi_migration_completed";
+
+ /**
* Value to specify whether network quality scores and badging should be shown in the UI.
*
* Type: int (0 for false, 1 for true)
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index 9a555c161300..2c260f6b8cbe 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -201,7 +201,9 @@ public final class ProtoOutputStream extends ProtoStream {
}
/**
- * Returns the uncompressed buffer size
+ * Returns the total size of the data that has been written, after full
+ * protobuf encoding has occurred.
+ *
* @return the uncompressed buffer size
*/
public int getRawSize() {
@@ -2271,9 +2273,12 @@ public final class ProtoOutputStream extends ProtoStream {
}
/**
- * Write a field tag to the stream.
+ * Write an individual field tag by hand.
+ *
+ * @see See <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a> for details on the structure of how tags and data are written.
*/
- public void writeTag(int id, int wireType) {
+ public void writeTag(int id, @WireType int wireType) {
mBuffer.writeRawVarint32((id << FIELD_ID_SHIFT) | wireType);
}
diff --git a/core/java/android/util/proto/ProtoStream.java b/core/java/android/util/proto/ProtoStream.java
index 4969d8a7fbe7..1940da907973 100644
--- a/core/java/android/util/proto/ProtoStream.java
+++ b/core/java/android/util/proto/ProtoStream.java
@@ -16,9 +16,14 @@
package android.util.proto;
+import android.annotation.IntDef;
+import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Base utility class for protobuf streams.
*
@@ -30,6 +35,71 @@ import android.annotation.Nullable;
public class ProtoStream {
/**
+ * A protobuf wire type. All application-level types are represented using
+ * varint, fixed64, length-delimited and fixed32 wire types. The start-group
+ * and end-group types are unused in modern protobuf versions (proto2 and proto3),
+ * but are included here for completeness.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ WIRE_TYPE_VARINT,
+ WIRE_TYPE_FIXED64,
+ WIRE_TYPE_LENGTH_DELIMITED,
+ WIRE_TYPE_START_GROUP,
+ WIRE_TYPE_END_GROUP,
+ WIRE_TYPE_FIXED32
+ })
+ public @interface WireType {}
+
+ /**
+ * Application-level protobuf field types, as would be used in a .proto file.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @LongDef({
+ FIELD_TYPE_UNKNOWN,
+ FIELD_TYPE_DOUBLE,
+ FIELD_TYPE_FLOAT,
+ FIELD_TYPE_INT64,
+ FIELD_TYPE_UINT64,
+ FIELD_TYPE_INT32,
+ FIELD_TYPE_FIXED64,
+ FIELD_TYPE_FIXED32,
+ FIELD_TYPE_BOOL,
+ FIELD_TYPE_STRING,
+ FIELD_TYPE_MESSAGE,
+ FIELD_TYPE_BYTES,
+ FIELD_TYPE_UINT32,
+ FIELD_TYPE_ENUM,
+ FIELD_TYPE_SFIXED32,
+ FIELD_TYPE_SFIXED64,
+ FIELD_TYPE_SINT32,
+ FIELD_TYPE_SINT64,
+ })
+ public @interface FieldType {}
+
+
+ /**
+ * Represents the cardinality of a protobuf field.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @LongDef({
+ FIELD_COUNT_UNKNOWN,
+ FIELD_COUNT_SINGLE,
+ FIELD_COUNT_REPEATED,
+ FIELD_COUNT_PACKED,
+ })
+ public @interface FieldCount {}
+
+ /**
* Number of bits to shift the field number to form a tag.
*
* <pre>
@@ -128,7 +198,7 @@ public class ProtoStream {
public static final long FIELD_TYPE_MASK = 0x0ffL << FIELD_TYPE_SHIFT;
/**
- * Not a real wire type.
+ * Not a real field type.
* @hide
*/
public static final long FIELD_TYPE_UNKNOWN = 0;
@@ -378,7 +448,7 @@ public class ProtoStream {
/**
* Get the developer-usable name of a field type.
*/
- public static @Nullable String getFieldTypeString(long fieldType) {
+ public static @Nullable String getFieldTypeString(@FieldType long fieldType) {
int index = ((int) ((fieldType & FIELD_TYPE_MASK) >>> FIELD_TYPE_SHIFT)) - 1;
if (index >= 0 && index < FIELD_TYPE_NAMES.length) {
return FIELD_TYPE_NAMES[index];
@@ -405,7 +475,7 @@ public class ProtoStream {
/**
* Get the developer-usable name of a wire type.
*/
- public static @Nullable String getWireTypeString(int wireType) {
+ public static @Nullable String getWireTypeString(@WireType int wireType) {
switch (wireType) {
case WIRE_TYPE_VARINT:
return "Varint";
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index f827eda07901..b70072877c66 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -196,11 +196,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
if (mCancelled || mFinished) {
return;
}
+ mShownOnFinish = shown;
setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */);
mFinished = true;
mListener.onFinished(this);
-
- mShownOnFinish = shown;
}
@Override
@@ -301,7 +300,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
.withAlpha(side == ISIDE_FLOATING ? 1 : alpha)
.withMatrix(mTmpMatrix)
.withVisibility(side == ISIDE_FLOATING
- ? state.getSource(source.getType()).isVisible()
+ ? mShownOnFinish
: inset != 0 /* visible */)
.build();
surfaceParams.add(params);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 708a09467247..fcab9d11f3d6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9581,18 +9581,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// First check if context has client, so it saves a service lookup when it doesn't
if (mContext.getContentCaptureOptions() == null) return;
- // Then check if it's enabled in the context...
- final ContentCaptureManager ccm = ai != null ? ai.getContentCaptureManager(mContext)
- : mContext.getSystemService(ContentCaptureManager.class);
- if (ccm == null || !ccm.isContentCaptureEnabled()) return;
-
- // ... and finally at the view level
- // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled()
- if (!isImportantForContentCapture()) return;
-
- ContentCaptureSession session = getContentCaptureSession();
- if (session == null) return;
-
if (appeared) {
if (!isLaidOut() || getVisibility() != VISIBLE
|| (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) {
@@ -9601,21 +9589,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
+ isLaidOut() + ", visibleToUser=" + isVisibleToUser()
+ ", visible=" + (getVisibility() == VISIBLE)
+ ": alreadyNotifiedAppeared=" + ((mPrivateFlags4
- & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
+ ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4
- & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
}
return;
}
- setNotifiedContentCaptureAppeared();
-
- if (ai != null) {
- ai.delayNotifyContentCaptureEvent(session, this, appeared);
- } else {
- if (DEBUG_CONTENT_CAPTURE) {
- Log.w(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on appeared for " + this);
- }
- }
} else {
if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) == 0
|| (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0) {
@@ -9624,12 +9603,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
+ isLaidOut() + ", visibleToUser=" + isVisibleToUser()
+ ", visible=" + (getVisibility() == VISIBLE)
+ ": alreadyNotifiedAppeared=" + ((mPrivateFlags4
- & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
+ ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4
- & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
}
return;
}
+ }
+
+ ContentCaptureSession session = getContentCaptureSession();
+ if (session == null) return;
+
+ // ... and finally at the view level
+ // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled()
+ if (!isImportantForContentCapture()) return;
+
+ if (appeared) {
+ setNotifiedContentCaptureAppeared();
+
+ if (ai != null) {
+ ai.delayNotifyContentCaptureEvent(session, this, appeared);
+ } else {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on appeared for " + this);
+ }
+ }
+ } else {
mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 4e7ae8a235e7..bedf55d52391 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -93,7 +93,6 @@ public class ConversationLayout extends FrameLayout
private MessagingLinearLayout mMessagingLinearLayout;
private boolean mShowHistoricMessages;
private ArrayList<MessagingGroup> mGroups = new ArrayList<>();
- private TextView mTitleView;
private int mLayoutColor;
private int mSenderTextColor;
private int mMessageTextColor;
@@ -108,8 +107,14 @@ public class ConversationLayout extends FrameLayout
private boolean mIsCollapsed;
private ImageResolver mImageResolver;
private ImageView mConversationIcon;
+ private View mConversationIconContainer;
+ private int mConversationIconTopPadding;
+ private int mConversationIconTopPaddingExpandedGroup;
+ private int mConversationIconTopPaddingNoAppName;
+ private int mExpandedGroupMessagePaddingNoAppName;
private TextView mConversationText;
private View mConversationIconBadge;
+ private ImageView mConversationIconBadgeBg;
private Icon mLargeIcon;
private View mExpandButtonContainer;
private ViewGroup mExpandButtonAndContentContainer;
@@ -117,11 +122,12 @@ public class ConversationLayout extends FrameLayout
private MessagingLinearLayout mImageMessageContainer;
private int mExpandButtonExpandedTopMargin;
private int mBadgedSideMargins;
- private int mIconSizeBadged;
- private int mIconSizeCentered;
+ private int mConversationAvatarSize;
+ private int mConversationAvatarSizeExpanded;
private CachingIconView mIcon;
private View mImportanceRingView;
- private int mExpandedGroupTopMargin;
+ private int mExpandedGroupSideMargin;
+ private int mExpandedGroupSideMarginFacePile;
private View mConversationFacePile;
private int mNotificationBackgroundColor;
private CharSequence mFallbackChatName;
@@ -133,7 +139,12 @@ public class ConversationLayout extends FrameLayout
private boolean mExpandable = true;
private int mContentMarginEnd;
private Rect mMessagingClipRect;
- private TextView mAppName;
+ private ObservableTextView mAppName;
+ private boolean mAppNameGone;
+ private int mFacePileAvatarSize;
+ private int mFacePileAvatarSizeExpandedGroup;
+ private int mFacePileProtectionWidth;
+ private int mFacePileProtectionWidthExpanded;
public ConversationLayout(@NonNull Context context) {
super(context);
@@ -165,14 +176,15 @@ public class ConversationLayout extends FrameLayout
int size = Math.max(displayMetrics.widthPixels, displayMetrics.heightPixels);
mMessagingClipRect = new Rect(0, 0, size, size);
setMessagingClippingDisabled(false);
- mTitleView = findViewById(R.id.title);
mAvatarSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setAntiAlias(true);
mConversationIcon = findViewById(R.id.conversation_icon);
+ mConversationIconContainer = findViewById(R.id.conversation_icon_container);
mIcon = findViewById(R.id.icon);
mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
+ mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg);
mIcon.setOnVisibilityChangedListener((visibility) -> {
// Always keep the badge visibility in sync with the icon. This is necessary in cases
// Where the icon is being hidden externally like in group children.
@@ -192,18 +204,40 @@ public class ConversationLayout extends FrameLayout
R.dimen.notification_content_margin_end);
mBadgedSideMargins = getResources().getDimensionPixelSize(
R.dimen.conversation_badge_side_margin);
- mIconSizeBadged = getResources().getDimensionPixelSize(
- R.dimen.conversation_icon_size_badged);
- mIconSizeCentered = getResources().getDimensionPixelSize(
- R.dimen.conversation_icon_size_centered);
- mExpandedGroupTopMargin = getResources().getDimensionPixelSize(
- R.dimen.conversation_icon_margin_top_centered);
+ mConversationAvatarSize = getResources().getDimensionPixelSize(
+ R.dimen.conversation_avatar_size);
+ mConversationAvatarSizeExpanded = getResources().getDimensionPixelSize(
+ R.dimen.conversation_avatar_size_group_expanded);
+ mConversationIconTopPadding = getResources().getDimensionPixelSize(
+ R.dimen.conversation_icon_container_top_padding);
+ mConversationIconTopPaddingExpandedGroup = getResources().getDimensionPixelSize(
+ R.dimen.conversation_icon_container_top_padding_small_avatar);
+ mConversationIconTopPaddingNoAppName = getResources().getDimensionPixelSize(
+ R.dimen.conversation_icon_container_top_padding_no_app_name);
+ mExpandedGroupMessagePaddingNoAppName = getResources().getDimensionPixelSize(
+ R.dimen.expanded_group_conversation_message_padding_without_app_name);
+ mExpandedGroupSideMargin = getResources().getDimensionPixelSize(
+ R.dimen.conversation_badge_side_margin_group_expanded);
+ mExpandedGroupSideMarginFacePile = getResources().getDimensionPixelSize(
+ R.dimen.conversation_badge_side_margin_group_expanded_face_pile);
mConversationFacePile = findViewById(R.id.conversation_face_pile);
+ mFacePileAvatarSize = getResources().getDimensionPixelSize(
+ R.dimen.conversation_face_pile_avatar_size);
+ mFacePileAvatarSizeExpandedGroup = getResources().getDimensionPixelSize(
+ R.dimen.conversation_face_pile_avatar_size_group_expanded);
+ mFacePileProtectionWidth = getResources().getDimensionPixelSize(
+ R.dimen.conversation_face_pile_protection_width);
+ mFacePileProtectionWidthExpanded = getResources().getDimensionPixelSize(
+ R.dimen.conversation_face_pile_protection_width_expanded);
mFallbackChatName = getResources().getString(
R.string.conversation_title_fallback_one_to_one);
mFallbackGroupChatName = getResources().getString(
R.string.conversation_title_fallback_group_chat);
mAppName = findViewById(R.id.app_name_text);
+ mAppNameGone = mAppName.getVisibility() == GONE;
+ mAppName.setOnVisibilityChangedListener((visibility) -> {
+ onAppNameVisibilityChanged();
+ });
}
@RemotableViewMethod
@@ -234,7 +268,7 @@ public class ConversationLayout extends FrameLayout
mIsCollapsed = isCollapsed;
mMessagingLinearLayout.setMaxDisplayedLines(isCollapsed ? 1 : Integer.MAX_VALUE);
updateExpandButton();
- updateContentPaddings();
+ updateContentEndPaddings();
}
@RemotableViewMethod
@@ -354,21 +388,17 @@ public class ConversationLayout extends FrameLayout
}
}
} else {
- if (mIsCollapsed) {
- if (mLargeIcon != null) {
- mConversationIcon.setVisibility(VISIBLE);
- mConversationFacePile.setVisibility(GONE);
- mConversationIcon.setImageIcon(mLargeIcon);
- } else {
- mConversationIcon.setVisibility(GONE);
- // This will also inflate it!
- mConversationFacePile.setVisibility(VISIBLE);
- mConversationFacePile = findViewById(R.id.conversation_face_pile);
- bindFacePile();
- }
- } else {
+ if (mLargeIcon != null) {
+ mConversationIcon.setVisibility(VISIBLE);
mConversationFacePile.setVisibility(GONE);
+ mConversationIcon.setImageIcon(mLargeIcon);
+ } else {
mConversationIcon.setVisibility(GONE);
+ // This will also inflate it!
+ mConversationFacePile.setVisibility(VISIBLE);
+ // rebind the value to the inflated view instead of the stub
+ mConversationFacePile = findViewById(R.id.conversation_face_pile);
+ bindFacePile();
}
}
if (TextUtils.isEmpty(conversationText)) {
@@ -384,9 +414,10 @@ public class ConversationLayout extends FrameLayout
&& TextUtils.equals(conversationText, messageSender);
messagingGroup.setCanHideSenderIfFirst(canHide);
}
+ updateAppName();
updateIconPositionAndSize();
updateImageMessages();
- updateAppName();
+ updatePaddingsBasedOnContentAvailability();
}
private void updateImageMessages() {
@@ -425,7 +456,7 @@ public class ConversationLayout extends FrameLayout
private void bindFacePile() {
// Let's bind the face pile
- View bottomBackground = mConversationFacePile.findViewById(
+ ImageView bottomBackground = mConversationFacePile.findViewById(
R.id.conversation_face_pile_bottom_background);
applyNotificationBackgroundColor(bottomBackground);
ImageView bottomView = mConversationFacePile.findViewById(
@@ -463,6 +494,38 @@ public class ConversationLayout extends FrameLayout
secondLastIcon = createAvatarSymbol("", "", mLayoutColor);
}
topView.setImageIcon(secondLastIcon);
+
+ int conversationAvatarSize;
+ int facepileAvatarSize;
+ int facePileBackgroundSize;
+ if (mIsCollapsed) {
+ conversationAvatarSize = mConversationAvatarSize;
+ facepileAvatarSize = mFacePileAvatarSize;
+ facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidth;
+ } else {
+ conversationAvatarSize = mConversationAvatarSizeExpanded;
+ facepileAvatarSize = mFacePileAvatarSizeExpandedGroup;
+ facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded;
+ }
+ LayoutParams layoutParams = (LayoutParams) mConversationIcon.getLayoutParams();
+ layoutParams.width = conversationAvatarSize;
+ layoutParams.height = conversationAvatarSize;
+ mConversationFacePile.setLayoutParams(layoutParams);
+
+ layoutParams = (LayoutParams) bottomView.getLayoutParams();
+ layoutParams.width = facepileAvatarSize;
+ layoutParams.height = facepileAvatarSize;
+ bottomView.setLayoutParams(layoutParams);
+
+ layoutParams = (LayoutParams) topView.getLayoutParams();
+ layoutParams.width = facepileAvatarSize;
+ layoutParams.height = facepileAvatarSize;
+ topView.setLayoutParams(layoutParams);
+
+ layoutParams = (LayoutParams) bottomBackground.getLayoutParams();
+ layoutParams.width = facePileBackgroundSize;
+ layoutParams.height = facePileBackgroundSize;
+ bottomBackground.setLayoutParams(layoutParams);
}
private void updateAppName() {
@@ -477,30 +540,61 @@ public class ConversationLayout extends FrameLayout
* update the icon position and sizing
*/
private void updateIconPositionAndSize() {
- int gravity;
- int marginStart;
- int marginTop;
- int iconSize;
+ int sidemargin;
+ int conversationAvatarSize;
if (mIsOneToOne || mIsCollapsed) {
- // Badged format
- gravity = Gravity.LEFT;
- marginStart = mBadgedSideMargins;
- marginTop = mBadgedSideMargins;
- iconSize = mIconSizeBadged;
+ sidemargin = mBadgedSideMargins;
+ conversationAvatarSize = mConversationAvatarSize;
} else {
- gravity = Gravity.CENTER_HORIZONTAL;
- marginStart = 0;
- marginTop = mExpandedGroupTopMargin;
- iconSize = mIconSizeCentered;
+ sidemargin = mConversationFacePile.getVisibility() == VISIBLE
+ ? mExpandedGroupSideMarginFacePile
+ : mExpandedGroupSideMargin;
+ conversationAvatarSize = mConversationAvatarSizeExpanded;
}
LayoutParams layoutParams =
(LayoutParams) mConversationIconBadge.getLayoutParams();
- layoutParams.gravity = gravity;
- layoutParams.topMargin = marginTop;
- layoutParams.setMarginStart(marginStart);
- layoutParams.width = iconSize;
- layoutParams.height = iconSize;
+ layoutParams.topMargin = sidemargin;
+ layoutParams.setMarginStart(sidemargin);
mConversationIconBadge.setLayoutParams(layoutParams);
+
+ if (mConversationIcon.getVisibility() == VISIBLE) {
+ layoutParams = (LayoutParams) mConversationIcon.getLayoutParams();
+ layoutParams.width = conversationAvatarSize;
+ layoutParams.height = conversationAvatarSize;
+ mConversationIcon.setLayoutParams(layoutParams);
+ }
+ }
+
+ private void updatePaddingsBasedOnContentAvailability() {
+ int containerTopPadding;
+ int messagingPadding = 0;
+ if (mIsOneToOne || mIsCollapsed) {
+ containerTopPadding = mConversationIconTopPadding;
+ } else {
+ if (mAppName.getVisibility() != GONE) {
+ // The app name is visible, let's center outselves in the two lines
+ containerTopPadding = mConversationIconTopPaddingExpandedGroup;
+ } else {
+ // App name is gone, let's center ourselves int he one remaining line
+ containerTopPadding = mConversationIconTopPaddingNoAppName;
+
+ // The app name is gone and we're a group, we'll need to add some extra padding
+ // to the messages, since otherwise it will overlap with the group
+ messagingPadding = mExpandedGroupMessagePaddingNoAppName;
+ }
+ }
+
+ mConversationIconContainer.setPaddingRelative(
+ mConversationIconContainer.getPaddingStart(),
+ containerTopPadding,
+ mConversationIconContainer.getPaddingEnd(),
+ mConversationIconContainer.getPaddingBottom());
+
+ mMessagingLinearLayout.setPaddingRelative(
+ mMessagingLinearLayout.getPaddingStart(),
+ messagingPadding,
+ mMessagingLinearLayout.getPaddingEnd(),
+ mMessagingLinearLayout.getPaddingBottom());
}
@RemotableViewMethod
@@ -678,11 +772,11 @@ public class ConversationLayout extends FrameLayout
@RemotableViewMethod
public void setNotificationBackgroundColor(int color) {
mNotificationBackgroundColor = color;
- applyNotificationBackgroundColor(mConversationIconBadge);
+ applyNotificationBackgroundColor(mConversationIconBadgeBg);
}
- private void applyNotificationBackgroundColor(View view) {
- view.setBackgroundTintList(ColorStateList.valueOf(mNotificationBackgroundColor));
+ private void applyNotificationBackgroundColor(ImageView view) {
+ view.setImageTintList(ColorStateList.valueOf(mNotificationBackgroundColor));
}
@RemotableViewMethod
@@ -922,7 +1016,7 @@ public class ConversationLayout extends FrameLayout
mExpandButtonContainer.setContentDescription(mContext.getText(contentDescriptionId));
}
- private void updateContentPaddings() {
+ private void updateContentEndPaddings() {
// Let's make sure the conversation header can't run into the expand button when we're
// collapsed and update the paddings of the content
@@ -951,6 +1045,14 @@ public class ConversationLayout extends FrameLayout
mContentContainer.getPaddingBottom());
}
+ private void onAppNameVisibilityChanged() {
+ boolean appNameGone = mAppName.getVisibility() == GONE;
+ if (appNameGone != mAppNameGone) {
+ mAppNameGone = appNameGone;
+ updatePaddingsBasedOnContentAvailability();
+ }
+ }
+
public void updateExpandability(boolean expandable, @Nullable OnClickListener onClickListener) {
mExpandable = expandable;
if (expandable) {
@@ -960,7 +1062,7 @@ public class ConversationLayout extends FrameLayout
// TODO: handle content paddings to end of layout
mExpandButtonContainer.setVisibility(GONE);
}
- updateContentPaddings();
+ updateContentEndPaddings();
}
@Override
diff --git a/core/java/com/android/internal/widget/ObservableTextView.java b/core/java/com/android/internal/widget/ObservableTextView.java
new file mode 100644
index 000000000000..1f3c296f0b60
--- /dev/null
+++ b/core/java/com/android/internal/widget/ObservableTextView.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 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.internal.widget;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.RemoteViews;
+import android.widget.TextView;
+
+import java.util.function.Consumer;
+
+/**
+ * A text view whose visibility can be observed.
+ */
+@RemoteViews.RemoteView
+public class ObservableTextView extends TextView {
+
+ private Consumer<Integer> mOnVisibilityChangedListener;
+
+ public ObservableTextView(Context context) {
+ super(context);
+ }
+
+ public ObservableTextView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ObservableTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public ObservableTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ if (changedView == this) {
+ if (mOnVisibilityChangedListener != null) {
+ mOnVisibilityChangedListener.accept(visibility);
+ }
+ }
+ }
+
+ public void setOnVisibilityChangedListener(Consumer<Integer> listener) {
+ mOnVisibilityChangedListener = listener;
+ }
+}
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index fc6e639f0aa0..ed2c5b2b4930 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2653,4 +2653,16 @@ enum PageId {
// CATEGORY: SETTINGS
// OS: R
ADB_WIRELESS_DEVICE_DETAILS = 1836;
+
+ // Open: Settings > Sound > Do Not Disturb > People > Conversations
+ // OS: R
+ DND_CONVERSATIONS = 1837;
+
+ // Open: Settings > Sound > Do Not Disturb > People > Calls
+ // OS: R
+ DND_CALLS = 1838;
+
+ // Open: Settings > Sound > Do Not Disturb > People > Messages
+ // OS: R
+ DND_MESSAGES = 1839;
}
diff --git a/core/res/res/layout/conversation_face_pile_layout.xml b/core/res/res/layout/conversation_face_pile_layout.xml
index 1db38702f926..528562534aab 100644
--- a/core/res/res/layout/conversation_face_pile_layout.xml
+++ b/core/res/res/layout/conversation_face_pile_layout.xml
@@ -23,21 +23,25 @@
>
<ImageView
android:id="@+id/conversation_face_pile_top"
- android:layout_width="36dp"
- android:layout_height="36dp"
+ android:layout_width="@dimen/messaging_avatar_size"
+ android:layout_height="@dimen/messaging_avatar_size"
android:scaleType="centerCrop"
android:layout_gravity="end|top"
/>
<FrameLayout
- android:id="@+id/conversation_face_pile_bottom_background"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:layout_gravity="start|bottom"
- android:background="@drawable/conversation_badge_background">
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start|bottom">
+ <ImageView
+ android:id="@+id/conversation_face_pile_bottom_background"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/conversation_badge_background"
+ />
<ImageView
android:id="@+id/conversation_face_pile_bottom"
- android:layout_width="36dp"
- android:layout_height="36dp"
+ android:layout_width="@dimen/messaging_avatar_size"
+ android:layout_height="@dimen/messaging_avatar_size"
android:scaleType="centerCrop"
android:layout_gravity="center"
/>
diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml
index 7bf13ec4ad65..7cadecbbdb91 100644
--- a/core/res/res/layout/notification_template_material_conversation.xml
+++ b/core/res/res/layout/notification_template_material_conversation.xml
@@ -25,6 +25,7 @@
>
<FrameLayout
+ android:id="@+id/conversation_icon_container"
android:layout_width="@dimen/conversation_content_start"
android:layout_height="wrap_content"
android:gravity="start|top"
@@ -175,7 +176,7 @@
</LinearLayout>
<!-- App Name -->
- <TextView
+ <com.android.internal.widget.ObservableTextView
android:id="@+id/app_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f2e25998e0ae..7edb86b2db18 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -694,10 +694,31 @@
<dimen name="conversation_badge_side_margin">36dp</dimen>
<!-- size of the notification badge when applied to the conversation icon -->
<dimen name="conversation_icon_size_badged">20dp</dimen>
- <!-- size of the notification badge when centered in a conversation -->
- <dimen name="conversation_icon_size_centered">26dp</dimen>
- <!-- margin on the top when the icon is centered for group conversations -->
- <dimen name="conversation_icon_margin_top_centered">12dp</dimen>
+ <!-- size of the conversation avatar in an expanded group -->
+ <dimen name="conversation_avatar_size_group_expanded">@dimen/messaging_avatar_size</dimen>
+ <!-- size of the face pile icons -->
+ <dimen name="conversation_face_pile_avatar_size">@dimen/messaging_avatar_size</dimen>
+ <!-- size of the face pile icons when the group is expanded -->
+ <dimen name="conversation_face_pile_avatar_size_group_expanded">25dp</dimen>
+ <!-- Side margins of the conversation badge in relation to the conversation icon when the group is expanded-->
+ <dimen name="conversation_badge_side_margin_group_expanded">22dp</dimen>
+ <!-- Side margins of the conversation badge in relation to the conversation icon when the group is expanded-->
+ <dimen name="conversation_badge_side_margin_group_expanded_face_pile">18dp</dimen>
+ <!-- The width of the protection of the face pile layout-->
+ <dimen name="conversation_face_pile_protection_width">2dp</dimen>
+ <!-- The width of the protection of the face pile layout when expanded-->
+ <dimen name="conversation_face_pile_protection_width_expanded">1dp</dimen>
+ <!-- The padding of the expanded message container when the app name is gone-->
+ <dimen name="expanded_group_conversation_message_padding_without_app_name">14dp</dimen>
+
+ <!-- The top padding of the conversation icon container in the regular state-->
+ <dimen name="conversation_icon_container_top_padding">12dp</dimen>
+
+ <!-- The top padding of the conversation icon container when there's no app name present in a group-->
+ <dimen name="conversation_icon_container_top_padding_no_app_name">9dp</dimen>
+
+ <!-- The top padding of the conversation icon container when the avatar is small-->
+ <dimen name="conversation_icon_container_top_padding_small_avatar">17.5dp</dimen>
<!-- The padding of the conversation header when expanded. This is calculated from the expand button size + notification_content_margin_end -->
<dimen name="conversation_header_expanded_padding_end">38dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 163501a5985e..0adef7513bb5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3874,15 +3874,25 @@
<java-symbol type="id" name="conversation_text" />
<java-symbol type="id" name="message_icon_container" />
<java-symbol type="id" name="conversation_image_message_container" />
+ <java-symbol type="id" name="conversation_icon_container" />
<java-symbol type="dimen" name="conversation_expand_button_top_margin_expanded" />
<java-symbol type="dimen" name="messaging_group_singleline_sender_padding_end" />
<java-symbol type="dimen" name="conversation_badge_side_margin" />
- <java-symbol type="dimen" name="conversation_icon_size_badged" />
- <java-symbol type="dimen" name="conversation_icon_size_centered" />
- <java-symbol type="dimen" name="conversation_icon_margin_top_centered" />
+ <java-symbol type="dimen" name="conversation_avatar_size" />
+ <java-symbol type="dimen" name="conversation_avatar_size_group_expanded" />
+ <java-symbol type="dimen" name="conversation_face_pile_avatar_size" />
+ <java-symbol type="dimen" name="conversation_face_pile_avatar_size_group_expanded" />
+ <java-symbol type="dimen" name="conversation_face_pile_protection_width" />
+ <java-symbol type="dimen" name="conversation_face_pile_protection_width_expanded" />
+ <java-symbol type="dimen" name="conversation_badge_side_margin_group_expanded" />
+ <java-symbol type="dimen" name="conversation_badge_side_margin_group_expanded_face_pile" />
<java-symbol type="dimen" name="conversation_content_start" />
+ <java-symbol type="dimen" name="expanded_group_conversation_message_padding_without_app_name" />
<java-symbol type="dimen" name="messaging_layout_margin_end" />
<java-symbol type="dimen" name="conversation_header_expanded_padding_end" />
+ <java-symbol type="dimen" name="conversation_icon_container_top_padding" />
+ <java-symbol type="dimen" name="conversation_icon_container_top_padding_small_avatar" />
+ <java-symbol type="dimen" name="conversation_icon_container_top_padding_no_app_name" />
<java-symbol type="layout" name="notification_template_material_conversation" />
<java-symbol type="layout" name="conversation_face_pile_layout" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index d8bd81e80ed5..1efde8681352 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -255,6 +255,7 @@ applications that come with the platform
</privapp-permissions>
<privapp-permissions package="com.android.networkstack.tethering">
+ <permission name="android.permission.BLUETOOTH_PRIVILEGED" />
<permission name="android.permission.MANAGE_USB"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
@@ -398,6 +399,10 @@ applications that come with the platform
<permission name="android.permission.REGISTER_STATS_PULL_ATOM"/>
<!-- Permission required for testing system audio effect APIs. -->
<permission name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/>
+ <!-- Permissions required for CTS test - TunerTest -->
+ <permission name="android.permission.ACCESS_TV_DESCRAMBLER" />
+ <permission name="android.permission.ACCESS_TV_TUNER" />
+ <permission name="android.permission.TUNER_RESOURCE_ACCESS" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index b943fe589270..d654b45da092 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -22,7 +22,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.TunerUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -178,13 +180,14 @@ public class Filter implements AutoCloseable {
*/
public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
-
private long mNativeContext;
private FilterCallback mCallback;
private Executor mExecutor;
private final int mId;
private int mMainType;
private int mSubtype;
+ private Filter mSource;
+ private boolean mStarted;
private native int nativeConfigureFilter(
int type, int subType, FilterConfiguration settings);
@@ -202,6 +205,9 @@ public class Filter implements AutoCloseable {
}
private void onFilterStatus(int status) {
+ if (mCallback != null && mExecutor != null) {
+ mExecutor.execute(() -> mCallback.onFilterStatusChanged(this, status));
+ }
}
private void onFilterEvent(FilterEvent[] events) {
@@ -266,10 +272,18 @@ public class Filter implements AutoCloseable {
* @param source the filter instance which provides data input. Switch to
* use demux as data source if the filter instance is NULL.
* @return result status of the operation.
+ * @throws IllegalStateException if the data source has been set.
*/
@Result
public int setDataSource(@Nullable Filter source) {
- return nativeSetDataSource(source);
+ if (mSource != null) {
+ throw new IllegalStateException("Data source is existing");
+ }
+ int res = nativeSetDataSource(source);
+ if (res == Tuner.RESULT_SUCCESS) {
+ mSource = source;
+ }
+ return res;
}
/**
@@ -328,6 +342,9 @@ public class Filter implements AutoCloseable {
*/
@Override
public void close() {
- nativeClose();
+ int res = nativeClose();
+ if (res != Tuner.RESULT_SUCCESS) {
+ TunerUtils.throwExceptionForResult(res, "Failed to close filter.");
+ }
}
}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 95ce07d3c55e..29dfd730a84c 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -2448,11 +2448,11 @@ static DemuxFilterSettings getFilterConfiguration(
return filterSettings;
}
-static int copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jint offset, int size) {
- ALOGD("copyData, size=%d, offset=%d", size, offset);
+static jint copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jlong offset, jlong size) {
+ ALOGD("copyData, size=%ld, offset=%ld", (long) size, (long) offset);
- int available = filter->mFilterMQ->availableToRead();
- ALOGD("copyData, available=%d", available);
+ jlong available = filter->mFilterMQ->availableToRead();
+ ALOGD("copyData, available=%ld", (long) available);
size = std::min(size, available);
jboolean isCopy;
@@ -2474,7 +2474,7 @@ static int copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jint offs
return size;
}
-static int android_media_tv_Tuner_configure_filter(
+static jint android_media_tv_Tuner_configure_filter(
JNIEnv *env, jobject filter, int type, int subtype, jobject settings) {
ALOGD("configure filter type=%d, subtype=%d", type, subtype);
sp<Filter> filterSp = getFilter(env, filter);
@@ -2485,9 +2485,14 @@ static int android_media_tv_Tuner_configure_filter(
}
DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings);
Result res = iFilterSp->configure(filterSettings);
+
+ if (res != Result::SUCCESS) {
+ return (jint) res;
+ }
+
MQDescriptorSync<uint8_t> filterMQDesc;
- if (res == Result::SUCCESS && filterSp->mFilterMQ == NULL) {
- Result getQueueDescResult = Result::UNKNOWN_ERROR;
+ Result getQueueDescResult = Result::UNKNOWN_ERROR;
+ if (filterSp->mFilterMQ == NULL) {
iFilterSp->getQueueDesc(
[&](Result r, const MQDescriptorSync<uint8_t>& desc) {
filterMQDesc = desc;
@@ -2500,59 +2505,97 @@ static int android_media_tv_Tuner_configure_filter(
filterSp->mFilterMQ->getEventFlagWord(), &(filterSp->mFilterMQEventFlag));
}
}
- return (int)res;
+ return (jint) getQueueDescResult;
}
-static int android_media_tv_Tuner_get_filter_id(JNIEnv*, jobject) {
- return 0;
+static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to get filter ID: filter not found");
+ return (int) Result::INVALID_STATE;
+ }
+ Result res;
+ uint32_t id;
+ iFilterSp->getId(
+ [&](Result r, uint32_t filterId) {
+ res = r;
+ id = filterId;
+ });
+ if (res != Result::SUCCESS) {
+ return (jint) Constant::INVALID_FILTER_ID;
+ }
+ return (jint) id;
}
-static int android_media_tv_Tuner_set_filter_data_source(JNIEnv*, jobject, jobject) {
- return 0;
+static jint android_media_tv_Tuner_set_filter_data_source(
+ JNIEnv* env, jobject filter, jobject srcFilter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to set filter data source: filter not found");
+ return (jint) Result::INVALID_STATE;
+ }
+ Result r;
+ if (srcFilter == NULL) {
+ r = iFilterSp->setDataSource(NULL);
+ } else {
+ sp<IFilter> srcSp = getFilter(env, srcFilter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to set filter data source: src filter not found");
+ return (jint) Result::INVALID_STATE;
+ }
+ r = iFilterSp->setDataSource(srcSp);
+ }
+ return (jint) r;
}
-static int android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) {
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (filterSp == NULL) {
+static jint android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
ALOGD("Failed to start filter: filter not found");
- return false;
+ return (jint) Result::INVALID_STATE;
}
- Result r = filterSp->start();
- return (int) r;
+ Result r = iFilterSp->start();
+ return (jint) r;
}
-static int android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) {
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (filterSp == NULL) {
+static jint android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
ALOGD("Failed to stop filter: filter not found");
- return false;
+ return (jint) Result::INVALID_STATE;
}
- Result r = filterSp->stop();
- return (int) r;
+ Result r = iFilterSp->stop();
+ return (jint) r;
}
-static int android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) {
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (filterSp == NULL) {
+static jint android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
ALOGD("Failed to flush filter: filter not found");
- return false;
+ return (jint) Result::INVALID_STATE;
}
- Result r = filterSp->flush();
- return (int) r;
+ Result r = iFilterSp->flush();
+ return (jint) r;
}
-static int android_media_tv_Tuner_read_filter_fmq(
+static jint android_media_tv_Tuner_read_filter_fmq(
JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) {
sp<Filter> filterSp = getFilter(env, filter);
if (filterSp == NULL) {
ALOGD("Failed to read filter FMQ: filter not found");
- return 0;
+ return (jint) Result::INVALID_STATE;
}
return copyData(env, filterSp, buffer, offset, size);
}
-static int android_media_tv_Tuner_close_filter(JNIEnv*, jobject) {
- return 0;
+static jint android_media_tv_Tuner_close_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to close filter: filter not found");
+ return (jint) Result::INVALID_STATE;
+ }
+ Result r = iFilterSp->close();
+ return (jint) r;
}
static sp<TimeFilter> getTimeFilter(JNIEnv *env, jobject filter) {
@@ -2660,8 +2703,8 @@ static int android_media_tv_Tuner_add_pid(
if (descramblerSp == NULL) {
return false;
}
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), filterSp);
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp);
return (int)result;
}
@@ -2671,8 +2714,8 @@ static int android_media_tv_Tuner_remove_pid(
if (descramblerSp == NULL) {
return false;
}
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), filterSp);
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp);
return (int)result;
}
@@ -2702,21 +2745,21 @@ static jobject android_media_tv_Tuner_get_demux_caps(JNIEnv*, jobject) {
static int android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (dvrSp == NULL || filterSp == NULL) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (dvrSp == NULL || iFilterSp == NULL) {
return false;
}
- Result result = dvrSp->attachFilter(filterSp);
+ Result result = dvrSp->attachFilter(iFilterSp);
return (int) result;
}
static int android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobject filter) {
sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (dvrSp == NULL || filterSp == NULL) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (dvrSp == NULL || iFilterSp == NULL) {
return false;
}
- Result result = dvrSp->detachFilter(filterSp);
+ Result result = dvrSp->detachFilter(iFilterSp);
return (int) result;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 9ae9b4a46227..b1300a97a324 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -440,8 +440,9 @@ public class LocalMediaManager implements BluetoothCallback {
MediaDevice connectDevice = getMediaDeviceById(mMediaDevices, id);
connectDevice = connectDevice != null
? connectDevice : updateCurrentConnectedDevice();
- connectDevice.setState(MediaDeviceState.STATE_CONNECTED);
-
+ if (connectDevice != null) {
+ connectDevice.setState(MediaDeviceState.STATE_CONNECTED);
+ }
if (connectDevice == mCurrentConnectedDevice) {
Log.d(TAG, "onConnectedDeviceChanged() this device all ready connected!");
return;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
index 559187d2c38c..6b3a97f8c8de 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
@@ -450,6 +450,12 @@ public class LocalMediaManagerTest {
}
@Test
+ public void onConnectedDeviceChanged_nullConnectedDevice_noException() {
+ mLocalMediaManager.registerCallback(mCallback);
+ mLocalMediaManager.mMediaDeviceCallback.onConnectedDeviceChanged(TEST_DEVICE_ID_2);
+ }
+
+ @Test
public void onDeviceAttributesChanged_shouldDispatchDeviceListUpdate() {
mLocalMediaManager.registerCallback(mCallback);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 24cc3c901920..a36949b9e1ff 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -540,6 +540,7 @@ public class SettingsBackupTest {
Settings.Global.WIFI_FREQUENCY_BAND,
Settings.Global.WIFI_IDLE_MS,
Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
+ Settings.Global.WIFI_MIGRATION_COMPLETED,
Settings.Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS,
Settings.Global.WIFI_NETWORK_SHOW_RSSI,
Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 0230970cfa83..c7fb00a8130c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -284,6 +284,11 @@
<!-- Permission required for testing system audio effect APIs. -->
<uses-permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/>
+ <!-- Permissions required for CTS test - TunerTest -->
+ <uses-permission android:name="android.permission.ACCESS_TV_DESCRAMBLER" />
+ <uses-permission android:name="android.permission.ACCESS_TV_TUNER" />
+ <uses-permission android:name="android.permission.TUNER_RESOURCE_ACCESS" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index b906442b6ba0..bb0fa2d2c7cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -340,7 +340,7 @@ public class KeyguardIndicationController implements StateListener,
mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
mTextView.setTextColor(mInitialTextColorState);
} else if (!TextUtils.isEmpty(mTransientIndication)) {
- if (powerIndication != null) {
+ if (powerIndication != null && !mTransientIndication.equals(powerIndication)) {
String indication = mContext.getResources().getString(
R.string.keyguard_indication_trust_unlocked_plugged_in,
mTransientIndication, powerIndication);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
index 4882a235c5d8..82f7c71c48cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
@@ -117,11 +117,6 @@ public class ImageTransformState extends TransformState {
}
@Override
- protected boolean transformScale(TransformState otherState) {
- return sameAs(otherState);
- }
-
- @Override
public void recycle() {
super.recycle();
if (getClass() == ImageTransformState.class) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 82fb49144181..27109d2acfa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -248,7 +248,7 @@ public class TransformState {
}
protected boolean transformScale(TransformState otherState) {
- return false;
+ return sameAs(otherState);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index 91a2e7c815d4..593de23c58de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -53,6 +53,9 @@ class NotificationConversationTemplateViewWrapper constructor(
private lateinit var conversationTitle: View
private lateinit var importanceRing: View
private lateinit var appName: View
+ private var facePileBottomBg: View? = null
+ private var facePileBottom: View? = null
+ private var facePileTop: View? = null
private fun resolveViews() {
messagingLinearLayout = conversationLayout.messagingLinearLayout
@@ -67,6 +70,10 @@ class NotificationConversationTemplateViewWrapper constructor(
importanceRing = requireViewById(com.android.internal.R.id.conversation_icon_badge_ring)
appName = requireViewById(com.android.internal.R.id.app_name_text)
conversationTitle = requireViewById(com.android.internal.R.id.conversation_text)
+ facePileTop = findViewById(com.android.internal.R.id.conversation_face_pile_top)
+ facePileBottom = findViewById(com.android.internal.R.id.conversation_face_pile_bottom)
+ facePileBottomBg =
+ findViewById(com.android.internal.R.id.conversation_face_pile_bottom_background)
}
}
@@ -118,7 +125,10 @@ class NotificationConversationTemplateViewWrapper constructor(
conversationIcon,
conversationBadgeBg,
expandButton,
- importanceRing
+ importanceRing,
+ facePileTop,
+ facePileBottom,
+ facePileBottomBg
)
}
@@ -140,9 +150,9 @@ class NotificationConversationTemplateViewWrapper constructor(
else
super.getMinLayoutHeight()
- private fun addTransformedViews(vararg vs: View) =
- vs.forEach(mTransformationHelper::addTransformedView)
+ private fun addTransformedViews(vararg vs: View?) =
+ vs.forEach { view -> view?.let(mTransformationHelper::addTransformedView) }
- private fun addViewsTransformingToSimilar(vararg vs: View) =
- vs.forEach(mTransformationHelper::addViewTransformingToSimilar)
+ private fun addViewsTransformingToSimilar(vararg vs: View?) =
+ vs.forEach { view -> view?.let(mTransformationHelper::addViewTransformingToSimilar) }
}
diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml
index c71d0d7bc543..9328611f5d3f 100644
--- a/packages/Tethering/AndroidManifest.xml
+++ b/packages/Tethering/AndroidManifest.xml
@@ -27,7 +27,7 @@
added to the privileged permissions whitelist for that package. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MANAGE_USB" />
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 61c6ef5cfda9..bc38fbf50000 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -274,23 +274,38 @@ public class TouchExplorer extends BaseEventStreamTransformation
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
+ if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+ sendsPendingA11yEventsIfNeed();
+ }
+ super.onAccessibilityEvent(event);
+ }
+
+ /*
+ * Sends pending {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END} or {@{@link
+ * AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}} after receiving last hover exit
+ * event.
+ */
+ private void sendsPendingA11yEventsIfNeed() {
+ // The last hover exit A11y event should be sent by view after receiving hover exit motion
+ // event. In some view hierarchy, the ViewGroup transforms hover move motion event to hover
+ // exit motion event and than dispatch to itself. It causes unexpected A11y exit events.
+ if (mSendHoverExitDelayed.isPending()) {
+ return;
+ }
// The event for gesture end should be strictly after the
// last hover exit event.
- if (mSendTouchExplorationEndDelayed.isPending()
- && eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
- mSendTouchExplorationEndDelayed.cancel();
+ if (mSendTouchExplorationEndDelayed.isPending()) {
+ mSendTouchExplorationEndDelayed.cancel();
mDispatcher.sendAccessibilityEvent(
AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END);
}
// The event for touch interaction end should be strictly after the
// last hover exit and the touch exploration gesture end events.
- if (mSendTouchInteractionEndDelayed.isPending()
- && eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+ if (mSendTouchInteractionEndDelayed.isPending()) {
mSendTouchInteractionEndDelayed.cancel();
mDispatcher.sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
}
- super.onAccessibilityEvent(event);
}
@Override
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f3d42ad1c793..1f0146ad815d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -693,7 +693,7 @@ public class AudioService extends IAudioService.Stub
AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
} else {
AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
- (maxCallVolume * 3) / 4;
+ (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
}
int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 28c5a2857aa6..6dded00321b5 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -657,12 +657,12 @@ public class TunerResourceManagerService extends SystemService {
}
private void enforceTunerAccessPermission(String apiName) {
- getContext().enforceCallingPermission("android.Manifest.permission.ACCESS_TV_TUNER",
+ getContext().enforceCallingPermission("android.permission.ACCESS_TV_TUNER",
TAG + ": " + apiName);
}
private void enforceDescramblerAccessPermission(String apiName) {
- getContext().enforceCallingPermission("android.Manifest.permission.ACCESS_TV_DESCRAMBLER",
+ getContext().enforceCallingPermission("android.permission.ACCESS_TV_DESCRAMBLER",
TAG + ": " + apiName);
}
}
diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java
index 87afdc59c2b9..5792d27a94f9 100755
--- a/wifi/java/android/net/wifi/WifiMigration.java
+++ b/wifi/java/android/net/wifi/WifiMigration.java
@@ -522,7 +522,12 @@ public final class WifiMigration {
*/
@NonNull
public static SettingsMigrationData loadFromSettings(@NonNull Context context) {
- return new SettingsMigrationData.Builder()
+ if (Settings.Global.getInt(
+ context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 0) == 1) {
+ // migration already complete, ignore.
+ return null;
+ }
+ SettingsMigrationData data = new SettingsMigrationData.Builder()
.setScanAlwaysAvailable(
Settings.Global.getInt(context.getContentResolver(),
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1)
@@ -545,5 +550,9 @@ public final class WifiMigration {
Settings.Global.getInt(context.getContentResolver(),
Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1)
.build();
+ Settings.Global.putInt(
+ context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 1);
+ return data;
+
}
}