1 /*
2  * Copyright (C) 2018 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 package com.android.server.hdmi;
17 
18 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
19 import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE;
20 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
21 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
22 import static com.android.server.hdmi.Constants.ADDR_INVALID;
23 import static com.android.server.hdmi.Constants.ADDR_TV;
24 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
25 
26 import static com.google.common.truth.Truth.assertThat;
27 
28 import android.content.Context;
29 import android.hardware.hdmi.HdmiControlManager;
30 import android.hardware.hdmi.HdmiDeviceInfo;
31 import android.hardware.hdmi.HdmiPortInfo;
32 import android.hardware.hdmi.IHdmiControlCallback;
33 import android.hardware.tv.cec.V1_0.SendMessageResult;
34 import android.os.Looper;
35 import android.os.RemoteException;
36 import android.os.test.TestLooper;
37 import android.platform.test.annotations.Presubmit;
38 import android.sysprop.HdmiProperties;
39 import android.view.KeyEvent;
40 
41 import androidx.test.InstrumentationRegistry;
42 import androidx.test.filters.SmallTest;
43 
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.junit.runners.JUnit4;
48 import org.mockito.MockitoAnnotations;
49 
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.concurrent.TimeUnit;
53 
54 @SmallTest
55 @Presubmit
56 @RunWith(JUnit4.class)
57 /** Tests for {@link HdmiCecLocalDevicePlayback} class. */
58 public class HdmiCecLocalDevicePlaybackTest {
59     private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1;
60     private static final int HOTPLUG_INTERVAL =
61             HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_PLAYBACK;
62 
63     private static final int PORT_1 = 1;
64     private static final HdmiDeviceInfo INFO_TV = HdmiDeviceInfo.cecDeviceBuilder()
65             .setLogicalAddress(ADDR_TV)
66             .setPhysicalAddress(0x0000)
67             .setPortId(PORT_1)
68             .setDeviceType(HdmiDeviceInfo.DEVICE_TV)
69             .setVendorId(0x1234)
70             .setDisplayName("TV")
71             .setDevicePowerStatus(HdmiControlManager.POWER_STATUS_ON)
72             .setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B)
73             .build();
74 
75     private HdmiControlService mHdmiControlService;
76     private HdmiCecController mHdmiCecController;
77     private HdmiCecLocalDevicePlayback mHdmiCecLocalDevicePlayback;
78     private FakeNativeWrapper mNativeWrapper;
79     private Looper mMyLooper;
80     private TestLooper mTestLooper = new TestLooper();
81     private FakePowerManagerWrapper mPowerManager;
82     private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
83     private int mPlaybackPhysicalAddress;
84     private int mPlaybackLogicalAddress;
85     private boolean mWokenUp;
86     private boolean mActiveMediaSessionsPaused;
87     private FakePowerManagerInternalWrapper mPowerManagerInternal =
88             new FakePowerManagerInternalWrapper();
89 
90     @Before
setUp()91     public void setUp() {
92         MockitoAnnotations.initMocks(this);
93 
94         Context context = InstrumentationRegistry.getTargetContext();
95         mMyLooper = mTestLooper.getLooper();
96 
97         FakeAudioFramework audioFramework = new FakeAudioFramework();
98         mHdmiControlService =
99                 new HdmiControlService(InstrumentationRegistry.getTargetContext(),
100                         Collections.singletonList(HdmiDeviceInfo.DEVICE_PLAYBACK),
101                         audioFramework.getAudioManager(),
102                         audioFramework.getAudioDeviceVolumeManager()) {
103 
104                     @Override
105                     void wakeUp() {
106                         mWokenUp = true;
107                         super.wakeUp();
108                     }
109 
110                     @Override
111                     void pauseActiveMediaSessions() {
112                         mActiveMediaSessionsPaused = true;
113                     }
114 
115                     @Override
116                     boolean isCecControlEnabled() {
117                         return true;
118                     }
119 
120                     @Override
121                     boolean isPlaybackDevice() {
122                         return true;
123                     }
124 
125                     @Override
126                     protected void writeStringSystemProperty(String key, String value) {
127                         // do nothing
128                     }
129 
130                     @Override
131                     boolean canGoToStandby() {
132                         return true;
133                     }
134                 };
135 
136         mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
137         mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
138         mHdmiControlService.setIoLooper(mMyLooper);
139         mNativeWrapper = new FakeNativeWrapper();
140         mHdmiCecController = HdmiCecController.createWithNativeWrapper(
141                 mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
142         mHdmiControlService.setCecController(mHdmiCecController);
143         mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
144         HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
145         hdmiPortInfos[0] =
146                 new HdmiPortInfo.Builder(1, HdmiPortInfo.PORT_OUTPUT, 0x0000)
147                         .setCecSupported(true)
148                         .setMhlSupported(false)
149                         .setArcSupported(false)
150                         .build();
151         mNativeWrapper.setPortInfo(hdmiPortInfos);
152         mNativeWrapper.setPortConnectionStatus(1, true);
153         mHdmiControlService.initService();
154         mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
155         mPowerManager = new FakePowerManagerWrapper(context);
156         mHdmiControlService.setPowerManager(mPowerManager);
157         mHdmiControlService.setPowerManagerInternal(mPowerManagerInternal);
158         mPlaybackPhysicalAddress = 0x2000;
159         mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress);
160         mTestLooper.dispatchAll();
161         mHdmiCecLocalDevicePlayback = mHdmiControlService.playback();
162         mLocalDevices.add(mHdmiCecLocalDevicePlayback);
163         mPlaybackLogicalAddress = mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress();
164         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
165         mNativeWrapper.clearResultMessages();
166         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
167                 HdmiProperties.playback_device_action_on_routing_control_values.NONE;
168         mHdmiControlService.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
169     }
170 
171     @Test
handleRoutingChange_None()172     public void handleRoutingChange_None() {
173         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
174                 HdmiProperties.playback_device_action_on_routing_control_values.NONE;
175 
176         mPowerManager.setInteractive(false);
177 
178         HdmiCecMessage message =
179                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
180                         mPlaybackPhysicalAddress);
181 
182         HdmiCecMessage expectedMessage =
183                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
184                         mPlaybackPhysicalAddress);
185 
186         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
187                 .isEqualTo(Constants.HANDLED);
188         mTestLooper.dispatchAll();
189         assertThat(mPowerManager.isInteractive()).isFalse();
190         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
191     }
192 
193     @Test
handleRoutingInformation_None()194     public void handleRoutingInformation_None() {
195         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
196                 HdmiProperties.playback_device_action_on_routing_control_values.NONE;
197 
198         mPowerManager.setInteractive(false);
199 
200         HdmiCecMessage message =
201                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
202                         mPlaybackPhysicalAddress);
203 
204         HdmiCecMessage expectedMessage =
205                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
206                         mPlaybackPhysicalAddress);
207 
208         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
209                 .isEqualTo(Constants.HANDLED);
210         mTestLooper.dispatchAll();
211         assertThat(mPowerManager.isInteractive()).isFalse();
212         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
213     }
214 
215     @Test
handleRoutingChange_WakeUpOnly()216     public void handleRoutingChange_WakeUpOnly() {
217         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
218                 HdmiProperties.playback_device_action_on_routing_control_values.WAKE_UP_ONLY;
219 
220         mPowerManager.setInteractive(false);
221 
222         HdmiCecMessage message =
223                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
224                         mPlaybackPhysicalAddress);
225 
226         HdmiCecMessage expectedMessage =
227                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
228                         mPlaybackPhysicalAddress);
229 
230         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
231                 .isEqualTo(Constants.HANDLED);
232         mTestLooper.dispatchAll();
233         assertThat(mPowerManager.isInteractive()).isTrue();
234         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
235     }
236 
237     @Test
handleRoutingInformation_WakeUpOnly()238     public void handleRoutingInformation_WakeUpOnly() {
239         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
240                 HdmiProperties.playback_device_action_on_routing_control_values.WAKE_UP_ONLY;
241 
242         mPowerManager.setInteractive(false);
243 
244         HdmiCecMessage message =
245                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
246                         mPlaybackPhysicalAddress);
247 
248         HdmiCecMessage expectedMessage =
249                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
250                         mPlaybackPhysicalAddress);
251 
252         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
253                 .isEqualTo(Constants.HANDLED);
254         mTestLooper.dispatchAll();
255         assertThat(mPowerManager.isInteractive()).isTrue();
256         assertThat(mNativeWrapper.getResultMessages().contains(expectedMessage)).isFalse();
257     }
258 
259     @Test
handleRoutingChange_WakeUpAndSendActiveSource()260     public void handleRoutingChange_WakeUpAndSendActiveSource() {
261         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
262                 HdmiProperties
263                         .playback_device_action_on_routing_control_values
264                         .WAKE_UP_AND_SEND_ACTIVE_SOURCE;
265 
266         mPowerManager.setInteractive(false);
267 
268         HdmiCecMessage message =
269                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
270                         mPlaybackPhysicalAddress);
271 
272         HdmiCecMessage expectedMessage =
273                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
274                         mPlaybackPhysicalAddress);
275 
276         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
277                 .isEqualTo(Constants.HANDLED);
278         mTestLooper.dispatchAll();
279         assertThat(mPowerManager.isInteractive()).isTrue();
280         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
281     }
282 
283     @Test
handleRoutingInformation_WakeUpAndSendActiveSource()284     public void handleRoutingInformation_WakeUpAndSendActiveSource() {
285         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
286                 HdmiProperties
287                         .playback_device_action_on_routing_control_values
288                         .WAKE_UP_AND_SEND_ACTIVE_SOURCE;
289 
290         mPowerManager.setInteractive(false);
291 
292         HdmiCecMessage message =
293                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
294                         mPlaybackPhysicalAddress);
295 
296         HdmiCecMessage expectedMessage =
297                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
298                         mPlaybackPhysicalAddress);
299 
300         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
301                 .isEqualTo(Constants.HANDLED);
302         mTestLooper.dispatchAll();
303         assertThat(mPowerManager.isInteractive()).isTrue();
304         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
305     }
306 
307     @Test
handleRoutingChange_otherDevice_None()308     public void handleRoutingChange_otherDevice_None() {
309         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
310                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
311                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
312         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
313                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
314         mPowerManager.setInteractive(true);
315         HdmiCecMessage message =
316                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
317         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
318                 .isEqualTo(Constants.HANDLED);
319         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
320         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
321                 0x5000);
322         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
323                 ADDR_INVALID);
324         assertThat(mPowerManager.isInteractive()).isTrue();
325     }
326 
327     @Test
handleRoutingChange_sameDevice_None_ActiveSource()328     public void handleRoutingChange_sameDevice_None_ActiveSource() {
329         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
330                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
331                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
332         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
333                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
334         mPowerManager.setInteractive(true);
335         HdmiCecMessage message =
336                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
337                         mPlaybackPhysicalAddress);
338         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
339                 .isEqualTo(Constants.HANDLED);
340         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
341         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
342                 mPlaybackPhysicalAddress);
343         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
344                 mPlaybackLogicalAddress);
345         assertThat(mPowerManager.isInteractive()).isTrue();
346     }
347 
348     @Test
handleRoutingChange_sameDevice_None_InactiveSource()349     public void handleRoutingChange_sameDevice_None_InactiveSource() {
350         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
351                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
352                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
353         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
354                 "HdmiCecLocalDevicePlaybackTest");
355         mPowerManager.setInteractive(true);
356         HdmiCecMessage message =
357                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
358                         mPlaybackPhysicalAddress);
359         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
360                 .isEqualTo(Constants.HANDLED);
361         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
362         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
363                 mPlaybackPhysicalAddress);
364         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
365                 ADDR_INVALID);
366         assertThat(mPowerManager.isInteractive()).isTrue();
367     }
368 
369     @Test
handleRoutingChange_otherDevice_StandbyNow()370     public void handleRoutingChange_otherDevice_StandbyNow() {
371         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
372                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
373                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
374         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
375                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
376         mPowerManager.setInteractive(true);
377         HdmiCecMessage message =
378                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
379         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
380                 .isEqualTo(Constants.HANDLED);
381         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
382         assertThat(mPowerManager.isInteractive()).isFalse();
383     }
384 
385     @Test
handleRoutingChange_otherDevice_StandbyNow_InactiveSource()386     public void handleRoutingChange_otherDevice_StandbyNow_InactiveSource() {
387         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
388                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
389                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
390         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
391                 "HdmiCecLocalDevicePlaybackTest");
392         mPowerManager.setInteractive(true);
393         HdmiCecMessage message =
394                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000, 0x5000);
395         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
396                 .isEqualTo(Constants.HANDLED);
397         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
398         assertThat(mPowerManager.isInteractive()).isTrue();
399     }
400 
401     @Test
handleRoutingChange_sameDevice_StandbyNow_ActiveSource()402     public void handleRoutingChange_sameDevice_StandbyNow_ActiveSource() {
403         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
404                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
405                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
406         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
407                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
408         mPowerManager.setInteractive(true);
409         HdmiCecMessage message =
410                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
411                         mPlaybackPhysicalAddress);
412         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
413                 .isEqualTo(Constants.HANDLED);
414         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
415         assertThat(mPowerManager.isInteractive()).isTrue();
416     }
417 
418     @Test
handleRoutingChange_otherDevice_ActiveSource_mediaSessionsPaused()419     public void handleRoutingChange_otherDevice_ActiveSource_mediaSessionsPaused() {
420         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
421                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
422         mActiveMediaSessionsPaused = false;
423         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
424                 0x5000);
425         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
426         mTestLooper.dispatchAll();
427         assertThat(mActiveMediaSessionsPaused).isTrue();
428     }
429 
430     @Test
handleRoutingChange_otherDevice_InactiveSource_mediaSessionsNotPaused()431     public void handleRoutingChange_otherDevice_InactiveSource_mediaSessionsNotPaused() {
432         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
433                 "HdmiCecLocalDevicePlaybackTest");
434         mActiveMediaSessionsPaused = false;
435         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
436                 0x5000);
437         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
438         mTestLooper.dispatchAll();
439         assertThat(mActiveMediaSessionsPaused).isFalse();
440     }
441 
442     @Test
handleRoutingChange_sameDevice_ActiveSource_mediaSessionsNotPaused()443     public void handleRoutingChange_sameDevice_ActiveSource_mediaSessionsNotPaused() {
444         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
445                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
446         mActiveMediaSessionsPaused = false;
447         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
448                 mPlaybackPhysicalAddress);
449         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
450         mTestLooper.dispatchAll();
451         assertThat(mActiveMediaSessionsPaused).isFalse();
452     }
453 
454     @Test
handleRoutingChange_sameDevice_InactiveSource_mediaSessionsNotPaused()455     public void handleRoutingChange_sameDevice_InactiveSource_mediaSessionsNotPaused() {
456         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
457                 "HdmiCecLocalDevicePlaybackTest");
458         mActiveMediaSessionsPaused = false;
459         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
460                 mPlaybackPhysicalAddress);
461         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
462         mTestLooper.dispatchAll();
463         assertThat(mActiveMediaSessionsPaused).isFalse();
464     }
465 
466     @Test
handleRoutingInformation_otherDevice_None()467     public void handleRoutingInformation_otherDevice_None() {
468         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
469                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
470                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
471         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
472                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
473         mPowerManager.setInteractive(true);
474         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
475         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
476                 .isEqualTo(Constants.HANDLED);
477         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
478         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
479                 0x5000);
480         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
481                 ADDR_INVALID);
482         assertThat(mPowerManager.isInteractive()).isTrue();
483     }
484 
485     @Test
handleRoutingInformation_sameDevice_None_ActiveSource()486     public void handleRoutingInformation_sameDevice_None_ActiveSource() {
487         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
488                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
489                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
490         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
491                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
492         mPowerManager.setInteractive(true);
493         HdmiCecMessage message =
494                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
495                         mPlaybackPhysicalAddress);
496         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
497                 .isEqualTo(Constants.HANDLED);
498         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
499         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
500                 mPlaybackPhysicalAddress);
501         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
502                 mPlaybackLogicalAddress);
503         assertThat(mPowerManager.isInteractive()).isTrue();
504     }
505 
506     @Test
handleRoutingInformation_sameDevice_None_InactiveSource()507     public void handleRoutingInformation_sameDevice_None_InactiveSource() {
508         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
509                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
510                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
511         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
512                 "HdmiCecLocalDevicePlaybackTest");
513         mPowerManager.setInteractive(true);
514         HdmiCecMessage message =
515                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
516                         mPlaybackPhysicalAddress);
517         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
518                 .isEqualTo(Constants.HANDLED);
519         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
520         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
521                 mPlaybackPhysicalAddress);
522         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
523                 ADDR_INVALID);
524         assertThat(mPowerManager.isInteractive()).isTrue();
525     }
526 
527     @Test
handleRoutingInformation_otherDevice_StandbyNow()528     public void handleRoutingInformation_otherDevice_StandbyNow() {
529         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
530                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
531                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
532         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
533                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
534         mPowerManager.setInteractive(true);
535         HdmiCecMessage message =
536                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
537         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
538                 .isEqualTo(Constants.HANDLED);
539         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
540         assertThat(mPowerManager.isInteractive()).isFalse();
541     }
542 
543     @Test
handleRoutingInformation_otherDevice_StandbyNow_InactiveSource()544     public void handleRoutingInformation_otherDevice_StandbyNow_InactiveSource() {
545         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
546                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
547                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
548         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
549                 "HdmiCecLocalDevicePlaybackTest");
550         mPowerManager.setInteractive(true);
551         HdmiCecMessage message =
552                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
553         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
554                 .isEqualTo(Constants.HANDLED);
555         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
556         assertThat(mPowerManager.isInteractive()).isTrue();
557     }
558 
559     @Test
handleRoutingInformation_sameDevice_StandbyNow_ActiveSource()560     public void handleRoutingInformation_sameDevice_StandbyNow_ActiveSource() {
561         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
562                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
563                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
564         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
565                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
566         mPowerManager.setInteractive(true);
567         HdmiCecMessage message =
568                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV,
569                         mPlaybackPhysicalAddress);
570         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
571                 .isEqualTo(Constants.HANDLED);
572         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
573         assertThat(mPowerManager.isInteractive()).isTrue();
574     }
575 
576     @Test
handleRoutingInformation_otherDevice_ActiveSource_mediaSessionsPaused()577     public void handleRoutingInformation_otherDevice_ActiveSource_mediaSessionsPaused() {
578         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
579                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
580         mActiveMediaSessionsPaused = false;
581         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
582         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
583         mTestLooper.dispatchAll();
584         assertThat(mActiveMediaSessionsPaused).isTrue();
585     }
586 
587     @Test
handleRoutingInformation_otherDevice_InactiveSource_mediaSessionsNotPaused()588     public void handleRoutingInformation_otherDevice_InactiveSource_mediaSessionsNotPaused() {
589         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
590                 "HdmiCecLocalDevicePlaybackTest");
591         mActiveMediaSessionsPaused = false;
592         HdmiCecMessage message = HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, 0x5000);
593         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
594         mTestLooper.dispatchAll();
595         assertThat(mActiveMediaSessionsPaused).isFalse();
596     }
597 
598     @Test
handleRoutingInformation_sameDevice_ActiveSource_mediaSessionsNotPaused()599     public void handleRoutingInformation_sameDevice_ActiveSource_mediaSessionsNotPaused() {
600         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
601                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
602         mActiveMediaSessionsPaused = false;
603         HdmiCecMessage message =
604                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, mPlaybackPhysicalAddress);
605         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
606         mTestLooper.dispatchAll();
607         assertThat(mActiveMediaSessionsPaused).isFalse();
608     }
609 
610     @Test
handleRoutingInformation_sameDevice_InactiveSource_mediaSessionsNotPaused()611     public void handleRoutingInformation_sameDevice_InactiveSource_mediaSessionsNotPaused() {
612         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
613                 "HdmiCecLocalDevicePlaybackTest");
614         mActiveMediaSessionsPaused = false;
615         HdmiCecMessage message =
616                 HdmiCecMessageBuilder.buildRoutingInformation(ADDR_TV, mPlaybackPhysicalAddress);
617         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
618         mTestLooper.dispatchAll();
619         assertThat(mActiveMediaSessionsPaused).isFalse();
620     }
621 
622     @Test
handleSetStreamPath()623     public void handleSetStreamPath() {
624         HdmiCecMessage message =
625                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x2100);
626         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
627                 .isEqualTo(Constants.HANDLED);
628     }
629 
630     @Test
handleSetSystemAudioModeOn_audioSystemBroadcast()631     public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
632         mHdmiControlService.setSystemAudioActivated(false);
633         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
634         HdmiCecMessage message =
635                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
636                         Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_BROADCAST, true);
637         assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message))
638                 .isEqualTo(Constants.HANDLED);
639         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
640     }
641 
642     @Test
handleSetSystemAudioModeOff_audioSystemToPlayback()643     public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
644         mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
645         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
646         // This direct message to Playback device is invalid.
647         // Test should ignore it and still keep the system audio mode on.
648         HdmiCecMessage message =
649                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
650                         Constants.ADDR_AUDIO_SYSTEM,
651                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
652                         false);
653         assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message))
654                 .isEqualTo(Constants.HANDLED);
655         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
656     }
657 
658     @Test
handleSystemAudioModeStatusOn_DirectlyToLocalDeviceFromAudioSystem()659     public void handleSystemAudioModeStatusOn_DirectlyToLocalDeviceFromAudioSystem() {
660         mHdmiControlService.setSystemAudioActivated(false);
661         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
662         HdmiCecMessage message =
663                 HdmiCecMessageBuilder.buildReportSystemAudioMode(
664                         Constants.ADDR_AUDIO_SYSTEM,
665                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
666                         true);
667         assertThat(mHdmiCecLocalDevicePlayback.handleSystemAudioModeStatus(message))
668                 .isEqualTo(Constants.HANDLED);
669         assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
670     }
671 
672     @Test
doNotWakeUpOnHotPlug_PlugIn()673     public void doNotWakeUpOnHotPlug_PlugIn() {
674         mPowerManager.setInteractive(false);
675         mHdmiCecLocalDevicePlayback.onHotplug(0, true);
676         assertThat(mPowerManager.isInteractive()).isFalse();
677     }
678 
679     @Test
doNotWakeUpOnHotPlug_PlugOut()680     public void doNotWakeUpOnHotPlug_PlugOut() {
681         mPowerManager.setInteractive(false);
682         mHdmiCecLocalDevicePlayback.onHotplug(0, false);
683         assertThat(mPowerManager.isInteractive()).isFalse();
684     }
685 
686     @Test
handleOnStandby_ScreenOff_NotActiveSource_ToTv()687     public void handleOnStandby_ScreenOff_NotActiveSource_ToTv() {
688         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
689                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
690                 HdmiControlManager.POWER_CONTROL_MODE_TV);
691         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
692                 "HdmiCecLocalDevicePlaybackTest");
693         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
694         mTestLooper.dispatchAll();
695 
696         HdmiCecMessage standbyMessageToTv =
697                 HdmiCecMessageBuilder.buildStandby(
698                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
699         HdmiCecMessage standbyMessageToAudioSystem =
700                 HdmiCecMessageBuilder.buildStandby(
701                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
702                         ADDR_AUDIO_SYSTEM);
703         HdmiCecMessage standbyMessageBroadcast =
704                 HdmiCecMessageBuilder.buildStandby(
705                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
706                         ADDR_BROADCAST);
707         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
708                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
709 
710         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
711         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
712         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
713         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
714     }
715 
716     @Test
handleOnStandby_ScreenOff_NotActiveSource_ToTvAndAudioSystem()717     public void handleOnStandby_ScreenOff_NotActiveSource_ToTvAndAudioSystem() {
718         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
719                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
720                 HdmiControlManager.POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM);
721         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
722                 "HdmiCecLocalDevicePlaybackTest");
723         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
724         mTestLooper.dispatchAll();
725 
726         HdmiCecMessage standbyMessageToTv =
727                 HdmiCecMessageBuilder.buildStandby(
728                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
729         HdmiCecMessage standbyMessageToAudioSystem =
730                 HdmiCecMessageBuilder.buildStandby(
731                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
732                         ADDR_AUDIO_SYSTEM);
733         HdmiCecMessage standbyMessageBroadcast =
734                 HdmiCecMessageBuilder.buildStandby(
735                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
736                         ADDR_BROADCAST);
737         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
738                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
739 
740         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
741         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
742         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
743         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
744     }
745 
746     @Test
handleOnStandby_ScreenOff_NotActiveSource_Broadcast()747     public void handleOnStandby_ScreenOff_NotActiveSource_Broadcast() {
748         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
749                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
750                 HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
751         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
752                 "HdmiCecLocalDevicePlaybackTest");
753         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
754         mTestLooper.dispatchAll();
755 
756         HdmiCecMessage standbyMessageToTv =
757                 HdmiCecMessageBuilder.buildStandby(
758                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
759         HdmiCecMessage standbyMessageToAudioSystem =
760                 HdmiCecMessageBuilder.buildStandby(
761                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
762                         ADDR_AUDIO_SYSTEM);
763         HdmiCecMessage standbyMessageBroadcast =
764                 HdmiCecMessageBuilder.buildStandby(
765                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
766                         ADDR_BROADCAST);
767         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
768                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
769 
770         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
771         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
772         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
773         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
774     }
775 
776     @Test
handleOnStandby_ScreenOff_NotActiveSource_None()777     public void handleOnStandby_ScreenOff_NotActiveSource_None() {
778         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
779                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
780                 HdmiControlManager.POWER_CONTROL_MODE_NONE);
781         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
782                 "HdmiCecLocalDevicePlaybackTest");
783         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
784         mTestLooper.dispatchAll();
785 
786         HdmiCecMessage standbyMessageToTv =
787                 HdmiCecMessageBuilder.buildStandby(
788                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
789         HdmiCecMessage standbyMessageToAudioSystem =
790                 HdmiCecMessageBuilder.buildStandby(
791                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
792                         ADDR_AUDIO_SYSTEM);
793         HdmiCecMessage standbyMessageBroadcast =
794                 HdmiCecMessageBuilder.buildStandby(
795                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
796                         ADDR_BROADCAST);
797         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
798                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
799 
800         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
801         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
802         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
803         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
804     }
805 
806     @Test
handleOnStandby_ScreenOff_ActiveSource_ToTv()807     public void handleOnStandby_ScreenOff_ActiveSource_ToTv() {
808         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
809                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
810                 HdmiControlManager.POWER_CONTROL_MODE_TV);
811         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
812                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
813         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
814         mTestLooper.dispatchAll();
815 
816         HdmiCecMessage standbyMessageToTv =
817                 HdmiCecMessageBuilder.buildStandby(
818                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
819         HdmiCecMessage standbyMessageToAudioSystem =
820                 HdmiCecMessageBuilder.buildStandby(
821                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
822                         ADDR_AUDIO_SYSTEM);
823         HdmiCecMessage standbyMessageBroadcast =
824                 HdmiCecMessageBuilder.buildStandby(
825                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
826                         ADDR_BROADCAST);
827         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
828                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
829 
830         assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageToTv);
831         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
832         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
833         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
834     }
835 
836     @Test
handleOnStandby_ScreenOff_ActiveSource_ToTvAndAudioSystem()837     public void handleOnStandby_ScreenOff_ActiveSource_ToTvAndAudioSystem() {
838         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
839                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
840                 HdmiControlManager.POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM);
841         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
842                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
843         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
844         mTestLooper.dispatchAll();
845 
846         HdmiCecMessage standbyMessageToTv =
847                 HdmiCecMessageBuilder.buildStandby(
848                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
849         HdmiCecMessage standbyMessageToAudioSystem =
850                 HdmiCecMessageBuilder.buildStandby(
851                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
852                         ADDR_AUDIO_SYSTEM);
853         HdmiCecMessage standbyMessageBroadcast =
854                 HdmiCecMessageBuilder.buildStandby(
855                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
856                         ADDR_BROADCAST);
857         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
858                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
859 
860         assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageToTv);
861         assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageToAudioSystem);
862         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
863         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
864     }
865 
866     @Test
handleOnStandby_ScreenOff_ActiveSource_Broadcast()867     public void handleOnStandby_ScreenOff_ActiveSource_Broadcast() {
868         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
869                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
870                 HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
871         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
872                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
873         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
874         mTestLooper.dispatchAll();
875 
876         HdmiCecMessage standbyMessageToTv =
877                 HdmiCecMessageBuilder.buildStandby(
878                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
879         HdmiCecMessage standbyMessageToAudioSystem =
880                 HdmiCecMessageBuilder.buildStandby(
881                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
882                         ADDR_AUDIO_SYSTEM);
883         HdmiCecMessage standbyMessageBroadcast =
884                 HdmiCecMessageBuilder.buildStandby(
885                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
886                         ADDR_BROADCAST);
887         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
888                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
889 
890         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
891         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
892         assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageBroadcast);
893         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(inactiveSource);
894     }
895 
896     @Test
handleOnStandby_ScreenOff_ActiveSource_None()897     public void handleOnStandby_ScreenOff_ActiveSource_None() {
898         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
899                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
900                 HdmiControlManager.POWER_CONTROL_MODE_NONE);
901         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
902                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
903         mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
904         mTestLooper.dispatchAll();
905 
906         HdmiCecMessage standbyMessageToTv =
907                 HdmiCecMessageBuilder.buildStandby(
908                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
909         HdmiCecMessage standbyMessageToAudioSystem =
910                 HdmiCecMessageBuilder.buildStandby(
911                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
912                         ADDR_AUDIO_SYSTEM);
913         HdmiCecMessage standbyMessageBroadcast =
914                 HdmiCecMessageBuilder.buildStandby(
915                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
916                         ADDR_BROADCAST);
917         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
918                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
919 
920         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
921         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToAudioSystem);
922         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
923         assertThat(mNativeWrapper.getResultMessages()).contains(inactiveSource);
924     }
925 
926     @Test
handleOnStandby_CecMessageReceived()927     public void handleOnStandby_CecMessageReceived() {
928         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
929                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
930                 HdmiControlManager.POWER_CONTROL_MODE_TV);
931         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
932                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
933         mHdmiCecLocalDevicePlayback.onStandby(true, HdmiControlService.STANDBY_SCREEN_OFF);
934         mTestLooper.dispatchAll();
935 
936         HdmiCecMessage standbyMessageToTv =
937                 HdmiCecMessageBuilder.buildStandby(
938                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
939         HdmiCecMessage standbyMessageBroadcast =
940                 HdmiCecMessageBuilder.buildStandby(
941                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
942                         ADDR_BROADCAST);
943         HdmiCecMessage inactiveSource = HdmiCecMessageBuilder.buildInactiveSource(
944                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
945 
946         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
947         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
948         assertThat(mNativeWrapper.getResultMessages()).contains(inactiveSource);
949     }
950 
951     @Test
handleOnInitializeCecComplete_ByEnableCec()952     public void handleOnInitializeCecComplete_ByEnableCec() {
953         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
954                 mHdmiControlService.INITIATED_BY_ENABLE_CEC);
955         mTestLooper.dispatchAll();
956 
957         HdmiCecMessage activeSource =
958                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
959                         mPlaybackPhysicalAddress);
960         HdmiCecMessage textViewOn =
961                 HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
962                         ADDR_TV);
963 
964         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
965         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
966     }
967 
968     @Test
handleOnInitializeCecComplete_ByBootUp()969     public void handleOnInitializeCecComplete_ByBootUp() {
970         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
971                 mHdmiControlService.INITIATED_BY_BOOT_UP);
972         mTestLooper.dispatchAll();
973 
974         HdmiCecMessage activeSource =
975                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
976                         mPlaybackPhysicalAddress);
977         HdmiCecMessage textViewOn =
978                 HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
979                         ADDR_TV);
980 
981         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
982         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
983     }
984 
985     @Test
handleOnInitializeCecComplete_ByScreenOn_PowerControlModeTv()986     public void handleOnInitializeCecComplete_ByScreenOn_PowerControlModeTv() {
987         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
988                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
989                 HdmiControlManager.POWER_CONTROL_MODE_TV);
990 
991         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
992                 mHdmiControlService.INITIATED_BY_SCREEN_ON);
993         mTestLooper.dispatchAll();
994 
995         HdmiCecMessage activeSource =
996                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
997                         mPlaybackPhysicalAddress);
998         HdmiCecMessage textViewOn =
999                 HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1000                         ADDR_TV);
1001 
1002         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1003         assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
1004     }
1005 
1006     @Test
handleOnInitializeCecComplete_ByScreenOn_PowerControlModeNone()1007     public void handleOnInitializeCecComplete_ByScreenOn_PowerControlModeNone() {
1008         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1009                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1010                 HdmiControlManager.POWER_CONTROL_MODE_NONE);
1011 
1012         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
1013                 mHdmiControlService.INITIATED_BY_SCREEN_ON);
1014         mTestLooper.dispatchAll();
1015 
1016         HdmiCecMessage activeSource =
1017                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1018                         mPlaybackPhysicalAddress);
1019         HdmiCecMessage textViewOn =
1020                 HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1021                         ADDR_TV);
1022 
1023         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
1024         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
1025     }
1026 
1027     @Test
handleOnInitializeCecComplete_ByWakeUpMessage()1028     public void handleOnInitializeCecComplete_ByWakeUpMessage() {
1029         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
1030                 mHdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE);
1031         mTestLooper.dispatchAll();
1032 
1033         HdmiCecMessage activeSource =
1034                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1035                         mPlaybackPhysicalAddress);
1036         HdmiCecMessage textViewOn =
1037                 HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1038                         ADDR_TV);
1039 
1040         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
1041         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
1042     }
1043 
1044     @Test
handleOnInitializeCecComplete_ByHotplug()1045     public void handleOnInitializeCecComplete_ByHotplug() {
1046         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
1047                 mHdmiControlService.INITIATED_BY_HOTPLUG);
1048         mTestLooper.dispatchAll();
1049 
1050         HdmiCecMessage activeSource =
1051                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1052                         mPlaybackPhysicalAddress);
1053         HdmiCecMessage textViewOn =
1054                 HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1055                         ADDR_TV);
1056 
1057         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
1058         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
1059     }
1060 
1061     @Test
handleActiveSource_ActiveSource_None()1062     public void handleActiveSource_ActiveSource_None() {
1063         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1064                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1065                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
1066         mPowerManager.setInteractive(true);
1067         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1068                 mPlaybackPhysicalAddress);
1069         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
1070                 .isEqualTo(Constants.HANDLED);
1071         mTestLooper.dispatchAll();
1072         assertThat(mPowerManager.isInteractive()).isTrue();
1073         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1074         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
1075                 mPlaybackPhysicalAddress);
1076         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
1077                 mPlaybackLogicalAddress);
1078     }
1079 
1080     @Test
handleActiveSource_notActiveSource_None()1081     public void handleActiveSource_notActiveSource_None() {
1082         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1083                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1084                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
1085         mPowerManager.setInteractive(true);
1086         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
1087         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
1088                 .isEqualTo(Constants.HANDLED);
1089         mTestLooper.dispatchAll();
1090         assertThat(mPowerManager.isInteractive()).isTrue();
1091         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1092         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
1093                 0x0000);
1094         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
1095                 ADDR_TV);
1096     }
1097 
1098     @Test
handleActiveSource_ActiveSource_StandbyNow()1099     public void handleActiveSource_ActiveSource_StandbyNow() {
1100         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1101                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1102                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
1103         mPowerManager.setInteractive(true);
1104         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1105                 mPlaybackPhysicalAddress);
1106         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
1107                 .isEqualTo(Constants.HANDLED);
1108         mTestLooper.dispatchAll();
1109         assertThat(mPowerManager.isInteractive()).isTrue();
1110         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1111     }
1112 
1113     @Test
handleActiveSource_notActiveSource_StandbyNow()1114     public void handleActiveSource_notActiveSource_StandbyNow() {
1115         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1116                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1117                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
1118         mPowerManager.setInteractive(true);
1119         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1120                 mPlaybackPhysicalAddress);
1121         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
1122                 .isEqualTo(Constants.HANDLED);
1123         message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
1124         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
1125                 .isEqualTo(Constants.HANDLED);
1126         mTestLooper.dispatchAll();
1127         assertThat(mPowerManager.isInteractive()).isFalse();
1128         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1129     }
1130 
1131     @Test
handleActiveSource_otherDevice_ActiveSource_mediaSessionsPaused()1132     public void handleActiveSource_otherDevice_ActiveSource_mediaSessionsPaused() {
1133         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
1134                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
1135         mActiveMediaSessionsPaused = false;
1136         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
1137         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1138         mTestLooper.dispatchAll();
1139         assertThat(mActiveMediaSessionsPaused).isTrue();
1140     }
1141 
1142     @Test
handleActiveSource_otherDevice_InactiveSource_mediaSessionsNotPaused()1143     public void handleActiveSource_otherDevice_InactiveSource_mediaSessionsNotPaused() {
1144         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
1145                 "HdmiCecLocalDevicePlaybackTest");
1146         mActiveMediaSessionsPaused = false;
1147         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
1148         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1149         mTestLooper.dispatchAll();
1150         assertThat(mActiveMediaSessionsPaused).isFalse();
1151     }
1152 
1153     @Test
handleActiveSource_sameDevice_ActiveSource_mediaSessionsNotPaused()1154     public void handleActiveSource_sameDevice_ActiveSource_mediaSessionsNotPaused() {
1155         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
1156                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
1157         mActiveMediaSessionsPaused = false;
1158         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1159                 mPlaybackPhysicalAddress);
1160         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1161         mTestLooper.dispatchAll();
1162         assertThat(mActiveMediaSessionsPaused).isFalse();
1163     }
1164 
1165     @Test
handleActiveSource_sameDevice_InactiveSource_mediaSessionsNotPaused()1166     public void handleActiveSource_sameDevice_InactiveSource_mediaSessionsNotPaused() {
1167         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
1168                 "HdmiCecLocalDevicePlaybackTest");
1169         mActiveMediaSessionsPaused = false;
1170         HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
1171                 mPlaybackPhysicalAddress);
1172         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1173         mTestLooper.dispatchAll();
1174         assertThat(mActiveMediaSessionsPaused).isFalse();
1175     }
1176 
1177     @Test
losingActiveSource_standbyNow_verifyStandbyMessageIsSentOnNextStandby()1178     public void losingActiveSource_standbyNow_verifyStandbyMessageIsSentOnNextStandby() {
1179         // As described in b/161097846.
1180         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1181                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1182                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
1183         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1184                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1185                 HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
1186         mPowerManager.setInteractive(true);
1187         // 1. DUT is <AS>.
1188         HdmiCecMessage message1 =
1189                 HdmiCecMessageBuilder.buildActiveSource(
1190                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1191                         mPlaybackPhysicalAddress);
1192         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message1))
1193                 .isEqualTo(Constants.HANDLED);
1194         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1195         assertThat(mPowerManager.isInteractive()).isTrue();
1196         // 2. DUT loses <AS> and goes to sleep.
1197         HdmiCecMessage message2 = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
1198         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message2))
1199                 .isEqualTo(Constants.HANDLED);
1200         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1201         assertThat(mPowerManager.isInteractive()).isFalse();
1202         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
1203         // 3. DUT becomes <AS> again.
1204         HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
1205                 mPlaybackPhysicalAddress);
1206         mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath);
1207         // The ActiveSourceAction created from the message above is deferred until the device wakes
1208         // up.
1209         mHdmiControlService.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
1210         mTestLooper.dispatchAll();
1211         HdmiCecMessage activeSource =
1212                 HdmiCecMessageBuilder.buildActiveSource(
1213                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1214                         mPlaybackPhysicalAddress);
1215         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1216         assertThat(mPowerManager.isInteractive()).isTrue();
1217         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1218         // 4. DUT turned off.
1219         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
1220         mTestLooper.dispatchAll();
1221         HdmiCecMessage standbyMessageBroadcast =
1222                 HdmiCecMessageBuilder.buildStandby(
1223                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1224                         ADDR_BROADCAST);
1225         assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageBroadcast);
1226     }
1227 
1228     @Test
sendVolumeKeyEvent_up_volumeEnabled()1229     public void sendVolumeKeyEvent_up_volumeEnabled() {
1230         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1231                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1232         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1233         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1234         mTestLooper.dispatchAll();
1235 
1236         HdmiCecMessage keyPressed =
1237                 HdmiCecMessageBuilder.buildUserControlPressed(
1238                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1239                         ADDR_TV,
1240                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1241         HdmiCecMessage keyReleased =
1242                 HdmiCecMessageBuilder.buildUserControlReleased(
1243                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
1244 
1245         assertThat(mNativeWrapper.getResultMessages()).contains(keyPressed);
1246         assertThat(mNativeWrapper.getResultMessages()).contains(keyReleased);
1247     }
1248 
1249     @Test
sendVolumeKeyEvent_down_volumeEnabled()1250     public void sendVolumeKeyEvent_down_volumeEnabled() {
1251         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1252                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1253         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
1254         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false);
1255         mTestLooper.dispatchAll();
1256 
1257         HdmiCecMessage keyPressed =
1258                 HdmiCecMessageBuilder.buildUserControlPressed(
1259                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1260                         ADDR_TV,
1261                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN);
1262         HdmiCecMessage keyReleased =
1263                 HdmiCecMessageBuilder.buildUserControlReleased(
1264                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
1265 
1266         assertThat(mNativeWrapper.getResultMessages()).contains(keyPressed);
1267         assertThat(mNativeWrapper.getResultMessages()).contains(keyReleased);
1268     }
1269 
1270     @Test
sendVolumeKeyEvent_mute_volumeEnabled()1271     public void sendVolumeKeyEvent_mute_volumeEnabled() {
1272         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1273                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1274         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true);
1275         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false);
1276         mTestLooper.dispatchAll();
1277 
1278         HdmiCecMessage keyPressed =
1279                 HdmiCecMessageBuilder.buildUserControlPressed(
1280                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1281                         ADDR_TV,
1282                         HdmiCecKeycode.CEC_KEYCODE_MUTE);
1283         HdmiCecMessage keyReleased =
1284                 HdmiCecMessageBuilder.buildUserControlReleased(
1285                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
1286 
1287         assertThat(mNativeWrapper.getResultMessages()).contains(keyPressed);
1288         assertThat(mNativeWrapper.getResultMessages()).contains(keyReleased);
1289     }
1290 
1291     @Test
sendVolumeKeyEvent_up_volumeDisabled()1292     public void sendVolumeKeyEvent_up_volumeDisabled() {
1293         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1294                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
1295         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1296         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1297         mTestLooper.dispatchAll();
1298 
1299         HdmiCecMessage keyPressed =
1300                 HdmiCecMessageBuilder.buildUserControlPressed(
1301                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1302                         ADDR_TV,
1303                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1304         HdmiCecMessage keyReleased =
1305                 HdmiCecMessageBuilder.buildUserControlReleased(
1306                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
1307 
1308         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyPressed);
1309         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyReleased);
1310     }
1311 
1312     @Test
sendVolumeKeyEvent_down_volumeDisabled()1313     public void sendVolumeKeyEvent_down_volumeDisabled() {
1314         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1315                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
1316         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
1317         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false);
1318         mTestLooper.dispatchAll();
1319 
1320         HdmiCecMessage keyPressed =
1321                 HdmiCecMessageBuilder.buildUserControlPressed(
1322                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1323                         ADDR_TV,
1324                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1325         HdmiCecMessage keyReleased =
1326                 HdmiCecMessageBuilder.buildUserControlReleased(
1327                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
1328 
1329         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyPressed);
1330         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyReleased);
1331     }
1332 
1333     @Test
sendVolumeKeyEvent_mute_volumeDisabled()1334     public void sendVolumeKeyEvent_mute_volumeDisabled() {
1335         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1336                 HdmiControlManager.VOLUME_CONTROL_DISABLED);
1337         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true);
1338         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false);
1339         mTestLooper.dispatchAll();
1340 
1341         HdmiCecMessage keyPressed =
1342                 HdmiCecMessageBuilder.buildUserControlPressed(
1343                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1344                         ADDR_TV,
1345                         HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1346         HdmiCecMessage keyReleased =
1347                 HdmiCecMessageBuilder.buildUserControlReleased(
1348                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
1349 
1350         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyPressed);
1351         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyReleased);
1352     }
1353 
1354     @Test
sendVolumeKeyEvent_toTv_activeSource()1355     public void sendVolumeKeyEvent_toTv_activeSource() {
1356         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1357                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1358         mHdmiControlService.setSystemAudioActivated(false);
1359         mHdmiControlService.setActiveSource(mPlaybackLogicalAddress, mPlaybackPhysicalAddress,
1360                 "HdmiCecLocalDevicePlaybackTest");
1361 
1362         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1363         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1364 
1365         HdmiCecMessage pressed = HdmiCecMessageBuilder.buildUserControlPressed(
1366                 mPlaybackLogicalAddress, ADDR_TV, HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1367         HdmiCecMessage released = HdmiCecMessageBuilder.buildUserControlReleased(
1368                 mPlaybackLogicalAddress, ADDR_TV);
1369         mTestLooper.dispatchAll();
1370 
1371         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1372         assertThat(mNativeWrapper.getResultMessages()).containsAtLeast(pressed, released);
1373     }
1374 
1375     @Test
sendVolumeKeyEvent_toAudio_activeSource()1376     public void sendVolumeKeyEvent_toAudio_activeSource() {
1377         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1378                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1379         mHdmiControlService.setSystemAudioActivated(true);
1380         mHdmiControlService.setActiveSource(mPlaybackLogicalAddress, mPlaybackPhysicalAddress,
1381                 "HdmiCecLocalDevicePlaybackTest");
1382 
1383         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1384         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1385 
1386         HdmiCecMessage pressed = HdmiCecMessageBuilder.buildUserControlPressed(
1387                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1388         HdmiCecMessage released = HdmiCecMessageBuilder.buildUserControlReleased(
1389                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM);
1390         mTestLooper.dispatchAll();
1391 
1392         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1393         assertThat(mNativeWrapper.getResultMessages()).containsAtLeast(pressed, released);
1394     }
1395 
1396     @Test
sendVolumeKeyEvent_toTv_inactiveSource()1397     public void sendVolumeKeyEvent_toTv_inactiveSource() {
1398         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1399                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1400         mHdmiControlService.setSystemAudioActivated(false);
1401         mHdmiControlService.setActiveSource(ADDR_TV, 0x0000, "HdmiCecLocalDevicePlaybackTest");
1402 
1403         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1404         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1405 
1406         HdmiCecMessage pressed = HdmiCecMessageBuilder.buildUserControlPressed(
1407                 mPlaybackLogicalAddress, ADDR_TV, HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1408         HdmiCecMessage released = HdmiCecMessageBuilder.buildUserControlReleased(
1409                 mPlaybackLogicalAddress, ADDR_TV);
1410         mTestLooper.dispatchAll();
1411 
1412         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1413         assertThat(mNativeWrapper.getResultMessages()).containsAtLeast(pressed, released);
1414     }
1415 
1416     @Test
sendVolumeKeyEvent_toAudio_inactiveSource()1417     public void sendVolumeKeyEvent_toAudio_inactiveSource() {
1418         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1419                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1420         mHdmiControlService.setSystemAudioActivated(true);
1421         mHdmiControlService.setActiveSource(ADDR_TV, 0x0000, "HdmiCecLocalDevicePlaybackTest");
1422 
1423         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1424         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1425 
1426         HdmiCecMessage pressed = HdmiCecMessageBuilder.buildUserControlPressed(
1427                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1428         HdmiCecMessage released = HdmiCecMessageBuilder.buildUserControlReleased(
1429                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM);
1430         mTestLooper.dispatchAll();
1431 
1432         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1433         assertThat(mNativeWrapper.getResultMessages()).containsAtLeast(pressed, released);
1434     }
1435 
1436     @Test
sendVolumeKeyEvent_toLocalDevice_discardMessage()1437     public void sendVolumeKeyEvent_toLocalDevice_discardMessage() {
1438         HdmiCecLocalDeviceAudioSystem audioSystem =
1439                 new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
1440         audioSystem.init();
1441         mLocalDevices.add(audioSystem);
1442         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1443         mTestLooper.dispatchAll();
1444 
1445         mHdmiControlService.setHdmiCecVolumeControlEnabledInternal(
1446                 HdmiControlManager.VOLUME_CONTROL_ENABLED);
1447         mHdmiControlService.setSystemAudioActivated(true);
1448 
1449         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
1450         mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
1451 
1452         HdmiCecMessage keyPressed = HdmiCecMessageBuilder.buildUserControlPressed(
1453                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
1454         HdmiCecMessage keyReleased = HdmiCecMessageBuilder.buildUserControlReleased(
1455                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM);
1456         mTestLooper.dispatchAll();
1457 
1458         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyPressed);
1459         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(keyReleased);
1460     }
1461 
1462     @Test
handleSetStreamPath_broadcastsActiveSource()1463     public void handleSetStreamPath_broadcastsActiveSource() {
1464         HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
1465                 mPlaybackPhysicalAddress);
1466         mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath);
1467         mTestLooper.dispatchAll();
1468 
1469         HdmiCecMessage activeSource =
1470                 HdmiCecMessageBuilder.buildActiveSource(
1471                         mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1472                         mPlaybackPhysicalAddress);
1473 
1474         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1475     }
1476 
1477     @Test
handleSetStreamPath_afterHotplug_broadcastsActiveSource()1478     public void handleSetStreamPath_afterHotplug_broadcastsActiveSource() {
1479         mNativeWrapper.onHotplugEvent(1, false);
1480         mNativeWrapper.onHotplugEvent(1, true);
1481         mTestLooper.dispatchAll();
1482 
1483         HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
1484                 mPlaybackPhysicalAddress);
1485         mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath);
1486         mTestLooper.dispatchAll();
1487 
1488         HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
1489                 mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1490                 mPlaybackPhysicalAddress);
1491 
1492         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1493     }
1494 
1495     @Test
handleSetStreamPath_afterHotplug_hasCorrectActiveSource()1496     public void handleSetStreamPath_afterHotplug_hasCorrectActiveSource() {
1497         mNativeWrapper.onHotplugEvent(1, false);
1498         mNativeWrapper.onHotplugEvent(1, true);
1499 
1500         HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
1501                 mPlaybackPhysicalAddress);
1502         mHdmiCecLocalDevicePlayback.dispatchMessage(setStreamPath);
1503         mTestLooper.dispatchAll();
1504 
1505         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
1506                 mPlaybackPhysicalAddress);
1507         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
1508                 mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress());
1509         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
1510     }
1511 
1512     @Test
handleSetStreamPath_Dreaming()1513     public void handleSetStreamPath_Dreaming() throws RemoteException {
1514         mPowerManager.setInteractive(true);
1515         mWokenUp = false;
1516 
1517         HdmiCecMessage message =
1518                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
1519                         mPlaybackPhysicalAddress);
1520 
1521         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
1522                 .isEqualTo(Constants.HANDLED);
1523         mTestLooper.dispatchAll();
1524         assertThat(mPowerManager.isInteractive()).isTrue();
1525         assertThat(mWokenUp).isTrue();
1526     }
1527 
1528     @Test
handleSetStreamPath_otherDevice_None()1529     public void handleSetStreamPath_otherDevice_None() {
1530         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1531                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1532                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE);
1533         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
1534                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
1535         mPowerManager.setInteractive(true);
1536         HdmiCecMessage message =
1537                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
1538         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
1539                 .isEqualTo(Constants.HANDLED);
1540         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1541         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress).isEqualTo(
1542                 0x5000);
1543         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
1544                 ADDR_INVALID);
1545         assertThat(mPowerManager.isInteractive()).isTrue();
1546     }
1547 
1548     @Test
handleSetStreamPath_otherDevice_StandbyNow()1549     public void handleSetStreamPath_otherDevice_StandbyNow() {
1550         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1551                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1552                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
1553         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
1554                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
1555         mPowerManager.setInteractive(true);
1556         HdmiCecMessage message =
1557                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
1558         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
1559                 .isEqualTo(Constants.HANDLED);
1560         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1561         assertThat(mPowerManager.isInteractive()).isFalse();
1562     }
1563 
1564     @Test
handleSetStreamPath_otherDevice_StandbyNow_InactiveSource()1565     public void handleSetStreamPath_otherDevice_StandbyNow_InactiveSource() {
1566         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1567                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
1568                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
1569         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
1570                 "HdmiCecLocalDevicePlaybackTest");
1571         mPowerManager.setInteractive(true);
1572         HdmiCecMessage message =
1573                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
1574         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
1575                 .isEqualTo(Constants.HANDLED);
1576         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
1577         assertThat(mPowerManager.isInteractive()).isTrue();
1578     }
1579 
1580     @Test
handleSetStreamPath_otherDevice_ActiveSource_mediaSessionsPaused()1581     public void handleSetStreamPath_otherDevice_ActiveSource_mediaSessionsPaused() {
1582         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
1583                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
1584         mActiveMediaSessionsPaused = false;
1585         HdmiCecMessage message =
1586                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
1587         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1588         mTestLooper.dispatchAll();
1589         assertThat(mActiveMediaSessionsPaused).isTrue();
1590     }
1591 
1592     @Test
handleSetStreamPath_otherDevice_InactiveSource_mediaSessionsNotPaused()1593     public void handleSetStreamPath_otherDevice_InactiveSource_mediaSessionsNotPaused() {
1594         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
1595                 "HdmiCecLocalDevicePlaybackTest");
1596         mActiveMediaSessionsPaused = false;
1597         HdmiCecMessage message =
1598                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x5000);
1599         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1600         mTestLooper.dispatchAll();
1601         assertThat(mActiveMediaSessionsPaused).isFalse();
1602     }
1603 
1604     @Test
handleSetStreamPath_sameDevice_ActiveSource_mediaSessionsNotPaused()1605     public void handleSetStreamPath_sameDevice_ActiveSource_mediaSessionsNotPaused() {
1606         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
1607                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
1608         mActiveMediaSessionsPaused = false;
1609         HdmiCecMessage message =
1610                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, mPlaybackPhysicalAddress);
1611         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1612         mTestLooper.dispatchAll();
1613         assertThat(mActiveMediaSessionsPaused).isFalse();
1614     }
1615 
1616     @Test
handleSetStreamPath_sameDevice_InactiveSource_mediaSessionsNotPaused()1617     public void handleSetStreamPath_sameDevice_InactiveSource_mediaSessionsNotPaused() {
1618         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
1619                 "HdmiCecLocalDevicePlaybackTest");
1620         mActiveMediaSessionsPaused = false;
1621         HdmiCecMessage message =
1622                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, mPlaybackPhysicalAddress);
1623         mHdmiCecLocalDevicePlayback.dispatchMessage(message);
1624         mTestLooper.dispatchAll();
1625         assertThat(mActiveMediaSessionsPaused).isFalse();
1626     }
1627 
1628     @Test
oneTouchPlay_PowerControlModeToTv()1629     public void oneTouchPlay_PowerControlModeToTv() {
1630         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1631                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1632                 HdmiControlManager.POWER_CONTROL_MODE_TV);
1633         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
1634             @Override
1635             public void onComplete(int result) {
1636             }
1637         });
1638         mTestLooper.dispatchAll();
1639 
1640         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1641                 ADDR_TV);
1642         HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
1643                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
1644         HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
1645                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
1646         assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
1647         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1648         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest);
1649     }
1650 
1651     @Test
oneTouchPlay_PowerControlModeToTvAndAudioSystem()1652     public void oneTouchPlay_PowerControlModeToTvAndAudioSystem() {
1653         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1654                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1655                 HdmiControlManager.POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM);
1656         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
1657             @Override
1658             public void onComplete(int result) {
1659             }
1660         });
1661         mTestLooper.dispatchAll();
1662 
1663         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1664                 ADDR_TV);
1665         HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
1666                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
1667         HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
1668                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
1669         assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
1670         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1671         assertThat(mNativeWrapper.getResultMessages()).contains(systemAudioModeRequest);
1672     }
1673 
1674     @Test
oneTouchPlay_PowerControlModeBroadcast()1675     public void oneTouchPlay_PowerControlModeBroadcast() {
1676         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1677                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1678                 HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
1679         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
1680             @Override
1681             public void onComplete(int result) {
1682             }
1683         });
1684         mTestLooper.dispatchAll();
1685 
1686         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1687                 ADDR_TV);
1688         HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
1689                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
1690         HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
1691                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
1692         assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
1693         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1694         assertThat(mNativeWrapper.getResultMessages()).contains(systemAudioModeRequest);
1695     }
1696 
1697     @Test
oneTouchPlay_PowerControlModeNone()1698     public void oneTouchPlay_PowerControlModeNone() {
1699         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1700                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1701                 HdmiControlManager.POWER_CONTROL_MODE_NONE);
1702         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
1703             @Override
1704             public void onComplete(int result) {
1705             }
1706         });
1707         mTestLooper.dispatchAll();
1708 
1709         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1710                 ADDR_TV);
1711         HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
1712                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
1713         HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
1714                 mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
1715         assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
1716         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1717         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest);
1718     }
1719 
1720     @Test
onAddressAllocated_invokesDeviceDiscovery()1721     public void onAddressAllocated_invokesDeviceDiscovery() {
1722         mNativeWrapper.setPollAddressResponse(Constants.ADDR_PLAYBACK_2, SendMessageResult.SUCCESS);
1723         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1724 
1725         mTestLooper.dispatchAll();
1726 
1727         // Check for <Give Physical Address> being sent to available device (ADDR_PLAYBACK_2).
1728         // This message is sent as part of the DeviceDiscoveryAction to available devices.
1729         HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress(
1730                 Constants.ADDR_PLAYBACK_1,
1731                 Constants.ADDR_PLAYBACK_2);
1732         assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress);
1733     }
1734 
1735     @Test
hotplugDetectionAction_addDevice()1736     public void hotplugDetectionAction_addDevice() {
1737         int otherPlaybackLogicalAddress = mPlaybackLogicalAddress == Constants.ADDR_PLAYBACK_2
1738                 ? Constants.ADDR_PLAYBACK_1 : Constants.ADDR_PLAYBACK_2;
1739         mNativeWrapper.setPollAddressResponse(otherPlaybackLogicalAddress,
1740                 SendMessageResult.NACK);
1741         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1742         mTestLooper.dispatchAll();
1743 
1744         mNativeWrapper.setPollAddressResponse(otherPlaybackLogicalAddress,
1745                 SendMessageResult.SUCCESS);
1746         mTestLooper.moveTimeForward(HOTPLUG_INTERVAL);
1747         mTestLooper.dispatchAll();
1748 
1749         // Check for <Give Physical Address> being sent to the newly discovered device.
1750         // This message is sent as part of the HotplugDetectionAction to available devices.
1751         HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress(
1752                 mPlaybackLogicalAddress, otherPlaybackLogicalAddress);
1753         assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress);
1754     }
1755 
1756     @Test
hotplugDetectionAction_removeDevice()1757     public void hotplugDetectionAction_removeDevice() {
1758         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1759         mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
1760         HdmiDeviceInfo infoPlayback = HdmiDeviceInfo.cecDeviceBuilder()
1761                 .setLogicalAddress(Constants.ADDR_PLAYBACK_2)
1762                 .setPhysicalAddress(0x1234)
1763                 .setPortId(PORT_1)
1764                 .setDeviceType(HdmiDeviceInfo.DEVICE_PLAYBACK)
1765                 .setVendorId(0x1234)
1766                 .setDisplayName("Playback 2")
1767                 .setDevicePowerStatus(HdmiControlManager.POWER_STATUS_ON)
1768                 .setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B)
1769                 .build();
1770         mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoPlayback);
1771         // This logical address (ADDR_PLAYBACK_2) won't acknowledge the poll message sent by the
1772         // HotplugDetectionAction so it shall be removed.
1773         mNativeWrapper.setPollAddressResponse(Constants.ADDR_PLAYBACK_2, SendMessageResult.NACK);
1774         mTestLooper.moveTimeForward(HOTPLUG_INTERVAL);
1775         mTestLooper.dispatchAll();
1776 
1777         assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)).isEmpty();
1778     }
1779 
1780     @Test
getActiveSource_noActiveSource()1781     public void getActiveSource_noActiveSource() {
1782         mHdmiControlService.setActiveSource(Constants.ADDR_UNREGISTERED,
1783                 Constants.INVALID_PHYSICAL_ADDRESS, "HdmiControlServiceTest");
1784 
1785         assertThat(mHdmiControlService.getActiveSource()).isNull();
1786     }
1787 
1788     @Test
getActiveSource_localPlaybackIsActiveSource()1789     public void getActiveSource_localPlaybackIsActiveSource() {
1790         mHdmiControlService.setActiveSource(
1791                 mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
1792                 mHdmiControlService.getPhysicalAddress(),
1793                 "HdmiControlServiceTest");
1794 
1795         assertThat(mHdmiControlService.getActiveSource()).isEqualTo(
1796                 mHdmiCecLocalDevicePlayback.getDeviceInfo());
1797     }
1798 
1799     @Test
getActiveSource_deviceInNetworkIsActiveSource()1800     public void getActiveSource_deviceInNetworkIsActiveSource() {
1801         HdmiDeviceInfo externalDevice = HdmiDeviceInfo.cecDeviceBuilder()
1802                 .setLogicalAddress(Constants.ADDR_PLAYBACK_3)
1803                 .setPhysicalAddress(0x3000)
1804                 .setPortId(0)
1805                 .setDeviceType(Constants.ADDR_PLAYBACK_1)
1806                 .setVendorId(0)
1807                 .setDisplayName("Test Device")
1808                 .build();
1809 
1810         mHdmiControlService.getHdmiCecNetwork().addCecDevice(externalDevice);
1811         mTestLooper.dispatchAll();
1812 
1813         mHdmiControlService.setActiveSource(externalDevice.getLogicalAddress(),
1814                 externalDevice.getPhysicalAddress(), "HdmiControlServiceTest");
1815 
1816         assertThat(mHdmiControlService.getActiveSource()).isEqualTo(externalDevice);
1817     }
1818 
1819     @Test
getActiveSource_unknownDeviceIsActiveSource()1820     public void getActiveSource_unknownDeviceIsActiveSource() {
1821         HdmiDeviceInfo externalDevice = HdmiDeviceInfo.cecDeviceBuilder()
1822                 .setLogicalAddress(Constants.ADDR_PLAYBACK_3)
1823                 .setPhysicalAddress(0x3000)
1824                 .setPortId(0)
1825                 .setDeviceType(Constants.ADDR_PLAYBACK_1)
1826                 .setVendorId(0)
1827                 .setDisplayName("Test Device")
1828                 .build();
1829 
1830         mHdmiControlService.setActiveSource(externalDevice.getLogicalAddress(),
1831                 externalDevice.getPhysicalAddress(), "HdmiControlServiceTest");
1832 
1833         assertThat(mHdmiControlService.getActiveSource().getPhysicalAddress()).isEqualTo(
1834                 externalDevice.getPhysicalAddress());
1835     }
1836 
1837     @Test
queryDisplayStatus()1838     public void queryDisplayStatus() {
1839         mTestLooper.moveTimeForward(TIMEOUT_MS);
1840         mHdmiControlService.queryDisplayStatus(new IHdmiControlCallback.Stub() {
1841             @Override
1842             public void onComplete(int result) {
1843             }
1844         });
1845         mTestLooper.dispatchAll();
1846 
1847         HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
1848                 mPlaybackLogicalAddress, Constants.ADDR_TV);
1849         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
1850     }
1851 
1852     @Test
toggleAndFollowTvPower_ToTv_TvStatusOn()1853     public void toggleAndFollowTvPower_ToTv_TvStatusOn() {
1854         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1855                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1856                 HdmiControlManager.POWER_CONTROL_MODE_TV);
1857         mPowerManager.setInteractive(true);
1858         mHdmiControlService.toggleAndFollowTvPower();
1859         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
1860                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
1861         assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
1862                 .isEqualTo(Constants.HANDLED);
1863         mTestLooper.dispatchAll();
1864 
1865         HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildStandby(
1866                 mPlaybackLogicalAddress, ADDR_TV);
1867         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
1868         assertThat(mPowerManager.isInteractive()).isFalse();
1869     }
1870 
1871     @Test
toggleAndFollowTvPower_Broadcast_TvStatusOn()1872     public void toggleAndFollowTvPower_Broadcast_TvStatusOn() {
1873         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1874                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1875                 HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
1876         mPowerManager.setInteractive(true);
1877         mHdmiControlService.toggleAndFollowTvPower();
1878         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
1879                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
1880         assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
1881                 .isEqualTo(Constants.HANDLED);
1882         mTestLooper.dispatchAll();
1883 
1884         HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildStandby(
1885                 mPlaybackLogicalAddress, ADDR_BROADCAST);
1886         assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
1887         assertThat(mPowerManager.isInteractive()).isFalse();
1888     }
1889 
1890     @Test
toggleAndFollowTvPower_TvStatusStandby()1891     public void toggleAndFollowTvPower_TvStatusStandby() {
1892         mPowerManager.setInteractive(true);
1893         mHdmiControlService.toggleAndFollowTvPower();
1894         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
1895                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_STANDBY);
1896         assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
1897                 .isEqualTo(Constants.HANDLED);
1898         mTestLooper.dispatchAll();
1899 
1900         HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
1901                 ADDR_TV);
1902         HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
1903                 mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
1904         assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
1905         assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
1906         assertThat(mPowerManager.isInteractive()).isTrue();
1907     }
1908 
1909     @Test
toggleAndFollowTvPower_TvStatusUnknown()1910     public void toggleAndFollowTvPower_TvStatusUnknown() {
1911         mPowerManager.setInteractive(true);
1912         mHdmiControlService.toggleAndFollowTvPower();
1913         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
1914                 mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_UNKNOWN);
1915         assertThat(mHdmiCecLocalDevicePlayback.dispatchMessage(tvPowerStatus))
1916                 .isEqualTo(Constants.HANDLED);
1917         mTestLooper.dispatchAll();
1918 
1919         HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed(
1920                 mPlaybackLogicalAddress, Constants.ADDR_TV,
1921                 HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION);
1922         HdmiCecMessage userControlReleased = HdmiCecMessageBuilder.buildUserControlReleased(
1923                 mPlaybackLogicalAddress, Constants.ADDR_TV);
1924         assertThat(mNativeWrapper.getResultMessages()).contains(userControlPressed);
1925         assertThat(mNativeWrapper.getResultMessages()).contains(userControlReleased);
1926         assertThat(mPowerManager.isInteractive()).isTrue();
1927     }
1928 
1929     @Test
toggleAndFollowTvPower_isInteractive()1930     public void toggleAndFollowTvPower_isInteractive() throws RemoteException {
1931         mPowerManager.setInteractive(true);
1932         mActiveMediaSessionsPaused = false;
1933         mWokenUp = false;
1934 
1935         mHdmiControlService.toggleAndFollowTvPower();
1936 
1937         assertThat(mActiveMediaSessionsPaused).isTrue();
1938         assertThat(mPowerManager.isInteractive()).isTrue();
1939         assertThat(mWokenUp).isFalse();
1940     }
1941 
1942     @Test
toggleAndFollowTvPower_isNotInteractive()1943     public void toggleAndFollowTvPower_isNotInteractive() throws RemoteException {
1944         mPowerManager.setInteractive(false);
1945         mActiveMediaSessionsPaused = false;
1946 
1947         mHdmiControlService.toggleAndFollowTvPower();
1948 
1949         assertThat(mActiveMediaSessionsPaused).isFalse();
1950         assertThat(mPowerManager.isInteractive()).isTrue();
1951     }
1952 
1953 
1954     @Test
shouldHandleTvPowerKey_CecDisabled()1955     public void shouldHandleTvPowerKey_CecDisabled() {
1956         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1957         HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus(
1958                 Constants.ADDR_TV, mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
1959         mNativeWrapper.onCecMessage(reportPowerStatusMessage);
1960         mTestLooper.dispatchAll();
1961 
1962         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setIntValue(
1963                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
1964                 HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
1965         assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse();
1966     }
1967 
1968     @Test
shouldHandleTvPowerKey_PowerControlModeNone()1969     public void shouldHandleTvPowerKey_PowerControlModeNone() {
1970         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1971         HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus(
1972                 Constants.ADDR_TV, mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
1973         mNativeWrapper.onCecMessage(reportPowerStatusMessage);
1974         mTestLooper.dispatchAll();
1975 
1976         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
1977                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
1978                 HdmiControlManager.POWER_CONTROL_MODE_NONE);
1979         assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse();
1980     }
1981 
1982     @Test
shouldHandleTvPowerKey_CecNotAvailable()1983     public void shouldHandleTvPowerKey_CecNotAvailable() {
1984         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1985         // TV doesn't report its power status
1986         mTestLooper.moveTimeForward(TIMEOUT_MS);
1987         mTestLooper.dispatchAll();
1988         assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse();
1989     }
1990 
1991     @Test
shouldHandleTvPowerKey_CecEnabled_PowerControlModeTv()1992     public void shouldHandleTvPowerKey_CecEnabled_PowerControlModeTv() {
1993         mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
1994         HdmiCecMessage reportPowerStatusMessage = HdmiCecMessageBuilder.buildReportPowerStatus(
1995                 Constants.ADDR_TV, mPlaybackLogicalAddress, HdmiControlManager.POWER_STATUS_ON);
1996         mNativeWrapper.onCecMessage(reportPowerStatusMessage);
1997         mTestLooper.dispatchAll();
1998 
1999         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setIntValue(
2000                 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
2001                 HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
2002         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
2003                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
2004                 HdmiControlManager.POWER_CONTROL_MODE_TV);
2005         assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isTrue();
2006     }
2007 
2008     @Test
getRcFeatures()2009     public void getRcFeatures() {
2010         ArrayList<Integer> features = new ArrayList<>(mHdmiCecLocalDevicePlayback.getRcFeatures());
2011         assertThat(features.contains(Constants.RC_PROFILE_SOURCE_HANDLES_ROOT_MENU)).isTrue();
2012         assertThat(features.contains(Constants.RC_PROFILE_SOURCE_HANDLES_SETUP_MENU)).isTrue();
2013         assertThat(features.contains(Constants.RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU)).isFalse();
2014         assertThat(features.contains(Constants.RC_PROFILE_SOURCE_HANDLES_TOP_MENU)).isFalse();
2015         assertThat(features.contains(
2016                 Constants.RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU)).isFalse();
2017     }
2018 
2019     @Test
doesNotSupportRecordTvScreen()2020     public void doesNotSupportRecordTvScreen() {
2021         HdmiCecMessage recordTvScreen = HdmiCecMessage.build(ADDR_TV, mPlaybackLogicalAddress,
2022                 Constants.MESSAGE_RECORD_TV_SCREEN, HdmiCecMessage.EMPTY_PARAM);
2023 
2024         mNativeWrapper.onCecMessage(recordTvScreen);
2025         mTestLooper.dispatchAll();
2026 
2027         HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
2028                 mPlaybackLogicalAddress, ADDR_TV, Constants.MESSAGE_RECORD_TV_SCREEN,
2029                 ABORT_UNRECOGNIZED_OPCODE);
2030         assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
2031     }
2032 
2033     @Test
shouldHandleUserControlPressedAndReleased()2034     public void shouldHandleUserControlPressedAndReleased() {
2035         HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed(
2036                 ADDR_TV, mPlaybackLogicalAddress,
2037                 HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP);
2038         HdmiCecMessage userControlReleased = HdmiCecMessageBuilder.buildUserControlReleased(
2039                 ADDR_TV, mPlaybackLogicalAddress);
2040 
2041         mNativeWrapper.onCecMessage(userControlPressed);
2042         mTestLooper.dispatchAll();
2043 
2044         // Move past the follower safety timeout
2045         mTestLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(2));
2046         mTestLooper.dispatchAll();
2047 
2048         mNativeWrapper.onCecMessage(userControlReleased);
2049         mTestLooper.dispatchAll();
2050 
2051         HdmiCecMessage featureAbortPressed = HdmiCecMessageBuilder.buildFeatureAbortCommand(
2052                 mPlaybackLogicalAddress, ADDR_TV, Constants.MESSAGE_USER_CONTROL_PRESSED,
2053                 ABORT_UNRECOGNIZED_OPCODE);
2054         HdmiCecMessage featureAbortReleased = HdmiCecMessageBuilder.buildFeatureAbortCommand(
2055                 mPlaybackLogicalAddress, ADDR_TV, Constants.MESSAGE_USER_CONTROL_RELEASED,
2056                 ABORT_UNRECOGNIZED_OPCODE);
2057         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortPressed);
2058         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortReleased);
2059     }
2060 
2061     @Test
onHotplugInAfterHotplugOut_noStandbyAfterDelay()2062     public void onHotplugInAfterHotplugOut_noStandbyAfterDelay() {
2063         mPowerManager.setInteractive(true);
2064         mNativeWrapper.onHotplugEvent(1, false);
2065         mTestLooper.dispatchAll();
2066 
2067         mTestLooper.moveTimeForward(
2068                 HdmiCecLocalDevicePlayback.STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS / 2);
2069         mNativeWrapper.onHotplugEvent(1, true);
2070         mTestLooper.dispatchAll();
2071 
2072         mPowerManagerInternal.setIdleDuration(
2073                 HdmiCecLocalDevicePlayback.STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS);
2074         mTestLooper.moveTimeForward(HdmiCecLocalDevicePlayback.STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS);
2075         mTestLooper.dispatchAll();
2076 
2077         assertThat(mPowerManager.isInteractive()).isTrue();
2078     }
2079 
2080     @Test
onHotplugOut_standbyAfterDelay_onlyAfterDeviceIdle()2081     public void onHotplugOut_standbyAfterDelay_onlyAfterDeviceIdle() {
2082         mPowerManager.setInteractive(true);
2083         mNativeWrapper.onHotplugEvent(1, false);
2084         mTestLooper.dispatchAll();
2085 
2086         mPowerManagerInternal.setIdleDuration(0);
2087         mTestLooper.moveTimeForward(HdmiCecLocalDevicePlayback.STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS);
2088         mTestLooper.dispatchAll();
2089         assertThat(mPowerManager.isInteractive()).isTrue();
2090 
2091         mPowerManagerInternal.setIdleDuration(
2092                 HdmiCecLocalDevicePlayback.STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS);
2093         mTestLooper.moveTimeForward(HdmiCecLocalDevicePlayback.STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS);
2094         mTestLooper.dispatchAll();
2095         assertThat(mPowerManager.isInteractive()).isFalse();
2096     }
2097 
2098     @Test
onHotplugClearsDevices()2099     public void onHotplugClearsDevices() {
2100         mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
2101         assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
2102                 .isEmpty();
2103         // Add a device to the network and assert that this device is included in the list of
2104         // devices.
2105         HdmiDeviceInfo infoPlayback = HdmiDeviceInfo.cecDeviceBuilder()
2106                 .setLogicalAddress(Constants.ADDR_PLAYBACK_3)
2107                 .setPhysicalAddress(0x1000)
2108                 .setPortId(PORT_1)
2109                 .setDeviceType(HdmiDeviceInfo.DEVICE_PLAYBACK)
2110                 .setVendorId(0x1000)
2111                 .setDisplayName("Playback 3")
2112                 .build();
2113         mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoPlayback);
2114         mTestLooper.dispatchAll();
2115         assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
2116                 .hasSize(1);
2117 
2118         // HAL detects a hotplug out. Assert that this device gets removed from the list of devices.
2119         mHdmiControlService.onHotplug(PORT_1, false);
2120         mTestLooper.dispatchAll();
2121 
2122         assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
2123                 .isEmpty();
2124     }
2125 
2126     @Test
handleRoutingChange_addressNotAllocated_removeActiveSourceAction()2127     public void handleRoutingChange_addressNotAllocated_removeActiveSourceAction() {
2128         long allocationDelay = TimeUnit.SECONDS.toMillis(60);
2129         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
2130                 HdmiProperties
2131                         .playback_device_action_on_routing_control_values
2132                         .WAKE_UP_AND_SEND_ACTIVE_SOURCE;
2133         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
2134                 "HdmiCecLocalDevicePlaybackTest");
2135         HdmiCecMessage routingChangeToPlayback =
2136                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
2137                         mPlaybackPhysicalAddress);
2138         HdmiCecMessage routingChangeToTv =
2139                 HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, mPlaybackPhysicalAddress,
2140                         0x0000);
2141         HdmiCecMessage unexpectedMessage =
2142                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
2143                         mPlaybackPhysicalAddress);
2144         // 1. DUT goes to sleep.
2145         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
2146         // Delay allocate logical address in order to trigger message buffering.
2147         mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
2148         mNativeWrapper.onCecMessage(routingChangeToPlayback);
2149         mTestLooper.dispatchAll();
2150         // 2. DUT wakes up and defer ActiveSourceAction.
2151         mHdmiControlService.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
2152         mTestLooper.dispatchAll();
2153         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isNotEmpty();
2154         // 3. DUT buffers <Routing Change> message to TV.
2155         mNativeWrapper.onCecMessage(routingChangeToTv);
2156         mTestLooper.dispatchAll();
2157         // 4. Allocation is finished and the ActiveSourceAction is removed from the queue.
2158         // No <Active Source> message is sent by the DUT.
2159         mTestLooper.moveTimeForward(allocationDelay);
2160         mTestLooper.dispatchAll();
2161         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isEmpty();
2162         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpectedMessage);
2163     }
2164 
2165     @Test
handleSetStreamPath_addressNotAllocated_removeActiveSourceAction()2166     public void handleSetStreamPath_addressNotAllocated_removeActiveSourceAction() {
2167         long allocationDelay = TimeUnit.SECONDS.toMillis(60);
2168         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
2169                 "HdmiCecLocalDevicePlaybackTest");
2170         HdmiCecMessage setStreamPathToPlayback =
2171                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, mPlaybackPhysicalAddress);
2172         HdmiCecMessage setStreamPathToTv =
2173                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, 0x0000);
2174         HdmiCecMessage unexpectedMessage =
2175                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
2176                         mPlaybackPhysicalAddress);
2177         // 1. DUT goes to sleep.
2178         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
2179         // Delay allocate logical address in order to trigger message buffering.
2180         mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
2181         mNativeWrapper.onCecMessage(setStreamPathToPlayback);
2182         mTestLooper.dispatchAll();
2183         // 2. DUT wakes up and defer ActiveSourceAction.
2184         mHdmiControlService.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
2185         mTestLooper.dispatchAll();
2186         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isNotEmpty();
2187         // 3. DUT buffers <Set Stream Path> message to TV.
2188         mNativeWrapper.onCecMessage(setStreamPathToTv);
2189         mTestLooper.dispatchAll();
2190         // 4. Allocation is finished and the ActiveSourceAction is removed from the queue.
2191         // No <Active Source> message is sent by the DUT.
2192         mTestLooper.moveTimeForward(allocationDelay);
2193         mTestLooper.dispatchAll();
2194         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isEmpty();
2195         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpectedMessage);
2196     }
2197 
2198     @Test
handleActiveSource_addressNotAllocated_removeActiveSourceAction()2199     public void handleActiveSource_addressNotAllocated_removeActiveSourceAction() {
2200         long allocationDelay = TimeUnit.SECONDS.toMillis(60);
2201 
2202         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
2203                 "HdmiCecLocalDevicePlaybackTest");
2204 
2205         HdmiCecMessage setStreamPathToPlayback =
2206                 HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV, mPlaybackPhysicalAddress);
2207         HdmiCecMessage activeSourceFromTv =
2208                 HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
2209         HdmiCecMessage unexpectedMessage =
2210                 HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
2211                         mPlaybackPhysicalAddress);
2212         // 1. DUT goes to sleep.
2213         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
2214         // Delay allocate logical address in order to trigger message buffering.
2215         mHdmiCecController.setLogicalAddressAllocationDelay(allocationDelay);
2216         mNativeWrapper.onCecMessage(setStreamPathToPlayback);
2217         mTestLooper.dispatchAll();
2218         // 2. DUT wakes up and defer ActiveSourceAction.
2219         mHdmiControlService.onWakeUp(HdmiControlService.WAKE_UP_SCREEN_ON);
2220         mTestLooper.dispatchAll();
2221         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isNotEmpty();
2222         // 3. DUT buffers <Active Source> message from TV.
2223         mNativeWrapper.onCecMessage(activeSourceFromTv);
2224         mTestLooper.dispatchAll();
2225         // 4. Allocation is finished and the ActiveSourceAction is removed from the queue.
2226         // No <Active Source> message is sent by the DUT.
2227         mTestLooper.moveTimeForward(allocationDelay);
2228         mTestLooper.dispatchAll();
2229         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isEmpty();
2230         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpectedMessage);
2231     }
2232 }
2233