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 17package com.android.car.radio; 18 19import android.content.Context; 20import android.media.session.PlaybackState; 21import android.text.TextUtils; 22import android.view.View; 23import android.view.ViewStub; 24import android.widget.ImageView; 25import android.widget.TextView; 26 27/** 28 * Controller that controls the appearance state of various UI elements in the radio. 29 */ 30public class RadioDisplayController { 31 private final Context mContext; 32 33 private TextView mChannelBand; 34 private TextView mChannelNumber; 35 36 private TextView mCurrentSongTitleAndArtist; 37 private TextView mCurrentStation; 38 39 private ImageView mBackwardSeekButton; 40 private ImageView mForwardSeekButton; 41 42 private PlayPauseButton mPlayButton; 43 private PlayPauseButton mPresetPlayButton; 44 45 private ImageView mPresetsListButton; 46 private ImageView mAddPresetsButton; 47 48 public RadioDisplayController(Context context) { 49 mContext = context; 50 } 51 52 public void initialize(View container) { 53 // Note that the band and channel number can exist without the stub 54 // single_channel_view_stub. Refer to setSingleChannelDisplay() for more information. 55 mChannelBand = container.findViewById(R.id.radio_station_band); 56 mChannelNumber = container.findViewById(R.id.radio_station_channel); 57 58 mCurrentSongTitleAndArtist = container.findViewById(R.id.radio_station_song_artist); 59 mCurrentStation = container.findViewById(R.id.radio_station_name); 60 61 mBackwardSeekButton = container.findViewById(R.id.radio_back_button); 62 mForwardSeekButton = container.findViewById(R.id.radio_forward_button); 63 64 mPlayButton = container.findViewById(R.id.radio_play_button); 65 mPresetPlayButton = container.findViewById(R.id.preset_radio_play_button); 66 67 mPresetsListButton = container.findViewById(R.id.radio_presets_list); 68 mAddPresetsButton = container.findViewById(R.id.radio_add_presets_button); 69 } 70 71 /** 72 * Sets this radio controller to display with a single box representing the current radio 73 * station. 74 */ 75 public void setSingleChannelDisplay(View container) { 76 ViewStub stub = container.findViewById(R.id.single_channel_view_stub); 77 78 if (stub != null) { 79 container = stub.inflate(); 80 } 81 82 // Update references to the band and channel number. 83 mChannelBand = container.findViewById(R.id.radio_station_band); 84 mChannelNumber = container.findViewById(R.id.radio_station_channel); 85 } 86 87 /** 88 * Set whether or not the buttons controlled by this controller are enabled. If {@code false} 89 * is passed to this method, then no {@link View.OnClickListener}s will be 90 * triggered when the buttons are pressed. In addition, the look of the button wil be updated 91 * to reflect their disabled state. 92 */ 93 public void setEnabled(boolean enabled) { 94 // Color the buttons so that they are grey in appearance if they are disabled. 95 int tint = enabled 96 ? mContext.getColor(R.color.car_radio_control_button) 97 : mContext.getColor(R.color.car_radio_control_button_disabled); 98 99 if (mPlayButton != null) { 100 // No need to tint the play button because its drawable already contains a disabled 101 // state. 102 mPlayButton.setEnabled(enabled); 103 } 104 105 if (mPresetPlayButton != null) { 106 // No need to tint the play button because its drawable already contains a disabled 107 // state. 108 mPresetPlayButton.setEnabled(enabled); 109 } 110 111 if (mForwardSeekButton != null) { 112 mForwardSeekButton.setEnabled(enabled); 113 mForwardSeekButton.setColorFilter(tint); 114 } 115 116 if (mBackwardSeekButton != null) { 117 mBackwardSeekButton.setEnabled(enabled); 118 mBackwardSeekButton.setColorFilter(tint); 119 } 120 121 if (mPresetsListButton != null) { 122 mPresetsListButton.setEnabled(enabled); 123 mPresetsListButton.setColorFilter(tint); 124 } 125 126 if (mAddPresetsButton != null) { 127 mAddPresetsButton.setEnabled(enabled); 128 mAddPresetsButton.setColorFilter(tint); 129 } 130 } 131 132 /** 133 * Sets the {@link android.view.View.OnClickListener} for the backwards seek button. 134 */ 135 public void setBackwardSeekButtonListener(View.OnClickListener listener) { 136 if (mBackwardSeekButton != null) { 137 mBackwardSeekButton.setOnClickListener(listener); 138 } 139 } 140 141 /** 142 * Sets the {@link android.view.View.OnClickListener} for the forward seek button. 143 */ 144 public void setForwardSeekButtonListener(View.OnClickListener listener) { 145 if (mForwardSeekButton != null) { 146 mForwardSeekButton.setOnClickListener(listener); 147 } 148 } 149 150 /** 151 * Sets the {@link android.view.View.OnClickListener} for the play button. Clicking on this 152 * button should toggle the radio from muted to un-muted. 153 */ 154 public void setPlayButtonListener(View.OnClickListener listener) { 155 if (mPlayButton != null) { 156 mPlayButton.setOnClickListener(listener); 157 } 158 159 if (mPresetPlayButton != null) { 160 mPresetPlayButton.setOnClickListener(listener); 161 } 162 } 163 164 /** 165 * Sets the {@link android.view.View.OnClickListener} for the button that will add the current 166 * radio station to a list of stored presets. 167 */ 168 public void setAddPresetButtonListener(View.OnClickListener listener) { 169 if (mAddPresetsButton != null) { 170 mAddPresetsButton.setOnClickListener(listener); 171 } 172 } 173 174 /** 175 * Sets the current radio channel (e.g. 88.5). 176 */ 177 public void setChannelNumber(String channel) { 178 if (mChannelNumber != null) { 179 mChannelNumber.setText(channel); 180 } 181 } 182 183 /** 184 * Sets the radio channel band (e.g. FM). 185 */ 186 public void setChannelBand(String channelBand) { 187 if (mChannelBand != null) { 188 mChannelBand.setText(channelBand); 189 mChannelBand.setVisibility( 190 !TextUtils.isEmpty(channelBand) ? View.VISIBLE : View.GONE); 191 } 192 } 193 194 /** 195 * Sets the title of the currently playing song. 196 */ 197 public void setCurrentSongTitleAndArtist(String songTitle, String songArtist) { 198 if (mCurrentSongTitleAndArtist != null) { 199 boolean isTitleEmpty = TextUtils.isEmpty(songTitle); 200 boolean isArtistEmpty = TextUtils.isEmpty(songArtist); 201 String titleAndArtist = null; 202 if (!isTitleEmpty) { 203 titleAndArtist = songTitle.trim(); 204 if (!isArtistEmpty) { 205 titleAndArtist += '\u2014' + songArtist.trim(); 206 } 207 } else if (!isArtistEmpty) { 208 titleAndArtist = songArtist.trim(); 209 } 210 mCurrentSongTitleAndArtist.setText(titleAndArtist); 211 mCurrentSongTitleAndArtist.setVisibility( 212 (isTitleEmpty && isArtistEmpty)? View.INVISIBLE : View.VISIBLE); 213 } 214 } 215 216 /** 217 * Sets the artist(s) of the currently playing song or current radio station information 218 * (e.g. KOIT). 219 */ 220 public void setCurrentStation(String stationName) { 221 if (mCurrentStation != null) { 222 boolean isEmpty = TextUtils.isEmpty(stationName); 223 mCurrentStation.setText(isEmpty ? null : stationName.trim()); 224 mCurrentStation.setVisibility(isEmpty ? View.INVISIBLE : View.VISIBLE); 225 } 226 } 227 228 /** 229 * Sets the current state of the play button. If the given {@code muted} value is {@code true}, 230 * then the button display a play icon. If {@code false}, then the button will display a 231 * pause icon. 232 */ 233 public void setPlayPauseButtonState(boolean muted) { 234 if (mPlayButton != null) { 235 mPlayButton.setPlayState(muted 236 ? PlaybackState.STATE_PAUSED : PlaybackState.STATE_PLAYING); 237 mPlayButton.refreshDrawableState(); 238 } 239 240 if (mPresetPlayButton != null) { 241 mPresetPlayButton.setPlayState(muted 242 ? PlaybackState.STATE_PAUSED : PlaybackState.STATE_PLAYING); 243 mPresetPlayButton.refreshDrawableState(); 244 } 245 } 246 247 /** 248 * Sets whether or not the current channel that is playing is a preset. If it is, then the 249 * icon in {@link #mPresetsListButton} will be updatd to reflect this state. 250 */ 251 public void setChannelIsPreset(boolean isPreset) { 252 if (mAddPresetsButton != null) { 253 mAddPresetsButton.setImageResource(isPreset 254 ? R.drawable.ic_star_filled 255 : R.drawable.ic_star_empty); 256 } 257 } 258} 259