1 /*
2  * Copyright (C) 2017 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.testing;
18 
19 import com.android.tv.data.ChannelImpl;
20 import com.android.tv.data.Lineup;
21 import com.android.tv.data.ProgramImpl;
22 import com.android.tv.data.api.Channel;
23 import com.android.tv.data.api.Program;
24 import com.android.tv.testing.fakes.FakeClock;
25 
26 import com.google.common.base.Function;
27 import com.google.common.collect.ImmutableList;
28 import com.google.common.collect.ImmutableListMultimap;
29 import com.google.common.collect.Iterables;
30 import com.google.common.collect.ListMultimap;
31 
32 import java.util.concurrent.TimeUnit;
33 
34 /** EPG data for use in tests. */
35 public abstract class EpgTestData {
36 
37     public static final androidx.tvprovider.media.tv.Channel CHANNEL_10 =
38             new androidx.tvprovider.media.tv.Channel.Builder()
39                     .setDisplayName("Channel TEN")
40                     .setDisplayNumber("10")
41                     .setNetworkAffiliation("Channel 10 Network Affiliation")
42                     .build();
43     public static final androidx.tvprovider.media.tv.Channel CHANNEL_11 =
44             new androidx.tvprovider.media.tv.Channel.Builder()
45                     .setDisplayName("Channel Eleven")
46                     .setDisplayNumber("11")
47                     .build();
48     public static final androidx.tvprovider.media.tv.Channel CHANNEL_90_2 =
49             new androidx.tvprovider.media.tv.Channel.Builder()
50                     .setDisplayName("Channel Ninety dot Two")
51                     .setDisplayNumber("90.2")
52                     .build();
53 
54     public static final Lineup LINEUP_1 =
55             new Lineup(
56                     "lineup1",
57                     Lineup.LINEUP_SATELLITE,
58                     "Lineup one",
59                     "Location one",
60                     ImmutableList.of("1", "2.2"));
61     public static final Lineup LINEUP_2 =
62             new Lineup(
63                     "lineup2",
64                     Lineup.LINEUP_SATELLITE,
65                     "Lineup two",
66                     "Location two",
67                     ImmutableList.of("1", "2.3"));
68 
69     public static final Lineup LINEUP_90210 =
70             new Lineup(
71                     "test90210",
72                     Lineup.LINEUP_BROADCAST_DIGITAL,
73                     "Test 90210",
74                     "Beverly Hills",
75                     ImmutableList.of("90.2", "10"));
76 
77     // Programs start and end times are set relative to 0.
78     // Then when loaded they are offset by the {@link #getStartTimeMs}.
79     // Start and end time may be negative meaning they happen before "now".
80 
81     public static final Program PROGRAM_1 =
82             new ProgramImpl.Builder()
83                     .setTitle("Program 1")
84                     .setStartTimeUtcMillis(0)
85                     .setEndTimeUtcMillis(TimeUnit.MINUTES.toMillis(30))
86                     .build();
87 
88     public static final Program PROGRAM_2 =
89             new ProgramImpl.Builder()
90                     .setTitle("Program 2")
91                     .setStartTimeUtcMillis(TimeUnit.MINUTES.toMillis(30))
92                     .setEndTimeUtcMillis(TimeUnit.MINUTES.toMillis(60))
93                     .build();
94 
95     public static final EpgTestData DATA_90210 =
96             new EpgTestData() {
97 
98                 //  Thursday, June 1, 2017 4:00:00 PM GMT-07:00
99                 private final long testStartTimeMs = 1496358000000L;
100 
101                 @Override
102                 public ListMultimap<String, Lineup> getLineups() {
103                     ImmutableListMultimap.Builder<String, Lineup> builder =
104                             ImmutableListMultimap.builder();
105                     return builder.putAll("90210", LINEUP_1, LINEUP_2, LINEUP_90210).build();
106                 }
107 
108                 @Override
109                 public ListMultimap<String, Channel> getLineupChannels() {
110                     ImmutableListMultimap.Builder<String, Channel> builder =
111                             ImmutableListMultimap.builder();
112                     return builder.putAll(
113                                     LINEUP_90210.getId(), toTvChannels(CHANNEL_90_2, CHANNEL_10))
114                             .putAll(LINEUP_1.getId(), toTvChannels(CHANNEL_10, CHANNEL_11))
115                             .build();
116                 }
117 
118                 @Override
119                 public ListMultimap<String, Program> getEpgPrograms() {
120                     ImmutableListMultimap.Builder<String, Program> builder =
121                             ImmutableListMultimap.builder();
122                     return builder.putAll(
123                                     CHANNEL_10.getDisplayNumber(),
124                                     EpgTestData.updateTime(getStartTimeMs(), PROGRAM_1))
125                             .putAll(
126                                     CHANNEL_11.getDisplayNumber(),
127                                     EpgTestData.updateTime(getStartTimeMs(), PROGRAM_2))
128                             .build();
129                 }
130 
131                 @Override
132                 public long getStartTimeMs() {
133                     return testStartTimeMs;
134                 }
135             };
136 
getLineups()137     public abstract ListMultimap<String, Lineup> getLineups();
138 
getLineupChannels()139     public abstract ListMultimap<String, Channel> getLineupChannels();
140 
getEpgPrograms()141     public abstract ListMultimap<String, Program> getEpgPrograms();
142 
143     /** The starting time for this test data */
getStartTimeMs()144     public abstract long getStartTimeMs();
145 
146     /**
147      * Loads test data
148      *
149      * <p>
150      *
151      * <ul>
152      *   <li>Sets clock to {@link #getStartTimeMs()} and boot time to 12 hours before that
153      *   <li>Loads lineups
154      *   <li>Loads lineupChannels
155      *   <li>Loads epgPrograms
156      * </ul>
157      */
loadData(FakeClock clock, FakeEpgReader epgReader)158     public final void loadData(FakeClock clock, FakeEpgReader epgReader) {
159         clock.setBootTimeMillis(getStartTimeMs() + TimeUnit.HOURS.toMillis(-12));
160         clock.setCurrentTimeMillis(getStartTimeMs());
161         epgReader.zip2lineups.putAll(getLineups());
162         epgReader.lineup2Channels.putAll(getLineupChannels());
163         epgReader.epgChannelId2Programs.putAll(getEpgPrograms());
164     }
165 
loadData(TestSingletonApp testSingletonApp)166     public final void loadData(TestSingletonApp testSingletonApp) {
167         loadData(testSingletonApp.fakeClock, testSingletonApp.epgReader);
168     }
169 
toTvChannels( androidx.tvprovider.media.tv.Channel... channels)170     private static Iterable<Channel> toTvChannels(
171             androidx.tvprovider.media.tv.Channel... channels) {
172         return Iterables.transform(
173                 ImmutableList.copyOf(channels),
174                 new Function<androidx.tvprovider.media.tv.Channel, Channel>() {
175                     @Override
176                     public Channel apply(androidx.tvprovider.media.tv.Channel original) {
177                         return toTvChannel(original);
178                     }
179                 });
180     }
181 
182     public static Channel toTvChannel(androidx.tvprovider.media.tv.Channel original) {
183         return new ChannelImpl.Builder()
184                 .setDisplayName(original.getDisplayName())
185                 .setDisplayNumber(original.getDisplayNumber())
186                 .setNetworkAffiliation(original.getNetworkAffiliation())
187                 // TODO implement the reset
188                 .build();
189     }
190 
191     /** Add time to the startTime and stopTime of each program */
192     private static Iterable<Program> updateTime(long time, Program... programs) {
193         return Iterables.transform(
194                 ImmutableList.copyOf(programs),
195                 new Function<Program, Program>() {
196                     @Override
197                     public Program apply(Program p) {
198                         return new ProgramImpl.Builder(p)
199                                 .setStartTimeUtcMillis(p.getStartTimeUtcMillis() + time)
200                                 .setEndTimeUtcMillis(p.getEndTimeUtcMillis() + time)
201                                 .build();
202                     }
203                 });
204     }
205 }
206