Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +40 −12 Original line number Diff line number Diff line Loading @@ -116,6 +116,8 @@ public class NotificationContentView extends FrameLayout { private boolean mForceSelectNextLayout = true; private PendingIntent mPreviousExpandedRemoteInputIntent; private PendingIntent mPreviousHeadsUpRemoteInputIntent; private RemoteInputView mCachedExpandedRemoteInput; private RemoteInputView mCachedHeadsUpRemoteInput; private int mContentHeightAtAnimationStart = UNDEFINED; private boolean mFocusOnVisibilityChange; Loading Loading @@ -298,6 +300,9 @@ public class NotificationContentView extends FrameLayout { mExpandedRemoteInput.onNotificationUpdateOrReset(); if (mExpandedRemoteInput.isActive()) { mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent(); mCachedExpandedRemoteInput = mExpandedRemoteInput; mExpandedRemoteInput.dispatchStartTemporaryDetach(); ((ViewGroup)mExpandedRemoteInput.getParent()).removeView(mExpandedRemoteInput); } } if (mExpandedChild != null) { Loading @@ -310,6 +315,9 @@ public class NotificationContentView extends FrameLayout { mHeadsUpRemoteInput.onNotificationUpdateOrReset(); if (mHeadsUpRemoteInput.isActive()) { mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent(); mCachedHeadsUpRemoteInput = mHeadsUpRemoteInput; mHeadsUpRemoteInput.dispatchStartTemporaryDetach(); ((ViewGroup)mHeadsUpRemoteInput.getParent()).removeView(mHeadsUpRemoteInput); } } if (mHeadsUpChild != null) { Loading Loading @@ -963,22 +971,35 @@ public class NotificationContentView extends FrameLayout { View bigContentView = mExpandedChild; if (bigContentView != null) { mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasRemoteInput, mPreviousExpandedRemoteInputIntent); mPreviousExpandedRemoteInputIntent, mCachedExpandedRemoteInput); } else { mExpandedRemoteInput = null; } if (mCachedExpandedRemoteInput != null && mCachedExpandedRemoteInput != mExpandedRemoteInput) { // We had a cached remote input but didn't reuse it. Clean up required. mCachedExpandedRemoteInput.dispatchFinishTemporaryDetach(); } mCachedExpandedRemoteInput = null; View headsUpContentView = mHeadsUpChild; if (headsUpContentView != null) { mHeadsUpRemoteInput = applyRemoteInput(headsUpContentView, entry, hasRemoteInput, mPreviousHeadsUpRemoteInputIntent); mPreviousHeadsUpRemoteInputIntent, mCachedHeadsUpRemoteInput); } else { mHeadsUpRemoteInput = null; } if (mCachedHeadsUpRemoteInput != null && mCachedHeadsUpRemoteInput != mHeadsUpRemoteInput) { // We had a cached remote input but didn't reuse it. Clean up required. mCachedHeadsUpRemoteInput.dispatchFinishTemporaryDetach(); } mCachedHeadsUpRemoteInput = null; } private RemoteInputView applyRemoteInput(View view, NotificationData.Entry entry, boolean hasRemoteInput, PendingIntent existingPendingIntent) { boolean hasRemoteInput, PendingIntent existingPendingIntent, RemoteInputView cachedView) { View actionContainerCandidate = view.findViewById( com.android.internal.R.id.actions_container); if (actionContainerCandidate instanceof FrameLayout) { Loading @@ -991,6 +1012,7 @@ public class NotificationContentView extends FrameLayout { if (existing == null && hasRemoteInput) { ViewGroup actionContainer = (FrameLayout) actionContainerCandidate; if (cachedView == null) { RemoteInputView riv = RemoteInputView.inflate( mContext, actionContainer, entry, mRemoteInputController); Loading @@ -1000,6 +1022,12 @@ public class NotificationContentView extends FrameLayout { ViewGroup.LayoutParams.MATCH_PARENT) ); existing = riv; } else { actionContainer.addView(cachedView); cachedView.dispatchFinishTemporaryDetach(); cachedView.requestFocus(); existing = cachedView; } } if (hasRemoteInput) { int color = entry.notification.getNotification().color; Loading packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +70 −19 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import com.android.systemui.statusbar.phone.StatusBarWindowManager; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.RemoteInputView; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Pair; import java.lang.ref.WeakReference; import java.util.ArrayList; Loading @@ -31,8 +33,9 @@ import java.util.ArrayList; */ public class RemoteInputController { private final ArrayList<WeakReference<NotificationData.Entry>> mOpen = new ArrayList<>(); private final ArraySet<String> mSpinning = new ArraySet<>(); private final ArrayList<Pair<WeakReference<NotificationData.Entry>, Object>> mOpen = new ArrayList<>(); private final ArrayMap<String, Object> mSpinning = new ArrayMap<>(); private final ArrayList<Callback> mCallbacks = new ArrayList<>(3); private final HeadsUpManager mHeadsUpManager; Loading @@ -41,36 +44,72 @@ public class RemoteInputController { mHeadsUpManager = headsUpManager; } public void addRemoteInput(NotificationData.Entry entry) { /** * Adds a currently active remote input. * * @param entry the entry for which a remote input is now active. * @param token a token identifying the view that is managing the remote input */ public void addRemoteInput(NotificationData.Entry entry, Object token) { Preconditions.checkNotNull(entry); Preconditions.checkNotNull(token); boolean found = pruneWeakThenRemoveAndContains( entry /* contains */, null /* remove */); entry /* contains */, null /* remove */, token /* removeToken */); if (!found) { mOpen.add(new WeakReference<>(entry)); mOpen.add(new Pair<>(new WeakReference<>(entry), token)); } apply(entry); } public void removeRemoteInput(NotificationData.Entry entry) { /** * Removes a currently active remote input. * * @param entry the entry for which a remote input should be removed. * @param token a token identifying the view that is requesting the removal. If non-null, * the entry is only removed if the token matches the last added token for this * entry. If null, the entry is removed regardless. */ public void removeRemoteInput(NotificationData.Entry entry, Object token) { Preconditions.checkNotNull(entry); pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */); pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */, token); apply(entry); } public void addSpinning(String key) { mSpinning.add(key); /** * Adds a currently spinning (i.e. sending) remote input. * * @param key the key of the entry that's spinning. * @param token the token of the view managing the remote input. */ public void addSpinning(String key, Object token) { Preconditions.checkNotNull(key); Preconditions.checkNotNull(token); mSpinning.put(key, token); } public void removeSpinning(String key) { /** * Removes a currently spinning remote input. * * @param key the key of the entry for which a remote input should be removed. * @param token a token identifying the view that is requesting the removal. If non-null, * the entry is only removed if the token matches the last added token for this * entry. If null, the entry is removed regardless. */ public void removeSpinning(String key, Object token) { Preconditions.checkNotNull(key); if (token == null || mSpinning.get(key) == token) { mSpinning.remove(key); } } public boolean isSpinning(String key) { return mSpinning.contains(key); return mSpinning.containsKey(key); } private void apply(NotificationData.Entry entry) { Loading @@ -86,14 +125,16 @@ public class RemoteInputController { * @return true if {@param entry} has an active RemoteInput */ public boolean isRemoteInputActive(NotificationData.Entry entry) { return pruneWeakThenRemoveAndContains(entry /* contains */, null /* remove */); return pruneWeakThenRemoveAndContains(entry /* contains */, null /* remove */, null /* removeToken */); } /** * @return true if any entry has an active RemoteInput */ public boolean isRemoteInputActive() { pruneWeakThenRemoveAndContains(null /* contains */, null /* remove */); pruneWeakThenRemoveAndContains(null /* contains */, null /* remove */, null /* removeToken */); return !mOpen.isEmpty(); } Loading @@ -101,19 +142,29 @@ public class RemoteInputController { * Prunes dangling weak references, removes entries referring to {@param remove} and returns * whether {@param contains} is part of the array in a single loop. * @param remove if non-null, removes this entry from the active remote inputs * @param removeToken if non-null, only removes an entry if this matches the token when the * entry was added. * @return true if {@param contains} is in the set of active remote inputs */ private boolean pruneWeakThenRemoveAndContains( NotificationData.Entry contains, NotificationData.Entry remove) { NotificationData.Entry contains, NotificationData.Entry remove, Object removeToken) { boolean found = false; for (int i = mOpen.size() - 1; i >= 0; i--) { NotificationData.Entry item = mOpen.get(i).get(); if (item == null || item == remove) { NotificationData.Entry item = mOpen.get(i).first.get(); Object itemToken = mOpen.get(i).second; boolean removeTokenMatches = (removeToken == null || itemToken == removeToken); if (item == null || (item == remove && removeTokenMatches)) { mOpen.remove(i); } else if (item == contains) { if (removeToken != null && removeToken != itemToken) { // We need to update the token. Remove here and let caller reinsert it. mOpen.remove(i); } else { found = true; } } } return found; } Loading @@ -138,7 +189,7 @@ public class RemoteInputController { // Make a copy because closing the remote inputs will modify mOpen. ArrayList<NotificationData.Entry> list = new ArrayList<>(mOpen.size()); for (int i = mOpen.size() - 1; i >= 0; i--) { NotificationData.Entry item = mOpen.get(i).get(); NotificationData.Entry item = mOpen.get(i).first.get(); if (item != null && item.row != null) { list.add(item); } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +2 −2 Original line number Diff line number Diff line Loading @@ -1719,7 +1719,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, protected void performRemoveNotification(StatusBarNotification n, boolean removeView) { Entry entry = mNotificationData.get(n.getKey()); if (mRemoteInputController.isRemoteInputActive(entry)) { mRemoteInputController.removeRemoteInput(entry); mRemoteInputController.removeRemoteInput(entry, null); } super.performRemoveNotification(n, removeView); } Loading Loading @@ -2667,7 +2667,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void removeRemoteInputEntriesKeptUntilCollapsed() { for (int i = 0; i < mRemoteInputEntriesToRemoveOnCollapse.size(); i++) { Entry entry = mRemoteInputEntriesToRemoveOnCollapse.valueAt(i); mRemoteInputController.removeRemoteInput(entry); mRemoteInputController.removeRemoteInput(entry, null); removeNotification(entry.key, mLatestRankingMap); } mRemoteInputEntriesToRemoveOnCollapse.clear(); Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +37 −9 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene // A marker object that let's us easily find views of this class. public static final Object VIEW_TAG = new Object(); public final Object mToken = new Object(); private RemoteEditText mEditText; private ImageButton mSendButton; private ProgressBar mProgressBar; Loading Loading @@ -140,8 +142,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mSendButton.setVisibility(INVISIBLE); mProgressBar.setVisibility(VISIBLE); mEntry.remoteInputText = mEditText.getText(); mController.addSpinning(mEntry.key); mController.removeRemoteInput(mEntry); mController.addSpinning(mEntry.key, mToken); mController.removeRemoteInput(mEntry, mToken); mEditText.mShowImeOnInputConnection = false; mController.remoteInputSent(mEntry); Loading Loading @@ -193,7 +195,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void onDefocus(boolean animate) { mController.removeRemoteInput(mEntry); mController.removeRemoteInput(mEntry, mToken); mEntry.remoteInputText = mEditText.getText(); // During removal, we get reattached and lose focus. Not hiding in that Loading Loading @@ -232,11 +234,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mEntry.row.isChangingPosition()) { if (mEntry.row.isChangingPosition() || isTemporarilyDetached()) { return; } mController.removeRemoteInput(mEntry); mController.removeSpinning(mEntry.key); mController.removeRemoteInput(mEntry, mToken); mController.removeSpinning(mEntry.key, mToken); } public void setPendingIntent(PendingIntent pendingIntent) { Loading Loading @@ -265,7 +267,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEntry.notification.getPackageName()); setVisibility(VISIBLE); mController.addRemoteInput(mEntry); mController.addRemoteInput(mEntry, mToken); mEditText.setInnerFocusable(true); mEditText.mShowImeOnInputConnection = true; mEditText.setText(mEntry.remoteInputText); Loading @@ -290,7 +292,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.setEnabled(true); mSendButton.setVisibility(VISIBLE); mProgressBar.setVisibility(INVISIBLE); mController.removeSpinning(mEntry.key); mController.removeSpinning(mEntry.key, mToken); updateSendButton(); onDefocus(false /* animate */); Loading Loading @@ -432,6 +434,24 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRevealR = r; } @Override public void dispatchStartTemporaryDetach() { super.dispatchStartTemporaryDetach(); // Detach the EditText temporarily such that it doesn't get onDetachedFromWindow and // won't lose IME focus. detachViewFromParent(mEditText); } @Override public void dispatchFinishTemporaryDetach() { if (isAttachedToWindow()) { attachViewToParent(mEditText, 0, mEditText.getLayoutParams()); } else { removeDetachedView(mEditText, false /* animate */); } super.dispatchFinishTemporaryDetach(); } /** * 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. Loading @@ -448,7 +468,15 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void defocusIfNeeded(boolean animate) { if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition()) { if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition() || isTemporarilyDetached()) { if (isTemporarilyDetached()) { // We might get reattached but then the other one of HUN / expanded might steal // our focus, so we'll need to save our text here. if (mRemoteInputView != null) { mRemoteInputView.mEntry.remoteInputText = getText(); } } return; } if (isFocusable() && isEnabled()) { Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +40 −12 Original line number Diff line number Diff line Loading @@ -116,6 +116,8 @@ public class NotificationContentView extends FrameLayout { private boolean mForceSelectNextLayout = true; private PendingIntent mPreviousExpandedRemoteInputIntent; private PendingIntent mPreviousHeadsUpRemoteInputIntent; private RemoteInputView mCachedExpandedRemoteInput; private RemoteInputView mCachedHeadsUpRemoteInput; private int mContentHeightAtAnimationStart = UNDEFINED; private boolean mFocusOnVisibilityChange; Loading Loading @@ -298,6 +300,9 @@ public class NotificationContentView extends FrameLayout { mExpandedRemoteInput.onNotificationUpdateOrReset(); if (mExpandedRemoteInput.isActive()) { mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent(); mCachedExpandedRemoteInput = mExpandedRemoteInput; mExpandedRemoteInput.dispatchStartTemporaryDetach(); ((ViewGroup)mExpandedRemoteInput.getParent()).removeView(mExpandedRemoteInput); } } if (mExpandedChild != null) { Loading @@ -310,6 +315,9 @@ public class NotificationContentView extends FrameLayout { mHeadsUpRemoteInput.onNotificationUpdateOrReset(); if (mHeadsUpRemoteInput.isActive()) { mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent(); mCachedHeadsUpRemoteInput = mHeadsUpRemoteInput; mHeadsUpRemoteInput.dispatchStartTemporaryDetach(); ((ViewGroup)mHeadsUpRemoteInput.getParent()).removeView(mHeadsUpRemoteInput); } } if (mHeadsUpChild != null) { Loading Loading @@ -963,22 +971,35 @@ public class NotificationContentView extends FrameLayout { View bigContentView = mExpandedChild; if (bigContentView != null) { mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasRemoteInput, mPreviousExpandedRemoteInputIntent); mPreviousExpandedRemoteInputIntent, mCachedExpandedRemoteInput); } else { mExpandedRemoteInput = null; } if (mCachedExpandedRemoteInput != null && mCachedExpandedRemoteInput != mExpandedRemoteInput) { // We had a cached remote input but didn't reuse it. Clean up required. mCachedExpandedRemoteInput.dispatchFinishTemporaryDetach(); } mCachedExpandedRemoteInput = null; View headsUpContentView = mHeadsUpChild; if (headsUpContentView != null) { mHeadsUpRemoteInput = applyRemoteInput(headsUpContentView, entry, hasRemoteInput, mPreviousHeadsUpRemoteInputIntent); mPreviousHeadsUpRemoteInputIntent, mCachedHeadsUpRemoteInput); } else { mHeadsUpRemoteInput = null; } if (mCachedHeadsUpRemoteInput != null && mCachedHeadsUpRemoteInput != mHeadsUpRemoteInput) { // We had a cached remote input but didn't reuse it. Clean up required. mCachedHeadsUpRemoteInput.dispatchFinishTemporaryDetach(); } mCachedHeadsUpRemoteInput = null; } private RemoteInputView applyRemoteInput(View view, NotificationData.Entry entry, boolean hasRemoteInput, PendingIntent existingPendingIntent) { boolean hasRemoteInput, PendingIntent existingPendingIntent, RemoteInputView cachedView) { View actionContainerCandidate = view.findViewById( com.android.internal.R.id.actions_container); if (actionContainerCandidate instanceof FrameLayout) { Loading @@ -991,6 +1012,7 @@ public class NotificationContentView extends FrameLayout { if (existing == null && hasRemoteInput) { ViewGroup actionContainer = (FrameLayout) actionContainerCandidate; if (cachedView == null) { RemoteInputView riv = RemoteInputView.inflate( mContext, actionContainer, entry, mRemoteInputController); Loading @@ -1000,6 +1022,12 @@ public class NotificationContentView extends FrameLayout { ViewGroup.LayoutParams.MATCH_PARENT) ); existing = riv; } else { actionContainer.addView(cachedView); cachedView.dispatchFinishTemporaryDetach(); cachedView.requestFocus(); existing = cachedView; } } if (hasRemoteInput) { int color = entry.notification.getNotification().color; Loading
packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +70 −19 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import com.android.systemui.statusbar.phone.StatusBarWindowManager; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.RemoteInputView; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Pair; import java.lang.ref.WeakReference; import java.util.ArrayList; Loading @@ -31,8 +33,9 @@ import java.util.ArrayList; */ public class RemoteInputController { private final ArrayList<WeakReference<NotificationData.Entry>> mOpen = new ArrayList<>(); private final ArraySet<String> mSpinning = new ArraySet<>(); private final ArrayList<Pair<WeakReference<NotificationData.Entry>, Object>> mOpen = new ArrayList<>(); private final ArrayMap<String, Object> mSpinning = new ArrayMap<>(); private final ArrayList<Callback> mCallbacks = new ArrayList<>(3); private final HeadsUpManager mHeadsUpManager; Loading @@ -41,36 +44,72 @@ public class RemoteInputController { mHeadsUpManager = headsUpManager; } public void addRemoteInput(NotificationData.Entry entry) { /** * Adds a currently active remote input. * * @param entry the entry for which a remote input is now active. * @param token a token identifying the view that is managing the remote input */ public void addRemoteInput(NotificationData.Entry entry, Object token) { Preconditions.checkNotNull(entry); Preconditions.checkNotNull(token); boolean found = pruneWeakThenRemoveAndContains( entry /* contains */, null /* remove */); entry /* contains */, null /* remove */, token /* removeToken */); if (!found) { mOpen.add(new WeakReference<>(entry)); mOpen.add(new Pair<>(new WeakReference<>(entry), token)); } apply(entry); } public void removeRemoteInput(NotificationData.Entry entry) { /** * Removes a currently active remote input. * * @param entry the entry for which a remote input should be removed. * @param token a token identifying the view that is requesting the removal. If non-null, * the entry is only removed if the token matches the last added token for this * entry. If null, the entry is removed regardless. */ public void removeRemoteInput(NotificationData.Entry entry, Object token) { Preconditions.checkNotNull(entry); pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */); pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */, token); apply(entry); } public void addSpinning(String key) { mSpinning.add(key); /** * Adds a currently spinning (i.e. sending) remote input. * * @param key the key of the entry that's spinning. * @param token the token of the view managing the remote input. */ public void addSpinning(String key, Object token) { Preconditions.checkNotNull(key); Preconditions.checkNotNull(token); mSpinning.put(key, token); } public void removeSpinning(String key) { /** * Removes a currently spinning remote input. * * @param key the key of the entry for which a remote input should be removed. * @param token a token identifying the view that is requesting the removal. If non-null, * the entry is only removed if the token matches the last added token for this * entry. If null, the entry is removed regardless. */ public void removeSpinning(String key, Object token) { Preconditions.checkNotNull(key); if (token == null || mSpinning.get(key) == token) { mSpinning.remove(key); } } public boolean isSpinning(String key) { return mSpinning.contains(key); return mSpinning.containsKey(key); } private void apply(NotificationData.Entry entry) { Loading @@ -86,14 +125,16 @@ public class RemoteInputController { * @return true if {@param entry} has an active RemoteInput */ public boolean isRemoteInputActive(NotificationData.Entry entry) { return pruneWeakThenRemoveAndContains(entry /* contains */, null /* remove */); return pruneWeakThenRemoveAndContains(entry /* contains */, null /* remove */, null /* removeToken */); } /** * @return true if any entry has an active RemoteInput */ public boolean isRemoteInputActive() { pruneWeakThenRemoveAndContains(null /* contains */, null /* remove */); pruneWeakThenRemoveAndContains(null /* contains */, null /* remove */, null /* removeToken */); return !mOpen.isEmpty(); } Loading @@ -101,19 +142,29 @@ public class RemoteInputController { * Prunes dangling weak references, removes entries referring to {@param remove} and returns * whether {@param contains} is part of the array in a single loop. * @param remove if non-null, removes this entry from the active remote inputs * @param removeToken if non-null, only removes an entry if this matches the token when the * entry was added. * @return true if {@param contains} is in the set of active remote inputs */ private boolean pruneWeakThenRemoveAndContains( NotificationData.Entry contains, NotificationData.Entry remove) { NotificationData.Entry contains, NotificationData.Entry remove, Object removeToken) { boolean found = false; for (int i = mOpen.size() - 1; i >= 0; i--) { NotificationData.Entry item = mOpen.get(i).get(); if (item == null || item == remove) { NotificationData.Entry item = mOpen.get(i).first.get(); Object itemToken = mOpen.get(i).second; boolean removeTokenMatches = (removeToken == null || itemToken == removeToken); if (item == null || (item == remove && removeTokenMatches)) { mOpen.remove(i); } else if (item == contains) { if (removeToken != null && removeToken != itemToken) { // We need to update the token. Remove here and let caller reinsert it. mOpen.remove(i); } else { found = true; } } } return found; } Loading @@ -138,7 +189,7 @@ public class RemoteInputController { // Make a copy because closing the remote inputs will modify mOpen. ArrayList<NotificationData.Entry> list = new ArrayList<>(mOpen.size()); for (int i = mOpen.size() - 1; i >= 0; i--) { NotificationData.Entry item = mOpen.get(i).get(); NotificationData.Entry item = mOpen.get(i).first.get(); if (item != null && item.row != null) { list.add(item); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +2 −2 Original line number Diff line number Diff line Loading @@ -1719,7 +1719,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, protected void performRemoveNotification(StatusBarNotification n, boolean removeView) { Entry entry = mNotificationData.get(n.getKey()); if (mRemoteInputController.isRemoteInputActive(entry)) { mRemoteInputController.removeRemoteInput(entry); mRemoteInputController.removeRemoteInput(entry, null); } super.performRemoveNotification(n, removeView); } Loading Loading @@ -2667,7 +2667,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void removeRemoteInputEntriesKeptUntilCollapsed() { for (int i = 0; i < mRemoteInputEntriesToRemoveOnCollapse.size(); i++) { Entry entry = mRemoteInputEntriesToRemoveOnCollapse.valueAt(i); mRemoteInputController.removeRemoteInput(entry); mRemoteInputController.removeRemoteInput(entry, null); removeNotification(entry.key, mLatestRankingMap); } mRemoteInputEntriesToRemoveOnCollapse.clear(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +37 −9 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene // A marker object that let's us easily find views of this class. public static final Object VIEW_TAG = new Object(); public final Object mToken = new Object(); private RemoteEditText mEditText; private ImageButton mSendButton; private ProgressBar mProgressBar; Loading Loading @@ -140,8 +142,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mSendButton.setVisibility(INVISIBLE); mProgressBar.setVisibility(VISIBLE); mEntry.remoteInputText = mEditText.getText(); mController.addSpinning(mEntry.key); mController.removeRemoteInput(mEntry); mController.addSpinning(mEntry.key, mToken); mController.removeRemoteInput(mEntry, mToken); mEditText.mShowImeOnInputConnection = false; mController.remoteInputSent(mEntry); Loading Loading @@ -193,7 +195,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void onDefocus(boolean animate) { mController.removeRemoteInput(mEntry); mController.removeRemoteInput(mEntry, mToken); mEntry.remoteInputText = mEditText.getText(); // During removal, we get reattached and lose focus. Not hiding in that Loading Loading @@ -232,11 +234,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mEntry.row.isChangingPosition()) { if (mEntry.row.isChangingPosition() || isTemporarilyDetached()) { return; } mController.removeRemoteInput(mEntry); mController.removeSpinning(mEntry.key); mController.removeRemoteInput(mEntry, mToken); mController.removeSpinning(mEntry.key, mToken); } public void setPendingIntent(PendingIntent pendingIntent) { Loading Loading @@ -265,7 +267,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEntry.notification.getPackageName()); setVisibility(VISIBLE); mController.addRemoteInput(mEntry); mController.addRemoteInput(mEntry, mToken); mEditText.setInnerFocusable(true); mEditText.mShowImeOnInputConnection = true; mEditText.setText(mEntry.remoteInputText); Loading @@ -290,7 +292,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.setEnabled(true); mSendButton.setVisibility(VISIBLE); mProgressBar.setVisibility(INVISIBLE); mController.removeSpinning(mEntry.key); mController.removeSpinning(mEntry.key, mToken); updateSendButton(); onDefocus(false /* animate */); Loading Loading @@ -432,6 +434,24 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRevealR = r; } @Override public void dispatchStartTemporaryDetach() { super.dispatchStartTemporaryDetach(); // Detach the EditText temporarily such that it doesn't get onDetachedFromWindow and // won't lose IME focus. detachViewFromParent(mEditText); } @Override public void dispatchFinishTemporaryDetach() { if (isAttachedToWindow()) { attachViewToParent(mEditText, 0, mEditText.getLayoutParams()); } else { removeDetachedView(mEditText, false /* animate */); } super.dispatchFinishTemporaryDetach(); } /** * 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. Loading @@ -448,7 +468,15 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void defocusIfNeeded(boolean animate) { if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition()) { if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition() || isTemporarilyDetached()) { if (isTemporarilyDetached()) { // We might get reattached but then the other one of HUN / expanded might steal // our focus, so we'll need to save our text here. if (mRemoteInputView != null) { mRemoteInputView.mEntry.remoteInputText = getText(); } } return; } if (isFocusable() && isEnabled()) { Loading