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

Commit 17ee3ec0 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Media notification updates

- Make text white.
- Adjust padding & metrics to redlines.
- Use different narrow layout when 3 or less notifications with big
  picture.
- Update action ripples.
- Fix progress bar size & fix color for indeterminate progress bar.
- Apply default background in SystemUI when no color is set, so we
  don't end up with white text on white background.

Bug: 15437369
Bug: 16625746
Bug: 15147533
Change-Id: Ie8bd5ad0bbca972685adb50034fff88ea97456bd
parent 6531ae2f
Loading
Loading
Loading
Loading
+93 −17
Original line number Original line Diff line number Diff line
@@ -22,7 +22,6 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff;
@@ -2624,6 +2623,13 @@ public class Notification implements Parcelable
        }
        }


        private RemoteViews applyStandardTemplate(int resId) {
        private RemoteViews applyStandardTemplate(int resId) {
            return applyStandardTemplate(resId, true /* hasProgress */);
        }

        /**
         * @param hasProgress whether the progress bar should be shown and set
         */
        private RemoteViews applyStandardTemplate(int resId, boolean hasProgress) {
            RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(),
            RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(),
                    mOriginatingUserId, resId);
                    mOriginatingUserId, resId);


@@ -2683,7 +2689,7 @@ public class Notification implements Parcelable
                }
                }
            } else {
            } else {
                contentView.setViewVisibility(R.id.text2, View.GONE);
                contentView.setViewVisibility(R.id.text2, View.GONE);
                if (mProgressMax != 0 || mProgressIndeterminate) {
                if (hasProgress && (mProgressMax != 0 || mProgressIndeterminate)) {
                    contentView.setProgressBar(
                    contentView.setProgressBar(
                            R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
                            R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
                    contentView.setViewVisibility(R.id.progress, View.VISIBLE);
                    contentView.setViewVisibility(R.id.progress, View.VISIBLE);
@@ -2698,7 +2704,7 @@ public class Notification implements Parcelable
                shrinkLine3Text(contentView);
                shrinkLine3Text(contentView);
            }
            }


            if (mWhen != 0 && mShowWhen) {
            if (showsTimeOrChronometer()) {
                if (mUseChronometer) {
                if (mUseChronometer) {
                    contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
                    contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
                    contentView.setLong(R.id.chronometer, "setBase",
                    contentView.setLong(R.id.chronometer, "setBase",
@@ -2731,6 +2737,14 @@ public class Notification implements Parcelable
            return contentView;
            return contentView;
        }
        }


        /**
         * @return true if the built notification will show the time or the chronometer; false
         *         otherwise
         */
        private boolean showsTimeOrChronometer() {
            return mWhen != 0 && mShowWhen;
        }

        /**
        /**
         * Logic to find out whether the notification is going to have three lines in the contracted
         * Logic to find out whether the notification is going to have three lines in the contracted
         * layout. This is used to adjust the top padding.
         * layout. This is used to adjust the top padding.
@@ -2740,13 +2754,14 @@ public class Notification implements Parcelable
         */
         */
        private boolean hasThreeLines() {
        private boolean hasThreeLines() {
            boolean contentTextInLine2 = mSubText != null && mContentText != null;
            boolean contentTextInLine2 = mSubText != null && mContentText != null;

            boolean hasProgress = mStyle == null || mStyle.hasProgress();
            // If we have content text in line 2, badge goes into line 2, or line 3 otherwise
            // If we have content text in line 2, badge goes into line 2, or line 3 otherwise
            boolean badgeInLine3 = getProfileBadgeDrawable() != null && !contentTextInLine2;
            boolean badgeInLine3 = getProfileBadgeDrawable() != null && !contentTextInLine2;
            boolean hasLine3 = mContentText != null || mContentInfo != null || mNumber > 0
            boolean hasLine3 = mContentText != null || mContentInfo != null || mNumber > 0
                    || badgeInLine3;
                    || badgeInLine3;
            boolean hasLine2 = (mSubText != null && mContentText != null) ||
            boolean hasLine2 = (mSubText != null && mContentText != null) ||
                    (mSubText == null && (mProgressMax != 0 || mProgressIndeterminate));
                    (hasProgress && mSubText == null
                            && (mProgressMax != 0 || mProgressIndeterminate));
            return hasLine2 && hasLine3;
            return hasLine2 && hasLine3;
        }
        }


@@ -3488,6 +3503,15 @@ public class Notification implements Parcelable
            checkBuilder();
            checkBuilder();
            return mBuilder.build();
            return mBuilder.build();
        }
        }

        /**
         * @hide
         * @return true if the style positions the progress bar on the second line; false if the
         *         style hides the progress bar
         */
        protected boolean hasProgress() {
            return true;
        }
    }
    }


    /**
    /**
@@ -3885,7 +3909,7 @@ public class Notification implements Parcelable
     * @see Notification#bigContentView
     * @see Notification#bigContentView
     */
     */
    public static class MediaStyle extends Style {
    public static class MediaStyle extends Style {
        static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 2;
        static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
        static final int MAX_MEDIA_BUTTONS = 5;
        static final int MAX_MEDIA_BUTTONS = 5;


        private int[] mActionsToShowInCompact = null;
        private int[] mActionsToShowInCompact = null;
@@ -3899,8 +3923,10 @@ public class Notification implements Parcelable
        }
        }


        /**
        /**
         * Request up to 2 actions (by index in the order of addition) to be shown in the compact
         * Request up to 3 actions (by index in the order of addition) to be shown in the compact
         * notification view.
         * notification view.
         *
         * @param actions the indices of the actions to show in the compact notification view
         */
         */
        public MediaStyle setShowActionsInCompactView(int...actions) {
        public MediaStyle setShowActionsInCompactView(int...actions) {
            mActionsToShowInCompact = actions;
            mActionsToShowInCompact = actions;
@@ -3977,6 +4003,9 @@ public class Notification implements Parcelable
            RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(),
            RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(),
                    R.layout.notification_material_media_action);
                    R.layout.notification_material_media_action);
            button.setImageViewResource(R.id.action0, action.icon);
            button.setImageViewResource(R.id.action0, action.icon);
            button.setDrawableParameters(R.id.action0, false, -1,
                    0xFFFFFFFF,
                    PorterDuff.Mode.SRC_ATOP, -1);
            if (!tombstone) {
            if (!tombstone) {
                button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
                button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
            }
            }
@@ -3986,14 +4015,14 @@ public class Notification implements Parcelable


        private RemoteViews makeMediaContentView() {
        private RemoteViews makeMediaContentView() {
            RemoteViews view = mBuilder.applyStandardTemplate(
            RemoteViews view = mBuilder.applyStandardTemplate(
                    R.layout.notification_template_material_media);
                    R.layout.notification_template_material_media, false /* hasProgress */);


            final int numActions = mBuilder.mActions.size();
            final int numActions = mBuilder.mActions.size();
            final int N = mActionsToShowInCompact == null
            final int N = mActionsToShowInCompact == null
                    ? 0
                    ? 0
                    : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
                    : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
            if (N > 0) {
            if (N > 0) {
                view.removeAllViews(R.id.actions);
                view.removeAllViews(com.android.internal.R.id.media_actions);
                for (int i = 0; i < N; i++) {
                for (int i = 0; i < N; i++) {
                    if (i >= numActions) {
                    if (i >= numActions) {
                        throw new IllegalArgumentException(String.format(
                        throw new IllegalArgumentException(String.format(
@@ -4003,26 +4032,73 @@ public class Notification implements Parcelable


                    final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
                    final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
                    final RemoteViews button = generateMediaActionButton(action);
                    final RemoteViews button = generateMediaActionButton(action);
                    view.addView(R.id.actions, button);
                    view.addView(com.android.internal.R.id.media_actions, button);
                }
                }
            }
            }
            styleText(view);
            hideRightIcon(view);
            return view;
            return view;
        }
        }


        private RemoteViews makeMediaBigContentView() {
        private RemoteViews makeMediaBigContentView() {
            RemoteViews big = mBuilder.applyStandardTemplate(
            final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
                    R.layout.notification_template_material_big_media);
            RemoteViews big = mBuilder.applyStandardTemplate(getBigLayoutResource(actionCount),
                    false /* hasProgress */);


            final int N = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
            if (actionCount > 0) {
            if (N > 0) {
                big.removeAllViews(com.android.internal.R.id.media_actions);
                big.removeAllViews(R.id.actions);
                for (int i = 0; i < actionCount; i++) {
                for (int i=0; i<N; i++) {
                    final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i));
                    final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i));
                    big.addView(R.id.actions, button);
                    big.addView(com.android.internal.R.id.media_actions, button);
                }
                }
            }
            }
            styleText(big);
            hideRightIcon(big);
            applyTopPadding(big);
            big.setViewVisibility(android.R.id.progress, View.GONE);
            return big;
            return big;
        }
        }

        private int getBigLayoutResource(int actionCount) {
            if (actionCount <= 3) {
                return R.layout.notification_template_material_big_media_narrow;
            } else {
                return R.layout.notification_template_material_big_media;
            }
        }

        private void hideRightIcon(RemoteViews contentView) {
            contentView.setViewVisibility(R.id.right_icon, View.GONE);
        }

        /**
         * Applies the special text colors for media notifications to all text views.
         */
        private void styleText(RemoteViews contentView) {
            int primaryColor = mBuilder.mContext.getResources().getColor(
                    R.color.notification_media_primary_color);
            int secondaryColor = mBuilder.mContext.getResources().getColor(
                    R.color.notification_media_secondary_color);
            contentView.setTextColor(R.id.title, primaryColor);
            if (mBuilder.showsTimeOrChronometer()) {
                if (mBuilder.mUseChronometer) {
                    contentView.setTextColor(R.id.chronometer, secondaryColor);
                } else {
                    contentView.setTextColor(R.id.time, secondaryColor);
                }
            }
            contentView.setTextColor(R.id.text2, secondaryColor);
            contentView.setTextColor(R.id.text, secondaryColor);
            contentView.setTextColor(R.id.info, secondaryColor);
        }

        /**
         * @hide
         */
        @Override
        protected boolean hasProgress() {
            return false;
        }
    }
    }


    // When adding a new Style subclass here, don't forget to update
    // When adding a new Style subclass here, don't forget to update
+3 −3
Original line number Original line Diff line number Diff line
@@ -864,7 +864,7 @@ public class RemoteViews implements Parcelable, Filter {
                if (alpha != -1) {
                if (alpha != -1) {
                    targetDrawable.setAlpha(alpha);
                    targetDrawable.setAlpha(alpha);
                }
                }
                if (colorFilter != -1 && filterMode != null) {
                if (filterMode != null) {
                    targetDrawable.setColorFilter(colorFilter, filterMode);
                    targetDrawable.setColorFilter(colorFilter, filterMode);
                }
                }
                if (level != -1) {
                if (level != -1) {
@@ -2189,8 +2189,8 @@ public class RemoteViews implements Parcelable, Filter {
     * @param alpha Specify an alpha value for the drawable, or -1 to leave
     * @param alpha Specify an alpha value for the drawable, or -1 to leave
     *            unchanged.
     *            unchanged.
     * @param colorFilter Specify a color for a
     * @param colorFilter Specify a color for a
     *            {@link android.graphics.ColorFilter} for this drawable, or -1
     *            {@link android.graphics.ColorFilter} for this drawable. This will be ignored if
     *            to leave unchanged.
     *            {@code mode} is {@code null}.
     * @param mode Specify a PorterDuff mode for this drawable, or null to leave
     * @param mode Specify a PorterDuff mode for this drawable, or null to leave
     *            unchanged.
     *            unchanged.
     * @param level Specify the level for the drawable, or -1 to leave
     * @param level Specify the level for the drawable, or -1 to leave
+23 −0
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2014 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
  -->

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="@color/ripple_material_light">
    <item android:id="@id/mask"
          android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>
+19 −0
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2014 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
  -->

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/ripple_material_dark" />
+0 −28
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@id/background" android:drawable="@color/transparent">
    </item>
    <item android:id="@id/secondaryProgress">
        <scale android:scaleWidth="100%"
            android:drawable="@color/notification_media_progress" />
    </item>
    <item android:id="@id/progress">
        <scale android:scaleWidth="100%"
            android:drawable="@color/notification_media_progress" />
    </item>
</layer-list>
Loading