1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.recommendation;
18 
19 import java.util.concurrent.TimeUnit;
20 
21 public class RecentChannelEvaluator extends Recommender.Evaluator {
22     private static final long WATCH_DURATION_MS_LOWER_BOUND = TimeUnit.MINUTES.toMillis(3);
23     private static final long WATCH_DURATION_MS_UPPER_BOUND = TimeUnit.MINUTES.toMillis(7);
24 
25     private static final double MAX_SCORE_FOR_LOWER_BOUND = 0.1;
26 
27     private long mLastWatchLogUpdateTimeMs;
28 
RecentChannelEvaluator()29     public RecentChannelEvaluator() {
30         mLastWatchLogUpdateTimeMs = System.currentTimeMillis();
31     }
32 
33     @Override
onNewWatchLog(ChannelRecord channelRecord)34     public void onNewWatchLog(ChannelRecord channelRecord) {
35         mLastWatchLogUpdateTimeMs = System.currentTimeMillis();
36     }
37 
38     @Override
evaluateChannel(long channelId)39     public double evaluateChannel(long channelId) {
40         ChannelRecord cr = getRecommender().getChannelRecord(channelId);
41         if (cr == null) {
42             return NOT_RECOMMENDED;
43         }
44         WatchedProgram[] watchHistory = cr.getWatchHistory();
45         double maxScore = 0.0;
46         for (int i = watchHistory.length - 1; i >= 0; --i) {
47             double recentWatchScore =
48                     (double) watchHistory[i].getWatchEndTimeMs() / mLastWatchLogUpdateTimeMs;
49             double watchDurationScore;
50             double watchDuration = watchHistory[i].getWatchedDurationMs();
51             if (watchDuration < WATCH_DURATION_MS_LOWER_BOUND) {
52                 watchDurationScore = MAX_SCORE_FOR_LOWER_BOUND;
53             } else if (watchDuration < WATCH_DURATION_MS_UPPER_BOUND) {
54                 watchDurationScore = (watchDuration - WATCH_DURATION_MS_LOWER_BOUND)
55                         / (WATCH_DURATION_MS_UPPER_BOUND - WATCH_DURATION_MS_LOWER_BOUND)
56                         * (1 - MAX_SCORE_FOR_LOWER_BOUND) + MAX_SCORE_FOR_LOWER_BOUND;
57             } else {
58                 watchDurationScore = 1.0;
59             }
60             maxScore = Math.max(maxScore, watchDurationScore * recentWatchScore);
61         }
62         return (maxScore > 0.0) ? maxScore : NOT_RECOMMENDED;
63     }
64 }