From c4ff8e2a2883bed2e52dc7a2fac049855d54eb7d Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Wed, 22 Sep 2021 18:06:15 -0400 Subject: [PATCH] [RemoteInputView] Introduce RemoteInputViewController Add a new Controller for RemoteInputView that will eventually house all of the non-View code currently located inside of RemoteInputView. This CL establishes the new Dagger configuration needed to instantiate the Controller, as well as the lifecycle management by the parent Controller (in this case, NotificationContentView, which doesn't have a Controller of its own; once a Controller is introduced for that class, the reference to the RemoteInputViewController will move there). Bug: 193539698 Test: mp sysuig, receive some notifications, nothing breaks Change-Id: Ib5397abe03569d2285764b69136ef44b903b1247 --- .../src/com/android/systemui/Dependency.java | 1 + .../row/ExpandableNotificationRow.java | 3 + .../ExpandableNotificationRowController.java | 5 + .../row/NotificationContentView.java | 158 +++++++++++------- .../ExpandableNotificationRowComponent.java | 7 +- .../row/dagger/RemoteInputViewModule.kt | 23 +++ .../statusbar/policy/RemoteInputView.java | 23 +++ .../policy/RemoteInputViewController.kt | 25 +++ .../statusbar/policy/dagger/RemoteInput.kt | 45 +++++ ...NotificationEntryManagerInflationTest.java | 2 + .../row/NotificationTestHelper.java | 2 + 11 files changed, 233 insertions(+), 61 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt 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),