1826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 3826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 4826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Licensed under the Apache License, Version 2.0 (the "License"); 5826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * you may not use this file except in compliance with the License. 6826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * You may obtain a copy of the License at 7826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 8826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * http://www.apache.org/licenses/LICENSE-2.0 9826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 10826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Unless required by applicable law or agreed to in writing, software 11826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * distributed under the License is distributed on an "AS IS" BASIS, 12826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * See the License for the specific language governing permissions and 14826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * limitations under the License. 15826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 16826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.media.app; 18826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.core.app.NotificationCompat.COLOR_DEFAULT; 21826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 22826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.app.Notification; 23826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.app.PendingIntent; 24826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.media.session.MediaSession; 25826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.os.Build; 26826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.os.Bundle; 27826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.os.IBinder; 28826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakeimport android.os.Parcel; 2989febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikasimport android.support.v4.media.session.MediaSessionCompat; 3089febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikasimport android.view.View; 3189febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikasimport android.widget.RemoteViews; 3289febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikas 33ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RequiresApi; 34ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RestrictTo; 35ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.core.app.BundleCompat; 36ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.core.app.NotificationBuilderWithBuilderAccessor; 3789febf83e2bd3720923474006bcdf6c91a3b88f2Aurimas Liutikasimport androidx.media.R; 38826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 39826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake/** 40ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Class containing media specfic {@link androidx.core.app.NotificationCompat.Style styles} 41ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * that you can use with {@link androidx.core.app.NotificationCompat.Builder#setStyle}. 42826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 43826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lakepublic class NotificationCompat { 44826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 45826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake private NotificationCompat() { 46826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 47826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 48826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 49826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Notification style for media playback notifications. 50826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 51826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * In the expanded form, up to 5 52ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Action actions} specified with 53ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder 54826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * #addAction(int, CharSequence, PendingIntent) addAction} will be shown as icon-only 55826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * pushbuttons, suitable for transport controls. The Bitmap given to 56ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder 57826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * #setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will 58826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * be treated as album artwork. 59826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 60826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Unlike the other styles provided here, MediaStyle can also modify the standard-size 61826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * content view; by providing action indices to 62826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * {@link #setShowActionsInCompactView(int...)} you can promote up to 3 actions to be displayed 63826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * in the standard view alongside the usual content. 64826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 65826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Notifications created with MediaStyle will have their category set to 66ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat#CATEGORY_TRANSPORT CATEGORY_TRANSPORT} 67826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * unless you set a different category using 68ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder#setCategory(String) 69826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * setCategory()}. 70826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 71826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Finally, if you attach a {@link MediaSession.Token} using 72ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link NotificationCompat.MediaStyle#setMediaSession}, the 73826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * System UI can identify this as a notification representing an active media session and 74826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * respond accordingly (by showing album artwork in the lockscreen, for example). 75826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 76826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * To use this style with your Notification, feed it to 77ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder#setStyle} like so: 78826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <pre class="prettyprint"> 79826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Notification noti = new NotificationCompat.Builder() 80826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setSmallIcon(R.drawable.ic_stat_player) 81826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setContentTitle("Track title") 82826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setContentText("Artist - Album") 83826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setLargeIcon(albumArtBitmap)) 84826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setStyle(<b>new NotificationCompat.MediaStyle()</b> 85826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setMediaSession(mySession)) 86826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .build(); 87826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * </pre> 88826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 89826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @see Notification#bigContentView 90826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 91ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas public static class MediaStyle extends androidx.core.app.NotificationCompat.Style { 92826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 93826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 94826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Extracts a {@link MediaSessionCompat.Token} from the extra values 95826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * in the {@link MediaStyle} {@link Notification notification}. 96826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 97826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @param notification The notification to extract a {@link MediaSessionCompat.Token} from. 98826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @return The {@link MediaSessionCompat.Token} in the {@code notification} if it contains, 99826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * null otherwise. 100826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 101826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public static MediaSessionCompat.Token getMediaSession(Notification notification) { 102ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas Bundle extras = androidx.core.app.NotificationCompat.getExtras(notification); 103826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (extras != null) { 104826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 105826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake Object tokenInner = extras.getParcelable( 106ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas androidx.core.app.NotificationCompat.EXTRA_MEDIA_SESSION); 107826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (tokenInner != null) { 108826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return MediaSessionCompat.Token.fromToken(tokenInner); 109826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 110826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } else { 111826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake IBinder tokenInner = BundleCompat.getBinder(extras, 112ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas androidx.core.app.NotificationCompat.EXTRA_MEDIA_SESSION); 113826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (tokenInner != null) { 114826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake Parcel p = Parcel.obtain(); 115826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake p.writeStrongBinder(tokenInner); 116826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake p.setDataPosition(0); 117826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake MediaSessionCompat.Token token = 118826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake MediaSessionCompat.Token.CREATOR.createFromParcel(p); 119826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake p.recycle(); 120826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return token; 121826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 122826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 123826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 124826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 125826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 126826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 127826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake private static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3; 128826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake private static final int MAX_MEDIA_BUTTONS = 5; 129826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 130826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake int[] mActionsToShowInCompact = null; 131826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake MediaSessionCompat.Token mToken; 132826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake boolean mShowCancelButton; 133826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake PendingIntent mCancelButtonIntent; 134826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 135826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public MediaStyle() { 136826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 137826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 138ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas public MediaStyle(androidx.core.app.NotificationCompat.Builder builder) { 139826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake setBuilder(builder); 140826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 141826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 142826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 143826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Requests up to 3 actions (by index in the order of addition) to be shown in the compact 144826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * notification view. 145826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 146826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @param actions the indices of the actions to show in the compact notification view 147826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 148826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public MediaStyle setShowActionsInCompactView(int...actions) { 149826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake mActionsToShowInCompact = actions; 150826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return this; 151826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 152826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 153826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 154826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Attaches a {@link MediaSessionCompat.Token} to this Notification 155826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * to provide additional playback information and control to the SystemUI. 156826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 157826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public MediaStyle setMediaSession(MediaSessionCompat.Token token) { 158826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake mToken = token; 159826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return this; 160826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 161826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 162826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 163826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Sets whether a cancel button at the top right should be shown in the notification on 164826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * platforms before Lollipop. 165826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 166826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>Prior to Lollipop, there was a bug in the framework which prevented the developer to 167826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * make a notification dismissable again after having used the same notification as the 168826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * ongoing notification for a foreground service. When the notification was posted by 169826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * {@link android.app.Service#startForeground}, but then the service exited foreground mode 170826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * via {@link android.app.Service#stopForeground}, without removing the notification, the 171826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * notification stayed ongoing, and thus not dismissable. 172826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 173826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>This is a common scenario for media notifications, as this is exactly the service 174826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * lifecycle that happens when playing/pausing media. Thus, a workaround is provided by the 175826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * support library: Instead of making the notification ongoing depending on the playback 176826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * state, the support library provides the ability to add an explicit cancel button to the 177826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * notification. 178826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 179826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>Note that the notification is enforced to be ongoing if a cancel button is shown to 180826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * provide a consistent user experience. 181826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 182826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>Also note that this method is a no-op when running on Lollipop and later. 183826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 184826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @param show whether to show a cancel button 185826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 186826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public MediaStyle setShowCancelButton(boolean show) { 187826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT < 21) { 188826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake mShowCancelButton = show; 189826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 190826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return this; 191826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 192826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 193826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 194826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Sets the pending intent to be sent when the cancel button is pressed. See {@link 195826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * #setShowCancelButton}. 196826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 197826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @param pendingIntent the intent to be sent when the cancel button is pressed 198826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 199826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public MediaStyle setCancelButtonIntent(PendingIntent pendingIntent) { 200826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake mCancelButtonIntent = pendingIntent; 201826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return this; 202826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 203826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 204826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 205826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 206826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 207826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 208826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 209826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public void apply(NotificationBuilderWithBuilderAccessor builder) { 210826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 211826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake builder.getBuilder().setStyle( 212826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake fillInMediaStyle(new Notification.MediaStyle())); 213826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } else if (mShowCancelButton) { 214826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake builder.getBuilder().setOngoing(true); 215826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 216826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 217826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 218826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RequiresApi(21) 219826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake Notification.MediaStyle fillInMediaStyle(Notification.MediaStyle style) { 220826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (mActionsToShowInCompact != null) { 221826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake style.setShowActionsInCompactView(mActionsToShowInCompact); 222826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 223826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (mToken != null) { 224826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake style.setMediaSession((MediaSession.Token) mToken.getToken()); 225826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 226826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return style; 227826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 228826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 229826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 230826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 231826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 232826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 233826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 234826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public RemoteViews makeContentView(NotificationBuilderWithBuilderAccessor builder) { 235826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 236826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No custom content view required 237826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 238826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 239826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return generateContentView(); 240826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 241826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 242826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews generateContentView() { 243826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews view = applyStandardTemplate(false /* showSmallIcon */, 244826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake getContentViewLayoutResource(), true /* fitIn1U */); 245826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 246826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake final int numActions = mBuilder.mActions.size(); 247826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake final int numActionsInCompact = mActionsToShowInCompact == null 248826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? 0 249826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT); 250826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.removeAllViews(R.id.media_actions); 251826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (numActionsInCompact > 0) { 252826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake for (int i = 0; i < numActionsInCompact; i++) { 253826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (i >= numActions) { 254826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake throw new IllegalArgumentException(String.format( 255826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake "setShowActionsInCompactView: action %d out of bounds (max %d)", 256826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake i, numActions - 1)); 257826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 258826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 259ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas final androidx.core.app.NotificationCompat.Action action = 260826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake mBuilder.mActions.get(mActionsToShowInCompact[i]); 261826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake final RemoteViews button = generateMediaActionButton(action); 262826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.addView(R.id.media_actions, button); 263826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 264826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 265826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (mShowCancelButton) { 266826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.setViewVisibility(R.id.end_padder, View.GONE); 267826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.setViewVisibility(R.id.cancel_action, View.VISIBLE); 268826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.setOnClickPendingIntent(R.id.cancel_action, mCancelButtonIntent); 269826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.setInt(R.id.cancel_action, "setAlpha", mBuilder.mContext 270826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake .getResources().getInteger(R.integer.cancel_button_image_alpha)); 271826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } else { 272826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.setViewVisibility(R.id.end_padder, View.VISIBLE); 273826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake view.setViewVisibility(R.id.cancel_action, View.GONE); 274826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 275826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return view; 276826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 277826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 278826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake private RemoteViews generateMediaActionButton( 279ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas androidx.core.app.NotificationCompat.Action action) { 280826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake final boolean tombstone = (action.getActionIntent() == null); 281826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(), 282826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake R.layout.notification_media_action); 283826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake button.setImageViewResource(R.id.action0, action.getIcon()); 284826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (!tombstone) { 285826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake button.setOnClickPendingIntent(R.id.action0, action.getActionIntent()); 286826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 287826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 15) { 288826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake button.setContentDescription(R.id.action0, action.getTitle()); 289826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 290826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return button; 291826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 292826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 293826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake int getContentViewLayoutResource() { 294826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return R.layout.notification_template_media; 295826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 296826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 297826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 298826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 299826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 300826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 301826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 302826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public RemoteViews makeBigContentView(NotificationBuilderWithBuilderAccessor builder) { 303826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 304826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No custom content view required 305826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 306826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 307826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return generateBigContentView(); 308826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 309826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 310826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews generateBigContentView() { 311826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS); 312826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews big = applyStandardTemplate(false /* showSmallIcon */, 313826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake getBigContentViewLayoutResource(actionCount), false /* fitIn1U */); 314826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 315826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake big.removeAllViews(R.id.media_actions); 316826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (actionCount > 0) { 317826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake for (int i = 0; i < actionCount; i++) { 318826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i)); 319826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake big.addView(R.id.media_actions, button); 320826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 321826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 322826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (mShowCancelButton) { 323826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake big.setViewVisibility(R.id.cancel_action, View.VISIBLE); 324826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake big.setInt(R.id.cancel_action, "setAlpha", mBuilder.mContext 325826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake .getResources().getInteger(R.integer.cancel_button_image_alpha)); 326826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake big.setOnClickPendingIntent(R.id.cancel_action, mCancelButtonIntent); 327826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } else { 328826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake big.setViewVisibility(R.id.cancel_action, View.GONE); 329826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 330826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return big; 331826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 332826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 333826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake int getBigContentViewLayoutResource(int actionCount) { 334826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return actionCount <= 3 335826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? R.layout.notification_template_big_media_narrow 336826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : R.layout.notification_template_big_media; 337826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 338826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 339826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 340826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 341826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Notification style for media custom views that are decorated by the system. 342826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 343826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>Instead of providing a media notification that is completely custom, a developer can set 344826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * this style and still obtain system decorations like the notification header with the expand 345826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * affordance and actions. 346826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 347ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * <p>Use {@link androidx.core.app.NotificationCompat.Builder 348826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * #setCustomContentView(RemoteViews)}, 349ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder 350826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * #setCustomBigContentView(RemoteViews)} and 351ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder 352826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * #setCustomHeadsUpContentView(RemoteViews)} to set the 353826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * corresponding custom views to display. 354826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 355826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>To use this style with your Notification, feed it to 356ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.core.app.NotificationCompat.Builder 357ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * #setStyle(androidx.core.app.NotificationCompat.Style)} like so: 358826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <pre class="prettyprint"> 359826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * Notification noti = new NotificationCompat.Builder() 360826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setSmallIcon(R.drawable.ic_stat_player) 361826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setLargeIcon(albumArtBitmap)) 362826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setCustomContentView(contentView) 363826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setStyle(<b>new NotificationCompat.DecoratedMediaCustomViewStyle()</b> 364826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .setMediaSession(mySession)) 365826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * .build(); 366826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * </pre> 367826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 368826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * <p>If you are using this style, consider using the corresponding styles like 369ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * {@link androidx.media.R.style#TextAppearance_Compat_Notification_Media} or 370826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * {@link 371ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * androidx.media.R.style#TextAppearance_Compat_Notification_Title_Media} in 372826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * your custom views in order to get the correct styling on each platform version. 373826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * 374ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * @see androidx.core.app.NotificationCompat.DecoratedCustomViewStyle 375826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @see MediaStyle 376826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 377826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public static class DecoratedMediaCustomViewStyle extends MediaStyle { 378826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 379826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public DecoratedMediaCustomViewStyle() { 380826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 381826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 382826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 383826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 384826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 385826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 386826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 387826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public void apply(NotificationBuilderWithBuilderAccessor builder) { 388826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 24) { 389826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake builder.getBuilder().setStyle( 390826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake fillInMediaStyle(new Notification.DecoratedMediaCustomViewStyle())); 391826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } else { 392826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake super.apply(builder); 393826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 394826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 395826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 396826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 397826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 398826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 399826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 400826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 401826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public RemoteViews makeContentView(NotificationBuilderWithBuilderAccessor builder) { 402826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 24) { 403826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No custom content view required 404826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 405826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 406826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake boolean hasContentView = mBuilder.getContentView() != null; 407826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 408826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // If we are on L/M the media notification will only be colored if the expanded 409826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // version is of media style, so we have to create a custom view for the collapsed 410826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // version as well in that case. 411826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake boolean createCustomContent = hasContentView 412826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake || mBuilder.getBigContentView() != null; 413826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (createCustomContent) { 414826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews contentView = generateContentView(); 415826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (hasContentView) { 416826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake buildIntoRemoteViews(contentView, mBuilder.getContentView()); 417826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 418826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake setBackgroundColor(contentView); 419826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return contentView; 420826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 421826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } else { 422826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews contentView = generateContentView(); 423826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (hasContentView) { 424826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake buildIntoRemoteViews(contentView, mBuilder.getContentView()); 425826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return contentView; 426826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 427826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 428826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 429826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 430826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 431826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 432826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake int getContentViewLayoutResource() { 433826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return mBuilder.getContentView() != null 434826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? R.layout.notification_template_media_custom 435826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : super.getContentViewLayoutResource(); 436826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 437826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 438826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 439826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 440826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 441826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 442826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 443826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public RemoteViews makeBigContentView(NotificationBuilderWithBuilderAccessor builder) { 444826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 24) { 445826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No custom big content view required 446826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 447826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 448826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews innerView = mBuilder.getBigContentView() != null 449826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? mBuilder.getBigContentView() 450826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : mBuilder.getContentView(); 451826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (innerView == null) { 452826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No expandable notification 453826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 454826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 455826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews bigContentView = generateBigContentView(); 456826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake buildIntoRemoteViews(bigContentView, innerView); 457826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 458826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake setBackgroundColor(bigContentView); 459826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 460826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return bigContentView; 461826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 462826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 463826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 464826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake int getBigContentViewLayoutResource(int actionCount) { 465826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return actionCount <= 3 466826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? R.layout.notification_template_big_media_narrow_custom 467826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : R.layout.notification_template_big_media_custom; 468826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 469826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 470826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake /** 471826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake * @hide 472826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake */ 473826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @RestrictTo(LIBRARY_GROUP) 474826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake @Override 475826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake public RemoteViews makeHeadsUpContentView(NotificationBuilderWithBuilderAccessor builder) { 476826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 24) { 477826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No custom heads up content view required 478826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 479826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 480826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews innerView = mBuilder.getHeadsUpContentView() != null 481826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? mBuilder.getHeadsUpContentView() 482826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : mBuilder.getContentView(); 483826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (innerView == null) { 484826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake // No expandable notification 485826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return null; 486826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 487826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake RemoteViews headsUpContentView = generateBigContentView(); 488826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake buildIntoRemoteViews(headsUpContentView, innerView); 489826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake if (Build.VERSION.SDK_INT >= 21) { 490826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake setBackgroundColor(headsUpContentView); 491826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 492826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake return headsUpContentView; 493826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 494826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake 495826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake private void setBackgroundColor(RemoteViews views) { 496826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake int color = mBuilder.getColor() != COLOR_DEFAULT 497826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake ? mBuilder.getColor() 498826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake : mBuilder.mContext.getResources().getColor( 499826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake R.color.notification_material_background_media_default_color); 500826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake views.setInt(R.id.status_bar_latest_event_content, "setBackgroundColor", color); 501826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 502826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake } 503826ed4f84805a4aeae559d8ec6e2d54fda40153fIan Lake} 504