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.telecom;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.media.AudioManager;
24 import android.os.UserHandle;
25 import android.provider.Settings;
26 import android.telecom.TelecomManager;
27 
28 import com.android.internal.util.IndentingPrintWriter;
29 
30 // TODO: Needed for move to system service: import com.android.internal.R;
31 
32 final class TtyManager implements WiredHeadsetManager.Listener {
33     private final TtyBroadcastReceiver mReceiver = new TtyBroadcastReceiver();
34     private final Context mContext;
35     private final WiredHeadsetManager mWiredHeadsetManager;
36     private int mPreferredTtyMode = TelecomManager.TTY_MODE_OFF;
37     private int mCurrentTtyMode = TelecomManager.TTY_MODE_OFF;
38 
TtyManager(Context context, WiredHeadsetManager wiredHeadsetManager)39     TtyManager(Context context, WiredHeadsetManager wiredHeadsetManager) {
40         mContext = context;
41         mWiredHeadsetManager = wiredHeadsetManager;
42         mWiredHeadsetManager.addListener(this);
43 
44         mPreferredTtyMode = Settings.Secure.getInt(
45                 mContext.getContentResolver(),
46                 Settings.Secure.PREFERRED_TTY_MODE,
47                 TelecomManager.TTY_MODE_OFF);
48 
49         IntentFilter intentFilter = new IntentFilter(
50                 TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
51         mContext.registerReceiver(mReceiver, intentFilter);
52 
53         updateCurrentTtyMode();
54     }
55 
isTtySupported()56     boolean isTtySupported() {
57         boolean isEnabled = mContext.getResources().getBoolean(R.bool.tty_enabled);
58         Log.v(this, "isTtySupported: %b", isEnabled);
59         return isEnabled;
60     }
61 
getCurrentTtyMode()62     int getCurrentTtyMode() {
63         return mCurrentTtyMode;
64     }
65 
66     @Override
onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn)67     public void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
68         Log.v(this, "onWiredHeadsetPluggedInChanged");
69         updateCurrentTtyMode();
70     }
71 
updateCurrentTtyMode()72     private void updateCurrentTtyMode() {
73         int newTtyMode = TelecomManager.TTY_MODE_OFF;
74         if (isTtySupported() && mWiredHeadsetManager.isPluggedIn()) {
75             newTtyMode = mPreferredTtyMode;
76         }
77         Log.v(this, "updateCurrentTtyMode, %d -> %d", mCurrentTtyMode, newTtyMode);
78 
79         if (mCurrentTtyMode != newTtyMode) {
80             mCurrentTtyMode = newTtyMode;
81             Intent ttyModeChanged = new Intent(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
82             ttyModeChanged.putExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE, mCurrentTtyMode);
83             mContext.sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
84 
85             updateAudioTtyMode();
86         }
87     }
88 
updateAudioTtyMode()89     private void updateAudioTtyMode() {
90         String audioTtyMode;
91         switch (mCurrentTtyMode) {
92             case TelecomManager.TTY_MODE_FULL:
93                 audioTtyMode = "tty_full";
94                 break;
95             case TelecomManager.TTY_MODE_VCO:
96                 audioTtyMode = "tty_vco";
97                 break;
98             case TelecomManager.TTY_MODE_HCO:
99                 audioTtyMode = "tty_hco";
100                 break;
101             case TelecomManager.TTY_MODE_OFF:
102             default:
103                 audioTtyMode = "tty_off";
104                 break;
105         }
106         Log.v(this, "updateAudioTtyMode, %s", audioTtyMode);
107 
108         AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
109         audioManager.setParameters("tty_mode=" + audioTtyMode);
110     }
111 
112     private final class TtyBroadcastReceiver extends BroadcastReceiver {
113         @Override
onReceive(Context context, Intent intent)114         public void onReceive(Context context, Intent intent) {
115             Log.startSession("TBR.oR");
116             try {
117                 String action = intent.getAction();
118                 Log.v(TtyManager.this, "onReceive, action: %s", action);
119                 if (action.equals(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED)) {
120                     int newPreferredTtyMode = intent.getIntExtra(
121                             TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
122                     if (mPreferredTtyMode != newPreferredTtyMode) {
123                         mPreferredTtyMode = newPreferredTtyMode;
124                         updateCurrentTtyMode();
125                     }
126                 }
127             } finally {
128                 Log.endSession();
129             }
130         }
131     }
132 
133     /**
134      * Dumps the state of the {@link TtyManager}.
135      *
136      * @param pw The {@code IndentingPrintWriter} to write the state to.
137      */
dump(IndentingPrintWriter pw)138     public void dump(IndentingPrintWriter pw) {
139         pw.println("mCurrentTtyMode: " + mCurrentTtyMode);
140     }
141 }
142