• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017 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 /*
18  * Defines the native inteface that is used by state machine/service to either or receive messages
19  * from the native stack. This file is registered for the native methods in corresponding CPP file.
20  */
21 package com.android.bluetooth.hfpclient;
22 
23 import android.bluetooth.BluetoothAdapter;
24 import android.bluetooth.BluetoothDevice;
25 import android.util.Log;
26 
27 class NativeInterface {
28     private static final String TAG = "NativeInterface";
29     private static final boolean DBG = false;
30 
NativeInterface()31     NativeInterface() {}
32 
33     // Native methods that call into the JNI interface
classInitNative()34     static native void classInitNative();
35 
initializeNative()36     static native void initializeNative();
37 
cleanupNative()38     static native void cleanupNative();
39 
connectNative(byte[] address)40     static native boolean connectNative(byte[] address);
41 
disconnectNative(byte[] address)42     static native boolean disconnectNative(byte[] address);
43 
connectAudioNative(byte[] address)44     static native boolean connectAudioNative(byte[] address);
45 
disconnectAudioNative(byte[] address)46     static native boolean disconnectAudioNative(byte[] address);
47 
startVoiceRecognitionNative(byte[] address)48     static native boolean startVoiceRecognitionNative(byte[] address);
49 
stopVoiceRecognitionNative(byte[] address)50     static native boolean stopVoiceRecognitionNative(byte[] address);
51 
setVolumeNative(byte[] address, int volumeType, int volume)52     static native boolean setVolumeNative(byte[] address, int volumeType, int volume);
53 
dialNative(byte[] address, String number)54     static native boolean dialNative(byte[] address, String number);
55 
dialMemoryNative(byte[] address, int location)56     static native boolean dialMemoryNative(byte[] address, int location);
57 
handleCallActionNative(byte[] address, int action, int index)58     static native boolean handleCallActionNative(byte[] address, int action, int index);
59 
queryCurrentCallsNative(byte[] address)60     static native boolean queryCurrentCallsNative(byte[] address);
61 
queryCurrentOperatorNameNative(byte[] address)62     static native boolean queryCurrentOperatorNameNative(byte[] address);
63 
retrieveSubscriberInfoNative(byte[] address)64     static native boolean retrieveSubscriberInfoNative(byte[] address);
65 
sendDtmfNative(byte[] address, byte code)66     static native boolean sendDtmfNative(byte[] address, byte code);
67 
requestLastVoiceTagNumberNative(byte[] address)68     static native boolean requestLastVoiceTagNumberNative(byte[] address);
69 
sendATCmdNative(byte[] address, int atCmd, int val1, int val2, String arg)70     static native boolean sendATCmdNative(byte[] address, int atCmd, int val1, int val2,
71             String arg);
72 
getDevice(byte[] address)73     private BluetoothDevice getDevice(byte[] address) {
74         return BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
75     }
76 
77     // Callbacks from the native back into the java framework. All callbacks are routed via the
78     // Service which will disambiguate which state machine the message should be routed through.
onConnectionStateChanged(int state, int peerFeat, int chldFeat, byte[] address)79     private void onConnectionStateChanged(int state, int peerFeat, int chldFeat, byte[] address) {
80         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
81         event.valueInt = state;
82         event.valueInt2 = peerFeat;
83         event.valueInt3 = chldFeat;
84         event.device = getDevice(address);
85         // BluetoothAdapter.getDefaultAdapter().getRemoteDevice(Utils.getAddressStringFromByte
86         // (address));
87         if (DBG) {
88             Log.d(TAG, "Device addr " + event.device.getAddress() + " State " + state);
89         }
90         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
91         if (service != null) {
92             service.messageFromNative(event);
93         } else {
94             Log.w(TAG, "Ignoring message because service not available: " + event);
95         }
96     }
97 
onAudioStateChanged(int state, byte[] address)98     private void onAudioStateChanged(int state, byte[] address) {
99         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED);
100         event.valueInt = state;
101         event.device = getDevice(address);
102         if (DBG) {
103             Log.d(TAG, "onAudioStateChanged: address " + address + " event " + event);
104         }
105         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
106         if (service != null) {
107             service.messageFromNative(event);
108         } else {
109             Log.w(TAG, "onAudioStateChanged: Ignoring message because service not available: "
110                     + event);
111         }
112     }
113 
onVrStateChanged(int state, byte[] address)114     private void onVrStateChanged(int state, byte[] address) {
115         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_VR_STATE_CHANGED);
116         event.valueInt = state;
117         event.device = getDevice(address);
118         if (DBG) {
119             Log.d(TAG, "onVrStateChanged: address " + address + " event " + event);
120         }
121 
122         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
123         if (service != null) {
124             service.messageFromNative(event);
125         } else {
126             Log.w(TAG,
127                     "onVrStateChanged: Ignoring message because service not available: " + event);
128         }
129     }
130 
onNetworkState(int state, byte[] address)131     private void onNetworkState(int state, byte[] address) {
132         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_NETWORK_STATE);
133         event.valueInt = state;
134         event.device = getDevice(address);
135         if (DBG) {
136             Log.d(TAG, "onNetworkStateChanged: address " + address + " event " + event);
137         }
138 
139         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
140         if (service != null) {
141             service.messageFromNative(event);
142         } else {
143             Log.w(TAG,
144                     "onNetworkStateChanged: Ignoring message because service not available: "
145                             + event);
146         }
147     }
148 
onNetworkRoaming(int state, byte[] address)149     private void onNetworkRoaming(int state, byte[] address) {
150         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_ROAMING_STATE);
151         event.valueInt = state;
152         event.device = getDevice(address);
153         if (DBG) {
154             Log.d(TAG, "onNetworkRoaming: incoming: " + event);
155         }
156         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
157         if (service != null) {
158             service.messageFromNative(event);
159         } else {
160             Log.w(TAG,
161                     "onNetworkRoaming: Ignoring message because service not available: " + event);
162         }
163     }
164 
onNetworkSignal(int signal, byte[] address)165     private void onNetworkSignal(int signal, byte[] address) {
166         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_NETWORK_SIGNAL);
167         event.valueInt = signal;
168         event.device = getDevice(address);
169         if (DBG) {
170             Log.d(TAG, "onNetworkSignal: address " + address + " event " + event);
171         }
172         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
173         if (service != null) {
174             service.messageFromNative(event);
175         } else {
176             Log.w(TAG, "onNetworkSignal: Ignoring message because service not available: " + event);
177         }
178     }
179 
onBatteryLevel(int level, byte[] address)180     private void onBatteryLevel(int level, byte[] address) {
181         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_BATTERY_LEVEL);
182         event.valueInt = level;
183         event.device = getDevice(address);
184         if (DBG) {
185             Log.d(TAG, "onBatteryLevel: address " + address + " event " + event);
186         }
187         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
188         if (service != null) {
189             service.messageFromNative(event);
190         } else {
191             Log.w(TAG, "onBatteryLevel: Ignoring message because service not available: " + event);
192         }
193     }
194 
onCurrentOperator(String name, byte[] address)195     private void onCurrentOperator(String name, byte[] address) {
196         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_OPERATOR_NAME);
197         event.valueString = name;
198         event.device = getDevice(address);
199         if (DBG) {
200             Log.d(TAG, "onCurrentOperator: address " + address + " event " + event);
201         }
202         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
203         if (service != null) {
204             service.messageFromNative(event);
205         } else {
206             Log.w(TAG,
207                     "onCurrentOperator: Ignoring message because service not available: " + event);
208         }
209     }
210 
onCall(int call, byte[] address)211     private void onCall(int call, byte[] address) {
212         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CALL);
213         event.valueInt = call;
214         event.device = getDevice(address);
215         if (DBG) {
216             Log.d(TAG, "onCall: address " + address + " event " + event);
217         }
218         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
219         if (service != null) {
220             service.messageFromNative(event);
221         } else {
222             Log.w(TAG, "onCall: Ignoring message because service not available: " + event);
223         }
224     }
225 
226     /**
227      * CIEV (Call indicators) notifying if call(s) are getting set up.
228      *
229      * Values include:
230      * 0 - No current call is in setup
231      * 1 - Incoming call process ongoing
232      * 2 - Outgoing call process ongoing
233      * 3 - Remote party being alerted for outgoing call
234      */
onCallSetup(int callsetup, byte[] address)235     private void onCallSetup(int callsetup, byte[] address) {
236         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CALLSETUP);
237         event.valueInt = callsetup;
238         event.device = getDevice(address);
239         if (DBG) {
240             Log.d(TAG, "onCallSetup: addr " + address + " device" + event.device);
241             Log.d(TAG, "onCallSetup: address " + address + " event " + event);
242         }
243         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
244         if (service != null) {
245             service.messageFromNative(event);
246         } else {
247             Log.w(TAG, "onCallSetup: Ignoring message because service not available: " + event);
248         }
249     }
250 
251     /**
252      * CIEV (Call indicators) notifying call held states.
253      *
254      * Values include:
255      * 0 - No calls held
256      * 1 - Call is placed on hold or active/held calls wapped (The AG has both an ACTIVE and HELD
257      * call)
258      * 2 - Call on hold, no active call
259      */
onCallHeld(int callheld, byte[] address)260     private void onCallHeld(int callheld, byte[] address) {
261         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CALLHELD);
262         event.valueInt = callheld;
263         event.device = getDevice(address);
264         if (DBG) {
265             Log.d(TAG, "onCallHeld: address " + address + " event " + event);
266         }
267         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
268         if (service != null) {
269             service.messageFromNative(event);
270         } else {
271             Log.w(TAG, "onCallHeld: Ignoring message because service not available: " + event);
272         }
273     }
274 
onRespAndHold(int respAndHold, byte[] address)275     private void onRespAndHold(int respAndHold, byte[] address) {
276         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_RESP_AND_HOLD);
277         event.valueInt = respAndHold;
278         event.device = getDevice(address);
279         if (DBG) {
280             Log.d(TAG, "onRespAndHold: address " + address + " event " + event);
281         }
282         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
283         if (service != null) {
284             service.messageFromNative(event);
285         } else {
286             Log.w(TAG, "onRespAndHold: Ignoring message because service not available: " + event);
287         }
288     }
289 
onClip(String number, byte[] address)290     private void onClip(String number, byte[] address) {
291         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CLIP);
292         event.valueString = number;
293         event.device = getDevice(address);
294         if (DBG) {
295             Log.d(TAG, "onClip: address " + address + " event " + event);
296         }
297         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
298         if (service != null) {
299             service.messageFromNative(event);
300         } else {
301             Log.w(TAG, "onClip: Ignoring message because service not available: " + event);
302         }
303     }
304 
onCallWaiting(String number, byte[] address)305     private void onCallWaiting(String number, byte[] address) {
306         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CALL_WAITING);
307         event.valueString = number;
308         event.device = getDevice(address);
309         if (DBG) {
310             Log.d(TAG, "onCallWaiting: address " + address + " event " + event);
311         }
312         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
313         if (service != null) {
314             service.messageFromNative(event);
315         } else {
316             Log.w(TAG, "onCallWaiting: Ignoring message because service not available: " + event);
317         }
318     }
319 
onCurrentCalls(int index, int dir, int state, int mparty, String number, byte[] address)320     private void onCurrentCalls(int index, int dir, int state, int mparty, String number,
321             byte[] address) {
322         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CURRENT_CALLS);
323         event.valueInt = index;
324         event.valueInt2 = dir;
325         event.valueInt3 = state;
326         event.valueInt4 = mparty;
327         event.valueString = number;
328         event.device = getDevice(address);
329         if (DBG) {
330             Log.d(TAG, "onCurrentCalls: address " + address + " event " + event);
331         }
332         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
333         if (service != null) {
334             service.messageFromNative(event);
335         } else {
336             Log.w(TAG, "onCurrentCalls: Ignoring message because service not available: " + event);
337         }
338     }
339 
onVolumeChange(int type, int volume, byte[] address)340     private void onVolumeChange(int type, int volume, byte[] address) {
341         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_VOLUME_CHANGED);
342         event.valueInt = type;
343         event.valueInt2 = volume;
344         event.device = getDevice(address);
345         if (DBG) {
346             Log.d(TAG, "onVolumeChange: address " + address + " event " + event);
347         }
348         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
349         if (service != null) {
350             service.messageFromNative(event);
351         } else {
352             Log.w(TAG, "onVolumeChange: Ignoring message because service not available: " + event);
353         }
354     }
355 
onCmdResult(int type, int cme, byte[] address)356     private void onCmdResult(int type, int cme, byte[] address) {
357         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_CMD_RESULT);
358         event.valueInt = type;
359         event.valueInt2 = cme;
360         event.device = getDevice(address);
361         if (DBG) {
362             Log.d(TAG, "onCmdResult: address " + address + " event " + event);
363         }
364         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
365         if (service != null) {
366             service.messageFromNative(event);
367         } else {
368             Log.w(TAG, "onCmdResult: Ignoring message because service not available: " + event);
369         }
370     }
371 
onSubscriberInfo(String number, int type, byte[] address)372     private void onSubscriberInfo(String number, int type, byte[] address) {
373         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_SUBSCRIBER_INFO);
374         event.valueInt = type;
375         event.valueString = number;
376         event.device = getDevice(address);
377         if (DBG) {
378             Log.d(TAG, "onSubscriberInfo: address " + address + " event " + event);
379         }
380         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
381         if (service != null) {
382             service.messageFromNative(event);
383         } else {
384             Log.w(TAG,
385                     "onSubscriberInfo: Ignoring message because service not available: " + event);
386         }
387     }
388 
onInBandRing(int inBand, byte[] address)389     private void onInBandRing(int inBand, byte[] address) {
390         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_IN_BAND_RINGTONE);
391         event.valueInt = inBand;
392         event.device = getDevice(address);
393         if (DBG) {
394             Log.d(TAG, "onInBandRing: address " + address + " event " + event);
395         }
396         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
397         if (service != null) {
398             service.messageFromNative(event);
399         } else {
400             Log.w(TAG,
401                     "onInBandRing: Ignoring message because service not available: " + event);
402         }
403     }
404 
onLastVoiceTagNumber(String number, byte[] address)405     private void onLastVoiceTagNumber(String number, byte[] address) {
406         Log.w(TAG, "onLastVoiceTagNumber not supported");
407     }
408 
onRingIndication(byte[] address)409     private void onRingIndication(byte[] address) {
410         StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_RING_INDICATION);
411         event.device = getDevice(address);
412         if (DBG) {
413             Log.d(TAG, "onRingIndication: address " + address + " event " + event);
414         }
415         HeadsetClientService service = HeadsetClientService.getHeadsetClientService();
416         if (service != null) {
417             service.messageFromNative(event);
418         } else {
419             Log.w(TAG,
420                     "onRingIndication: Ignoring message because service not available: " + event);
421         }
422     }
423 }
424