1 /* 2 * Copyright (C) 2015 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.tv.menu; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.support.annotation.Nullable; 22 import android.text.TextUtils; 23 import android.util.AttributeSet; 24 import android.util.Log; 25 import android.view.View; 26 import android.widget.ImageView; 27 import android.widget.ProgressBar; 28 import android.widget.TextView; 29 30 import com.android.tv.MainActivity; 31 import com.android.tv.R; 32 import com.android.tv.data.Channel; 33 import com.android.tv.data.Program; 34 import com.android.tv.parental.ParentalControlSettings; 35 import com.android.tv.util.ImageLoader; 36 37 /** 38 * A view to render channel card. 39 */ 40 public class ChannelCardView extends BaseCardView<Channel> { 41 private static final String TAG = MenuView.TAG; 42 private static final boolean DEBUG = MenuView.DEBUG; 43 44 private final int mCardImageWidth; 45 private final int mCardImageHeight; 46 47 private ImageView mImageView; 48 private View mGradientView; 49 private TextView mChannelNumberNameView; 50 private ProgressBar mProgressBar; 51 private Channel mChannel; 52 private Program mProgram; 53 private final MainActivity mMainActivity; 54 ChannelCardView(Context context)55 public ChannelCardView(Context context) { 56 this(context, null); 57 } 58 ChannelCardView(Context context, AttributeSet attrs)59 public ChannelCardView(Context context, AttributeSet attrs) { 60 this(context, attrs, 0); 61 } 62 ChannelCardView(Context context, AttributeSet attrs, int defStyle)63 public ChannelCardView(Context context, AttributeSet attrs, int defStyle) { 64 super(context, attrs, defStyle); 65 mCardImageWidth = getResources().getDimensionPixelSize(R.dimen.card_image_layout_width); 66 mCardImageHeight = getResources().getDimensionPixelSize(R.dimen.card_image_layout_height); 67 mMainActivity = (MainActivity) context; 68 } 69 70 @Override onFinishInflate()71 protected void onFinishInflate() { 72 super.onFinishInflate(); 73 mImageView = (ImageView) findViewById(R.id.image); 74 mGradientView = findViewById(R.id.image_gradient); 75 mChannelNumberNameView = (TextView) findViewById(R.id.channel_number_and_name); 76 mProgressBar = (ProgressBar) findViewById(R.id.progress); 77 } 78 79 @Override onBind(Channel channel, boolean selected)80 public void onBind(Channel channel, boolean selected) { 81 if (DEBUG) { 82 Log.d(TAG, "onBind(channelName=" + channel.getDisplayName() + ", selected=" + selected 83 + ")"); 84 } 85 mChannel = channel; 86 mProgram = null; 87 mChannelNumberNameView.setText(mChannel.getDisplayText()); 88 mChannelNumberNameView.setVisibility(VISIBLE); 89 mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default); 90 mImageView.setBackgroundResource(R.color.channel_card); 91 mGradientView.setVisibility(View.GONE); 92 mProgressBar.setVisibility(GONE); 93 94 setTextViewEnabled(true); 95 if (mMainActivity.getParentalControlSettings().isParentalControlsEnabled() 96 && mChannel.isLocked()) { 97 setText(R.string.program_title_for_blocked_channel); 98 return; 99 } else { 100 setText(""); 101 } 102 103 updateProgramInformation(); 104 // Call super.onBind() at the end intentionally. In order to correctly handle extension of 105 // text view, text should be set before calling super.onBind. 106 super.onBind(channel, selected); 107 } 108 createProgramPosterArtCallback( ChannelCardView cardView, final Program program)109 private static ImageLoader.ImageLoaderCallback<ChannelCardView> createProgramPosterArtCallback( 110 ChannelCardView cardView, final Program program) { 111 return new ImageLoader.ImageLoaderCallback<ChannelCardView>(cardView) { 112 @Override 113 public void onBitmapLoaded(ChannelCardView cardView, @Nullable Bitmap posterArt) { 114 if (posterArt == null || cardView.mProgram == null 115 || program.getChannelId() != cardView.mProgram.getChannelId() 116 || program.getChannelId() != cardView.mChannel.getId()) { 117 return; 118 } 119 cardView.updatePosterArt(posterArt); 120 } 121 }; 122 } 123 124 private void updatePosterArt(Bitmap posterArt) { 125 mImageView.setImageBitmap(posterArt); 126 mGradientView.setVisibility(View.VISIBLE); 127 } 128 129 private void updateProgramInformation() { 130 if (mChannel == null) { 131 return; 132 } 133 mProgram = mMainActivity.getProgramDataManager().getCurrentProgram(mChannel.getId()); 134 if (mProgram == null || TextUtils.isEmpty(mProgram.getTitle())) { 135 setTextViewEnabled(false); 136 setText(R.string.program_title_for_no_information); 137 } else { 138 setText(mProgram.getTitle()); 139 } 140 141 if (mProgram == null) { 142 return; 143 } 144 145 long startTime = mProgram.getStartTimeUtcMillis(); 146 long endTime = mProgram.getEndTimeUtcMillis(); 147 long currTime = System.currentTimeMillis(); 148 mProgressBar.setVisibility(View.VISIBLE); 149 if (currTime <= startTime) { 150 mProgressBar.setProgress(0); 151 } else if (currTime >= endTime) { 152 mProgressBar.setProgress(100); 153 } else { 154 mProgressBar.setProgress((int) (100 * (currTime - startTime) / (endTime - startTime))); 155 } 156 157 if (!(getContext() instanceof MainActivity)) { 158 Log.e(TAG, "Fails to check program's content rating."); 159 return; 160 } 161 ParentalControlSettings parental = mMainActivity.getParentalControlSettings(); 162 if ((!parental.isParentalControlsEnabled() 163 || !parental.isRatingBlocked(mProgram.getContentRatings())) 164 && !TextUtils.isEmpty(mProgram.getPosterArtUri())) { 165 mProgram.loadPosterArt(getContext(), mCardImageWidth, mCardImageHeight, 166 createProgramPosterArtCallback(this, mProgram)); 167 } 168 } 169 } 170