1631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo/*
2631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * Copyright (C) 2016 The Android Open Source Project
3631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo *
4631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * Licensed under the Apache License, Version 2.0 (the "License");
5631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * you may not use this file except in compliance with the License.
6631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * You may obtain a copy of the License at
7631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo *
8631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo *      http://www.apache.org/licenses/LICENSE-2.0
9631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo *
10631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * Unless required by applicable law or agreed to in writing, software
11631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * distributed under the License is distributed on an "AS IS" BASIS,
12631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * See the License for the specific language governing permissions and
14631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * limitations under the License.
15631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo */
16631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
17631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzopackage android.bluetooth;
18631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
19631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.app.PendingIntent;
20631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.content.ComponentName;
21631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.content.Context;
22631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.content.Intent;
23631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.content.ServiceConnection;
24631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.net.Uri;
25631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.os.IBinder;
26631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.os.RemoteException;
27631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport android.util.Log;
28631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
29631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport java.util.ArrayList;
30631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzoimport java.util.List;
31631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
32631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo/**
33631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * This class provides the APIs to control the Bluetooth MAP MCE Profile.
34631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo *
35631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo * @hide
36631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo */
37631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzopublic final class BluetoothMapClient implements BluetoothProfile {
38631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
39631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private static final String TAG = "BluetoothMapClient";
40631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
41631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
42631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
43631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final String ACTION_CONNECTION_STATE_CHANGED =
44631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED";
45631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final String ACTION_MESSAGE_RECEIVED =
46631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            "android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED";
47631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /* Actions to be used for pending intents */
48631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final String ACTION_MESSAGE_SENT_SUCCESSFULLY =
49631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            "android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY";
50631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY =
51631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY";
52631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
5386a8c1cabb7de0b7c5868fad8edb7d0df176d4e1Srinivas Visvanathan    /* Extras used in ACTION_MESSAGE_RECEIVED intent.
5486a8c1cabb7de0b7c5868fad8edb7d0df176d4e1Srinivas Visvanathan     * NOTE: HANDLE is only valid for a single session with the device. */
5586a8c1cabb7de0b7c5868fad8edb7d0df176d4e1Srinivas Visvanathan    public static final String EXTRA_MESSAGE_HANDLE =
5686a8c1cabb7de0b7c5868fad8edb7d0df176d4e1Srinivas Visvanathan            "android.bluetooth.mapmce.profile.extra.MESSAGE_HANDLE";
57ad90338d2b26044a2606897e4444a99ac3e49eceSrinivas Visvanathan    public static final String EXTRA_SENDER_CONTACT_URI =
58ad90338d2b26044a2606897e4444a99ac3e49eceSrinivas Visvanathan            "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_URI";
59ad90338d2b26044a2606897e4444a99ac3e49eceSrinivas Visvanathan    public static final String EXTRA_SENDER_CONTACT_NAME =
60ad90338d2b26044a2606897e4444a99ac3e49eceSrinivas Visvanathan            "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME";
61ad90338d2b26044a2606897e4444a99ac3e49eceSrinivas Visvanathan
62631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private IBluetoothMapClient mService;
63631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private final Context mContext;
64631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private ServiceListener mServiceListener;
65631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private BluetoothAdapter mAdapter;
66631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
67631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /** There was an error trying to obtain the state */
68631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final int STATE_ERROR = -1;
69631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
70631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final int RESULT_FAILURE = 0;
71631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final int RESULT_SUCCESS = 1;
72631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /** Connection canceled before completion. */
73631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public static final int RESULT_CANCELED = 2;
74631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
75631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
76631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            new IBluetoothStateChangeCallback.Stub() {
77631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                public void onBluetoothStateChange(boolean up) {
78631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
79631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    if (!up) {
80631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                        if (VDBG) Log.d(TAG, "Unbinding service...");
81631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                        synchronized (mConnection) {
82631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                            try {
83631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                mService = null;
84631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                mContext.unbindService(mConnection);
85631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                            } catch (Exception re) {
86631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                Log.e(TAG, "", re);
87631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                            }
88631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                        }
89631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    } else {
90631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                        synchronized (mConnection) {
91631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                            try {
92631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                if (mService == null) {
93631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                    if (VDBG) Log.d(TAG, "Binding service...");
94631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                    doBind();
95631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                }
96631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                            } catch (Exception re) {
97631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                                Log.e(TAG, "", re);
98631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                            }
99631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                        }
100631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    }
101631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                }
102631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            };
103631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
104631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
105631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Create a BluetoothMapClient proxy object.
106631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
107631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /*package*/ BluetoothMapClient(Context context, ServiceListener l) {
108631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "Create BluetoothMapClient proxy object");
109631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        mContext = context;
110631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        mServiceListener = l;
111631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        mAdapter = BluetoothAdapter.getDefaultAdapter();
112631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        IBluetoothManager mgr = mAdapter.getBluetoothManager();
113631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mgr != null) {
114631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
115631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
116631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
117631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, "", e);
118631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
119631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
120631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        doBind();
121631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
122631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
123631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    boolean doBind() {
124631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        Intent intent = new Intent(IBluetoothMapClient.class.getName());
125631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
126631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        intent.setComponent(comp);
127631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
128631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                android.os.Process.myUserHandle())) {
129631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            Log.e(TAG, "Could not bind to Bluetooth MAP MCE Service with " + intent);
130631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            return false;
131631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
132631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return true;
133631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
134631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
135631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    protected void finalize() throws Throwable {
136631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        try {
137631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            close();
138631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        } finally {
139631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            super.finalize();
140631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
141631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
142631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
143631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
144631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Close the connection to the backing service.
145631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Other public functions of BluetoothMap will return default error
146631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * results once close() has been called. Multiple invocations of close()
147631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * are ok.
148631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
149631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public void close() {
150631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        IBluetoothManager mgr = mAdapter.getBluetoothManager();
151631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mgr != null) {
152631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
153631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
154631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (Exception e) {
155631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, "", e);
156631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
157631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
158631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
159631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        synchronized (mConnection) {
160631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (mService != null) {
161631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                try {
162631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    mService = null;
163631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    mContext.unbindService(mConnection);
164631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                } catch (Exception re) {
165631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    Log.e(TAG, "", re);
166631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                }
167631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
168631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
169631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        mServiceListener = null;
170631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
171631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
172631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
173631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Returns true if the specified Bluetooth device is connected.
174631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Returns false if not connected, or if this proxy object is not
175631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * currently connected to the Map service.
176631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
177631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public boolean isConnected(BluetoothDevice device) {
178631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
179631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null) {
180631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
181631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.isConnected(device);
182631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
183631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, e.toString());
184631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
185631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        } else {
186631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
187631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
188631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
189631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
190631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
191631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
192631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
193631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Initiate connection. Initiation of outgoing connections is not
194631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * supported for MAP server.
195631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
196631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public boolean connect(BluetoothDevice device) {
197631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
198631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null) {
199631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
200631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.connect(device);
201631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
202631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, e.toString());
203631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
204631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        } else {
205631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            Log.w(TAG, "Proxy not attached to service");
206631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
207631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
208631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
209631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
210631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
211631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
212631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Initiate disconnect.
213631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
214631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param device Remote Bluetooth Device
215631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return false on error, true otherwise
216631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
217631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public boolean disconnect(BluetoothDevice device) {
218631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "disconnect(" + device + ")");
219631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled() &&
220631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                isValidDevice(device)) {
221631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
222631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.disconnect(device);
223631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
224631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
225631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
226631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
227631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService == null) Log.w(TAG, "Proxy not attached to service");
228631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
229631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
230631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
231631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
232631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Get the list of connected devices. Currently at most one.
233631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
234631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return list of connected devices
235631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
236631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    @Override
237631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public List<BluetoothDevice> getConnectedDevices() {
238631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "getConnectedDevices()");
239631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled()) {
240631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
241631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.getConnectedDevices();
242631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
243631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
244631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return new ArrayList<>();
245631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
246631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
247631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService == null) Log.w(TAG, "Proxy not attached to service");
248631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return new ArrayList<>();
249631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
250631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
251631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
252631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Get the list of devices matching specified states. Currently at most one.
253631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
254631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return list of matching devices
255631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
256631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    @Override
257631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
258631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
259631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled()) {
260631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
261631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.getDevicesMatchingConnectionStates(states);
262631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
263631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
264631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return new ArrayList<>();
265631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
266631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
267631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService == null) Log.w(TAG, "Proxy not attached to service");
268631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return new ArrayList<>();
269631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
270631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
271631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
272631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Get connection state of device
273631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
274631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return device connection state
275631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
276631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    @Override
277631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public int getConnectionState(BluetoothDevice device) {
278631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
279631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled() &&
280631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                isValidDevice(device)) {
281631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
282631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.getConnectionState(device);
283631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
284631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
285631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return BluetoothProfile.STATE_DISCONNECTED;
286631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
287631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
288631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService == null) Log.w(TAG, "Proxy not attached to service");
289631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return BluetoothProfile.STATE_DISCONNECTED;
290631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
291631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
292631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
293631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Set priority of the profile
294631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
295631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * <p> The device should already be paired.  Priority can be one of {@link #PRIORITY_ON} or
296631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * {@link #PRIORITY_OFF},
297631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
298631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param device Paired bluetooth device
299631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return true if priority is set, false on error
300631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
301631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public boolean setPriority(BluetoothDevice device, int priority) {
302631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
303631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled() &&
304631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                isValidDevice(device)) {
305631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (priority != BluetoothProfile.PRIORITY_OFF &&
306631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    priority != BluetoothProfile.PRIORITY_ON) {
307631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return false;
308631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
309631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
310631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.setPriority(device, priority);
311631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
312631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
313631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return false;
314631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
315631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
316631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService == null) Log.w(TAG, "Proxy not attached to service");
317631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
318631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
319631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
320631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
321631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Get the priority of the profile.
322631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
323631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * <p> The priority can be any of:
324631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
325631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
326631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
327631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param device Bluetooth device
328631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return priority of the device
329631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
330631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public int getPriority(BluetoothDevice device) {
331631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
332631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled() &&
333631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                isValidDevice(device)) {
334631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
335631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.getPriority(device);
336631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
337631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
338631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return PRIORITY_OFF;
339631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
340631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
341631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService == null) Log.w(TAG, "Proxy not attached to service");
342631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return PRIORITY_OFF;
343631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
344631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
345631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
346631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Send a message.
347631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
348631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * Send an SMS message to either the contacts primary number or the telephone number specified.
349631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
350631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param device          Bluetooth device
351631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param contacts        Uri[] of the contacts
352631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param message         Message to be sent
353631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param sentIntent      intent issued when message is sent
354631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param deliveredIntent intent issued when message is delivered
355631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return true if the message is enqueued, false on error
356631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
357631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
358631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            PendingIntent sentIntent, PendingIntent deliveredIntent) {
359631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
360631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled() && isValidDevice(device)) {
361631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
362631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
363631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
364631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
365631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return false;
366631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
367631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
368631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
369631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
370631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
371631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    /**
372b8fc0679e84f9cadc08524ea89f6e1b28631f3e5Joseph Pirozzo     * Get unread messages.  Unread messages will be published via {@link #ACTION_MESSAGE_RECEIVED}.
373631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     *
374631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @param device Bluetooth device
375631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     * @return true if the message is enqueued, false on error
376631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo     */
377631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    public boolean getUnreadMessages(BluetoothDevice device) {
378631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
379631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (mService != null && isEnabled() && isValidDevice(device)) {
380631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            try {
381631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return mService.getUnreadMessages(device);
382631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            } catch (RemoteException e) {
383631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                Log.e(TAG, Log.getStackTraceString(new Throwable()));
384631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                return false;
385631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
386631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
387631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
388631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
389631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
390631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private final ServiceConnection mConnection = new ServiceConnection() {
391631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        public void onServiceConnected(ComponentName className, IBinder service) {
392631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (DBG) Log.d(TAG, "Proxy object connected");
393631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            mService = IBluetoothMapClient.Stub.asInterface(service);
394631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (mServiceListener != null) {
395631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT,
396631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                    BluetoothMapClient.this);
397631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
398631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
399631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
400631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        public void onServiceDisconnected(ComponentName className) {
401631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (DBG) Log.d(TAG, "Proxy object disconnected");
402631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            mService = null;
403631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            if (mServiceListener != null) {
404631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo                mServiceListener.onServiceDisconnected(BluetoothProfile.MAP_CLIENT);
405631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo            }
406631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        }
407631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    };
408631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
409631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private boolean isEnabled() {
410631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
411631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true;
412631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (DBG) Log.d(TAG, "Bluetooth is Not enabled");
413631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
414631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
415631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
416631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    private boolean isValidDevice(BluetoothDevice device) {
417631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (device == null) return false;
418631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
419631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
420631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo        return false;
421631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo    }
422631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
423631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo
424631768d81469f83552de05bf0ec839d1cd6eab04Joseph Pirozzo}
425