• 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 
17 package com.android.car.stream.radio;
18 
19 import android.app.PendingIntent;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.graphics.Bitmap;
24 import android.graphics.Canvas;
25 import android.graphics.drawable.VectorDrawable;
26 import android.support.annotation.ColorInt;
27 import com.android.car.radio.service.RadioStation;
28 import com.android.car.stream.MediaPlaybackExtension;
29 import com.android.car.stream.R;
30 import com.android.car.stream.StreamCard;
31 import com.android.car.stream.StreamConstants;
32 import com.android.car.stream.StreamServiceConstants;
33 
34 /**
35  * A converter that is responsible for transforming a {@link RadioStation} into a
36  * {@link StreamCard}.
37  */
38 public class RadioConverter {
39     /**
40      * The separator between the radio channel and band (e.g. between 99.7 and FM).
41      */
42     private static final String CHANNEL_AND_BAND_SEPARATOR = " ";
43 
44     private final Context mContext;
45 
46     private final PendingIntent mGoToRadioAction;
47     private final PendingIntent mPauseAction;
48     private final PendingIntent mForwardSeekAction;
49     private final PendingIntent mBackwardSeekAction;
50     private final PendingIntent mPlayAction;
51     private final PendingIntent mStopAction;
52 
53     @ColorInt
54     private final int mAccentColor;
55 
56     private final Bitmap mPlayIcon;
57     private final Bitmap mPauseIcon;
58 
RadioConverter(Context context)59     public RadioConverter(Context context) {
60         mContext = context;
61 
62         mGoToRadioAction = createGoToRadioIntent();
63         mPauseAction = createRadioActionIntent(RadioStreamProducer.ACTION_PAUSE);
64         mPlayAction = createRadioActionIntent(RadioStreamProducer.ACTION_PLAY);
65         mStopAction = createRadioActionIntent(RadioStreamProducer.ACTION_STOP);
66         mForwardSeekAction = createRadioActionIntent(RadioStreamProducer.ACTION_SEEK_FORWARD);
67         mBackwardSeekAction = createRadioActionIntent(RadioStreamProducer.ACTION_SEEK_BACKWARD);
68 
69         mAccentColor = mContext.getColor(R.color.car_radio_accent_color);
70 
71         int iconSize = context.getResources()
72                 .getDimensionPixelSize(R.dimen.stream_card_secondary_icon_dimen);
73         mPlayIcon = getBitmap((VectorDrawable)
74                 mContext.getDrawable(R.drawable.ic_play_arrow), iconSize, iconSize);
75         mPauseIcon = getBitmap((VectorDrawable)
76                 mContext.getDrawable(R.drawable.ic_pause), iconSize, iconSize);
77     }
78 
79     /**
80      * Converts the given {@link RadioStation} and play status into a {@link StreamCard} that can
81      * be used to display a radio card.
82      */
convert(RadioStation station, boolean isPlaying)83     public StreamCard convert(RadioStation station, boolean isPlaying) {
84         StreamCard.Builder builder = new StreamCard.Builder(StreamConstants.CARD_TYPE_MEDIA,
85                 StreamConstants.RADIO_CARD_ID, System.currentTimeMillis());
86 
87         builder.setClickAction(mGoToRadioAction);
88 
89         String title = createTitleText(station);
90         builder.setPrimaryText(title);
91 
92         String subtitle = null;
93         if (station.getRds() != null) {
94             subtitle = station.getRds().getProgramService();
95             builder.setSecondaryText(subtitle);
96         }
97 
98         Bitmap icon = isPlaying ? mPlayIcon : mPauseIcon;
99         builder.setPrimaryIcon(icon);
100 
101         MediaPlaybackExtension extension = new MediaPlaybackExtension(title, subtitle,
102                 null /* albumArt */, mAccentColor, true /* canSkipToNext */,
103                 true /* canSkipToPrevious */, true /* hasPause */, isPlaying,
104                 mContext.getString(R.string.radio_app_name), mStopAction, mPauseAction, mPlayAction,
105                 mForwardSeekAction, mBackwardSeekAction);
106 
107         builder.setCardExtension(extension);
108         return builder.build();
109     }
110 
111     /**
112      * Returns the String that represents the title text of the radio card. The title should be
113      * a combination of the current channel number and radio band.
114      */
createTitleText(RadioStation station)115     private String createTitleText(RadioStation station) {
116         int radioBand = station.getRadioBand();
117         String channel = RadioFormatter.formatRadioChannel(radioBand,
118                 station.getChannelNumber());
119         String band = RadioFormatter.formatRadioBand(mContext, radioBand);
120 
121         return channel + CHANNEL_AND_BAND_SEPARATOR + band;
122     }
123 
124     /**
125      * Returns an {@link Intent} that will take the user to the radio application.
126      */
createGoToRadioIntent()127     private PendingIntent createGoToRadioIntent() {
128         ComponentName radioComponent = new ComponentName(
129                 mContext.getString(R.string.car_radio_component_package),
130                 mContext.getString(R.string.car_radio_component_activity));
131 
132         Intent intent = new Intent();
133         intent.setComponent(radioComponent);
134         intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
135 
136         return PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
137     }
138 
139     /**
140      * Returns an {@link Intent} that will perform the given action.
141      *
142      * @param action One of the action values in {@link RadioStreamProducer}. e.g.
143      *               {@link RadioStreamProducer#ACTION_PAUSE}.
144      */
createRadioActionIntent(int action)145     private PendingIntent createRadioActionIntent(int action) {
146         Intent intent = new Intent(RadioStreamProducer.RADIO_INTENT_ACTION);
147         intent.setPackage(mContext.getPackageName());
148         intent.putExtra(RadioStreamProducer.RADIO_ACTION_EXTRA, action);
149 
150         return PendingIntent.getBroadcast(mContext, action /* requestCode */,
151                 intent, PendingIntent.FLAG_CANCEL_CURRENT);
152     }
153 
154     /**
155      * Returns a {@link Bitmap} that corresponds to the given {@link VectorDrawable}.
156      */
getBitmap(VectorDrawable vectorDrawable, int width, int height)157     private static Bitmap getBitmap(VectorDrawable vectorDrawable, int width, int height) {
158         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
159         Canvas canvas = new Canvas(bitmap);
160         vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
161         vectorDrawable.draw(canvas);
162         return bitmap;
163     }
164 }
165