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