ChannelBannerView.java revision f8367f0d7dc6abc4876b52e04e2530c06464698e
1590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/* 2590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Copyright (C) 2014 The Android Open Source Project 3590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 4590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * you may not use this file except in compliance with the License. 6590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * You may obtain a copy of the License at 7590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 8590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * 10590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Unless required by applicable law or agreed to in writing, software 11590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * See the License for the specific language governing permissions and 14590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * limitations under the License. 15590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 16590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 174e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonpackage com.android.tv.ui; 18590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 196be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.content.Context; 206be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.database.ContentObserver; 214e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonimport android.media.tv.TvContract; 226be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.net.Uri; 236be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.Handler; 2474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport android.text.TextUtils; 256be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.text.format.DateFormat; 26590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.util.AttributeSet; 273dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pellyimport android.util.Log; 286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.view.View; 296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.widget.LinearLayout; 30590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.widget.ProgressBar; 31590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.widget.TextView; 3274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 336be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport com.android.tv.R; 3474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport com.android.tv.data.ChannelMap; 3574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport com.android.tv.data.Program; 3674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport com.android.tv.data.StreamInfo; 3774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport com.android.tv.util.Utils; 3874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 3974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly/** 4074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * A view to render channel banner. 4174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly */ 4274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellypublic class ChannelBannerView extends LinearLayout { 4374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mClosedCaptionTextView; 4474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mResolutionTextView; 4574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mAspectRatioTextView; 4639cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly private TextView mAudioChannelTextView; 4774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private ProgressBar mRemainingTimeView; 4874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mProgrameDescriptionTextView; 4974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mChannelTextView; 5074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mChannelNameTextView; 5174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mProgramTextView; 5274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private TextView mProgramTimeTextView; 5374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private Uri mCurrentChannelUri; 5465e37ee936e2406e58719584ce30b6aa21792ce0Paul Quei 5574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private final ContentObserver mProgramUpdateObserver = new ContentObserver(new Handler()) { 5674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly @Override 5774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly public void onChange(boolean selfChange, Uri uri) { 5874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly updateProgramInfo(); 5974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 6074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly }; 6174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 6274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly public ChannelBannerView(Context context) { 6374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly super(context); 6474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mContext = context; 6574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 6674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 676be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public ChannelBannerView(Context context, AttributeSet attrs) { 6839cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly super(context, attrs); 6939cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly mContext = context; 70590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 716be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 723dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly public ChannelBannerView(Context context, AttributeSet attrs, int defStyle) { 733dd6c458530476eccb33bc05c9c9cd83823bcf8dNick Pelly super(context, attrs, defStyle); 743300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen mContext = context; 753300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen } 763300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen 773300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen @Override 783300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen protected void onAttachedToWindow() { 793300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen super.onAttachedToWindow(); 80590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly getContext().getContentResolver().registerContentObserver(TvContract.Programs.CONTENT_URI, 8172df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen true, mProgramUpdateObserver); 8272df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen } 8372df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen 846d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen @Override 856d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen protected void onDetachedFromWindow() { 866d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen getContext().getContentResolver().unregisterContentObserver(mProgramUpdateObserver); 873300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen super.onDetachedFromWindow(); 883300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen } 893300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen 90d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen @Override 91d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen protected void onFinishInflate() { 92d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen super.onFinishInflate(); 93f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly 94f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mClosedCaptionTextView = (TextView) findViewById(R.id.closed_caption); 95f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mResolutionTextView = (TextView) findViewById(R.id.resolution); 96f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mAspectRatioTextView = (TextView) findViewById(R.id.aspect_ratio); 97f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mAudioChannelTextView = (TextView) findViewById(R.id.audio_channel); 98f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mRemainingTimeView = (ProgressBar) findViewById(R.id.remaining_time); 99f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mChannelTextView = (TextView) findViewById(R.id.channel_text); 100f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mChannelNameTextView = (TextView) findViewById(R.id.channel_name); 101f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mProgramTimeTextView = (TextView) findViewById(R.id.program_time_text); 102f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mProgrameDescriptionTextView = (TextView) findViewById(R.id.program_description); 103f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mProgramTextView = (TextView) findViewById(R.id.program_text); 104f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly } 1055644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton 1065644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton public void updateViews(ChannelMap channelMap, StreamInfo info) { 107f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly if (channelMap == null || !channelMap.isLoadFinished()) { 108f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly return; 109f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly } 110f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly 11174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly if (info.hasClosedCaption()) { 112f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mClosedCaptionTextView.setText("CC"); 11374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mClosedCaptionTextView.setVisibility(View.VISIBLE); 114f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly } else { 11574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mClosedCaptionTextView.setVisibility(View.GONE); 116f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly } 11774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly if (info.getVideoDefinitionLevel() != StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN) { 118f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mResolutionTextView.setText(Utils.getVideoDefinitionLevelString( 11974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly info.getVideoDefinitionLevel())); 120f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mResolutionTextView.setVisibility(View.VISIBLE); 1215644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton } else { 1225644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton mResolutionTextView.setVisibility(View.GONE); 1235644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton } 1245644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton // TODO: implement aspect ratio. 1255644d0e18ad847b66a8cb4f185cb28edebe75d88Jeff Hamilton mAspectRatioTextView.setVisibility(View.GONE); 126d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen if (!TextUtils.isEmpty(Utils.getAudioChannelString(info.getAudioChannelCount()))) { 1273300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen mAudioChannelTextView.setText(Utils.getAudioChannelString(info.getAudioChannelCount())); 1283300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen mAudioChannelTextView.setVisibility(View.VISIBLE); 129e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen } else { 130d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen mAudioChannelTextView.setVisibility(View.GONE); 1316d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen } 132590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 13374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly String displayNumber = channelMap.getCurrentDisplayNumber(); 13474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly String displayName = channelMap.getCurrentDisplayName(); 13574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly if (displayNumber == null) { 13674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly displayNumber = ""; 13774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 13874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly if (displayName == null) { 1394e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton displayName = ""; 14074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 14174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mChannelTextView.setText(displayNumber); 1420bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen mChannelNameTextView.setText(displayName); 1430bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen 1444e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton mCurrentChannelUri = channelMap.getCurrentChannelUri(); 1454e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton updateProgramInfo(); 1464e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 1474e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton 1484e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton private String getFormattedTimeString(long time) { 1494e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return DateFormat.format( 1504e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton getContext().getString(R.string.channel_banner_time_format), time).toString(); 1514e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 1524e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton 1534e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public void updateProgramInfo() { 1544e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (mCurrentChannelUri == null) { 155590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly handleNoProgramInformation(); 156590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return; 157590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 1584e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton 1594e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton Program program = Utils.getCurrentProgram(mContext, mCurrentChannelUri); 1604e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (program == null) { 1616d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen handleNoProgramInformation(); 1623300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen return; 1633300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen } 164e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen if (!TextUtils.isEmpty(program.getTitle())) { 165d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen mProgramTextView.setText(program.getTitle()); 1666d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen 1673300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen long startTime = program.getStartTimeUtcMillis(); 1686d9fc7e1efa9e99bdab366fc5d579c139fd04e71Martijn Coenen long endTime = program.getEndTimeUtcMillis(); 1693300e4c3ea2f2317532ded6f9e79d6ad9e038679Martijn Coenen if (startTime > 0 && endTime > 0) { 1706be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mRemainingTimeView.setVisibility(View.VISIBLE); 171a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau 1726be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton String startTimeText = getFormattedTimeString(startTime); 17374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly String endTimeText = getFormattedTimeString(endTime); 17474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 17574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mProgramTimeTextView.setText(mContext.getString( 17674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly R.string.channel_banner_program_time_format, startTimeText, endTimeText)); 17774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 178a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen long currTime = System.currentTimeMillis(); 179a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen if (currTime <= startTime) { 180a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen mRemainingTimeView.setProgress(0); 18174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } else if (currTime >= endTime) { 182a032783241cbbed47ed05df32c56298ee0f9902bMartijn Coenen mRemainingTimeView.setProgress(100); 1836be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } else { 184e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen mRemainingTimeView.setProgress( 185e3f6336bcffc250da90ec864bccfa73ad1d016b9Martijn Coenen (int) (100 *(currTime - startTime) / (endTime - startTime))); 186a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau } 187a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau } else { 188a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau mProgramTimeTextView.setVisibility(View.GONE); 18974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mRemainingTimeView.setVisibility(View.GONE); 19074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 191ddbb2c997b8462d7242b50ea1689a53122d4fce4Nick Pelly } 192ddbb2c997b8462d7242b50ea1689a53122d4fce4Nick Pelly if (!TextUtils.isEmpty(program.getDescription())) { 19374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mProgrameDescriptionTextView.setText(program.getDescription()); 19474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 19574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly } 19674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 19774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly private void handleNoProgramInformation() { 19874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly mProgramTextView.setText(mContext.getString(R.string.channel_banner_no_title)); 199d27ebf1e698c4e6929cb635768031a2e25b18acdMartijn Coenen mProgramTimeTextView.setVisibility(View.GONE); 200f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mRemainingTimeView.setVisibility(View.GONE); 201f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly mProgrameDescriptionTextView.setVisibility(View.GONE); 202f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly } 203f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly} 204f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly