Home | History | Annotate | Download | only in hdmi
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.hdmi;
     18 
     19 import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
     20 
     21 /**
     22  * Action to initiate system audio once AVR is detected on Device discovery action.
     23  */
     24 // Seq #27
     25 final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
     26     private final int mAvrAddress;
     27 
     28     // State that waits for <System Audio Mode Status> once send
     29     // <Give System Audio Mode Status> to AV Receiver.
     30     private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
     31 
     32     SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
     33         super(source);
     34         mAvrAddress = avrAddress;
     35     }
     36 
     37     @Override
     38     boolean start() {
     39         mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
     40 
     41         addTimer(mState, HdmiConfig.TIMEOUT_MS);
     42         sendGiveSystemAudioModeStatus();
     43         return true;
     44     }
     45 
     46     private void sendGiveSystemAudioModeStatus() {
     47         sendCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(getSourceAddress(),
     48                 mAvrAddress), new SendMessageCallback() {
     49             @Override
     50             public void onSendCompleted(int error) {
     51                 if (error != Constants.SEND_RESULT_SUCCESS) {
     52                     tv().setSystemAudioMode(false, true);
     53                     finish();
     54                 }
     55             }
     56         });
     57     }
     58 
     59     @Override
     60     boolean processCommand(HdmiCecMessage cmd) {
     61         if (mState != STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS
     62                 || mAvrAddress != cmd.getSource()) {
     63             return false;
     64         }
     65 
     66         if (cmd.getOpcode() == Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS) {
     67             handleSystemAudioModeStatusMessage();
     68             return true;
     69         }
     70         return false;
     71     }
     72 
     73     private void handleSystemAudioModeStatusMessage() {
     74         if (!canChangeSystemAudio()) {
     75             HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
     76             finish();
     77             return;
     78         }
     79 
     80         boolean systemAudioModeSetting = tv().getSystemAudioModeSetting();
     81         // Update AVR's system audio mode regardless of AVR's status.
     82         addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, systemAudioModeSetting,
     83                 null));
     84         finish();
     85     }
     86 
     87     @Override
     88     void handleTimerEvent(int state) {
     89         if (mState != state) {
     90             return;
     91         }
     92 
     93         switch (mState) {
     94             case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
     95                 handleSystemAudioModeStatusTimeout();
     96                 break;
     97         }
     98     }
     99 
    100     private void handleSystemAudioModeStatusTimeout() {
    101         if (tv().getSystemAudioModeSetting()) {
    102             if (canChangeSystemAudio()) {
    103                 addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
    104             }
    105         } else {
    106             tv().setSystemAudioMode(false, true);
    107         }
    108         finish();
    109     }
    110 
    111     private boolean canChangeSystemAudio() {
    112         return !(tv().hasAction(SystemAudioActionFromTv.class)
    113                || tv().hasAction(SystemAudioActionFromAvr.class));
    114     }
    115 }
    116