| /* |
| * 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; |
| } |
| } |