BluetoothDevice.java revision 32d8571f509c392dca732c243e9b2138c15daecf
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
2bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Copyright (C) 2009 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.bluetooth;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pellyimport android.annotation.SdkConstant;
20005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pellyimport android.annotation.SdkConstant.SdkConstantType;
21bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport android.content.Context;
22bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport android.os.IBinder;
23bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport android.os.Parcel;
24bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport android.os.Parcelable;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
26bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport android.os.ServiceManager;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellyimport java.io.IOException;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.UnsupportedEncodingException;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
33bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly * Represents a remote Bluetooth device.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>Use {@link BluetoothAdapter#getRemoteDevice} to create a {@link
3645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * BluetoothDevice}.
3745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly *
3845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * <p>This class is really just a thin wrapper for a Bluetooth hardware
3945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * address. Objects of this class are immutable. Operations on this class
4045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * are performed on the remote Bluetooth hardware address, using the
4145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * {@link BluetoothAdapter} that was used to create this {@link
4245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly * BluetoothDevice}.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
44bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pellypublic final class BluetoothDevice implements Parcelable {
45bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    private static final String TAG = "BluetoothDevice";
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly    /**
48b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly     * Sentinel error value for this class. Guaranteed to not equal any other
49b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly     * integer constant in this class. Provided as a convenience for functions
50b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly     * that require a sentinel error value, for example:
51005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
52005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * BluetoothDevice.ERROR)</code>
53005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
54005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final int ERROR = Integer.MIN_VALUE;
55005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
56005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
57005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Remote device discovered.
58005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Sent when a remote device is found during discovery.
59005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
60005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
61005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #EXTRA_RSSI} if they are available.
62005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
63005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
64005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     // TODO: Change API to not broadcast RSSI if not available (incoming connection)
65005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
66005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_FOUND =
67005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.FOUND";
68005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
69005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
70005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Remote device disappeared.
71005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Sent when a remote device that was found in the last discovery is not
72005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * found in the current discovery.
73005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
74005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
75005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @hide
76005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
77005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
78005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_DISAPPEARED =
79005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.DISAPPEARED";
80005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
81005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
82005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Bluetooth class of a remote device has changed.
83005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
84005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * #EXTRA_CLASS}.
85005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
86005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @see {@link BluetoothClass}
87005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
88005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
89005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_CLASS_CHANGED =
90005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.CLASS_CHANGED";
91005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
92005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
93005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Indicates a low level (ACL) connection has been
94005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * established with a remote device.
95005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
96005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>ACL connections are managed automatically by the Android Bluetooth
97005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * stack.
98005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
99005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
100005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
101005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_ACL_CONNECTED =
102005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.ACL_CONNECTED";
103005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
104005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
105005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Indicates that a low level (ACL) disconnection has
106005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * been requested for a remote device, and it will soon be disconnected.
107005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>This is useful for graceful disconnection. Applications should use
108005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * this intent as a hint to immediately terminate higher level connections
109005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * (RFCOMM, L2CAP, or profile connections) to the remote device.
110005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
111005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
112005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
113005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
114005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_ACL_DISCONNECT_REQUESTED =
115005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
116005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
117005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
118005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Indicates a low level (ACL) disconnection from a
119005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * remote device.
120005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
121005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>ACL connections are managed automatically by the Android Bluetooth
122005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * stack.
123005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
124005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
125005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
126005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_ACL_DISCONNECTED =
127005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.ACL_DISCONNECTED";
128005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
129005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
130005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Indicates the friendly name of a remote device has
131005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * been retrieved for the first time, or changed since the last retrieval.
132005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
133005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * #EXTRA_NAME}.
134005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
135005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
136005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
137005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_NAME_CHANGED =
138005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.NAME_CHANGED";
139005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
140005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
141005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Indicates a change in the bond state of a remote
142005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * device. For example, if a device is bonded (paired).
143005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
144005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
145005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
146005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
147005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
148005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    // contain a hidden extra field EXTRA_REASON with the result code.
149005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
150005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_BOND_STATE_CHANGED =
151005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.BOND_STATE_CHANGED";
152005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
153005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
154005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
155005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * broadcast by this class. It contains the {@link BluetoothDevice} that
156005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * the intent applies to.
157005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
158005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
159005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
160005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
161005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link
162005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * #ACTION_FOUND} intents. It contains the friendly Bluetooth name.
163005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
164005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
165005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
166005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
167005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Used as an optional short extra field in {@link #ACTION_FOUND} intents.
168005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Contains the RSSI value of the remote device as reported by the
169005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Bluetooth hardware.
170005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
171005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
172005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
173005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
174005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Used as an Parcelable {@link BluetoothClass} extra field in {@link
175005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
176005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
177005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
178005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
179005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
180005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
181005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Contains the bond state of the remote device.
182005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Possible values are:
183005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_NONE},
184005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_BONDING},
185005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_BONDED}.
186005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly      */
187005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
188005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
189005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
190005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Contains the previous bond state of the remote device.
191005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Possible values are:
192005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_NONE},
193005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_BONDING},
194005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_BONDED}.
195005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly      */
196005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_PREVIOUS_BOND_STATE =
197005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
198005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
199005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Indicates the remote device is not bonded (paired).
200005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>There is no shared link key with the remote device, so communication
201005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * (if it is allowed at all) will be unauthenticated and unencrypted.
202005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
203005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final int BOND_NONE = 10;
204005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
205005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Indicates bonding (pairing) is in progress with the remote device.
206005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
207005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final int BOND_BONDING = 11;
208005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
209005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Indicates the remote device is bonded (paired).
210005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>A shared link keys exists locally for the remote device, so
211005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * communication can be authenticated and encrypted.
212005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p><i>Being bonded (paired) with a remote device does not necessarily
213005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * mean the device is currently connected. It just means that the ponding
214005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * procedure was compeleted at some earlier time, and the link key is still
215005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * stored locally, ready to use on the next connection.
216005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * </i>
217005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
218005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final int BOND_BONDED = 12;
219005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
220005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /** @hide */
221005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
222005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /** @hide */
223005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_PAIRING_VARIANT =
224005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.extra.PAIRING_VARIANT";
225005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /** @hide */
226005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY";
227005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
228005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
229005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Broadcast Action: Indicates a failure to retrieve the name of a remote
230005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * device.
231005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
232005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
233005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @hide
234005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
235005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    //TODO: is this actually useful?
236005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
237005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_NAME_FAILED =
238005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.NAME_FAILED";
239005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
240005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /** @hide */
241005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
242005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_PAIRING_REQUEST =
243005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.PAIRING_REQUEST";
244005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /** @hide */
245005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
246005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public static final String ACTION_PAIRING_CANCEL =
247005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            "android.bluetooth.device.action.PAIRING_CANCEL";
248a4433af5ac677be7c1f63447c0cd78829bdee159Yue Lixin
249b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly    /** A bond attempt succeeded
250b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly     * @hide */
251b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly    public static final int BOND_SUCCESS = 0;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** A bond attempt failed because pins did not match, or remote device did
25332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh     * not respond to pin request in time
25445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int UNBOND_REASON_AUTH_FAILED = 1;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** A bond attempt failed because the other side explicilty rejected
25745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * bonding
25845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int UNBOND_REASON_AUTH_REJECTED = 2;
26045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** A bond attempt failed because we canceled the bonding process
26145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int UNBOND_REASON_AUTH_CANCELED = 3;
26345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** A bond attempt failed because we could not contact the remote device
26445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
26645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** A bond attempt failed because a discovery is in progress
26745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
26932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    /** A bond attempt failed because of authentication timeout
27032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh     * @hide */
27132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
27232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    /** A bond attempt failed because of repeated attempts
27332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh     * @hide */
27432d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
27545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** An existing bond was explicitly revoked
27645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
27732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    public static final int UNBOND_REASON_REMOVED = 8;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** The user will be prompted to enter a pin
28045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
281b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    public static final int PAIRING_VARIANT_PIN = 0;
28245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** The user will be prompted to enter a passkey
28345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
284b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    public static final int PAIRING_VARIANT_PASSKEY = 1;
28545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** The user will be prompted to confirm the passkey displayed on the screen
28645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide */
28732d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
28832d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    /** The user will be prompted to accept or deny the incoming pairing request
28932d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh     * @hide */
29032d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    public static final int PAIRING_VARIANT_CONSENT = 3;
29132d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    /** The user will be prompted to enter the passkey displayed on remote device
29232d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh     * @hide */
29332d8571f509c392dca732c243e9b2138c15daecfJaikumar Ganesh    public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
294b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
295bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
296bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
297bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    private final String mAddress;
298d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
300bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Create a new BluetoothDevice
301bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
302bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * and is validated in this constructor.
303bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @param address valid Bluetooth MAC address
304bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @throws RuntimeException Bluetooth is not available on this platform
305bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @throws IllegalArgumentException address is invalid
306bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @hide
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
308bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /*package*/ BluetoothDevice(String address) {
309bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        synchronized (BluetoothDevice.class) {
310bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            if (sService == null) {
311bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                IBinder b = ServiceManager.getService(Context.BLUETOOTH_SERVICE);
312bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                if (b == null) {
313bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                    throw new RuntimeException("Bluetooth service not available");
314bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                }
315bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly                sService = IBluetooth.Stub.asInterface(b);
316bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            }
317bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        }
318bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
319005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
320bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
321bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        }
322bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
323bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        mAddress = address;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
326bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    @Override
327bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean equals(Object o) {
328bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        if (o instanceof BluetoothDevice) {
329bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return mAddress.equals(((BluetoothDevice)o).getAddress());
330bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
334bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    @Override
335bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public int hashCode() {
336bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return mAddress.hashCode();
337105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
338105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
33945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /**
34045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * Returns a string representation of this BluetoothDevice.
34145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Currently this is the Bluetooth hardware address, for example
34245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
34345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * if you explicitly require the Bluetooth hardware address in case the
34445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * {@link #toString} representation changes in the future.
34545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @return string representation of this BluetoothDevice
34645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     */
347bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    @Override
348bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public String toString() {
349bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return mAddress;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
353bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public int describeContents() {
354bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return 0;
355bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    }
356bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
35745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
358bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public static final Parcelable.Creator<BluetoothDevice> CREATOR =
359bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            new Parcelable.Creator<BluetoothDevice>() {
360bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        public BluetoothDevice createFromParcel(Parcel in) {
361bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return new BluetoothDevice(in.readString());
362bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        }
363bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        public BluetoothDevice[] newArray(int size) {
364bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return new BluetoothDevice[size];
365bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        }
366bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    };
367bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
36845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
369bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public void writeToParcel(Parcel out, int flags) {
370bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        out.writeString(mAddress);
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /**
37445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * Returns the hardware address of this BluetoothDevice.
37545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p> For example, "00:11:22:AA:BB:CC".
37645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @return Bluetooth hardware address as string
37745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     */
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getAddress() {
379bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return mAddress;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
38345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * Get the friendly Bluetooth name of the remote device.
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
38545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>The local adapter will automatically retrieve remote names when
38645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * performing a device scan, and will cache them. This method just returns
38745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * the name for this device from the cache.
388de893f550301a60274e87aa8168225e7a7a42184Nick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the Bluetooth name, or null if there was a problem.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getName() {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
394bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.getRemoteName(mAddress);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
400005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Start the bonding (pairing) process with the remote device.
401005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>This is an asynchronous call, it will return immediately. Register
402005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
403005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * the bonding process completes, and its result.
404005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Android system services will handle the necessary user interactions
405005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * to confirm and complete the bonding process.
406005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
408005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @return false on immediate error, true if bonding will begin
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
410bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean createBond() {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
412bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.createBond(mAddress);
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
418005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Cancel an in-progress bonding request started with {@link #createBond}.
419005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
420005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     *
421005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @return true on sucess, false on error
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
423bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean cancelBondProcess() {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
425bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.cancelBondProcess(mAddress);
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
431005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Remove bond (pairing) with the remote device.
432005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Delete the link key associated with the remote device, and
433005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * immediately terminate connections to that device that require
434005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * authentication and encryption.
435005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
437005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @return true on sucess, false on error
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
439bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean removeBond() {
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
441bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.removeBond(mAddress);
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
443bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return false;
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
447005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Get the bond state of the remote device.
448005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Possible values for the bond state are:
449005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_NONE},
450005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_BONDING},
451005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * {@link #BOND_BONDED}.
452005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
454005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @return the bond state
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
456bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public int getBondState() {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
458bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.getBondState(mAddress);
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
460005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly        return BOND_NONE;
461005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    }
462005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly
463005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    /**
464005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * Get the Bluetooth class of the remote device.
465005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
466005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     *
467005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     * @return Bluetooth class object, or null on error
468005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly     */
469005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly    public BluetoothClass getBluetoothClass() {
470005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly        try {
471005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            int classInt = sService.getRemoteClass(mAddress);
472005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            if (classInt == BluetoothClass.ERROR) return null;
473005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly            return new BluetoothClass(classInt);
474005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly        } catch (RemoteException e) {Log.e(TAG, "", e);}
475005b228cdfb369d9b3b325884c0337ba5968bf8cNick Pelly        return null;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
478efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    /**
479efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     * Get trust state of a remote device.
480efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     * @hide
481efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     */
482efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    public boolean getTrustState() {
483efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        try {
484efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            return sService.getTrustState(mAddress);
485efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        } catch (RemoteException e) {
486efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            Log.e(TAG, "", e);
487efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        }
488efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        return false;
489efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    }
490efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
491efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    /**
492efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     * Set trust state for a remote device.
493efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     * @param value the trust state value (true or false)
494efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     * @hide
495efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue     */
496efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    public boolean setTrust(boolean value) {
497efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        try {
498efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            return sService.setTrust(mAddress, value);
499efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        } catch (RemoteException e) {
500efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue            Log.e(TAG, "", e);
501efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        }
502efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue        return false;
503efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue    }
504efa1dd716da3372cc74a201d11de5e0ef1a9fe9aLixin Yue
50545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
506bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     public String[] getUuids() {
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
508bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.getRemoteUuids(mAddress);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
512d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh
51345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
514bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public int getServiceChannel(String uuid) {
515d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         try {
516bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly             return sService.getRemoteServiceChannel(mAddress, uuid);
517d5ac1ae36b4e096eb97984334f86d0c68abea2f7Jaikumar Ganesh         } catch (RemoteException e) {Log.e(TAG, "", e);}
518b24e11baac589fe16426f2d243b460ab84991c7bNick Pelly         return BluetoothDevice.ERROR;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52145e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
522bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean setPin(byte[] pin) {
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
524bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.setPin(mAddress, pin);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
528b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
52945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
530bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean setPasskey(int passkey) {
531b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        try {
532bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.setPasskey(mAddress, passkey);
533b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        } catch (RemoteException e) {Log.e(TAG, "", e);}
534b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return false;
535b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
536b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
53745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
538bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean setPairingConfirmation(boolean confirm) {
539b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        try {
540bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.setPairingConfirmation(mAddress, confirm);
541b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        } catch (RemoteException e) {Log.e(TAG, "", e);}
542b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh        return false;
543b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh    }
544b0eca41de0bb6747d8648b134912782e45e4cbefJaikumar Ganesh
54545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    /** @hide */
546bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public boolean cancelPairingUserInput() {
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
548bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly            return sService.cancelPairingUserInput(mAddress);
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {Log.e(TAG, "", e);}
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
55445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
55545e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * outgoing connection to this remote device.
55645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>The remote device will be authenticated and communication on this
55745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * socket will be encrypted.
55845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
55945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * connection.
56045e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * <p>Valid RFCOMM channels are in range 1 to 30.
561cf44059813539bf7f36dabd278cef93ba3122c56Nick Pelly     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
562de893f550301a60274e87aa8168225e7a7a42184Nick Pelly     *
56345e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @param channel RFCOMM channel to connect to
56445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
565bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @throws IOException on error, for example Bluetooth not available, or
56645e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     *                     insufficient permissions
567bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     */
56845e2704ff512d41e22af2801d76e96955469ce8dNick Pelly    public BluetoothSocket createRfcommSocket(int channel) throws IOException {
56945e2704ff512d41e22af2801d76e96955469ce8dNick Pelly        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel);
570bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    }
571bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
572bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /**
573bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Construct an insecure RFCOMM socket ready to start an outgoing
574bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * connection.
575bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Call #connect on the returned #BluetoothSocket to begin the connection.
576bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * The remote device will not be authenticated and communication on this
577bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * socket will not be encrypted.
578bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @param port    remote port
579bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @return An RFCOMM BluetoothSocket
580bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @throws IOException On error, for example Bluetooth not available, or
581bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     *                     insufficient permissions.
58245e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide
583bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     */
584bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
585bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port);
586bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    }
587bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
588bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /**
589bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Construct a SCO socket ready to start an outgoing connection.
590bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * Call #connect on the returned #BluetoothSocket to begin the connection.
591bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @return a SCO BluetoothSocket
592bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     * @throws IOException on error, for example Bluetooth not available, or
593bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     *                     insufficient permissions.
59445e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide
595bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly     */
596bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    public BluetoothSocket createScoSocket() throws IOException {
597bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly        return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1);
598bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    }
599bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly
600bd022f423a33f0794bb53e5b0720da2d67e4631cNick Pelly    /**
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Check that a pin is valid and convert to byte array.
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bluetooth pin's are 1 to 16 bytes of UTF8 characters.
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pin pin as java String
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the pin code as a UTF8 byte array, or null if it is an invalid
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         Bluetooth pin.
60745e2704ff512d41e22af2801d76e96955469ce8dNick Pelly     * @hide
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static byte[] convertPinToBytes(String pin) {
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pin == null) {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        byte[] pinBytes;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pinBytes = pin.getBytes("UTF8");
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (UnsupportedEncodingException uee) {
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "UTF8 not supported?!?");  // this should not happen
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pinBytes.length <= 0 || pinBytes.length > 16) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return pinBytes;
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
627