1 /*
2  * Copyright (C) 2020 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.settings.media;
18 
19 import static android.app.slice.Slice.EXTRA_RANGE_VALUE;
20 import static android.app.slice.Slice.HINT_LIST_ITEM;
21 import static android.app.slice.SliceItem.FORMAT_SLICE;
22 
23 import static com.android.settings.slices.CustomSliceRegistry.REMOTE_MEDIA_SLICE_URI;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.spy;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.content.Context;
34 import android.content.Intent;
35 import android.media.MediaRouter2Manager;
36 import android.media.RoutingSessionInfo;
37 import android.net.Uri;
38 
39 import androidx.slice.Slice;
40 import androidx.slice.SliceMetadata;
41 import androidx.slice.SliceProvider;
42 import androidx.slice.core.SliceAction;
43 import androidx.slice.core.SliceQuery;
44 import androidx.slice.widget.SliceLiveData;
45 
46 import com.android.settings.slices.SliceBackgroundWorker;
47 import com.android.settingslib.media.LocalMediaManager;
48 
49 import org.junit.Before;
50 import org.junit.Ignore;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.robolectric.RobolectricTestRunner;
56 import org.robolectric.RuntimeEnvironment;
57 import org.robolectric.annotation.Config;
58 import org.robolectric.annotation.Implementation;
59 import org.robolectric.annotation.Implements;
60 
61 import java.util.ArrayList;
62 import java.util.List;
63 
64 @RunWith(RobolectricTestRunner.class)
65 @Config(shadows = RemoteMediaSliceTest.ShadowSliceBackgroundWorker.class)
66 public class RemoteMediaSliceTest {
67 
68     private static final String MEDIA_ID = "media_id";
69     private static final String TEST_SESSION_1_ID = "test_session_1_id";
70     private static final String TEST_SESSION_1_NAME = "test_session_1_name";
71     private static final int TEST_VOLUME = 3;
72 
73     private static MediaDeviceUpdateWorker sMediaDeviceUpdateWorker;
74 
75     @Mock
76     private LocalMediaManager mLocalMediaManager;
77 
78     private final List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
79 
80     private Context mContext;
81     private RemoteMediaSlice mRemoteMediaSlice;
82 
83     @Before
setUp()84     public void setUp() throws Exception {
85         MockitoAnnotations.initMocks(this);
86         mContext = spy(RuntimeEnvironment.application);
87 
88         // Set-up specs for SliceMetadata.
89         SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
90 
91         mRemoteMediaSlice = new RemoteMediaSlice(mContext);
92         sMediaDeviceUpdateWorker = spy(new MediaDeviceUpdateWorker(mContext,
93                 REMOTE_MEDIA_SLICE_URI));
94         sMediaDeviceUpdateWorker.mLocalMediaManager = mLocalMediaManager;
95         sMediaDeviceUpdateWorker.mManager = mock(MediaRouter2Manager.class);
96         final RoutingSessionInfo remoteSessionInfo = mock(RoutingSessionInfo.class);
97         when(remoteSessionInfo.getId()).thenReturn(TEST_SESSION_1_ID);
98         when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME);
99         when(remoteSessionInfo.getVolumeMax()).thenReturn(100);
100         when(remoteSessionInfo.getVolume()).thenReturn(10);
101         when(remoteSessionInfo.isSystemSession()).thenReturn(false);
102         mRoutingSessionInfos.add(remoteSessionInfo);
103         when(sMediaDeviceUpdateWorker.getActiveRemoteMediaDevices())
104                 .thenReturn(mRoutingSessionInfos);
105     }
106 
107     @Test
onNotifyChange_noId_doNothing()108     public void onNotifyChange_noId_doNothing() {
109         final Intent intent = new Intent();
110         intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME);
111 
112         mRemoteMediaSlice.onNotifyChange(intent);
113 
114         verify(sMediaDeviceUpdateWorker, never())
115                 .adjustSessionVolume(TEST_SESSION_1_ID, TEST_VOLUME);
116     }
117 
118     @Test
onNotifyChange_verifyAdjustVolume()119     public void onNotifyChange_verifyAdjustVolume() {
120         final Intent intent = new Intent();
121         intent.putExtra(MEDIA_ID, TEST_SESSION_1_ID);
122         intent.putExtra(EXTRA_RANGE_VALUE, TEST_VOLUME);
123 
124         mRemoteMediaSlice.onNotifyChange(intent);
125 
126         verify(sMediaDeviceUpdateWorker).adjustSessionVolume(TEST_SESSION_1_ID, TEST_VOLUME);
127     }
128 
129     @Test
getSlice_noActiveSession_checkRowNumber()130     public void getSlice_noActiveSession_checkRowNumber() {
131         mRoutingSessionInfos.clear();
132         final Slice slice = mRemoteMediaSlice.getSlice();
133         final int rows = SliceQuery.findAll(slice, FORMAT_SLICE, HINT_LIST_ITEM, null).size();
134 
135         assertThat(rows).isEqualTo(0);
136     }
137 
138     @Test
139     @Ignore
getSlice_withActiveSession_checkRowNumber()140     public void getSlice_withActiveSession_checkRowNumber() {
141         final Slice slice = mRemoteMediaSlice.getSlice();
142         final int rows = SliceQuery.findAll(slice, FORMAT_SLICE, HINT_LIST_ITEM, null).size();
143 
144         // InputRange and Row
145         assertThat(rows).isEqualTo(2);
146     }
147 
148     @Test
149     @Ignore
getSlice_withActiveSession_checkTitle()150     public void getSlice_withActiveSession_checkTitle() {
151         final Slice slice = mRemoteMediaSlice.getSlice();
152         final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
153         final SliceAction primaryAction = metadata.getPrimaryAction();
154 
155         assertThat(primaryAction.getTitle().toString()).isEqualTo(mContext.getText(
156                 com.android.settings.R.string.remote_media_volume_option_title));
157     }
158 
159     @Implements(SliceBackgroundWorker.class)
160     public static class ShadowSliceBackgroundWorker {
161 
162         @Implementation
getInstance(Uri uri)163         public static SliceBackgroundWorker getInstance(Uri uri) {
164             return sMediaDeviceUpdateWorker;
165         }
166     }
167 }
168