diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 7a3902910e471..ce493d0ea6f1c 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -511,6 +511,7 @@ public class Dependency { mProviders.put(KeyguardEnvironment.class, mKeyguardEnvironment::get); mProviders.put(ShadeController.class, mShadeController::get); + mProviders.put(NotificationRemoteInputManager.Callback.class, mNotificationRemoteInputManagerCallback::get); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 210ac27e31744..b0ee37b8fba87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -114,6 +114,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.InflatedSmartReplyState; +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.util.DumpUtilsKt; import com.android.systemui.wmshell.BubblesManager; @@ -1568,6 +1569,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView */ public void initialize( NotificationEntry entry, + RemoteInputViewSubcomponent.Factory rivSubcomponentFactory, String appName, String notificationKey, ExpansionLogger logger, @@ -1612,6 +1614,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mPeopleNotificationIdentifier = peopleNotificationIdentifier; for (NotificationContentView l : mLayouts) { l.setPeopleNotificationIdentifier(mPeopleNotificationIdentifier); + l.setRemoteInputViewSubcomponentFactory(rivSubcomponentFactory); } mOnUserInteractionCallback = onUserInteractionCallback; mBubblesManagerOptional = bubblesManagerOptional; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index 0662a1eba8b6b..0b29ae57510cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -44,6 +44,7 @@ import com.android.systemui.statusbar.notification.row.dagger.NotificationRowSco import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.policy.HeadsUpManager; +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.util.time.SystemClock; import com.android.systemui.wmshell.BubblesManager; @@ -60,6 +61,7 @@ import javax.inject.Named; public class ExpandableNotificationRowController implements NodeController { private final ExpandableNotificationRow mView; private final NotificationListContainer mListContainer; + private final RemoteInputViewSubcomponent.Factory mRemoteInputViewSubcomponentFactory; private final ActivatableNotificationViewController mActivatableNotificationViewController; private final NotificationMediaManager mMediaManager; private final PluginManager mPluginManager; @@ -92,6 +94,7 @@ public class ExpandableNotificationRowController implements NodeController { public ExpandableNotificationRowController( ExpandableNotificationRow view, NotificationListContainer listContainer, + RemoteInputViewSubcomponent.Factory rivSubcomponentFactory, ActivatableNotificationViewController activatableNotificationViewController, NotificationMediaManager mediaManager, PluginManager pluginManager, @@ -116,6 +119,7 @@ public class ExpandableNotificationRowController implements NodeController { ExpandableNotificationRowDragController dragController) { mView = view; mListContainer = listContainer; + mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory; mActivatableNotificationViewController = activatableNotificationViewController; mMediaManager = mediaManager; mPluginManager = pluginManager; @@ -148,6 +152,7 @@ public class ExpandableNotificationRowController implements NodeController { mActivatableNotificationViewController.init(); mView.initialize( entry, + mRemoteInputViewSubcomponentFactory, mAppName, mNotificationKey, mExpansionLogger, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index df484dd8ed77c..81b363507e3fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -54,9 +54,11 @@ import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewW import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.RemoteInputView; +import com.android.systemui.statusbar.policy.RemoteInputViewController; import com.android.systemui.statusbar.policy.SmartReplyConstants; import com.android.systemui.statusbar.policy.SmartReplyStateInflaterKt; import com.android.systemui.statusbar.policy.SmartReplyView; +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.wmshell.BubblesManager; import java.io.FileDescriptor; @@ -101,6 +103,8 @@ public class NotificationContentView extends FrameLayout { private SmartReplyConstants mSmartReplyConstants; private SmartReplyView mExpandedSmartReplyView; private SmartReplyView mHeadsUpSmartReplyView; + @Nullable private RemoteInputViewController mExpandedRemoteInputController; + @Nullable private RemoteInputViewController mHeadsUpRemoteInputController; private SmartReplyController mSmartReplyController; private InflatedSmartReplyViewHolder mExpandedInflatedSmartReplies; private InflatedSmartReplyViewHolder mHeadsUpInflatedSmartReplies; @@ -125,6 +129,8 @@ public class NotificationContentView extends FrameLayout { private RemoteInputController mRemoteInputController; private Runnable mExpandedVisibleListener; private PeopleNotificationIdentifier mPeopleIdentifier; + private RemoteInputViewSubcomponent.Factory mRemoteInputSubcomponentFactory; + /** * List of listeners for when content views become inactive (i.e. not the showing view). */ @@ -159,10 +165,17 @@ public class NotificationContentView extends FrameLayout { private boolean mUserExpanding; private int mSingleLineWidthIndention; private boolean mForceSelectNextLayout = true; - private PendingIntent mPreviousExpandedRemoteInputIntent; - private PendingIntent mPreviousHeadsUpRemoteInputIntent; + + // Cache for storing the RemoteInputView during a notification update. Needed because + // setExpandedChild sets the actual field to null, but then onNotificationUpdated will restore + // it from the cache, if present, otherwise inflate a new one. + // ONLY USED WHEN THE ORIGINAL WAS isActive() WHEN REPLACED private RemoteInputView mCachedExpandedRemoteInput; private RemoteInputView mCachedHeadsUpRemoteInput; + private RemoteInputViewController mCachedExpandedRemoteInputViewController; + private RemoteInputViewController mCachedHeadsUpRemoteInputViewController; + private PendingIntent mPreviousExpandedRemoteInputIntent; + private PendingIntent mPreviousHeadsUpRemoteInputIntent; private int mContentHeightAtAnimationStart = UNDEFINED; private boolean mFocusOnVisibilityChange; @@ -399,6 +412,7 @@ public class NotificationContentView extends FrameLayout { if (mExpandedRemoteInput.isActive()) { mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent(); mCachedExpandedRemoteInput = mExpandedRemoteInput; + mCachedExpandedRemoteInputViewController = mExpandedRemoteInputController; mExpandedRemoteInput.dispatchStartTemporaryDetach(); ((ViewGroup)mExpandedRemoteInput.getParent()).removeView(mExpandedRemoteInput); } @@ -407,6 +421,7 @@ public class NotificationContentView extends FrameLayout { mExpandedChild.animate().cancel(); removeView(mExpandedChild); mExpandedRemoteInput = null; + mExpandedRemoteInputController = null; } if (child == null) { mExpandedChild = null; @@ -441,6 +456,7 @@ public class NotificationContentView extends FrameLayout { if (mHeadsUpRemoteInput.isActive()) { mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent(); mCachedHeadsUpRemoteInput = mHeadsUpRemoteInput; + mCachedHeadsUpRemoteInputViewController = mHeadsUpRemoteInputController; mHeadsUpRemoteInput.dispatchStartTemporaryDetach(); ((ViewGroup)mHeadsUpRemoteInput.getParent()).removeView(mHeadsUpRemoteInput); } @@ -449,6 +465,7 @@ public class NotificationContentView extends FrameLayout { mHeadsUpChild.animate().cancel(); removeView(mHeadsUpChild); mHeadsUpRemoteInput = null; + mHeadsUpRemoteInputController = null; } if (child == null) { mHeadsUpChild = null; @@ -1127,7 +1144,7 @@ public class NotificationContentView extends FrameLayout { if (mHeadsUpChild != null) { mHeadsUpWrapper.onContentUpdated(row); } - applyRemoteInputAndSmartReply(entry); + applyRemoteInputAndSmartReply(); updateLegacy(); mForceSelectNextLayout = true; mPreviousExpandedRemoteInputIntent = null; @@ -1165,13 +1182,11 @@ public class NotificationContentView extends FrameLayout { return null != notification.findRemoteInputActionPair(true /* freeform */); } - private void applyRemoteInputAndSmartReply(final NotificationEntry entry) { - if (mRemoteInputController == null) { - return; + private void applyRemoteInputAndSmartReply() { + if (mRemoteInputController != null) { + applyRemoteInput(); } - applyRemoteInput(entry, hasFreeformRemoteInput(entry)); - if (mCurrentSmartReplyState == null) { if (DEBUG) { Log.d(TAG, "InflatedSmartReplies are null, don't add smart replies."); @@ -1180,21 +1195,25 @@ public class NotificationContentView extends FrameLayout { } if (DEBUG) { Log.d(TAG, String.format("Adding suggestions for %s, %d actions, and %d replies.", - entry.getSbn().getKey(), + mNotificationEntry.getSbn().getKey(), mCurrentSmartReplyState.getSmartActionsList().size(), mCurrentSmartReplyState.getSmartRepliesList().size())); } - applySmartReplyView(mCurrentSmartReplyState, entry); + applySmartReplyView(); } - private void applyRemoteInput(NotificationEntry entry, boolean hasFreeformRemoteInput) { - View bigContentView = mExpandedChild; - if (bigContentView != null) { - mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasFreeformRemoteInput, - mPreviousExpandedRemoteInputIntent, mCachedExpandedRemoteInput, + private void applyRemoteInput() { + boolean hasFreeformRemoteInput = hasFreeformRemoteInput(mNotificationEntry); + if (mExpandedChild != null) { + RemoteInputViewData expandedData = applyRemoteInput(mExpandedChild, mNotificationEntry, + hasFreeformRemoteInput, mPreviousExpandedRemoteInputIntent, + mCachedExpandedRemoteInput, mCachedExpandedRemoteInputViewController, mExpandedWrapper); + mExpandedRemoteInput = expandedData.mView; + mExpandedRemoteInputController = expandedData.mController; } else { mExpandedRemoteInput = null; + mExpandedRemoteInputController = null; } if (mCachedExpandedRemoteInput != null && mCachedExpandedRemoteInput != mExpandedRemoteInput) { @@ -1202,14 +1221,18 @@ public class NotificationContentView extends FrameLayout { mCachedExpandedRemoteInput.dispatchFinishTemporaryDetach(); } mCachedExpandedRemoteInput = null; + mCachedExpandedRemoteInputViewController = null; - View headsUpContentView = mHeadsUpChild; - if (headsUpContentView != null) { - mHeadsUpRemoteInput = applyRemoteInput( - headsUpContentView, entry, hasFreeformRemoteInput, - mPreviousHeadsUpRemoteInputIntent, mCachedHeadsUpRemoteInput, mHeadsUpWrapper); + if (mHeadsUpChild != null) { + RemoteInputViewData headsUpData = applyRemoteInput(mHeadsUpChild, mNotificationEntry, + hasFreeformRemoteInput, mPreviousHeadsUpRemoteInputIntent, + mCachedHeadsUpRemoteInput, mCachedHeadsUpRemoteInputViewController, + mHeadsUpWrapper); + mHeadsUpRemoteInput = headsUpData.mView; + mHeadsUpRemoteInputController = headsUpData.mController; } else { mHeadsUpRemoteInput = null; + mHeadsUpRemoteInputController = null; } if (mCachedHeadsUpRemoteInput != null && mCachedHeadsUpRemoteInput != mHeadsUpRemoteInput) { @@ -1217,22 +1240,24 @@ public class NotificationContentView extends FrameLayout { mCachedHeadsUpRemoteInput.dispatchFinishTemporaryDetach(); } mCachedHeadsUpRemoteInput = null; + mCachedHeadsUpRemoteInputViewController = null; } - - private RemoteInputView applyRemoteInput(View view, NotificationEntry entry, - boolean hasRemoteInput, PendingIntent existingPendingIntent, - RemoteInputView cachedView, NotificationViewWrapper wrapper) { + private RemoteInputViewData applyRemoteInput(View view, NotificationEntry entry, + boolean hasRemoteInput, PendingIntent existingPendingIntent, RemoteInputView cachedView, + RemoteInputViewController cachedController, NotificationViewWrapper wrapper) { + RemoteInputViewData result = new RemoteInputViewData(); View actionContainerCandidate = view.findViewById( com.android.internal.R.id.actions_container); if (actionContainerCandidate instanceof FrameLayout) { - RemoteInputView existing = view.findViewWithTag(RemoteInputView.VIEW_TAG); + result.mView = view.findViewWithTag(RemoteInputView.VIEW_TAG); - if (existing != null) { - existing.onNotificationUpdateOrReset(); + if (result.mView != null) { + result.mView.onNotificationUpdateOrReset(); + result.mController = result.mView.getController(); } - if (existing == null && hasRemoteInput) { + if (result.mView == null && hasRemoteInput) { ViewGroup actionContainer = (FrameLayout) actionContainerCandidate; if (cachedView == null) { RemoteInputView riv = RemoteInputView.inflate( @@ -1243,44 +1268,50 @@ public class NotificationContentView extends FrameLayout { ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) ); - existing = riv; + result.mView = riv; + // Create a new controller for the view. The lifetime of the controller is 1:1 + // with that of the view. + RemoteInputViewSubcomponent subcomponent = + mRemoteInputSubcomponentFactory.create(); + result.mController = subcomponent.getController(); + result.mView.setController(result.mController); } else { actionContainer.addView(cachedView); cachedView.dispatchFinishTemporaryDetach(); cachedView.requestFocus(); - existing = cachedView; + result.mView = cachedView; + result.mController = cachedController; } } if (hasRemoteInput) { - existing.setWrapper(wrapper); - existing.addOnVisibilityChangedListener(this::setRemoteInputVisible); + result.mView.setWrapper(wrapper); + result.mView.addOnVisibilityChangedListener(this::setRemoteInputVisible); - if (existingPendingIntent != null || existing.isActive()) { + if (existingPendingIntent != null || result.mView.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.getSbn().getNotification().actions; if (existingPendingIntent != null) { - existing.setPendingIntent(existingPendingIntent); + result.mView.setPendingIntent(existingPendingIntent); } - if (existing.updatePendingIntentFromActions(actions)) { - if (!existing.isActive()) { - existing.focus(); + if (result.mView.updatePendingIntentFromActions(actions)) { + if (!result.mView.isActive()) { + result.mView.focus(); } } else { - if (existing.isActive()) { - existing.close(); + if (result.mView.isActive()) { + result.mView.close(); } } } } - if (existing != null) { + if (result.mView != null) { int backgroundColor = entry.getRow().getCurrentBackgroundTint(); - boolean colorized = mNotificationEntry.getSbn().getNotification().isColorized(); - existing.setBackgroundTintColor(backgroundColor, colorized); + boolean colorized = entry.getSbn().getNotification().isColorized(); + result.mView.setBackgroundTintColor(backgroundColor, colorized); } - return existing; } - return null; + return result; } /** @@ -1373,19 +1404,19 @@ public class NotificationContentView extends FrameLayout { actionContainer.setVisibility(VISIBLE); } - private void applySmartReplyView( - InflatedSmartReplyState state, - NotificationEntry entry) { + private void applySmartReplyView() { if (mContractedChild != null) { - applyExternalSmartReplyState(mContractedChild, state); + applyExternalSmartReplyState(mContractedChild, mCurrentSmartReplyState); } if (mExpandedChild != null) { - applyExternalSmartReplyState(mExpandedChild, state); - mExpandedSmartReplyView = applySmartReplyView(mExpandedChild, state, - entry, mExpandedInflatedSmartReplies); + applyExternalSmartReplyState(mExpandedChild, mCurrentSmartReplyState); + mExpandedSmartReplyView = applySmartReplyView(mExpandedChild, mCurrentSmartReplyState, + mNotificationEntry, mExpandedInflatedSmartReplies); if (mExpandedSmartReplyView != null) { - SmartReplyView.SmartReplies smartReplies = state.getSmartReplies(); - SmartReplyView.SmartActions smartActions = state.getSmartActions(); + SmartReplyView.SmartReplies smartReplies = + mCurrentSmartReplyState.getSmartReplies(); + SmartReplyView.SmartActions smartActions = + mCurrentSmartReplyState.getSmartActions(); if (smartReplies != null || smartActions != null) { int numSmartReplies = smartReplies == null ? 0 : smartReplies.choices.size(); int numSmartActions = smartActions == null ? 0 : smartActions.actions.size(); @@ -1396,16 +1427,16 @@ public class NotificationContentView extends FrameLayout { && mSmartReplyConstants.getEffectiveEditChoicesBeforeSending( smartReplies.remoteInput.getEditChoicesBeforeSending()); - mSmartReplyController.smartSuggestionsAdded(entry, numSmartReplies, + mSmartReplyController.smartSuggestionsAdded(mNotificationEntry, numSmartReplies, numSmartActions, fromAssistant, editBeforeSending); } } } if (mHeadsUpChild != null) { - applyExternalSmartReplyState(mHeadsUpChild, state); + applyExternalSmartReplyState(mHeadsUpChild, mCurrentSmartReplyState); if (mSmartReplyConstants.getShowInHeadsUp()) { - mHeadsUpSmartReplyView = applySmartReplyView(mHeadsUpChild, state, - entry, mHeadsUpInflatedSmartReplies); + mHeadsUpSmartReplyView = applySmartReplyView(mHeadsUpChild, mCurrentSmartReplyState, + mNotificationEntry, mHeadsUpInflatedSmartReplies); } } } @@ -1439,7 +1470,7 @@ public class NotificationContentView extends FrameLayout { } @Nullable - private SmartReplyView applySmartReplyView(View view, + private static SmartReplyView applySmartReplyView(View view, InflatedSmartReplyState smartReplyState, NotificationEntry entry, InflatedSmartReplyViewHolder inflatedSmartReplyViewHolder) { View smartReplyContainerCandidate = view.findViewById( @@ -1481,7 +1512,7 @@ public class NotificationContentView extends FrameLayout { inflatedSmartReplyViewHolder.getSmartSuggestionButtons()); // Ensure the colors of the smart suggestion buttons are up-to-date. int backgroundColor = entry.getRow().getCurrentBackgroundTint(); - boolean colorized = mNotificationEntry.getSbn().getNotification().isColorized(); + boolean colorized = entry.getSbn().getNotification().isColorized(); smartReplyView.setBackgroundTintColor(backgroundColor, colorized); smartReplyContainer.setVisibility(View.VISIBLE); } @@ -1977,4 +2008,13 @@ public class NotificationContentView extends FrameLayout { } return Notification.COLOR_INVALID; } + + public void setRemoteInputViewSubcomponentFactory(RemoteInputViewSubcomponent.Factory factory) { + mRemoteInputSubcomponentFactory = factory; + } + + private static class RemoteInputViewData { + @Nullable RemoteInputView mView; + @Nullable RemoteInputViewController mController; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java index becc9a772b28b..a12d0073ef575 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java @@ -37,8 +37,11 @@ import dagger.Subcomponent; /** * Dagger Component for a {@link ExpandableNotificationRow}. */ -@Subcomponent(modules = {ExpandableNotificationRowComponent.ExpandableNotificationRowModule.class, - ActivatableNotificationViewModule.class}) +@Subcomponent(modules = { + ActivatableNotificationViewModule.class, + ExpandableNotificationRowComponent.ExpandableNotificationRowModule.class, + RemoteInputViewModule.class +}) @NotificationRowScope public interface ExpandableNotificationRowComponent { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt new file mode 100644 index 0000000000000..feb7ab5754b7b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger + +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent +import dagger.Module + +@Module(subcomponents = [RemoteInputViewSubcomponent::class]) +interface RemoteInputViewModule \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index e39e8ba370906..7e3f5fd87ed11 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -138,6 +138,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private boolean mRemoved; private NotificationViewWrapper mWrapper; + // TODO(b/193539698): remove this; views shouldn't have access to their controller, and places + // that need the controller shouldn't have access to the view + private RemoteInputViewController mViewController; + /** * Enum for logged notification remote input UiEvents. */ @@ -283,6 +287,24 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene }); } + /** + * @deprecated TODO(b/193539698): views shouldn't have access to their controller, and places + * that need the controller shouldn't have access to the view + */ + @Deprecated + public void setController(RemoteInputViewController controller) { + mViewController = controller; + } + + /** + * @deprecated TODO(b/193539698): views shouldn't have access to their controller, and places + * that need the controller shouldn't have access to the view + */ + @Deprecated + public RemoteInputViewController getController() { + return mViewController; + } + @VisibleForTesting protected void setAttachment(ContentInfo item) { if (mEntry.remoteInputAttachment != null && mEntry.remoteInputAttachment != item) { @@ -298,6 +320,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEntry.remoteInputUri = item.getClip().getItemAt(0).getUri(); mEntry.remoteInputMimeType = item.getClip().getDescription().getMimeType(0); } + View attachment = findViewById(R.id.remote_input_content_container); ImageView iconView = findViewById(R.id.remote_input_attachment_image); iconView.setImageDrawable(null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt new file mode 100644 index 0000000000000..f948030af7208 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy + +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewScope +import javax.inject.Inject + +interface RemoteInputViewController + +@RemoteInputViewScope +class RemoteInputViewControllerImpl @Inject constructor() : RemoteInputViewController \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt new file mode 100644 index 0000000000000..fe56a9840024c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy.dagger + +import com.android.systemui.statusbar.policy.RemoteInputViewController +import com.android.systemui.statusbar.policy.RemoteInputViewControllerImpl +import dagger.Binds +import dagger.Module +import dagger.Subcomponent +import javax.inject.Qualifier + +@Subcomponent(modules = [InternalRemoteInputViewModule::class]) +@RemoteInputViewScope +interface RemoteInputViewSubcomponent { + val controller: RemoteInputViewController + + @Subcomponent.Factory + interface Factory { + fun create(): RemoteInputViewSubcomponent + } +} + +@Module +private interface InternalRemoteInputViewModule { + @Binds + fun bindController(impl: RemoteInputViewControllerImpl): RemoteInputViewController +} + +@Qualifier +@Retention(AnnotationRetention.BINARY) +internal annotation class RemoteInputViewScope \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index d3738f42e020f..ed42ac3efe806 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -87,6 +87,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.SmartReplyStateInflater; +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.leak.LeakDetector; import com.android.systemui.util.time.FakeSystemClock; @@ -251,6 +252,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { new ExpandableNotificationRowController( viewCaptor.getValue(), mListContainer, + mock(RemoteInputViewSubcomponent.Factory.class), mock(ActivatableNotificationViewController.class), mNotificationMediaManager, mock(PluginManager.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index e3dcfab604f66..f3eece84e34f3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -72,6 +72,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.SmartReplyStateInflater; +import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.tests.R; import com.android.systemui.wmshell.BubblesManager; import com.android.systemui.wmshell.BubblesTestActivity; @@ -479,6 +480,7 @@ public class NotificationTestHelper { row.initialize( entry, + mock(RemoteInputViewSubcomponent.Factory.class), APP_NAME, entry.getKey(), mock(ExpansionLogger.class),