Merge "Fix remote input view clobbering" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1a101dbc81
@@ -3351,7 +3351,8 @@ public class Notification implements Parcelable
|
||||
}
|
||||
|
||||
private void resetStandardTemplateWithActions(RemoteViews big) {
|
||||
big.setViewVisibility(R.id.actions_container, View.GONE);
|
||||
// actions_container is only reset when there are no actions to avoid focus issues with
|
||||
// remote inputs.
|
||||
big.setViewVisibility(R.id.actions, View.GONE);
|
||||
big.removeAllViews(R.id.actions);
|
||||
|
||||
@@ -3396,6 +3397,8 @@ public class Notification implements Parcelable
|
||||
}
|
||||
big.addView(R.id.actions, button);
|
||||
}
|
||||
} else {
|
||||
big.setViewVisibility(R.id.actions_container, View.GONE);
|
||||
}
|
||||
|
||||
CharSequence[] replyText = mN.extras.getCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.RemoteInput;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
@@ -118,6 +119,8 @@ public class NotificationContentView extends FrameLayout {
|
||||
private int mTransformationStartVisibleType;
|
||||
private boolean mUserExpanding;
|
||||
private int mSingleLineWidthIndention;
|
||||
private PendingIntent mPreviousExpandedRemoteInputIntent;
|
||||
private PendingIntent mPreviousHeadsUpRemoteInputIntent;
|
||||
|
||||
public NotificationContentView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -280,13 +283,19 @@ public class NotificationContentView extends FrameLayout {
|
||||
mContractedChild.animate().cancel();
|
||||
removeView(mContractedChild);
|
||||
}
|
||||
mPreviousExpandedRemoteInputIntent =
|
||||
mExpandedRemoteInput != null ? mExpandedRemoteInput.getPendingIntent() : null;
|
||||
if (mExpandedChild != null) {
|
||||
mExpandedChild.animate().cancel();
|
||||
removeView(mExpandedChild);
|
||||
mExpandedRemoteInput = null;
|
||||
}
|
||||
mPreviousHeadsUpRemoteInputIntent =
|
||||
mHeadsUpRemoteInput != null ? mHeadsUpRemoteInput.getPendingIntent() : null;
|
||||
if (mHeadsUpChild != null) {
|
||||
mHeadsUpChild.animate().cancel();
|
||||
removeView(mHeadsUpChild);
|
||||
mHeadsUpRemoteInput = null;
|
||||
}
|
||||
mContractedChild = null;
|
||||
mExpandedChild = null;
|
||||
@@ -496,6 +505,12 @@ public class NotificationContentView extends FrameLayout {
|
||||
}
|
||||
int visibleType = calculateVisibleType();
|
||||
if (visibleType != mVisibleType || force) {
|
||||
View visibleView = getViewForVisibleType(visibleType);
|
||||
if (visibleView != null) {
|
||||
visibleView.setVisibility(VISIBLE);
|
||||
transferRemoteInputFocus(visibleType);
|
||||
}
|
||||
|
||||
if (animate && ((visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null)
|
||||
|| (visibleType == VISIBLE_TYPE_HEADSUP && mHeadsUpChild != null)
|
||||
|| (visibleType == VISIBLE_TYPE_SINGLELINE && mSingleLineView != null)
|
||||
@@ -559,6 +574,19 @@ public class NotificationContentView extends FrameLayout {
|
||||
});
|
||||
}
|
||||
|
||||
private void transferRemoteInputFocus(int visibleType) {
|
||||
if (visibleType == VISIBLE_TYPE_HEADSUP
|
||||
&& mHeadsUpRemoteInput != null
|
||||
&& (mExpandedRemoteInput != null && mExpandedRemoteInput.isActive())) {
|
||||
mHeadsUpRemoteInput.stealFocusFrom(mExpandedRemoteInput);
|
||||
}
|
||||
if (visibleType == VISIBLE_TYPE_EXPANDED
|
||||
&& mExpandedRemoteInput != null
|
||||
&& (mHeadsUpRemoteInput != null && mHeadsUpRemoteInput.isActive())) {
|
||||
mExpandedRemoteInput.stealFocusFrom(mHeadsUpRemoteInput);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visibleType one of the static enum types in this view
|
||||
* @return the corresponding transformable view according to the given visible type
|
||||
@@ -736,6 +764,8 @@ public class NotificationContentView extends FrameLayout {
|
||||
updateShowingLegacyBackground();
|
||||
selectLayout(false /* animate */, true /* force */);
|
||||
setDark(mDark, false /* animate */, 0 /* delay */);
|
||||
mPreviousExpandedRemoteInputIntent = null;
|
||||
mPreviousHeadsUpRemoteInputIntent = null;
|
||||
}
|
||||
|
||||
private void updateSingleLineView() {
|
||||
@@ -771,19 +801,23 @@ public class NotificationContentView extends FrameLayout {
|
||||
|
||||
View bigContentView = mExpandedChild;
|
||||
if (bigContentView != null) {
|
||||
mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasRemoteInput);
|
||||
mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasRemoteInput,
|
||||
mPreviousExpandedRemoteInputIntent);
|
||||
} else {
|
||||
mExpandedRemoteInput = null;
|
||||
}
|
||||
|
||||
View headsUpContentView = mHeadsUpChild;
|
||||
if (headsUpContentView != null) {
|
||||
mHeadsUpRemoteInput = applyRemoteInput(headsUpContentView, entry, hasRemoteInput);
|
||||
mHeadsUpRemoteInput = applyRemoteInput(headsUpContentView, entry, hasRemoteInput,
|
||||
mPreviousHeadsUpRemoteInputIntent);
|
||||
} else {
|
||||
mHeadsUpRemoteInput = null;
|
||||
}
|
||||
}
|
||||
|
||||
private RemoteInputView applyRemoteInput(View view, NotificationData.Entry entry, boolean hasRemoteInput) {
|
||||
private RemoteInputView applyRemoteInput(View view, NotificationData.Entry entry,
|
||||
boolean hasRemoteInput, PendingIntent existingPendingIntent) {
|
||||
View actionContainerCandidate = view.findViewById(
|
||||
com.android.internal.R.id.actions_container);
|
||||
if (actionContainerCandidate instanceof FrameLayout) {
|
||||
@@ -814,6 +848,24 @@ public class NotificationContentView extends FrameLayout {
|
||||
existing.setBackgroundColor(NotificationColorUtil.ensureTextBackgroundColor(color,
|
||||
mContext.getColor(R.color.remote_input_text),
|
||||
mContext.getColor(R.color.remote_input_hint)));
|
||||
|
||||
if (existingPendingIntent != null || existing.isActive()) {
|
||||
// The current action could be gone, or the pending intent no longer valid.
|
||||
// If we find a matching action in the new notification, focus, otherwise close.
|
||||
Notification.Action[] actions = entry.notification.getNotification().actions;
|
||||
if (existingPendingIntent != null) {
|
||||
existing.setPendingIntent(existingPendingIntent);
|
||||
}
|
||||
if (existing.updatePendingIntentFromActions(actions)) {
|
||||
if (!existing.isActive()) {
|
||||
existing.focus();
|
||||
}
|
||||
} else {
|
||||
if (existing.isActive()) {
|
||||
existing.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.RemoteInput;
|
||||
import android.content.Context;
|
||||
@@ -197,6 +198,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
||||
}
|
||||
|
||||
public void focus() {
|
||||
setVisibility(VISIBLE);
|
||||
mController.addRemoteInput(mEntry);
|
||||
mEditText.setInnerFocusable(true);
|
||||
mEditText.mShowImeOnInputConnection = true;
|
||||
@@ -275,6 +277,63 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return mEditText.isFocused();
|
||||
}
|
||||
|
||||
public void stealFocusFrom(RemoteInputView other) {
|
||||
other.close();
|
||||
setPendingIntent(other.mPendingIntent);
|
||||
setRemoteInput(other.mRemoteInputs, other.mRemoteInput);
|
||||
focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find an action in {@param actions} that matches the current pending intent
|
||||
* of this view and updates its state to that of the found action
|
||||
*
|
||||
* @return true if a matching action was found, false otherwise
|
||||
*/
|
||||
public boolean updatePendingIntentFromActions(Notification.Action[] actions) {
|
||||
boolean found = false;
|
||||
if (mPendingIntent == null || actions == null) {
|
||||
return false;
|
||||
}
|
||||
Intent current = mPendingIntent.getIntent();
|
||||
if (current == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Notification.Action a : actions) {
|
||||
RemoteInput[] inputs = a.getRemoteInputs();
|
||||
if (a.actionIntent == null || inputs == null) {
|
||||
continue;
|
||||
}
|
||||
Intent candidate = a.actionIntent.getIntent();
|
||||
if (!current.filterEquals(candidate)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RemoteInput input = null;
|
||||
for (RemoteInput i : inputs) {
|
||||
if (i.getAllowFreeFormInput()) {
|
||||
input = i;
|
||||
}
|
||||
}
|
||||
if (input == null) {
|
||||
continue;
|
||||
}
|
||||
setPendingIntent(a.actionIntent);
|
||||
setRemoteInput(inputs, input);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PendingIntent getPendingIntent() {
|
||||
return mPendingIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* An EditText that changes appearance based on whether it's focusable and becomes
|
||||
* un-focusable whenever the user navigates away from it or it becomes invisible.
|
||||
|
||||
Reference in New Issue
Block a user