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