blob: edc23c53774eb48b12029bed825091ca54965fbe [file] [log] [blame]
/*
* Copyright (C) 2017 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.recommendation;
import android.content.Context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;
import com.android.tv.TvSingletons;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.PreviewProgramContent;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/** Class to update the preview data for {@link RecordedProgram} */
@RequiresApi(Build.VERSION_CODES.O)
@SuppressWarnings("AndroidApiChecker") // TODO(b/32513850) remove when error prone is updated
public class RecordedProgramPreviewUpdater {
private static final String TAG = "RecordedProgramPreviewUpdater";
private static final boolean DEBUG = false;
private static final int RECOMMENDATION_COUNT = 6;
private static RecordedProgramPreviewUpdater sRecordedProgramPreviewUpdater;
/** Creates and returns the {@link RecordedProgramPreviewUpdater}. */
public static RecordedProgramPreviewUpdater getInstance(Context context) {
if (sRecordedProgramPreviewUpdater == null) {
sRecordedProgramPreviewUpdater =
new RecordedProgramPreviewUpdater(context.getApplicationContext());
}
return sRecordedProgramPreviewUpdater;
}
private final Context mContext;
private final PreviewDataManager mPreviewDataManager;
private final DvrDataManager mDvrDataManager;
private RecordedProgramPreviewUpdater(Context context) {
mContext = context.getApplicationContext();
TvSingletons tvSingletons = TvSingletons.getSingletons(mContext);
mPreviewDataManager = tvSingletons.getPreviewDataManager();
mDvrDataManager = tvSingletons.getDvrDataManager();
mDvrDataManager.addRecordedProgramListener(
new DvrDataManager.RecordedProgramListener() {
@Override
public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
if (DEBUG) Log.d(TAG, "Add new preview recorded programs");
updatePreviewDataForRecordedPrograms();
}
@Override
public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
if (DEBUG) Log.d(TAG, "Update preview recorded programs");
updatePreviewDataForRecordedPrograms();
}
@Override
public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
if (DEBUG) Log.d(TAG, "Delete preview recorded programs");
updatePreviewDataForRecordedPrograms();
}
});
}
/** Updates the preview data for recorded programs. */
public void updatePreviewDataForRecordedPrograms() {
if (!mPreviewDataManager.isLoadFinished()) {
mPreviewDataManager.addListener(
new PreviewDataManager.PreviewDataListener() {
@Override
public void onPreviewDataLoadFinished() {
mPreviewDataManager.removeListener(this);
updatePreviewDataForRecordedPrograms();
}
@Override
public void onPreviewDataUpdateFinished() {}
});
return;
}
if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
mDvrDataManager.addRecordedProgramLoadFinishedListener(
new DvrDataManager.OnRecordedProgramLoadFinishedListener() {
@Override
public void onRecordedProgramLoadFinished() {
mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
updatePreviewDataForRecordedPrograms();
}
});
return;
}
updatePreviewDataForRecordedProgramsInternal();
}
private void updatePreviewDataForRecordedProgramsInternal() {
Set<RecordedProgram> recordedPrograms = generateRecommendationRecordedPrograms();
Long recordedPreviewChannelId =
mPreviewDataManager.getPreviewChannelId(
PreviewDataManager.TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL);
if (recordedPreviewChannelId == PreviewDataManager.INVALID_PREVIEW_CHANNEL_ID
&& !recordedPrograms.isEmpty()) {
createPreviewChannelForRecordedPrograms();
} else {
mPreviewDataManager.updatePreviewProgramsForChannel(
recordedPreviewChannelId,
generatePreviewProgramContentsFromRecordedPrograms(
recordedPreviewChannelId, recordedPrograms),
null);
}
}
private void createPreviewChannelForRecordedPrograms() {
mPreviewDataManager.createPreviewChannel(
PreviewDataManager.TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL,
new PreviewDataManager.OnPreviewChannelCreationResultListener() {
@Override
public void onPreviewChannelCreationResult(long createdPreviewChannelId) {
if (createdPreviewChannelId
!= PreviewDataManager.INVALID_PREVIEW_CHANNEL_ID) {
updatePreviewDataForRecordedProgramsInternal();
}
}
});
}
private Set<RecordedProgram> generateRecommendationRecordedPrograms() {
Set<RecordedProgram> programs = new HashSet<>();
ArrayList<RecordedProgram> sortedRecordedPrograms =
new ArrayList<>(mDvrDataManager.getRecordedPrograms());
Collections.sort(
sortedRecordedPrograms, RecordedProgram.START_TIME_THEN_ID_COMPARATOR.reversed());
for (RecordedProgram recordedProgram : sortedRecordedPrograms) {
if (!TextUtils.isEmpty(recordedProgram.getPosterArtUri())) {
programs.add(recordedProgram);
if (programs.size() >= RECOMMENDATION_COUNT) {
break;
}
}
}
return programs;
}
private Set<PreviewProgramContent> generatePreviewProgramContentsFromRecordedPrograms(
long previewChannelId, Set<RecordedProgram> recordedPrograms) {
Set<PreviewProgramContent> result = new HashSet<>();
for (RecordedProgram recordedProgram : recordedPrograms) {
result.add(
PreviewProgramContent.createFromRecordedProgram(
mContext, previewChannelId, recordedProgram));
}
return result;
}
}