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(HdmiUtils.parseCommandParamSystemAudioStatus(cmd));
     68             return true;
     69         }
     70         return false;
     71     }
     72 
     73     private void handleSystemAudioModeStatusMessage(boolean isSystemAudioModeOn) {
     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         if (systemAudioModeSetting && !isSystemAudioModeOn) {
     82             addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, systemAudioModeSetting, null));
     83         } else {
     84             tv().setSystemAudioMode(isSystemAudioModeOn, true);
     85         }
     86         finish();
     87     }
     88 
     89     @Override
     90     void handleTimerEvent(int state) {
     91         if (mState != state) {
     92             return;
     93         }
     94 
     95         switch (mState) {
     96             case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
     97                 handleSystemAudioModeStatusTimeout();
     98                 break;
     99         }
    100     }
    101 
    102     private void handleSystemAudioModeStatusTimeout() {
    103         if (tv().getSystemAudioModeSetting()) {
    104             if (canChangeSystemAudio()) {
    105                 addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
    106             }
    107         } else {
    108             tv().setSystemAudioMode(false, true);
    109         }
    110         finish();
    111     }
    112 
    113     private boolean canChangeSystemAudio() {
    114         return !(tv().hasAction(SystemAudioActionFromTv.class)
    115                || tv().hasAction(SystemAudioActionFromAvr.class));
    116     }
    117 }
    118