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.data;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.content.ContentProvider;
22 import android.content.ContentValues;
23 import android.content.pm.ProviderInfo;
24 import android.database.Cursor;
25 import android.database.SQLException;
26 import android.net.Uri;
27 import android.support.annotation.NonNull;
28 import android.support.annotation.Nullable;
29 import android.util.Log;
30 import android.util.Pair;
31 
32 import androidx.tvprovider.media.tv.PreviewProgram;
33 import androidx.tvprovider.media.tv.TvContractCompat;
34 
35 import com.android.tv.data.api.Channel;
36 import com.android.tv.data.api.Program;
37 import com.android.tv.dvr.data.RecordedProgram;
38 import com.android.tv.testing.TvRobolectricTestRunner;
39 import com.android.tv.testing.constants.ConfigConstants;
40 
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.robolectric.Robolectric;
44 import org.robolectric.RuntimeEnvironment;
45 import org.robolectric.annotation.Config;
46 import org.robolectric.shadows.ShadowContentResolver;
47 import org.robolectric.shadows.ShadowLog;
48 
49 import java.util.List;
50 
51 /** Tests for {@link PreviewDataManager}. */
52 @RunWith(TvRobolectricTestRunner.class)
53 @Config(sdk = ConfigConstants.SDK)
54 public class PreviewDataManagerTest {
55     private static final long FAKE_PREVIEW_CHANNEL_ID = 2002;
56     private static final long FAKE_PROGRAM_ID = 1001;
57     private static final String FAKE_PROGRAM_TITLE = "test program";
58     private static final String FAKE_PROGRAM_POSTER_URI = "http://fake.uri/poster.jpg";
59     private static final long FAKE_CHANNEL_ID = 1002;
60     private static final String FAKE_CHANNEL_DISPLAY_NAME = "test channel";
61     private static final String FAKE_INPUT_ID = "test input";
62 
63     private static class QueryExceptionProvider extends ContentProvider {
64         @Override
onCreate()65         public boolean onCreate() {
66             return false;
67         }
68 
69         @Nullable
70         @Override
query( @onNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder)71         public Cursor query(
72                 @NonNull Uri uri,
73                 @Nullable String[] projection,
74                 @Nullable String selection,
75                 @Nullable String[] selectionArgs,
76                 @Nullable String sortOrder) {
77             throw new SQLException("Testing " + uri);
78         }
79 
80         @Nullable
81         @Override
getType(@onNull Uri uri)82         public String getType(@NonNull Uri uri) {
83             return null;
84         }
85 
86         @Nullable
87         @Override
insert(@onNull Uri uri, @Nullable ContentValues values)88         public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
89             return null;
90         }
91 
92         @Override
delete( @onNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs)93         public int delete(
94                 @NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
95             return 0;
96         }
97 
98         @Override
update( @onNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs)99         public int update(
100                 @NonNull Uri uri,
101                 @Nullable ContentValues values,
102                 @Nullable String selection,
103                 @Nullable String[] selectionArgs) {
104             return 0;
105         }
106     }
107 
108     @Test
start()109     public void start() {
110         PreviewDataManager previewDataManager =
111                 new PreviewDataManager(RuntimeEnvironment.application);
112         assertThat(previewDataManager.isLoadFinished()).isFalse();
113         previewDataManager.start();
114         assertThat(previewDataManager.isLoadFinished()).isTrue();
115     }
116 
117     @Test
queryPreviewData_sqlexception()118     public void queryPreviewData_sqlexception() {
119         ProviderInfo info = new ProviderInfo();
120         info.authority = TvContractCompat.AUTHORITY;
121         QueryExceptionProvider provider =
122                 Robolectric.buildContentProvider(QueryExceptionProvider.class).create(info).get();
123         ShadowContentResolver.registerProviderInternal(TvContractCompat.AUTHORITY, provider);
124 
125         PreviewDataManager previewDataManager =
126                 new PreviewDataManager(RuntimeEnvironment.application);
127         assertThat(previewDataManager.isLoadFinished()).isFalse();
128         previewDataManager.start();
129         List<ShadowLog.LogItem> logs = ShadowLog.getLogsForTag("PreviewDataManager");
130         // The only warning should be the test one
131         // NOTE: I am not using hamcrest matchers because of weird class loading issues
132         // TODO: use truth
133         for (ShadowLog.LogItem log : logs) {
134             if (log.type == Log.WARN) {
135                 assertThat(log.msg).isEqualTo("Unable to get preview data");
136                 assertThat(log.throwable).isInstanceOf(SQLException.class);
137                 assertThat(log.throwable)
138                         .hasMessageThat()
139                         .isEqualTo("Testing content://android.media.tv/channel?preview=true");
140             }
141         }
142     }
143 
144     @Test
createPreviewProgram_fromProgram()145     public void createPreviewProgram_fromProgram() {
146         Program program =
147                 new ProgramImpl.Builder()
148                         .setId(FAKE_PROGRAM_ID)
149                         .setTitle(FAKE_PROGRAM_TITLE)
150                         .setPosterArtUri(FAKE_PROGRAM_POSTER_URI)
151                         .build();
152         Channel channel =
153                 new ChannelImpl.Builder()
154                         .setId(FAKE_CHANNEL_ID)
155                         .setDisplayName(FAKE_CHANNEL_DISPLAY_NAME)
156                         .setInputId(FAKE_INPUT_ID)
157                         .build();
158 
159         PreviewProgram previewProgram =
160                 PreviewDataManager.PreviewDataUtils.createPreviewProgramFromContent(
161                         PreviewProgramContent.createFromProgram(
162                                 FAKE_PREVIEW_CHANNEL_ID, program, channel),
163                         0);
164 
165         assertThat(previewProgram.getChannelId()).isEqualTo(FAKE_PREVIEW_CHANNEL_ID);
166         assertThat(previewProgram.getType())
167                 .isEqualTo(TvContractCompat.PreviewPrograms.TYPE_CHANNEL);
168         assertThat(previewProgram.isLive()).isTrue();
169         assertThat(previewProgram.getTitle()).isEqualTo(FAKE_PROGRAM_TITLE);
170         assertThat(previewProgram.getDescription()).isEqualTo(FAKE_CHANNEL_DISPLAY_NAME);
171         assertThat(previewProgram.getPosterArtUri().toString()).isEqualTo(FAKE_PROGRAM_POSTER_URI);
172         assertThat(previewProgram.getIntentUri()).isEqualTo(channel.getUri());
173         assertThat(previewProgram.getPreviewVideoUri())
174                 .isEqualTo(
175                         PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
176                                 channel.getUri(),
177                                 Pair.create(PreviewProgramContent.PARAM_INPUT, FAKE_INPUT_ID)));
178         assertThat(previewProgram.getInternalProviderId())
179                 .isEqualTo(Long.toString(FAKE_PROGRAM_ID));
180         assertThat(previewProgram.getContentId()).isEqualTo(channel.getUri().toString());
181     }
182 
183     @Test
createPreviewProgram_fromRecordedProgram()184     public void createPreviewProgram_fromRecordedProgram() {
185         RecordedProgram program =
186                 RecordedProgram.builder()
187                         .setId(FAKE_PROGRAM_ID)
188                         .setTitle(FAKE_PROGRAM_TITLE)
189                         .setPosterArtUri(FAKE_PROGRAM_POSTER_URI)
190                         .setInputId(FAKE_INPUT_ID)
191                         .build();
192         Uri recordedProgramUri = TvContractCompat.buildRecordedProgramUri(FAKE_PROGRAM_ID);
193 
194         PreviewProgram previewProgram =
195                 PreviewDataManager.PreviewDataUtils.createPreviewProgramFromContent(
196                         PreviewProgramContent.createFromRecordedProgram(
197                                 FAKE_PREVIEW_CHANNEL_ID, program, null),
198                         0);
199 
200         assertThat(previewProgram.getChannelId()).isEqualTo(FAKE_PREVIEW_CHANNEL_ID);
201         assertThat(previewProgram.getType()).isEqualTo(TvContractCompat.PreviewPrograms.TYPE_CLIP);
202         assertThat(previewProgram.isLive()).isFalse();
203         assertThat(previewProgram.getTitle()).isEqualTo(FAKE_PROGRAM_TITLE);
204         assertThat(previewProgram.getDescription()).isEmpty();
205         assertThat(previewProgram.getPosterArtUri().toString()).isEqualTo(FAKE_PROGRAM_POSTER_URI);
206         assertThat(previewProgram.getIntentUri()).isEqualTo(recordedProgramUri);
207         assertThat(previewProgram.getPreviewVideoUri())
208                 .isEqualTo(
209                         PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
210                                 recordedProgramUri,
211                                 Pair.create(PreviewProgramContent.PARAM_INPUT, FAKE_INPUT_ID)));
212         assertThat(previewProgram.getContentId()).isEqualTo(recordedProgramUri.toString());
213     }
214 }
215