Loading core/java/android/provider/Settings.java +6 −5 Original line number Diff line number Diff line Loading @@ -13933,6 +13933,7 @@ public final class Settings { * max_squeeze_remeasure_attempts (int) * edit_choices_before_sending (boolean) * show_in_heads_up (boolean) * min_num_system_generated_replies (int) * </pre> * @see com.android.systemui.statusbar.policy.SmartReplyConstants * @hide packages/SystemUI/res/values/config.xml +5 −0 Original line number Diff line number Diff line Loading @@ -458,6 +458,11 @@ heads-up notifications. --> <bool name="config_smart_replies_in_notifications_show_in_heads_up">true</bool> <!-- Smart replies in notifications: Minimum number of system generated smart replies that should be shown in a notification. If we cannot show at least this many replies we instead show none. --> <integer name="config_smart_replies_in_notifications_min_num_system_generated_replies">0</integer> <!-- Screenshot editing default activity. Must handle ACTION_EDIT image/png intents. Blank sends the user to the Chooser first. This name is in the ComponentName flattened format (package/class) --> Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java +15 −0 Original line number Diff line number Diff line Loading @@ -46,18 +46,21 @@ public final class SmartReplyConstants extends ContentObserver { private static final String KEY_EDIT_CHOICES_BEFORE_SENDING = "edit_choices_before_sending"; private static final String KEY_SHOW_IN_HEADS_UP = "show_in_heads_up"; private static final String KEY_MIN_NUM_REPLIES = "min_num_system_generated_replies"; private final boolean mDefaultEnabled; private final boolean mDefaultRequiresP; private final int mDefaultMaxSqueezeRemeasureAttempts; private final boolean mDefaultEditChoicesBeforeSending; private final boolean mDefaultShowInHeadsUp; private final int mDefaultMinNumSystemGeneratedReplies; private boolean mEnabled; private boolean mRequiresTargetingP; private int mMaxSqueezeRemeasureAttempts; private boolean mEditChoicesBeforeSending; private boolean mShowInHeadsUp; private int mMinNumSystemGeneratedReplies; private final Context mContext; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading @@ -78,6 +81,8 @@ public final class SmartReplyConstants extends ContentObserver { R.bool.config_smart_replies_in_notifications_edit_choices_before_sending); mDefaultShowInHeadsUp = resources.getBoolean( R.bool.config_smart_replies_in_notifications_show_in_heads_up); mDefaultMinNumSystemGeneratedReplies = resources.getInteger( R.integer.config_smart_replies_in_notifications_min_num_system_generated_replies); mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS), Loading Loading @@ -105,6 +110,8 @@ public final class SmartReplyConstants extends ContentObserver { mEditChoicesBeforeSending = mParser.getBoolean( KEY_EDIT_CHOICES_BEFORE_SENDING, mDefaultEditChoicesBeforeSending); mShowInHeadsUp = mParser.getBoolean(KEY_SHOW_IN_HEADS_UP, mDefaultShowInHeadsUp); mMinNumSystemGeneratedReplies = mParser.getInt(KEY_MIN_NUM_REPLIES, mDefaultMinNumSystemGeneratedReplies); } } Loading Loading @@ -155,4 +162,12 @@ public final class SmartReplyConstants extends ContentObserver { public boolean getShowInHeadsUp() { return mShowInHeadsUp; } /** * Returns the minimum number of system generated replies to show in a notification. * If we cannot show at least this many system generated replies we should show none. */ public int getMinNumSystemGeneratedReplies() { return mMinNumSystemGeneratedReplies; } } packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +104 −26 Original line number Diff line number Diff line Loading @@ -88,6 +88,12 @@ public class SmartReplyView extends ViewGroup { private View mSmartReplyContainer; /** * Whether the smart replies in this view were generated by the notification assistant. If not * they're provided by the app. */ private boolean mSmartRepliesGeneratedByAssistant = false; @ColorInt private int mCurrentBackgroundColor; @ColorInt Loading Loading @@ -202,6 +208,7 @@ public class SmartReplyView extends ViewGroup { getContext(), this, i, smartReplies, smartReplyController, entry); addView(replyButton); } this.mSmartRepliesGeneratedByAssistant = smartReplies.fromAssistant; } } reallocateCandidateButtonQueueForSqueezing(); Loading Loading @@ -344,10 +351,11 @@ public class SmartReplyView extends ViewGroup { mCandidateButtonQueueForSqueezing.clear(); } int measuredWidth = mPaddingLeft + mPaddingRight; int maxChildHeight = 0; SmartSuggestionMeasures accumulatedMeasures = new SmartSuggestionMeasures( mPaddingLeft + mPaddingRight, 0 /* maxChildHeight */, mSingleLineButtonPaddingHorizontal); int displayedChildCount = 0; int buttonPaddingHorizontal = mSingleLineButtonPaddingHorizontal; // Set up a list of suggestions where actions come before replies. Note that the Buttons // themselves have already been added to the view hierarchy in an order such that Smart Loading @@ -360,11 +368,15 @@ public class SmartReplyView extends ViewGroup { smartSuggestions.addAll(smartReplies); List<View> coveredSuggestions = new ArrayList<>(); // SmartSuggestionMeasures for all action buttons, this will be filled in when the first // reply button is added. SmartSuggestionMeasures actionsMeasures = null; for (View child : smartSuggestions) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(), buttonPaddingHorizontal, child.getPaddingBottom()); child.setPadding(accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingTop(), accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingBottom()); child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec); coveredSuggestions.add(child); Loading @@ -380,45 +392,52 @@ public class SmartReplyView extends ViewGroup { } // Remember the current measurements in case the current button doesn't fit in. final int originalMaxChildHeight = maxChildHeight; final int originalMeasuredWidth = measuredWidth; final int originalButtonPaddingHorizontal = buttonPaddingHorizontal; SmartSuggestionMeasures originalMeasures = accumulatedMeasures.clone(); if (actionsMeasures == null && lp.buttonType == SmartButtonType.REPLY) { // We've added all actions (we go through actions first), now add their // measurements. actionsMeasures = accumulatedMeasures.clone(); } final int spacing = displayedChildCount == 0 ? 0 : mSpacing; final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); measuredWidth += spacing + childWidth; maxChildHeight = Math.max(maxChildHeight, childHeight); accumulatedMeasures.mMeasuredWidth += spacing + childWidth; accumulatedMeasures.mMaxChildHeight = Math.max(accumulatedMeasures.mMaxChildHeight, childHeight); // Do we need to increase the number of lines in smart reply buttons to two? final boolean increaseToTwoLines = buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal && (lineCount == 2 || measuredWidth > targetWidth); (accumulatedMeasures.mButtonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) && (lineCount == 2 || accumulatedMeasures.mMeasuredWidth > targetWidth); if (increaseToTwoLines) { measuredWidth += (displayedChildCount + 1) * mSingleToDoubleLineButtonWidthIncrease; buttonPaddingHorizontal = mDoubleLineButtonPaddingHorizontal; accumulatedMeasures.mMeasuredWidth += (displayedChildCount + 1) * mSingleToDoubleLineButtonWidthIncrease; accumulatedMeasures.mButtonPaddingHorizontal = mDoubleLineButtonPaddingHorizontal; } // If the last button doesn't fit into the remaining width, try squeezing preceding // smart reply buttons. if (measuredWidth > targetWidth) { if (accumulatedMeasures.mMeasuredWidth > targetWidth) { // Keep squeezing preceding and current smart reply buttons until they all fit. while (measuredWidth > targetWidth while (accumulatedMeasures.mMeasuredWidth > targetWidth && !mCandidateButtonQueueForSqueezing.isEmpty()) { final Button candidate = mCandidateButtonQueueForSqueezing.poll(); final int squeezeReduction = squeezeButton(candidate, heightMeasureSpec); if (squeezeReduction != SQUEEZE_FAILED) { maxChildHeight = Math.max(maxChildHeight, candidate.getMeasuredHeight()); measuredWidth -= squeezeReduction; accumulatedMeasures.mMaxChildHeight = Math.max(accumulatedMeasures.mMaxChildHeight, candidate.getMeasuredHeight()); accumulatedMeasures.mMeasuredWidth -= squeezeReduction; } } // If the current button still doesn't fit after squeezing all buttons, undo the // last squeezing round. if (measuredWidth > targetWidth) { measuredWidth = originalMeasuredWidth; maxChildHeight = originalMaxChildHeight; buttonPaddingHorizontal = originalButtonPaddingHorizontal; if (accumulatedMeasures.mMeasuredWidth > targetWidth) { accumulatedMeasures = originalMeasures; // Mark all buttons from the last squeezing round as "failed to squeeze", so // that they're re-measured without squeezing later. Loading @@ -440,16 +459,75 @@ public class SmartReplyView extends ViewGroup { displayedChildCount++; } if (mSmartRepliesGeneratedByAssistant) { if (!gotEnoughSmartReplies(smartReplies)) { // We don't have enough smart replies - hide all of them. for (View smartReplyButton : smartReplies) { final LayoutParams lp = (LayoutParams) smartReplyButton.getLayoutParams(); lp.show = false; } // Reset our measures back to when we had only added actions (before adding // replies). accumulatedMeasures = actionsMeasures; } } // We're done squeezing buttons, so we can clear the priority queue. mCandidateButtonQueueForSqueezing.clear(); // Finally, we need to re-measure some buttons. remeasureButtonsIfNecessary(buttonPaddingHorizontal, maxChildHeight); remeasureButtonsIfNecessary(accumulatedMeasures.mButtonPaddingHorizontal, accumulatedMeasures.mMaxChildHeight); setMeasuredDimension( resolveSize(Math.max(getSuggestedMinimumWidth(), measuredWidth), widthMeasureSpec), resolveSize(Math.max(getSuggestedMinimumHeight(), mPaddingTop + maxChildHeight + mPaddingBottom), heightMeasureSpec)); resolveSize(Math.max(getSuggestedMinimumWidth(), accumulatedMeasures.mMeasuredWidth), widthMeasureSpec), resolveSize(Math.max(getSuggestedMinimumHeight(), mPaddingTop + accumulatedMeasures.mMaxChildHeight + mPaddingBottom), heightMeasureSpec)); } /** * Fields we keep track of inside onMeasure() to correctly measure the SmartReplyView depending * on which suggestions are added. */ private static class SmartSuggestionMeasures { int mMeasuredWidth = -1; int mMaxChildHeight = -1; int mButtonPaddingHorizontal = -1; SmartSuggestionMeasures(int measuredWidth, int maxChildHeight, int buttonPaddingHorizontal) { this.mMeasuredWidth = measuredWidth; this.mMaxChildHeight = maxChildHeight; this.mButtonPaddingHorizontal = buttonPaddingHorizontal; } public SmartSuggestionMeasures clone() { return new SmartSuggestionMeasures( mMeasuredWidth, mMaxChildHeight, mButtonPaddingHorizontal); } } /** * Returns whether our notification contains at least N smart replies (or 0) where N is * determined by {@link SmartReplyConstants}. */ private boolean gotEnoughSmartReplies(List<View> smartReplies) { int numShownReplies = 0; for (View smartReplyButton : smartReplies) { final LayoutParams lp = (LayoutParams) smartReplyButton.getLayoutParams(); if (lp.show) { numShownReplies++; } } if (numShownReplies == 0 || numShownReplies >= mConstants.getMinNumSystemGeneratedReplies()) { // We have enough replies, yay! return true; } return false; } private List<View> filterActionsOrReplies(SmartButtonType buttonType) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ public class SmartReplyConstantsTest extends SysuiTestCase { resources.addOverride( R.bool.config_smart_replies_in_notifications_edit_choices_before_sending, false); resources.addOverride(R.bool.config_smart_replies_in_notifications_show_in_heads_up, true); resources.addOverride( R.integer.config_smart_replies_in_notifications_min_num_system_generated_replies, 2); mConstants = new SmartReplyConstants(Handler.createAsync(Looper.myLooper()), mContext); } Loading Loading @@ -178,6 +181,19 @@ public class SmartReplyConstantsTest extends SysuiTestCase { Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS, flags); } @Test public void testGetMinNumSystemGeneratedRepliesWithNoConfig() { assertTrue(mConstants.isEnabled()); assertEquals(2, mConstants.getMinNumSystemGeneratedReplies()); } @Test public void testGetMinNumSystemGeneratedRepliesWithValidConfig() { overrideSetting("enabled=true,min_num_system_generated_replies=5"); triggerConstantsOnChange(); assertEquals(5, mConstants.getMinNumSystemGeneratedReplies()); } private void triggerConstantsOnChange() { // Since Settings.Global is mocked in TestableContext, we need to manually trigger the // content observer. Loading Loading
core/java/android/provider/Settings.java +6 −5 Original line number Diff line number Diff line Loading @@ -13933,6 +13933,7 @@ public final class Settings { * max_squeeze_remeasure_attempts (int) * edit_choices_before_sending (boolean) * show_in_heads_up (boolean) * min_num_system_generated_replies (int) * </pre> * @see com.android.systemui.statusbar.policy.SmartReplyConstants * @hide
packages/SystemUI/res/values/config.xml +5 −0 Original line number Diff line number Diff line Loading @@ -458,6 +458,11 @@ heads-up notifications. --> <bool name="config_smart_replies_in_notifications_show_in_heads_up">true</bool> <!-- Smart replies in notifications: Minimum number of system generated smart replies that should be shown in a notification. If we cannot show at least this many replies we instead show none. --> <integer name="config_smart_replies_in_notifications_min_num_system_generated_replies">0</integer> <!-- Screenshot editing default activity. Must handle ACTION_EDIT image/png intents. Blank sends the user to the Chooser first. This name is in the ComponentName flattened format (package/class) --> Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java +15 −0 Original line number Diff line number Diff line Loading @@ -46,18 +46,21 @@ public final class SmartReplyConstants extends ContentObserver { private static final String KEY_EDIT_CHOICES_BEFORE_SENDING = "edit_choices_before_sending"; private static final String KEY_SHOW_IN_HEADS_UP = "show_in_heads_up"; private static final String KEY_MIN_NUM_REPLIES = "min_num_system_generated_replies"; private final boolean mDefaultEnabled; private final boolean mDefaultRequiresP; private final int mDefaultMaxSqueezeRemeasureAttempts; private final boolean mDefaultEditChoicesBeforeSending; private final boolean mDefaultShowInHeadsUp; private final int mDefaultMinNumSystemGeneratedReplies; private boolean mEnabled; private boolean mRequiresTargetingP; private int mMaxSqueezeRemeasureAttempts; private boolean mEditChoicesBeforeSending; private boolean mShowInHeadsUp; private int mMinNumSystemGeneratedReplies; private final Context mContext; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading @@ -78,6 +81,8 @@ public final class SmartReplyConstants extends ContentObserver { R.bool.config_smart_replies_in_notifications_edit_choices_before_sending); mDefaultShowInHeadsUp = resources.getBoolean( R.bool.config_smart_replies_in_notifications_show_in_heads_up); mDefaultMinNumSystemGeneratedReplies = resources.getInteger( R.integer.config_smart_replies_in_notifications_min_num_system_generated_replies); mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS), Loading Loading @@ -105,6 +110,8 @@ public final class SmartReplyConstants extends ContentObserver { mEditChoicesBeforeSending = mParser.getBoolean( KEY_EDIT_CHOICES_BEFORE_SENDING, mDefaultEditChoicesBeforeSending); mShowInHeadsUp = mParser.getBoolean(KEY_SHOW_IN_HEADS_UP, mDefaultShowInHeadsUp); mMinNumSystemGeneratedReplies = mParser.getInt(KEY_MIN_NUM_REPLIES, mDefaultMinNumSystemGeneratedReplies); } } Loading Loading @@ -155,4 +162,12 @@ public final class SmartReplyConstants extends ContentObserver { public boolean getShowInHeadsUp() { return mShowInHeadsUp; } /** * Returns the minimum number of system generated replies to show in a notification. * If we cannot show at least this many system generated replies we should show none. */ public int getMinNumSystemGeneratedReplies() { return mMinNumSystemGeneratedReplies; } }
packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +104 −26 Original line number Diff line number Diff line Loading @@ -88,6 +88,12 @@ public class SmartReplyView extends ViewGroup { private View mSmartReplyContainer; /** * Whether the smart replies in this view were generated by the notification assistant. If not * they're provided by the app. */ private boolean mSmartRepliesGeneratedByAssistant = false; @ColorInt private int mCurrentBackgroundColor; @ColorInt Loading Loading @@ -202,6 +208,7 @@ public class SmartReplyView extends ViewGroup { getContext(), this, i, smartReplies, smartReplyController, entry); addView(replyButton); } this.mSmartRepliesGeneratedByAssistant = smartReplies.fromAssistant; } } reallocateCandidateButtonQueueForSqueezing(); Loading Loading @@ -344,10 +351,11 @@ public class SmartReplyView extends ViewGroup { mCandidateButtonQueueForSqueezing.clear(); } int measuredWidth = mPaddingLeft + mPaddingRight; int maxChildHeight = 0; SmartSuggestionMeasures accumulatedMeasures = new SmartSuggestionMeasures( mPaddingLeft + mPaddingRight, 0 /* maxChildHeight */, mSingleLineButtonPaddingHorizontal); int displayedChildCount = 0; int buttonPaddingHorizontal = mSingleLineButtonPaddingHorizontal; // Set up a list of suggestions where actions come before replies. Note that the Buttons // themselves have already been added to the view hierarchy in an order such that Smart Loading @@ -360,11 +368,15 @@ public class SmartReplyView extends ViewGroup { smartSuggestions.addAll(smartReplies); List<View> coveredSuggestions = new ArrayList<>(); // SmartSuggestionMeasures for all action buttons, this will be filled in when the first // reply button is added. SmartSuggestionMeasures actionsMeasures = null; for (View child : smartSuggestions) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(), buttonPaddingHorizontal, child.getPaddingBottom()); child.setPadding(accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingTop(), accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingBottom()); child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec); coveredSuggestions.add(child); Loading @@ -380,45 +392,52 @@ public class SmartReplyView extends ViewGroup { } // Remember the current measurements in case the current button doesn't fit in. final int originalMaxChildHeight = maxChildHeight; final int originalMeasuredWidth = measuredWidth; final int originalButtonPaddingHorizontal = buttonPaddingHorizontal; SmartSuggestionMeasures originalMeasures = accumulatedMeasures.clone(); if (actionsMeasures == null && lp.buttonType == SmartButtonType.REPLY) { // We've added all actions (we go through actions first), now add their // measurements. actionsMeasures = accumulatedMeasures.clone(); } final int spacing = displayedChildCount == 0 ? 0 : mSpacing; final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); measuredWidth += spacing + childWidth; maxChildHeight = Math.max(maxChildHeight, childHeight); accumulatedMeasures.mMeasuredWidth += spacing + childWidth; accumulatedMeasures.mMaxChildHeight = Math.max(accumulatedMeasures.mMaxChildHeight, childHeight); // Do we need to increase the number of lines in smart reply buttons to two? final boolean increaseToTwoLines = buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal && (lineCount == 2 || measuredWidth > targetWidth); (accumulatedMeasures.mButtonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) && (lineCount == 2 || accumulatedMeasures.mMeasuredWidth > targetWidth); if (increaseToTwoLines) { measuredWidth += (displayedChildCount + 1) * mSingleToDoubleLineButtonWidthIncrease; buttonPaddingHorizontal = mDoubleLineButtonPaddingHorizontal; accumulatedMeasures.mMeasuredWidth += (displayedChildCount + 1) * mSingleToDoubleLineButtonWidthIncrease; accumulatedMeasures.mButtonPaddingHorizontal = mDoubleLineButtonPaddingHorizontal; } // If the last button doesn't fit into the remaining width, try squeezing preceding // smart reply buttons. if (measuredWidth > targetWidth) { if (accumulatedMeasures.mMeasuredWidth > targetWidth) { // Keep squeezing preceding and current smart reply buttons until they all fit. while (measuredWidth > targetWidth while (accumulatedMeasures.mMeasuredWidth > targetWidth && !mCandidateButtonQueueForSqueezing.isEmpty()) { final Button candidate = mCandidateButtonQueueForSqueezing.poll(); final int squeezeReduction = squeezeButton(candidate, heightMeasureSpec); if (squeezeReduction != SQUEEZE_FAILED) { maxChildHeight = Math.max(maxChildHeight, candidate.getMeasuredHeight()); measuredWidth -= squeezeReduction; accumulatedMeasures.mMaxChildHeight = Math.max(accumulatedMeasures.mMaxChildHeight, candidate.getMeasuredHeight()); accumulatedMeasures.mMeasuredWidth -= squeezeReduction; } } // If the current button still doesn't fit after squeezing all buttons, undo the // last squeezing round. if (measuredWidth > targetWidth) { measuredWidth = originalMeasuredWidth; maxChildHeight = originalMaxChildHeight; buttonPaddingHorizontal = originalButtonPaddingHorizontal; if (accumulatedMeasures.mMeasuredWidth > targetWidth) { accumulatedMeasures = originalMeasures; // Mark all buttons from the last squeezing round as "failed to squeeze", so // that they're re-measured without squeezing later. Loading @@ -440,16 +459,75 @@ public class SmartReplyView extends ViewGroup { displayedChildCount++; } if (mSmartRepliesGeneratedByAssistant) { if (!gotEnoughSmartReplies(smartReplies)) { // We don't have enough smart replies - hide all of them. for (View smartReplyButton : smartReplies) { final LayoutParams lp = (LayoutParams) smartReplyButton.getLayoutParams(); lp.show = false; } // Reset our measures back to when we had only added actions (before adding // replies). accumulatedMeasures = actionsMeasures; } } // We're done squeezing buttons, so we can clear the priority queue. mCandidateButtonQueueForSqueezing.clear(); // Finally, we need to re-measure some buttons. remeasureButtonsIfNecessary(buttonPaddingHorizontal, maxChildHeight); remeasureButtonsIfNecessary(accumulatedMeasures.mButtonPaddingHorizontal, accumulatedMeasures.mMaxChildHeight); setMeasuredDimension( resolveSize(Math.max(getSuggestedMinimumWidth(), measuredWidth), widthMeasureSpec), resolveSize(Math.max(getSuggestedMinimumHeight(), mPaddingTop + maxChildHeight + mPaddingBottom), heightMeasureSpec)); resolveSize(Math.max(getSuggestedMinimumWidth(), accumulatedMeasures.mMeasuredWidth), widthMeasureSpec), resolveSize(Math.max(getSuggestedMinimumHeight(), mPaddingTop + accumulatedMeasures.mMaxChildHeight + mPaddingBottom), heightMeasureSpec)); } /** * Fields we keep track of inside onMeasure() to correctly measure the SmartReplyView depending * on which suggestions are added. */ private static class SmartSuggestionMeasures { int mMeasuredWidth = -1; int mMaxChildHeight = -1; int mButtonPaddingHorizontal = -1; SmartSuggestionMeasures(int measuredWidth, int maxChildHeight, int buttonPaddingHorizontal) { this.mMeasuredWidth = measuredWidth; this.mMaxChildHeight = maxChildHeight; this.mButtonPaddingHorizontal = buttonPaddingHorizontal; } public SmartSuggestionMeasures clone() { return new SmartSuggestionMeasures( mMeasuredWidth, mMaxChildHeight, mButtonPaddingHorizontal); } } /** * Returns whether our notification contains at least N smart replies (or 0) where N is * determined by {@link SmartReplyConstants}. */ private boolean gotEnoughSmartReplies(List<View> smartReplies) { int numShownReplies = 0; for (View smartReplyButton : smartReplies) { final LayoutParams lp = (LayoutParams) smartReplyButton.getLayoutParams(); if (lp.show) { numShownReplies++; } } if (numShownReplies == 0 || numShownReplies >= mConstants.getMinNumSystemGeneratedReplies()) { // We have enough replies, yay! return true; } return false; } private List<View> filterActionsOrReplies(SmartButtonType buttonType) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ public class SmartReplyConstantsTest extends SysuiTestCase { resources.addOverride( R.bool.config_smart_replies_in_notifications_edit_choices_before_sending, false); resources.addOverride(R.bool.config_smart_replies_in_notifications_show_in_heads_up, true); resources.addOverride( R.integer.config_smart_replies_in_notifications_min_num_system_generated_replies, 2); mConstants = new SmartReplyConstants(Handler.createAsync(Looper.myLooper()), mContext); } Loading Loading @@ -178,6 +181,19 @@ public class SmartReplyConstantsTest extends SysuiTestCase { Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS, flags); } @Test public void testGetMinNumSystemGeneratedRepliesWithNoConfig() { assertTrue(mConstants.isEnabled()); assertEquals(2, mConstants.getMinNumSystemGeneratedReplies()); } @Test public void testGetMinNumSystemGeneratedRepliesWithValidConfig() { overrideSetting("enabled=true,min_num_system_generated_replies=5"); triggerConstantsOnChange(); assertEquals(5, mConstants.getMinNumSystemGeneratedReplies()); } private void triggerConstantsOnChange() { // Since Settings.Global is mocked in TestableContext, we need to manually trigger the // content observer. Loading