/*
 * 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.data;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.data.api.Channel;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageLoader;
import java.net.URISyntaxException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/** A convenience class to create and insert channel entries into the database. */
public final class ChannelImpl implements Channel {
    private static final String TAG = "ChannelImpl";

    /** Compares the channel numbers of channels which belong to the same input. */
    public static final Comparator<Channel> CHANNEL_NUMBER_COMPARATOR =
            new Comparator<Channel>() {
                @Override
                public int compare(Channel lhs, Channel rhs) {
                    return ChannelNumber.compare(lhs.getDisplayNumber(), rhs.getDisplayNumber());
                }
            };

    private static final int APP_LINK_TYPE_NOT_SET = 0;
    private static final String INVALID_PACKAGE_NAME = "packageName";

    public static final String[] PROJECTION = {
        // Columns must match what is read in ChannelImpl.fromCursor()
        TvContract.Channels._ID,
        TvContract.Channels.COLUMN_PACKAGE_NAME,
        TvContract.Channels.COLUMN_INPUT_ID,
        TvContract.Channels.COLUMN_TYPE,
        TvContract.Channels.COLUMN_DISPLAY_NUMBER,
        TvContract.Channels.COLUMN_DISPLAY_NAME,
        TvContract.Channels.COLUMN_DESCRIPTION,
        TvContract.Channels.COLUMN_VIDEO_FORMAT,
        TvContract.Channels.COLUMN_BROWSABLE,
        TvContract.Channels.COLUMN_SEARCHABLE,
        TvContract.Channels.COLUMN_LOCKED,
        TvContract.Channels.COLUMN_APP_LINK_TEXT,
        TvContract.Channels.COLUMN_APP_LINK_COLOR,
        TvContract.Channels.COLUMN_APP_LINK_ICON_URI,
        TvContract.Channels.COLUMN_APP_LINK_POSTER_ART_URI,
        TvContract.Channels.COLUMN_APP_LINK_INTENT_URI,
        TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG2, // Only used in bundled input
    };

    /**
     * Creates {@code ChannelImpl} object from cursor.
     *
     * <p>The query that created the cursor MUST use {@link #PROJECTION}
     */
    public static ChannelImpl fromCursor(Cursor cursor) {
        // Columns read must match the order of {@link #PROJECTION}
        ChannelImpl channel = new ChannelImpl();
        int index = 0;
        channel.mId = cursor.getLong(index++);
        channel.mPackageName = Utils.intern(cursor.getString(index++));
        channel.mInputId = Utils.intern(cursor.getString(index++));
        channel.mType = Utils.intern(cursor.getString(index++));
        channel.mDisplayNumber = normalizeDisplayNumber(cursor.getString(index++));
        channel.mDisplayName = cursor.getString(index++);
        channel.mDescription = cursor.getString(index++);
        channel.mVideoFormat = Utils.intern(cursor.getString(index++));
        channel.mBrowsable = cursor.getInt(index++) == 1;
        channel.mSearchable = cursor.getInt(index++) == 1;
        channel.mLocked = cursor.getInt(index++) == 1;
        channel.mAppLinkText = cursor.getString(index++);
        channel.mAppLinkColor = cursor.getInt(index++);
        channel.mAppLinkIconUri = cursor.getString(index++);
        channel.mAppLinkPosterArtUri = cursor.getString(index++);
        channel.mAppLinkIntentUri = cursor.getString(index++);
        if (CommonUtils.isBundledInput(channel.mInputId)) {
            channel.mRecordingProhibited = cursor.getInt(index++) != 0;
        }
        return channel;
    }

    /** Replaces the channel number separator with dash('-'). */
    public static String normalizeDisplayNumber(String string) {
        if (!TextUtils.isEmpty(string)) {
            int length = string.length();
            for (int i = 0; i < length; i++) {
                char c = string.charAt(i);
                if (c == '.'
                        || Character.isWhitespace(c)
                        || Character.getType(c) == Character.DASH_PUNCTUATION) {
                    StringBuilder sb = new StringBuilder(string);
                    sb.setCharAt(i, CHANNEL_NUMBER_DELIMITER);
                    return sb.toString();
                }
            }
        }
        return string;
    }

    /** ID of this channel. Matches to BaseColumns._ID. */
    private long mId;

    private String mPackageName;
    private String mInputId;
    private String mType;
    private String mDisplayNumber;
    private String mDisplayName;
    private String mDescription;
    private String mVideoFormat;
    private boolean mBrowsable;
    private boolean mSearchable;
    private boolean mLocked;
    private boolean mIsPassthrough;
    private String mAppLinkText;
    private int mAppLinkColor;
    private String mAppLinkIconUri;
    private String mAppLinkPosterArtUri;
    private String mAppLinkIntentUri;
    private Intent mAppLinkIntent;
    private int mAppLinkType;
    private String mLogoUri;
    private boolean mRecordingProhibited;

    private boolean mChannelLogoExist;

    private ChannelImpl() {
        // Do nothing.
    }

    @Override
    public long getId() {
        return mId;
    }

    @Override
    public Uri getUri() {
        if (isPassthrough()) {
            return TvContract.buildChannelUriForPassthroughInput(mInputId);
        } else {
            return TvContract.buildChannelUri(mId);
        }
    }

    @Override
    public String getPackageName() {
        return mPackageName;
    }

    @Override
    public String getInputId() {
        return mInputId;
    }

    @Override
    public String getType() {
        return mType;
    }

    @Override
    public String getDisplayNumber() {
        return mDisplayNumber;
    }

    @Override
    @Nullable
    public String getDisplayName() {
        return mDisplayName;
    }

    @Override
    public String getDescription() {
        return mDescription;
    }

    @Override
    public String getVideoFormat() {
        return mVideoFormat;
    }

    @Override
    public boolean isPassthrough() {
        return mIsPassthrough;
    }

    /**
     * Gets identification text for displaying or debugging. It's made from Channels' display number
     * plus their display name.
     */
    @Override
    public String getDisplayText() {
        return TextUtils.isEmpty(mDisplayName)
                ? mDisplayNumber
                : mDisplayNumber + " " + mDisplayName;
    }

    @Override
    public String getAppLinkText() {
        return mAppLinkText;
    }

    @Override
    public int getAppLinkColor() {
        return mAppLinkColor;
    }

    @Override
    public String getAppLinkIconUri() {
        return mAppLinkIconUri;
    }

    @Override
    public String getAppLinkPosterArtUri() {
        return mAppLinkPosterArtUri;
    }

    @Override
    public String getAppLinkIntentUri() {
        return mAppLinkIntentUri;
    }

    /** Returns channel logo uri which is got from cloud, it's used only for ChannelLogoFetcher. */
    @Override
    public String getLogoUri() {
        return mLogoUri;
    }

    @Override
    public boolean isRecordingProhibited() {
        return mRecordingProhibited;
    }

    /** Checks whether this channel is physical tuner channel or not. */
    @Override
    public boolean isPhysicalTunerChannel() {
        return !TextUtils.isEmpty(mType) && !TvContract.Channels.TYPE_OTHER.equals(mType);
    }

    /** Checks if two channels equal by checking ids. */
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof ChannelImpl)) {
            return false;
        }
        ChannelImpl other = (ChannelImpl) o;
        // All pass-through TV channels have INVALID_ID value for mId.
        return mId == other.mId
                && TextUtils.equals(mInputId, other.mInputId)
                && mIsPassthrough == other.mIsPassthrough;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mId, mInputId, mIsPassthrough);
    }

    @Override
    public boolean isBrowsable() {
        return mBrowsable;
    }

    /** Checks whether this channel is searchable or not. */
    @Override
    public boolean isSearchable() {
        return mSearchable;
    }

    @Override
    public boolean isLocked() {
        return mLocked;
    }

    public void setBrowsable(boolean browsable) {
        mBrowsable = browsable;
    }

    public void setLocked(boolean locked) {
        mLocked = locked;
    }

    /** Sets channel logo uri which is got from cloud. */
    public void setLogoUri(String logoUri) {
        mLogoUri = logoUri;
    }

    /**
     * Check whether {@code other} has same read-only channel info as this. But, it cannot check two
     * channels have same logos. It also excludes browsable and locked, because two fields are
     * changed by TV app.
     */
    @Override
    public boolean hasSameReadOnlyInfo(Channel other) {
        return other != null
                && Objects.equals(mId, other.getId())
                && Objects.equals(mPackageName, other.getPackageName())
                && Objects.equals(mInputId, other.getInputId())
                && Objects.equals(mType, other.getType())
                && Objects.equals(mDisplayNumber, other.getDisplayNumber())
                && Objects.equals(mDisplayName, other.getDisplayName())
                && Objects.equals(mDescription, other.getDescription())
                && Objects.equals(mVideoFormat, other.getVideoFormat())
                && mIsPassthrough == other.isPassthrough()
                && Objects.equals(mAppLinkText, other.getAppLinkText())
                && mAppLinkColor == other.getAppLinkColor()
                && Objects.equals(mAppLinkIconUri, other.getAppLinkIconUri())
                && Objects.equals(mAppLinkPosterArtUri, other.getAppLinkPosterArtUri())
                && Objects.equals(mAppLinkIntentUri, other.getAppLinkIntentUri())
                && Objects.equals(mRecordingProhibited, other.isRecordingProhibited());
    }

    @Override
    public String toString() {
        return "Channel{"
                + "id="
                + mId
                + ", packageName="
                + mPackageName
                + ", inputId="
                + mInputId
                + ", type="
                + mType
                + ", displayNumber="
                + mDisplayNumber
                + ", displayName="
                + mDisplayName
                + ", description="
                + mDescription
                + ", videoFormat="
                + mVideoFormat
                + ", isPassthrough="
                + mIsPassthrough
                + ", browsable="
                + mBrowsable
                + ", searchable="
                + mSearchable
                + ", locked="
                + mLocked
                + ", appLinkText="
                + mAppLinkText
                + ", recordingProhibited="
                + mRecordingProhibited
                + "}";
    }

    @Override
    public void copyFrom(Channel channel) {
        if (channel instanceof ChannelImpl) {
            copyFrom((ChannelImpl) channel);
        } else {
            // copy what we can
            mId = channel.getId();
            mPackageName = channel.getPackageName();
            mInputId = channel.getInputId();
            mType = channel.getType();
            mDisplayNumber = channel.getDisplayNumber();
            mDisplayName = channel.getDisplayName();
            mDescription = channel.getDescription();
            mVideoFormat = channel.getVideoFormat();
            mIsPassthrough = channel.isPassthrough();
            mBrowsable = channel.isBrowsable();
            mSearchable = channel.isSearchable();
            mLocked = channel.isLocked();
            mAppLinkText = channel.getAppLinkText();
            mAppLinkColor = channel.getAppLinkColor();
            mAppLinkIconUri = channel.getAppLinkIconUri();
            mAppLinkPosterArtUri = channel.getAppLinkPosterArtUri();
            mAppLinkIntentUri = channel.getAppLinkIntentUri();
            mRecordingProhibited = channel.isRecordingProhibited();
            mChannelLogoExist = channel.channelLogoExists();
        }
    }

    @SuppressWarnings("ReferenceEquality")
    public void copyFrom(ChannelImpl channel) {
        ChannelImpl other = (ChannelImpl) channel;
        if (this == other) {
            return;
        }
        mId = other.mId;
        mPackageName = other.mPackageName;
        mInputId = other.mInputId;
        mType = other.mType;
        mDisplayNumber = other.mDisplayNumber;
        mDisplayName = other.mDisplayName;
        mDescription = other.mDescription;
        mVideoFormat = other.mVideoFormat;
        mIsPassthrough = other.mIsPassthrough;
        mBrowsable = other.mBrowsable;
        mSearchable = other.mSearchable;
        mLocked = other.mLocked;
        mAppLinkText = other.mAppLinkText;
        mAppLinkColor = other.mAppLinkColor;
        mAppLinkIconUri = other.mAppLinkIconUri;
        mAppLinkPosterArtUri = other.mAppLinkPosterArtUri;
        mAppLinkIntentUri = other.mAppLinkIntentUri;
        mAppLinkIntent = other.mAppLinkIntent;
        mAppLinkType = other.mAppLinkType;
        mRecordingProhibited = other.mRecordingProhibited;
        mChannelLogoExist = other.mChannelLogoExist;
    }

    /** Creates a channel for a passthrough TV input. */
    public static ChannelImpl createPassthroughChannel(Uri uri) {
        if (!TvContract.isChannelUriForPassthroughInput(uri)) {
            throw new IllegalArgumentException("URI is not a passthrough channel URI");
        }
        String inputId = uri.getPathSegments().get(1);
        return createPassthroughChannel(inputId);
    }

    /** Creates a channel for a passthrough TV input with {@code inputId}. */
    public static ChannelImpl createPassthroughChannel(String inputId) {
        return new Builder().setInputId(inputId).setPassthrough(true).build();
    }

    /** Checks whether the channel is valid or not. */
    public static boolean isValid(Channel channel) {
        return channel != null && (channel.getId() != INVALID_ID || channel.isPassthrough());
    }

    /**
     * Builder class for {@code ChannelImpl}. Suppress using this outside of ChannelDataManager so
     * Channels could be managed by ChannelDataManager.
     */
    public static final class Builder {
        private final ChannelImpl mChannel;

        public Builder() {
            mChannel = new ChannelImpl();
            // Fill initial data.
            mChannel.mId = INVALID_ID;
            mChannel.mPackageName = INVALID_PACKAGE_NAME;
            mChannel.mInputId = "inputId";
            mChannel.mType = "type";
            mChannel.mDisplayNumber = "0";
            mChannel.mDisplayName = "name";
            mChannel.mDescription = "description";
            mChannel.mBrowsable = true;
            mChannel.mSearchable = true;
        }

        public Builder(Channel other) {
            mChannel = new ChannelImpl();
            mChannel.copyFrom(other);
        }

        @VisibleForTesting
        public Builder setId(long id) {
            mChannel.mId = id;
            return this;
        }

        @VisibleForTesting
        public Builder setPackageName(String packageName) {
            mChannel.mPackageName = packageName;
            return this;
        }

        public Builder setInputId(String inputId) {
            mChannel.mInputId = inputId;
            return this;
        }

        public Builder setType(String type) {
            mChannel.mType = type;
            return this;
        }

        @VisibleForTesting
        public Builder setDisplayNumber(String displayNumber) {
            mChannel.mDisplayNumber = normalizeDisplayNumber(displayNumber);
            return this;
        }

        @VisibleForTesting
        public Builder setDisplayName(String displayName) {
            mChannel.mDisplayName = displayName;
            return this;
        }

        @VisibleForTesting
        public Builder setDescription(String description) {
            mChannel.mDescription = description;
            return this;
        }

        public Builder setVideoFormat(String videoFormat) {
            mChannel.mVideoFormat = videoFormat;
            return this;
        }

        public Builder setBrowsable(boolean browsable) {
            mChannel.mBrowsable = browsable;
            return this;
        }

        public Builder setSearchable(boolean searchable) {
            mChannel.mSearchable = searchable;
            return this;
        }

        public Builder setLocked(boolean locked) {
            mChannel.mLocked = locked;
            return this;
        }

        public Builder setPassthrough(boolean isPassthrough) {
            mChannel.mIsPassthrough = isPassthrough;
            return this;
        }

        @VisibleForTesting
        public Builder setAppLinkText(String appLinkText) {
            mChannel.mAppLinkText = appLinkText;
            return this;
        }

        public Builder setAppLinkColor(int appLinkColor) {
            mChannel.mAppLinkColor = appLinkColor;
            return this;
        }

        public Builder setAppLinkIconUri(String appLinkIconUri) {
            mChannel.mAppLinkIconUri = appLinkIconUri;
            return this;
        }

        public Builder setAppLinkPosterArtUri(String appLinkPosterArtUri) {
            mChannel.mAppLinkPosterArtUri = appLinkPosterArtUri;
            return this;
        }

        @VisibleForTesting
        public Builder setAppLinkIntentUri(String appLinkIntentUri) {
            mChannel.mAppLinkIntentUri = appLinkIntentUri;
            return this;
        }

        public Builder setRecordingProhibited(boolean recordingProhibited) {
            mChannel.mRecordingProhibited = recordingProhibited;
            return this;
        }

        public ChannelImpl build() {
            ChannelImpl channel = new ChannelImpl();
            channel.copyFrom(mChannel);
            return channel;
        }
    }

    /** Prefetches the images for this channel. */
    public void prefetchImage(Context context, int type, int maxWidth, int maxHeight) {
        String uriString = getImageUriString(type);
        if (!TextUtils.isEmpty(uriString)) {
            ImageLoader.prefetchBitmap(context, uriString, maxWidth, maxHeight);
        }
    }

    /**
     * Loads the bitmap of this channel and returns it via {@code callback}. The loaded bitmap will
     * be cached and resized with given params.
     *
     * <p>Note that it may directly call {@code callback} if the bitmap is already loaded.
     *
     * @param context A context.
     * @param type The type of bitmap which will be loaded. It should be one of follows: {@link
     *     Channel#LOAD_IMAGE_TYPE_CHANNEL_LOGO}, {@link Channel#LOAD_IMAGE_TYPE_APP_LINK_ICON}, or
     *     {@link Channel#LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART}.
     * @param maxWidth The max width of the loaded bitmap.
     * @param maxHeight The max height of the loaded bitmap.
     * @param callback A callback which will be called after the loading finished.
     */
    @UiThread
    public void loadBitmap(
            Context context,
            final int type,
            int maxWidth,
            int maxHeight,
            ImageLoader.ImageLoaderCallback callback) {
        String uriString = getImageUriString(type);
        ImageLoader.loadBitmap(context, uriString, maxWidth, maxHeight, callback);
    }

    /**
     * Sets if the channel logo exists. This method should be only called from {@link
     * ChannelDataManager}.
     */
    @Override
    public void setChannelLogoExist(boolean exist) {
        mChannelLogoExist = exist;
    }

    /** Returns if channel logo exists. */
    public boolean channelLogoExists() {
        return mChannelLogoExist;
    }

    /**
     * Returns the type of app link for this channel. It returns {@link
     * Channel#APP_LINK_TYPE_CHANNEL} if the channel has a non null app link text and a valid app
     * link intent, it returns {@link Channel#APP_LINK_TYPE_APP} if the input service which holds
     * the channel has leanback launch intent, and it returns {@link Channel#APP_LINK_TYPE_NONE}
     * otherwise.
     */
    public int getAppLinkType(Context context) {
        if (mAppLinkType == APP_LINK_TYPE_NOT_SET) {
            initAppLinkTypeAndIntent(context);
        }
        return mAppLinkType;
    }

    /**
     * Returns the app link intent for this channel. If the type of app link is {@link
     * Channel#APP_LINK_TYPE_NONE}, it returns {@code null}.
     */
    public Intent getAppLinkIntent(Context context) {
        if (mAppLinkType == APP_LINK_TYPE_NOT_SET) {
            initAppLinkTypeAndIntent(context);
        }
        return mAppLinkIntent;
    }

    private void initAppLinkTypeAndIntent(Context context) {
        mAppLinkType = APP_LINK_TYPE_NONE;
        mAppLinkIntent = null;
        PackageManager pm = context.getPackageManager();
        if (!TextUtils.isEmpty(mAppLinkText) && !TextUtils.isEmpty(mAppLinkIntentUri)) {
            try {
                Intent intent = Intent.parseUri(mAppLinkIntentUri, Intent.URI_INTENT_SCHEME);
                if (intent.resolveActivityInfo(pm, 0) != null) {
                    mAppLinkIntent = intent;
                    mAppLinkIntent.putExtra(
                            CommonConstants.EXTRA_APP_LINK_CHANNEL_URI, getUri().toString());
                    mAppLinkType = APP_LINK_TYPE_CHANNEL;
                    return;
                } else {
                    Log.w(TAG, "No activity exists to handle : " + mAppLinkIntentUri);
                }
            } catch (URISyntaxException e) {
                Log.w(TAG, "Unable to set app link for " + mAppLinkIntentUri, e);
                // Do nothing.
            }
        }
        if (mPackageName.equals(context.getApplicationContext().getPackageName())) {
            return;
        }
        mAppLinkIntent = pm.getLeanbackLaunchIntentForPackage(mPackageName);
        if (mAppLinkIntent != null) {
            mAppLinkIntent.putExtra(
                    CommonConstants.EXTRA_APP_LINK_CHANNEL_URI, getUri().toString());
            mAppLinkType = APP_LINK_TYPE_APP;
        }
    }

    private String getImageUriString(int type) {
        switch (type) {
            case LOAD_IMAGE_TYPE_CHANNEL_LOGO:
                return TvContract.buildChannelLogoUri(mId).toString();
            case LOAD_IMAGE_TYPE_APP_LINK_ICON:
                return mAppLinkIconUri;
            case LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART:
                return mAppLinkPosterArtUri;
        }
        return null;
    }

    /**
     * Default Channel ordering.
     *
     * <p>Ordering
     * <li>{@link TvInputManagerHelper#isPartnerInput(String)}
     * <li>{@link #getInputLabelForChannel(Channel)}
     * <li>{@link #getInputId()}
     * <li>{@link ChannelNumber#compare(String, String)}
     * <li>
     * </ol>
     */
    public static class DefaultComparator implements Comparator<Channel> {
        private final Context mContext;
        private final TvInputManagerHelper mInputManager;
        private final Map<String, String> mInputIdToLabelMap = new HashMap<>();
        private boolean mDetectDuplicatesEnabled;

        public DefaultComparator(Context context, TvInputManagerHelper inputManager) {
            mContext = context;
            mInputManager = inputManager;
        }

        public void setDetectDuplicatesEnabled(boolean detectDuplicatesEnabled) {
            mDetectDuplicatesEnabled = detectDuplicatesEnabled;
        }

        @SuppressWarnings("ReferenceEquality")
        @Override
        public int compare(Channel lhs, Channel rhs) {
            if (lhs == rhs) {
                return 0;
            }
            // Put channels from OEM/SOC inputs first.
            boolean lhsIsPartner = mInputManager.isPartnerInput(lhs.getInputId());
            boolean rhsIsPartner = mInputManager.isPartnerInput(rhs.getInputId());
            if (lhsIsPartner != rhsIsPartner) {
                return lhsIsPartner ? -1 : 1;
            }
            // Compare the input labels.
            String lhsLabel = getInputLabelForChannel(lhs);
            String rhsLabel = getInputLabelForChannel(rhs);
            int result =
                    lhsLabel == null
                            ? (rhsLabel == null ? 0 : 1)
                            : rhsLabel == null ? -1 : lhsLabel.compareTo(rhsLabel);
            if (result != 0) {
                return result;
            }
            // Compare the input IDs. The input IDs cannot be null.
            result = lhs.getInputId().compareTo(rhs.getInputId());
            if (result != 0) {
                return result;
            }
            // Compare the channel numbers if both channels belong to the same input.
            result = ChannelNumber.compare(lhs.getDisplayNumber(), rhs.getDisplayNumber());
            if (mDetectDuplicatesEnabled && result == 0) {
                Log.w(
                        TAG,
                        "Duplicate channels detected! - \""
                                + lhs.getDisplayText()
                                + "\" and \""
                                + rhs.getDisplayText()
                                + "\"");
            }
            return result;
        }

        @VisibleForTesting
        String getInputLabelForChannel(Channel channel) {
            String label = mInputIdToLabelMap.get(channel.getInputId());
            if (label == null) {
                TvInputInfo info = mInputManager.getTvInputInfo(channel.getInputId());
                if (info != null) {
                    label = Utils.loadLabel(mContext, info);
                    if (label != null) {
                        mInputIdToLabelMap.put(channel.getInputId(), label);
                    }
                }
            }
            return label;
        }
    }
}
