blob: bfb5e3f1ae762aa2ddd8c147802bf4a675384877 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tv.menu;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.data.Channel;
import com.android.tv.util.BitmapUtils;
import com.android.tv.util.ImageLoader;
import com.android.tv.util.TvInputManagerHelper;
/**
* A view to render an app link card.
*/
public class AppLinkCardView extends BaseCardView<Channel> {
private static final String TAG = MenuView.TAG;
private static final boolean DEBUG = MenuView.DEBUG;
private final int mCardImageWidth;
private final int mCardImageHeight;
private final int mIconWidth;
private final int mIconHeight;
private final int mIconPadding;
private final int mIconColorFilter;
private ImageView mImageView;
private View mGradientView;
private TextView mAppInfoView;
private View mMetaViewHolder;
private Channel mChannel;
private Intent mIntent;
private final PackageManager mPackageManager;
private final TvInputManagerHelper mTvInputManagerHelper;
public AppLinkCardView(Context context) {
this(context, null);
}
public AppLinkCardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AppLinkCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mCardImageWidth = getResources().getDimensionPixelSize(R.dimen.card_image_layout_width);
mCardImageHeight = getResources().getDimensionPixelSize(R.dimen.card_image_layout_height);
mIconWidth = getResources().getDimensionPixelSize(R.dimen.app_link_card_icon_width);
mIconHeight = getResources().getDimensionPixelSize(R.dimen.app_link_card_icon_height);
mIconPadding = getResources().getDimensionPixelOffset(R.dimen.app_link_card_icon_padding);
mPackageManager = context.getPackageManager();
mTvInputManagerHelper = ((MainActivity) context).getTvInputManagerHelper();
mIconColorFilter = getResources().getColor(R.color.app_link_card_icon_color_filter, null);
}
/**
* Returns the intent which will be started once this card is clicked.
*/
public Intent getIntent() {
return mIntent;
}
@Override
public void onBind(Channel channel, boolean selected) {
if (DEBUG) {
Log.d(TAG, "onBind(channelName=" + channel.getDisplayName() + ", selected=" + selected
+ ")");
}
mChannel = channel;
ApplicationInfo appInfo = mTvInputManagerHelper.getTvInputAppInfo(mChannel.getInputId());
int linkType = mChannel.getAppLinkType(getContext());
mIntent = mChannel.getAppLinkIntent(getContext());
switch (linkType) {
case Channel.APP_LINK_TYPE_CHANNEL:
setText(mChannel.getAppLinkText());
mAppInfoView.setVisibility(VISIBLE);
mGradientView.setVisibility(VISIBLE);
mAppInfoView.setCompoundDrawablePadding(mIconPadding);
mAppInfoView.setCompoundDrawables(null, null, null, null);
mAppInfoView.setText(mPackageManager.getApplicationLabel(appInfo));
if (!TextUtils.isEmpty(mChannel.getAppLinkIconUri())) {
mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON,
mIconWidth, mIconHeight, createChannelLogoCallback(this, mChannel,
Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON));
} else if (appInfo.icon != 0) {
Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
BitmapUtils.setColorFilterToDrawable(mIconColorFilter, appIcon);
appIcon.setBounds(0, 0, mIconWidth, mIconHeight);
mAppInfoView.setCompoundDrawables(appIcon, null, null, null);
}
break;
case Channel.APP_LINK_TYPE_APP:
setText(getContext().getString(
R.string.channels_item_app_link_app_launcher,
mPackageManager.getApplicationLabel(appInfo)));
mAppInfoView.setVisibility(GONE);
mGradientView.setVisibility(GONE);
break;
default:
mAppInfoView.setVisibility(GONE);
mGradientView.setVisibility(GONE);
Log.d(TAG, "Should not be here.");
}
if (mChannel.getAppLinkColor() == 0) {
mMetaViewHolder.setBackgroundResource(R.color.channel_card_meta_background);
} else {
mMetaViewHolder.setBackgroundColor(mChannel.getAppLinkColor());
}
if (!TextUtils.isEmpty(mChannel.getAppLinkPosterArtUri())) {
mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default);
mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART,
mCardImageWidth, mCardImageHeight, createChannelLogoCallback(this, mChannel,
Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART));
} else {
setCardImageWithBanner(appInfo);
}
// Call super.onBind() at the end intentionally. In order to correctly handle extension of
// text view, text should be set before calling super.onBind.
super.onBind(channel, selected);
}
private static ImageLoader.ImageLoaderCallback<AppLinkCardView> createChannelLogoCallback(
AppLinkCardView cardView, final Channel channel, final int type) {
return new ImageLoader.ImageLoaderCallback<AppLinkCardView>(cardView) {
@Override
public void onBitmapLoaded(AppLinkCardView cardView, @Nullable Bitmap bitmap) {
// mChannel can be changed before the image load finished.
if (!cardView.mChannel.hasSameReadOnlyInfo(channel)) {
return;
}
cardView.updateChannelLogo(bitmap, type);
}
};
}
private void updateChannelLogo(@Nullable Bitmap bitmap, int type) {
if (type == Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON) {
BitmapDrawable drawable = null;
if (bitmap != null) {
drawable = new BitmapDrawable(getResources(), bitmap);
if (bitmap.getWidth() > bitmap.getHeight()) {
drawable.setBounds(0, 0, mIconWidth,
mIconWidth * bitmap.getHeight() / bitmap.getWidth());
} else {
drawable.setBounds(0, 0,
mIconHeight * bitmap.getWidth() / bitmap.getHeight(),
mIconHeight);
}
}
BitmapUtils.setColorFilterToDrawable(mIconColorFilter, drawable);
mAppInfoView.setCompoundDrawables(drawable, null, null, null);
} else if (type == Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART) {
if (bitmap == null) {
setCardImageWithBanner(
mTvInputManagerHelper.getTvInputAppInfo(mChannel.getInputId()));
} else {
mImageView.setImageBitmap(bitmap);
if (mChannel.getAppLinkColor() == 0) {
extractAndSetMetaViewBackgroundColor(bitmap);
}
}
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mImageView = (ImageView) findViewById(R.id.image);
mGradientView = findViewById(R.id.image_gradient);
mAppInfoView = (TextView) findViewById(R.id.app_info);
mMetaViewHolder = findViewById(R.id.app_link_text_holder);
}
// Try to set the card image with following order:
// 1) Provided poster art image, 2) Activity banner, 3) Activity icon, 4) Application banner,
// 5) Application icon, and 6) default image.
private void setCardImageWithBanner(ApplicationInfo appInfo) {
Drawable banner = null;
if (mIntent != null) {
try {
banner = mPackageManager.getActivityBanner(mIntent);
if (banner == null) {
banner = mPackageManager.getActivityIcon(mIntent);
}
} catch (PackageManager.NameNotFoundException e) {
// do nothing.
}
}
if (banner == null && appInfo != null) {
if (appInfo.banner != 0) {
banner = mPackageManager.getApplicationBanner(appInfo);
}
if (banner == null && appInfo.icon != 0) {
banner = mPackageManager.getApplicationIcon(appInfo);
}
}
if (banner == null) {
mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default);
mImageView.setBackgroundResource(R.color.channel_card);
} else {
Bitmap bitmap =
Bitmap.createBitmap(mCardImageWidth, mCardImageHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
banner.setBounds(0, 0, mCardImageWidth, mCardImageHeight);
banner.draw(canvas);
mImageView.setImageDrawable(banner);
if (mChannel.getAppLinkColor() == 0) {
extractAndSetMetaViewBackgroundColor(bitmap);
}
}
}
private void extractAndSetMetaViewBackgroundColor(Bitmap bitmap) {
new Palette.Builder(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
mMetaViewHolder.setBackgroundColor(palette.getDarkVibrantColor(
getResources().getColor(R.color.channel_card_meta_background, null)));
}
});
}
}