1816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/* 2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project 3816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 4816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 5816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * you may not use this file except in compliance with the License. 6816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * You may obtain a copy of the License at 7816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 8816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 9816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 10816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Unless required by applicable law or agreed to in writing, software 11816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 12816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * See the License for the specific language governing permissions and 14816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * limitations under the License. 15816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 16816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 17816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopackage com.android.tv.recommendation; 18816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.concurrent.TimeUnit; 20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopublic class RecentChannelEvaluator extends Recommender.Evaluator { 22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final long WATCH_DURATION_MS_LOWER_BOUND = TimeUnit.MINUTES.toMillis(3); 23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final long WATCH_DURATION_MS_UPPER_BOUND = TimeUnit.MINUTES.toMillis(7); 24816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final double MAX_SCORE_FOR_LOWER_BOUND = 0.1; 26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private long mLastWatchLogUpdateTimeMs; 28816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 29816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public RecentChannelEvaluator() { 30816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mLastWatchLogUpdateTimeMs = System.currentTimeMillis(); 31816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 32816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onNewWatchLog(ChannelRecord channelRecord) { 35816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko mLastWatchLogUpdateTimeMs = System.currentTimeMillis(); 36816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 38816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 39816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public double evaluateChannel(long channelId) { 40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko ChannelRecord cr = getRecommender().getChannelRecord(channelId); 41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (cr == null) { 42816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return NOT_RECOMMENDED; 43816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko WatchedProgram[] watchHistory = cr.getWatchHistory(); 45816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko double maxScore = 0.0; 46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko for (int i = watchHistory.length - 1; i >= 0; --i) { 47816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko double recentWatchScore = 48816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko (double) watchHistory[i].getWatchEndTimeMs() / mLastWatchLogUpdateTimeMs; 49816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko double watchDurationScore; 50816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko double watchDuration = watchHistory[i].getWatchedDurationMs(); 51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (watchDuration < WATCH_DURATION_MS_LOWER_BOUND) { 52816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko watchDurationScore = MAX_SCORE_FOR_LOWER_BOUND; 53816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else if (watchDuration < WATCH_DURATION_MS_UPPER_BOUND) { 54816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko watchDurationScore = (watchDuration - WATCH_DURATION_MS_LOWER_BOUND) 55816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko / (WATCH_DURATION_MS_UPPER_BOUND - WATCH_DURATION_MS_LOWER_BOUND) 56816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * (1 - MAX_SCORE_FOR_LOWER_BOUND) + MAX_SCORE_FOR_LOWER_BOUND; 57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 58816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko watchDurationScore = 1.0; 59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko maxScore = Math.max(maxScore, watchDurationScore * recentWatchScore); 61816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 62816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return (maxScore > 0.0) ? maxScore : NOT_RECOMMENDED; 63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 647d67089aa1e9aa2123c3cd2f386d7019a1544db1Nick Chalko}