[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
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user