• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.car.stream.media;
17 
18 import android.app.PendingIntent;
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.graphics.Bitmap;
23 import android.graphics.Canvas;
24 import android.graphics.drawable.VectorDrawable;
25 import android.view.KeyEvent;
26 import android.widget.RemoteViews;
27 import com.android.car.stream.MediaPlaybackExtension;
28 import com.android.car.stream.R;
29 import com.android.car.stream.StreamCard;
30 import com.android.car.stream.StreamConstants;
31 import com.android.car.stream.StreamServiceConstants;
32 
33 /**
34  * A converter that creates a {@link StreamCard} for currently playing media.
35  */
36 public class MediaConverter {
37     private final PendingIntent mGotoMediaFacetAction;
38     private final PendingIntent mPauseAction;
39     private final PendingIntent mSkipToNextAction;
40     private final PendingIntent mSkipToPreviousAction;
41     private final PendingIntent mPlayAction;
42     private final PendingIntent mStopAction;
43 
44     private Bitmap mPlayIcon;
45     private Bitmap mPauseIcon;
46 
MediaConverter(Context context)47     public MediaConverter(Context context) {
48         String mediaPackage = context.getString(R.string.car_media_component_package);
49         mGotoMediaFacetAction = createGoToMediaFacetIntent(context, mediaPackage);
50 
51         mPauseAction = getMediaActionIntent(context,
52                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE),
53                 KeyEvent.KEYCODE_MEDIA_PAUSE /* requestCode */);
54 
55         mSkipToNextAction = getMediaActionIntent(context,
56                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_SKIP_FORWARD),
57                 KeyEvent.KEYCODE_MEDIA_SKIP_FORWARD /* requestCode */);
58 
59         mSkipToPreviousAction = getMediaActionIntent(context,
60                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD),
61                 KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD /* requestCode */);
62 
63 
64         mPlayAction = getMediaActionIntent(context,
65                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY),
66                 KeyEvent.KEYCODE_MEDIA_PLAY /* requestCode */);
67 
68         mStopAction = getMediaActionIntent(context,
69                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP),
70                 KeyEvent.KEYCODE_MEDIA_STOP /* requestCode */);
71 
72         int iconSize = context.getResources()
73                 .getDimensionPixelSize(R.dimen.stream_card_secondary_icon_dimen);
74         mPlayIcon = getBitmap((VectorDrawable)
75                 context.getDrawable(R.drawable.ic_play_arrow), iconSize, iconSize);
76         mPauseIcon = getBitmap((VectorDrawable)
77                 context.getDrawable(R.drawable.ic_pause), iconSize, iconSize);
78     }
79 
convert( String title, String subtitle, Bitmap albumArt, int appAccentColor, String appName, boolean canSkipToNext, boolean canSkipToPrevious, boolean hasPause, boolean isPlaying)80     public StreamCard convert(
81             String title,
82             String subtitle,
83             Bitmap albumArt,
84             int appAccentColor,
85             String appName,
86             boolean canSkipToNext,
87             boolean canSkipToPrevious,
88             boolean hasPause,
89             boolean isPlaying) {
90 
91         StreamCard.Builder builder = new StreamCard.Builder(StreamConstants.CARD_TYPE_MEDIA,
92                 StreamConstants.MEDIA_CARD_ID, System.currentTimeMillis());
93         builder.setClickAction(mGotoMediaFacetAction);
94         builder.setPrimaryText(title);
95         builder.setSecondaryText(subtitle);
96         Bitmap icon = isPlaying ? mPlayIcon : mPauseIcon;
97         builder.setPrimaryIcon(icon);
98 
99         MediaPlaybackExtension extension = new MediaPlaybackExtension(title, subtitle, albumArt,
100                 appAccentColor, canSkipToNext, canSkipToPrevious, hasPause, isPlaying, appName,
101                 mStopAction, mPauseAction, mPlayAction, mSkipToNextAction, mSkipToPreviousAction);
102 
103         builder.setCardExtension(extension);
104         return builder.build();
105     }
106 
107     /**
108      * Attaches a {@link PendingIntent} to the given {@link RemoteViews}. The PendingIntent will
109      * send the user to the CarMediaApp when touched. Note that this does not resolve to the
110      * application currently in the media card; instead, it just opens the last music app. For
111      * example, if the card is generated by Google Play Music, but the last opened music app
112      * was Spotify, then Spotify will open when the music card is tapped.
113      */
createGoToMediaFacetIntent(Context context, String mediaPackage)114     private PendingIntent createGoToMediaFacetIntent(Context context, String mediaPackage) {
115         Intent intent = context.getPackageManager().getLaunchIntentForPackage(mediaPackage);
116         intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
117 
118         return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
119     }
120 
getMediaActionIntent(Context context, KeyEvent ke, int requestCode)121     private PendingIntent getMediaActionIntent(Context context, KeyEvent ke, int requestCode) {
122         Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
123         i.setPackage(context.getPackageName());
124         i.putExtra(Intent.EXTRA_KEY_EVENT, ke);
125 
126         PendingIntent pendingIntent =
127                 PendingIntent.getBroadcast(
128                         context,
129                         requestCode,
130                         i,
131                         PendingIntent.FLAG_CANCEL_CURRENT
132                 );
133         return pendingIntent;
134     }
135 
getBitmap(VectorDrawable vectorDrawable, int width, int height)136     private static Bitmap getBitmap(VectorDrawable vectorDrawable, int width, int height) {
137         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
138         Canvas canvas = new Canvas(bitmap);
139         vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
140         vectorDrawable.draw(canvas);
141         return bitmap;
142     }
143 }
144