Loading core/java/android/app/Notification.java +25 −6 Original line number Diff line number Diff line Loading @@ -3519,6 +3519,8 @@ public class Notification implements Parcelable boolean validRemoteInput = false; int N = mActions.size(); boolean emphazisedMode = mN.fullScreenIntent != null; big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode); if (N > 0) { big.setViewVisibility(R.id.actions_container, View.VISIBLE); big.setViewVisibility(R.id.actions, View.VISIBLE); Loading @@ -3529,7 +3531,8 @@ public class Notification implements Parcelable Action action = mActions.get(i); validRemoteInput |= hasValidRemoteInput(action); final RemoteViews button = generateActionButton(action); final RemoteViews button = generateActionButton(action, emphazisedMode, i % 2 != 0); big.addView(R.id.actions, button); } } else { Loading Loading @@ -3694,10 +3697,12 @@ public class Notification implements Parcelable private RemoteViews generateActionButton(Action action) { private RemoteViews generateActionButton(Action action, boolean emphazisedMode, boolean oddAction) { final boolean tombstone = (action.actionIntent == null); RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(), tombstone ? getActionTombstoneLayoutResource() emphazisedMode ? getEmphasizedActionLayoutResource() : tombstone ? getActionTombstoneLayoutResource() : getActionLayoutResource()); final Icon ai = action.getIcon(); button.setTextViewText(R.id.action0, processLegacyText(action.title)); Loading @@ -3708,9 +3713,19 @@ public class Notification implements Parcelable if (action.mRemoteInputs != null) { button.setRemoteInputs(R.id.action0, action.mRemoteInputs); } if (emphazisedMode) { // change the background color int color = resolveContrastColor(); if (oddAction) { color = NotificationColorUtil.lightenColor(color, 10); } button.setDrawableParameters(R.id.button_holder, true, -1, color, PorterDuff.Mode.SRC_ATOP, -1); } else { if (mN.color != COLOR_DEFAULT) { button.setTextColor(R.id.action0, resolveContrastColor()); } } return button; } Loading Loading @@ -3979,6 +3994,10 @@ public class Notification implements Parcelable return R.layout.notification_material_action; } private int getEmphasizedActionLayoutResource() { return R.layout.notification_material_action_emphasized; } private int getActionTombstoneLayoutResource() { return R.layout.notification_material_action_tombstone; } Loading core/java/com/android/internal/util/NotificationColorUtil.java +17 −3 Original line number Diff line number Diff line Loading @@ -340,6 +340,20 @@ public class NotificationColorUtil { return color; } /** * Lighten a color by a specified value * @param baseColor the base color to lighten * @param amount the amount to lighten the color from 0 to 100. This corresponds to the L * increase in the LAB color space. * @return the lightened color */ public static int lightenColor(int baseColor, int amount) { final double[] result = ColorUtilsFromCompat.getTempDouble3Array(); ColorUtilsFromCompat.colorToLAB(baseColor, result); result[0] = Math.min(100, result[0] + amount); return ColorUtilsFromCompat.LABToColor(result[0], result[1], result[2]); } /** * Framework copy of functions needed from android.support.v4.graphics.ColorUtils. */ Loading Loading @@ -434,7 +448,7 @@ public class NotificationColorUtil { * Convert RGB components to its CIE Lab representative components. * * <ul> * <li>outLab[0] is L [0 ...1)</li> * <li>outLab[0] is L [0 ...100)</li> * <li>outLab[1] is a [-128...127)</li> * <li>outLab[2] is b [-128...127)</li> * </ul> Loading Loading @@ -516,7 +530,7 @@ public class NotificationColorUtil { * 2° Standard Observer (1931).</p> * * <ul> * <li>outLab[0] is L [0 ...1)</li> * <li>outLab[0] is L [0 ...100)</li> * <li>outLab[1] is a [-128...127)</li> * <li>outLab[2] is b [-128...127)</li> * </ul> Loading Loading @@ -634,7 +648,7 @@ public class NotificationColorUtil { : (XYZ_KAPPA * component + 16) / 116; } private static double[] getTempDouble3Array() { public static double[] getTempDouble3Array() { double[] result = TEMP_ARRAY.get(); if (result == null) { result = new double[3]; Loading core/java/com/android/internal/widget/NotificationActionListLayout.java +31 −20 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ package com.android.internal.widget; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Pair; import android.view.Gravity; import android.view.RemotableViewMethod; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RemoteViews; import android.widget.TextView; Loading @@ -33,11 +35,14 @@ import java.util.Comparator; * the remaining available width, and the last action consumes the remaining space. */ @RemoteViews.RemoteView public class NotificationActionListLayout extends ViewGroup { public class NotificationActionListLayout extends LinearLayout { private int mTotalWidth = 0; private ArrayList<Pair<Integer, TextView>> mMeasureOrderTextViews = new ArrayList<>(); private ArrayList<View> mMeasureOrderOther = new ArrayList<>(); private boolean mMeasureLinearly; private int mDefaultPaddingEnd; private Drawable mDefaultBackground; public NotificationActionListLayout(Context context, AttributeSet attrs) { super(context, attrs); Loading @@ -45,6 +50,10 @@ public class NotificationActionListLayout extends ViewGroup { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mMeasureLinearly) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } final int N = getChildCount(); int textViews = 0; int otherViews = 0; Loading Loading @@ -186,6 +195,10 @@ public class NotificationActionListLayout extends ViewGroup { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { if (mMeasureLinearly) { super.onLayout(changed, left, top, right, bottom); return; } final boolean isLayoutRtl = isLayoutRtl(); final int paddingTop = mPaddingTop; Loading Loading @@ -241,26 +254,24 @@ public class NotificationActionListLayout extends ViewGroup { } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected LayoutParams generateDefaultLayoutParams() { return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); } @Override protected LayoutParams generateLayoutParams(LayoutParams p) { if (p instanceof MarginLayoutParams) { return new MarginLayoutParams((MarginLayoutParams)p); } return new MarginLayoutParams(p); protected void onFinishInflate() { super.onFinishInflate(); mDefaultPaddingEnd = getPaddingEnd(); mDefaultBackground = getBackground(); } @Override protected boolean checkLayoutParams(LayoutParams p) { return p instanceof MarginLayoutParams; /** * Set whether the list is in a mode where some actions are emphasized. This will trigger an * equal measuring where all actions are full height and change a few parameters like * the padding. */ @RemotableViewMethod public void setEmphasizedMode(boolean emphasizedMode) { mMeasureLinearly = emphasizedMode; setPaddingRelative(getPaddingStart(), getPaddingTop(), emphasizedMode ? 0 : mDefaultPaddingEnd, getPaddingBottom()); setBackground(emphasizedMode ? null : mDefaultBackground); requestLayout(); } public static final Comparator<Pair<Integer, TextView>> MEASURE_ORDER_COMPARATOR Loading core/res/res/drawable/notification_material_action_background_emphasized.xml 0 → 100644 +24 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2016 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"> <item android:id="@id/mask"> <color android:color="@color/white" /> </item> </ripple> core/res/res/layout/notification_material_action_emphasized.xml 0 → 100644 +34 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2016 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 --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/button_holder" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="#ff000000"> <Button style="@android:style/Widget.Material.Light.Button.Borderless.Small" android:id="@+id/action0" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textColor="#ffffffff" android:singleLine="true" android:ellipsize="end" android:background="@drawable/notification_material_action_background_emphasized" /> </FrameLayout> Loading
core/java/android/app/Notification.java +25 −6 Original line number Diff line number Diff line Loading @@ -3519,6 +3519,8 @@ public class Notification implements Parcelable boolean validRemoteInput = false; int N = mActions.size(); boolean emphazisedMode = mN.fullScreenIntent != null; big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode); if (N > 0) { big.setViewVisibility(R.id.actions_container, View.VISIBLE); big.setViewVisibility(R.id.actions, View.VISIBLE); Loading @@ -3529,7 +3531,8 @@ public class Notification implements Parcelable Action action = mActions.get(i); validRemoteInput |= hasValidRemoteInput(action); final RemoteViews button = generateActionButton(action); final RemoteViews button = generateActionButton(action, emphazisedMode, i % 2 != 0); big.addView(R.id.actions, button); } } else { Loading Loading @@ -3694,10 +3697,12 @@ public class Notification implements Parcelable private RemoteViews generateActionButton(Action action) { private RemoteViews generateActionButton(Action action, boolean emphazisedMode, boolean oddAction) { final boolean tombstone = (action.actionIntent == null); RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(), tombstone ? getActionTombstoneLayoutResource() emphazisedMode ? getEmphasizedActionLayoutResource() : tombstone ? getActionTombstoneLayoutResource() : getActionLayoutResource()); final Icon ai = action.getIcon(); button.setTextViewText(R.id.action0, processLegacyText(action.title)); Loading @@ -3708,9 +3713,19 @@ public class Notification implements Parcelable if (action.mRemoteInputs != null) { button.setRemoteInputs(R.id.action0, action.mRemoteInputs); } if (emphazisedMode) { // change the background color int color = resolveContrastColor(); if (oddAction) { color = NotificationColorUtil.lightenColor(color, 10); } button.setDrawableParameters(R.id.button_holder, true, -1, color, PorterDuff.Mode.SRC_ATOP, -1); } else { if (mN.color != COLOR_DEFAULT) { button.setTextColor(R.id.action0, resolveContrastColor()); } } return button; } Loading Loading @@ -3979,6 +3994,10 @@ public class Notification implements Parcelable return R.layout.notification_material_action; } private int getEmphasizedActionLayoutResource() { return R.layout.notification_material_action_emphasized; } private int getActionTombstoneLayoutResource() { return R.layout.notification_material_action_tombstone; } Loading
core/java/com/android/internal/util/NotificationColorUtil.java +17 −3 Original line number Diff line number Diff line Loading @@ -340,6 +340,20 @@ public class NotificationColorUtil { return color; } /** * Lighten a color by a specified value * @param baseColor the base color to lighten * @param amount the amount to lighten the color from 0 to 100. This corresponds to the L * increase in the LAB color space. * @return the lightened color */ public static int lightenColor(int baseColor, int amount) { final double[] result = ColorUtilsFromCompat.getTempDouble3Array(); ColorUtilsFromCompat.colorToLAB(baseColor, result); result[0] = Math.min(100, result[0] + amount); return ColorUtilsFromCompat.LABToColor(result[0], result[1], result[2]); } /** * Framework copy of functions needed from android.support.v4.graphics.ColorUtils. */ Loading Loading @@ -434,7 +448,7 @@ public class NotificationColorUtil { * Convert RGB components to its CIE Lab representative components. * * <ul> * <li>outLab[0] is L [0 ...1)</li> * <li>outLab[0] is L [0 ...100)</li> * <li>outLab[1] is a [-128...127)</li> * <li>outLab[2] is b [-128...127)</li> * </ul> Loading Loading @@ -516,7 +530,7 @@ public class NotificationColorUtil { * 2° Standard Observer (1931).</p> * * <ul> * <li>outLab[0] is L [0 ...1)</li> * <li>outLab[0] is L [0 ...100)</li> * <li>outLab[1] is a [-128...127)</li> * <li>outLab[2] is b [-128...127)</li> * </ul> Loading Loading @@ -634,7 +648,7 @@ public class NotificationColorUtil { : (XYZ_KAPPA * component + 16) / 116; } private static double[] getTempDouble3Array() { public static double[] getTempDouble3Array() { double[] result = TEMP_ARRAY.get(); if (result == null) { result = new double[3]; Loading
core/java/com/android/internal/widget/NotificationActionListLayout.java +31 −20 Original line number Diff line number Diff line Loading @@ -17,11 +17,13 @@ package com.android.internal.widget; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Pair; import android.view.Gravity; import android.view.RemotableViewMethod; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RemoteViews; import android.widget.TextView; Loading @@ -33,11 +35,14 @@ import java.util.Comparator; * the remaining available width, and the last action consumes the remaining space. */ @RemoteViews.RemoteView public class NotificationActionListLayout extends ViewGroup { public class NotificationActionListLayout extends LinearLayout { private int mTotalWidth = 0; private ArrayList<Pair<Integer, TextView>> mMeasureOrderTextViews = new ArrayList<>(); private ArrayList<View> mMeasureOrderOther = new ArrayList<>(); private boolean mMeasureLinearly; private int mDefaultPaddingEnd; private Drawable mDefaultBackground; public NotificationActionListLayout(Context context, AttributeSet attrs) { super(context, attrs); Loading @@ -45,6 +50,10 @@ public class NotificationActionListLayout extends ViewGroup { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mMeasureLinearly) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } final int N = getChildCount(); int textViews = 0; int otherViews = 0; Loading Loading @@ -186,6 +195,10 @@ public class NotificationActionListLayout extends ViewGroup { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { if (mMeasureLinearly) { super.onLayout(changed, left, top, right, bottom); return; } final boolean isLayoutRtl = isLayoutRtl(); final int paddingTop = mPaddingTop; Loading Loading @@ -241,26 +254,24 @@ public class NotificationActionListLayout extends ViewGroup { } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected LayoutParams generateDefaultLayoutParams() { return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); } @Override protected LayoutParams generateLayoutParams(LayoutParams p) { if (p instanceof MarginLayoutParams) { return new MarginLayoutParams((MarginLayoutParams)p); } return new MarginLayoutParams(p); protected void onFinishInflate() { super.onFinishInflate(); mDefaultPaddingEnd = getPaddingEnd(); mDefaultBackground = getBackground(); } @Override protected boolean checkLayoutParams(LayoutParams p) { return p instanceof MarginLayoutParams; /** * Set whether the list is in a mode where some actions are emphasized. This will trigger an * equal measuring where all actions are full height and change a few parameters like * the padding. */ @RemotableViewMethod public void setEmphasizedMode(boolean emphasizedMode) { mMeasureLinearly = emphasizedMode; setPaddingRelative(getPaddingStart(), getPaddingTop(), emphasizedMode ? 0 : mDefaultPaddingEnd, getPaddingBottom()); setBackground(emphasizedMode ? null : mDefaultBackground); requestLayout(); } public static final Comparator<Pair<Integer, TextView>> MEASURE_ORDER_COMPARATOR Loading
core/res/res/drawable/notification_material_action_background_emphasized.xml 0 → 100644 +24 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2016 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"> <item android:id="@id/mask"> <color android:color="@color/white" /> </item> </ripple>
core/res/res/layout/notification_material_action_emphasized.xml 0 → 100644 +34 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2016 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 --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/button_holder" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="#ff000000"> <Button style="@android:style/Widget.Material.Light.Button.Borderless.Small" android:id="@+id/action0" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textColor="#ffffffff" android:singleLine="true" android:ellipsize="end" android:background="@drawable/notification_material_action_background_emphasized" /> </FrameLayout>