Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e458aa8d authored by Adrian Roos's avatar Adrian Roos
Browse files

Add reply text section to notifications

Also fixes a potential NPE in the failed
inflation logging in SystemUI.

Bug: 22452379
Change-Id: I829c332f7f708de8374740f6d02a2bc10a33386b
parent 1d724e02
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4851,6 +4851,7 @@ package android.app {
    field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
    field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
    field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
    field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
    field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
    field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
    field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -5017,6 +5018,7 @@ package android.app {
    method public android.app.Notification.Builder setPriority(int);
    method public android.app.Notification.Builder setProgress(int, int, boolean);
    method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
    method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
    method public android.app.Notification.Builder setShowWhen(boolean);
    method public android.app.Notification.Builder setSmallIcon(int);
    method public android.app.Notification.Builder setSmallIcon(int, int);
+2 −0
Original line number Diff line number Diff line
@@ -4971,6 +4971,7 @@ package android.app {
    field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
    field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
    field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
    field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
    field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
    field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
    field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -5137,6 +5138,7 @@ package android.app {
    method public android.app.Notification.Builder setPriority(int);
    method public android.app.Notification.Builder setProgress(int, int, boolean);
    method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
    method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
    method public android.app.Notification.Builder setShowWhen(boolean);
    method public android.app.Notification.Builder setSmallIcon(int);
    method public android.app.Notification.Builder setSmallIcon(int, int);
+2 −0
Original line number Diff line number Diff line
@@ -4851,6 +4851,7 @@ package android.app {
    field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
    field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
    field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
    field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
    field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
    field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
    field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -5017,6 +5018,7 @@ package android.app {
    method public android.app.Notification.Builder setPriority(int);
    method public android.app.Notification.Builder setProgress(int, int, boolean);
    method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
    method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
    method public android.app.Notification.Builder setShowWhen(boolean);
    method public android.app.Notification.Builder setSmallIcon(int);
    method public android.app.Notification.Builder setSmallIcon(int, int);
+92 −1
Original line number Diff line number Diff line
@@ -144,6 +144,11 @@ public class Notification implements Parcelable
     */
    private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;

    /**
     * Maximum entries of reply text that are accepted by Builder and friends.
     */
    private static final int MAX_REPLY_HISTORY = 5;

    /**
     * A timestamp related to this notification, in milliseconds since the epoch.
     *
@@ -744,6 +749,12 @@ public class Notification implements Parcelable
     */
    public static final String EXTRA_SUB_TEXT = "android.subText";

    /**
     * {@link #extras} key: this is the remote input history, as supplied to
     * {@link Builder#setRemoteInputHistory(CharSequence[])}.
     */
    public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";

    /**
     * {@link #extras} key: this is a small piece of additional text as supplied to
     * {@link Builder#setContentInfo(CharSequence)}.
@@ -2323,6 +2334,34 @@ public class Notification implements Parcelable
            return this;
        }

        /**
         * Set the remote input history.
         *
         * This should be set to the most recent inputs that have been sent
         * through a {@link RemoteInput} of this Notification and cleared once the it is no
         * longer relevant (e.g. for chat notifications once the other party has responded).
         *
         * The most recent input must be stored at the 0 index, the second most recent at the
         * 1 index, etc. Note that the system will limit both how far back the inputs will be shown
         * and how much of each individual input is shown.
         *
         * <p>Note: The reply text will only be shown on notifications that have least one action
         * with a {@code RemoteInput}.</p>
         */
        public Builder setRemoteInputHistory(CharSequence[] text) {
            if (text == null) {
                mN.extras.putCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY, null);
            } else {
                final int N = Math.min(MAX_REPLY_HISTORY, text.length);
                CharSequence[] safe = new CharSequence[N];
                for (int i = 0; i < N; i++) {
                    safe[i] = safeCharSequence(text[i]);
                }
                mN.extras.putCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY, safe);
            }
            return this;
        }

        /**
         * Set the large number at the right-hand side of the notification.  This is
         * equivalent to setContentInfo, although it might show the number in a different
@@ -3214,6 +3253,14 @@ public class Notification implements Parcelable
        private void resetStandardTemplateWithActions(RemoteViews big) {
            big.setViewVisibility(R.id.actions, View.GONE);
            big.removeAllViews(R.id.actions);

            big.setViewVisibility(R.id.notification_material_reply_container, View.GONE);
            big.setTextViewText(R.id.notification_material_reply_text_1, null);

            big.setViewVisibility(R.id.notification_material_reply_text_2, View.GONE);
            big.setTextViewText(R.id.notification_material_reply_text_2, null);
            big.setViewVisibility(R.id.notification_material_reply_text_3, View.GONE);
            big.setTextViewText(R.id.notification_material_reply_text_3, null);
        }

        private RemoteViews applyStandardTemplateWithActions(int layoutId) {
@@ -3221,18 +3268,62 @@ public class Notification implements Parcelable

            resetStandardTemplateWithActions(big);

            boolean validRemoteInput = false;

            int N = mActions.size();
            if (N > 0) {
                big.setViewVisibility(R.id.actions, View.VISIBLE);
                if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
                for (int i=0; i<N; i++) {
                    final RemoteViews button = generateActionButton(mActions.get(i));
                    Action action = mActions.get(i);
                    validRemoteInput |= hasValidRemoteInput(action);

                    final RemoteViews button = generateActionButton(action);
                    big.addView(R.id.actions, button);
                }
            }

            CharSequence[] replyText = mN.extras.getCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY);
            if (validRemoteInput && replyText != null
                    && replyText.length > 0 && !TextUtils.isEmpty(replyText[0])) {
                big.setViewVisibility(R.id.notification_material_reply_container, View.VISIBLE);
                big.setTextViewText(R.id.notification_material_reply_text_1, replyText[0]);

                if (replyText.length > 1 && !TextUtils.isEmpty(replyText[1])) {
                    big.setViewVisibility(R.id.notification_material_reply_text_2, View.VISIBLE);
                    big.setTextViewText(R.id.notification_material_reply_text_2, replyText[1]);

                    if (replyText.length > 2 && !TextUtils.isEmpty(replyText[2])) {
                        big.setViewVisibility(
                                R.id.notification_material_reply_text_3, View.VISIBLE);
                        big.setTextViewText(R.id.notification_material_reply_text_3, replyText[2]);
                    }
                }
            }

            return big;
        }

        private boolean hasValidRemoteInput(Action action) {
            if (TextUtils.isEmpty(action.title) || action.actionIntent == null) {
                // Weird actions
                return false;
            }

            RemoteInput[] remoteInputs = action.getRemoteInputs();
            if (remoteInputs == null) {
                return false;
            }

            for (RemoteInput r : remoteInputs) {
                CharSequence[] choices = r.getChoices();
                if (r.getAllowFreeFormInput() || (choices != null && choices.length != 0)) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Construct a RemoteViews for the final 1U notification layout. In order:
         *   1. Custom contentView from the caller
+61 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2015 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
  -->

<!-- Note: this layout is included from a view stub; layout attributes will be overridden. -->
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/notification_material_reply_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingStart="@dimen/notification_content_margin_start">

    <ImageView
            android:layout_width="match_parent"
            android:layout_height="1dip"
            android:id="@+id/action_divider"
            android:layout_marginBottom="15dp"
            android:background="@drawable/notification_template_divider" />

    <TextView
            android:id="@+id/notification_material_reply_text_3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/notification_content_margin_end"
            android:visibility="gone"
            android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
            android:singleLine="true" />

    <TextView
            android:id="@+id/notification_material_reply_text_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/notification_content_margin_end"
            android:visibility="gone"
            android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
            android:singleLine="true" />

    <TextView
            android:id="@+id/notification_material_reply_text_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="15dp"
            android:layout_marginEnd="@dimen/notification_content_margin_end"
            android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
            android:singleLine="true" />

</LinearLayout>
Loading