Home | History | Annotate | Download | only in playback
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 
     15 package com.example.android.tv.channelsprograms.playback;
     16 
     17 import android.content.ContentUris;
     18 import android.content.Context;
     19 import android.net.Uri;
     20 import android.support.annotation.NonNull;
     21 import android.support.media.tv.TvContractCompat;
     22 import android.support.media.tv.WatchNextProgram;
     23 import android.util.Log;
     24 
     25 import com.example.android.tv.channelsprograms.model.MockDatabase;
     26 import com.example.android.tv.channelsprograms.model.Movie;
     27 import com.example.android.tv.channelsprograms.util.AppLinkHelper;
     28 
     29 /** Adds, updates, and removes the currently playing {@link Movie} from the "Watch Next" channel. */
     30 public class WatchNextAdapter {
     31 
     32     private static final String TAG = "WatchNextAdapter";
     33 
     34     public void updateProgress(
     35             Context context, long channelId, Movie movie, long position, long duration) {
     36         Log.d(TAG, String.format("Updating the movie (%d) in watch next.", movie.getId()));
     37 
     38         Movie entity = MockDatabase.findMovieById(context, channelId, movie.getId());
     39         if (entity == null) {
     40             Log.e(
     41                     TAG,
     42                     String.format(
     43                             "Could not find movie in channel: channel id: %d, movie id: %d",
     44                             channelId, movie.getId()));
     45             return;
     46         }
     47 
     48         // TODO: step 12 add watch next program.
     49         WatchNextProgram program = createWatchNextProgram(channelId, entity, position, duration);
     50         if (entity.getWatchNextId() < 1L) {
     51             // Create a program.
     52             Uri watchNextProgramUri =
     53                     context.getContentResolver()
     54                             .insert(
     55                                     TvContractCompat.WatchNextPrograms.CONTENT_URI,
     56                                     program.toContentValues());
     57             long watchNextId = ContentUris.parseId(watchNextProgramUri);
     58             entity.setWatchNextId(watchNextId);
     59             MockDatabase.saveMovie(context, channelId, entity);
     60 
     61             Log.d(TAG, "Watch Next program added: " + watchNextId);
     62         } else {
     63             // TODO: step 14 update program.
     64             // Updates the progress and last engagement time of the program.
     65             context.getContentResolver()
     66                     .update(
     67                             TvContractCompat.buildWatchNextProgramUri(entity.getWatchNextId()),
     68                             program.toContentValues(),
     69                             null,
     70                             null);
     71 
     72             Log.d(TAG, "Watch Next program updated: " + entity.getWatchNextId());
     73         }
     74     }
     75 
     76     @NonNull
     77     private WatchNextProgram createWatchNextProgram(
     78             long channelId, Movie movie, long position, long duration) {
     79         // TODO: step 13 convert movie
     80         Uri posterArtUri = Uri.parse(movie.getCardImageUrl());
     81         Uri intentUri = AppLinkHelper.buildPlaybackUri(channelId, movie.getId(), position);
     82 
     83         WatchNextProgram.Builder builder = new WatchNextProgram.Builder();
     84         builder.setType(TvContractCompat.PreviewProgramColumns.TYPE_MOVIE)
     85                 .setWatchNextType(TvContractCompat.WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE)
     86                 .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
     87                 .setLastPlaybackPositionMillis((int) position)
     88                 .setDurationMillis((int) duration)
     89                 .setTitle(movie.getTitle())
     90                 .setDescription(movie.getDescription())
     91                 .setPosterArtUri(posterArtUri)
     92                 .setIntentUri(intentUri);
     93         return builder.build();
     94     }
     95 
     96     public void removeFromWatchNext(Context context, long channelId, long movieId) {
     97         Movie movie = MockDatabase.findMovieById(context, channelId, movieId);
     98         if (movie == null || movie.getWatchNextId() < 1L) {
     99             Log.d(TAG, "No program to remove from watch next.");
    100             return;
    101         }
    102 
    103         // TODO: step 15 remove program
    104         int rows =
    105                 context.getContentResolver()
    106                         .delete(
    107                                 TvContractCompat.buildWatchNextProgramUri(movie.getWatchNextId()),
    108                                 null,
    109                                 null);
    110         Log.d(TAG, String.format("Deleted %d programs(s) from watch next", rows));
    111 
    112         // Sync our records with the system; remove reference to watch next program.
    113         movie.setWatchNextId(-1);
    114         MockDatabase.saveMovie(context, channelId, movie);
    115     }
    116 }
    117