• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.bluetooth;
18 
19 import android.app.ActivityManager;
20 import android.bluetooth.BluetoothAdapter;
21 import android.bluetooth.BluetoothDevice;
22 import android.content.ContextWrapper;
23 import android.os.Binder;
24 import android.os.ParcelUuid;
25 import android.os.UserHandle;
26 import android.util.Log;
27 
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.nio.ByteBuffer;
32 import java.nio.ByteOrder;
33 import java.util.UUID;
34 import java.util.concurrent.TimeUnit;
35 
36 /**
37  * @hide
38  */
39 
40 final public class Utils {
41     private static final String TAG = "BluetoothUtils";
42     private static final int MICROS_PER_UNIT = 625;
43 
44     static final int BD_ADDR_LEN = 6; // bytes
45     static final int BD_UUID_LEN = 16; // bytes
46 
getAddressStringFromByte(byte[] address)47     public static String getAddressStringFromByte(byte[] address) {
48         if (address == null || address.length != BD_ADDR_LEN) {
49             return null;
50         }
51 
52         return String.format("%02X:%02X:%02X:%02X:%02X:%02X",
53                 address[0], address[1], address[2], address[3], address[4],
54                 address[5]);
55     }
56 
getByteAddress(BluetoothDevice device)57     public static byte[] getByteAddress(BluetoothDevice device) {
58         return getBytesFromAddress(device.getAddress());
59     }
60 
getBytesFromAddress(String address)61     public static byte[] getBytesFromAddress(String address) {
62         int i, j = 0;
63         byte[] output = new byte[BD_ADDR_LEN];
64 
65         for (i = 0; i < address.length(); i++) {
66             if (address.charAt(i) != ':') {
67                 output[j] = (byte) Integer.parseInt(address.substring(i, i + 2), BD_UUID_LEN);
68                 j++;
69                 i++;
70             }
71         }
72 
73         return output;
74     }
75 
byteArrayToInt(byte[] valueBuf)76     public static int byteArrayToInt(byte[] valueBuf) {
77         return byteArrayToInt(valueBuf, 0);
78     }
79 
byteArrayToShort(byte[] valueBuf)80     public static short byteArrayToShort(byte[] valueBuf) {
81         ByteBuffer converter = ByteBuffer.wrap(valueBuf);
82         converter.order(ByteOrder.nativeOrder());
83         return converter.getShort();
84     }
85 
byteArrayToInt(byte[] valueBuf, int offset)86     public static int byteArrayToInt(byte[] valueBuf, int offset) {
87         ByteBuffer converter = ByteBuffer.wrap(valueBuf);
88         converter.order(ByteOrder.nativeOrder());
89         return converter.getInt(offset);
90     }
91 
intToByteArray(int value)92     public static byte[] intToByteArray(int value) {
93         ByteBuffer converter = ByteBuffer.allocate(4);
94         converter.order(ByteOrder.nativeOrder());
95         converter.putInt(value);
96         return converter.array();
97     }
98 
uuidToByteArray(ParcelUuid pUuid)99     public static byte[] uuidToByteArray(ParcelUuid pUuid) {
100         int length = BD_UUID_LEN;
101         ByteBuffer converter = ByteBuffer.allocate(length);
102         converter.order(ByteOrder.BIG_ENDIAN);
103         long msb, lsb;
104         UUID uuid = pUuid.getUuid();
105         msb = uuid.getMostSignificantBits();
106         lsb = uuid.getLeastSignificantBits();
107         converter.putLong(msb);
108         converter.putLong(8, lsb);
109         return converter.array();
110     }
111 
uuidsToByteArray(ParcelUuid[] uuids)112     public static byte[] uuidsToByteArray(ParcelUuid[] uuids) {
113         int length = uuids.length * BD_UUID_LEN;
114         ByteBuffer converter = ByteBuffer.allocate(length);
115         converter.order(ByteOrder.BIG_ENDIAN);
116         UUID uuid;
117         long msb, lsb;
118         for (int i = 0; i < uuids.length; i++) {
119             uuid = uuids[i].getUuid();
120             msb = uuid.getMostSignificantBits();
121             lsb = uuid.getLeastSignificantBits();
122             converter.putLong(i * BD_UUID_LEN, msb);
123             converter.putLong(i * BD_UUID_LEN + 8, lsb);
124         }
125         return converter.array();
126     }
127 
byteArrayToUuid(byte[] val)128     public static ParcelUuid[] byteArrayToUuid(byte[] val) {
129         int numUuids = val.length / BD_UUID_LEN;
130         ParcelUuid[] puuids = new ParcelUuid[numUuids];
131         UUID uuid;
132         int offset = 0;
133 
134         ByteBuffer converter = ByteBuffer.wrap(val);
135         converter.order(ByteOrder.BIG_ENDIAN);
136 
137         for (int i = 0; i < numUuids; i++) {
138             puuids[i] = new ParcelUuid(new UUID(converter.getLong(offset),
139                     converter.getLong(offset + 8)));
140             offset += BD_UUID_LEN;
141         }
142         return puuids;
143     }
144 
debugGetAdapterStateString(int state)145     public static String debugGetAdapterStateString(int state) {
146         switch (state) {
147             case BluetoothAdapter.STATE_OFF:
148                 return "STATE_OFF";
149             case BluetoothAdapter.STATE_ON:
150                 return "STATE_ON";
151             case BluetoothAdapter.STATE_TURNING_ON:
152                 return "STATE_TURNING_ON";
153             case BluetoothAdapter.STATE_TURNING_OFF:
154                 return "STATE_TURNING_OFF";
155             default:
156                 return "UNKNOWN";
157         }
158     }
159 
copyStream(InputStream is, OutputStream os, int bufferSize)160     public static void copyStream(InputStream is, OutputStream os, int bufferSize)
161             throws IOException {
162         if (is != null && os != null) {
163             byte[] buffer = new byte[bufferSize];
164             int bytesRead = 0;
165             while ((bytesRead = is.read(buffer)) >= 0) {
166                 os.write(buffer, 0, bytesRead);
167             }
168         }
169     }
170 
safeCloseStream(InputStream is)171     public static void safeCloseStream(InputStream is) {
172         if (is != null) {
173             try {
174                 is.close();
175             } catch (Throwable t) {
176                 Log.d(TAG, "Error closing stream", t);
177             }
178         }
179     }
180 
safeCloseStream(OutputStream os)181     public static void safeCloseStream(OutputStream os) {
182         if (os != null) {
183             try {
184                 os.close();
185             } catch (Throwable t) {
186                 Log.d(TAG, "Error closing stream", t);
187             }
188         }
189     }
190 
checkCaller()191     public static boolean checkCaller() {
192         boolean ok;
193         // Get the caller's user id then clear the calling identity
194         // which will be restored in the finally clause.
195         int callingUser = UserHandle.getCallingUserId();
196         long ident = Binder.clearCallingIdentity();
197 
198         try {
199             // With calling identity cleared the current user is the foreground user.
200             int foregroundUser = ActivityManager.getCurrentUser();
201             ok = (foregroundUser == callingUser);
202         } catch (Exception ex) {
203             Log.e(TAG, "checkIfCallerIsSelfOrForegroundUser: Exception ex=" + ex);
204             ok = false;
205         } finally {
206             Binder.restoreCallingIdentity(ident);
207         }
208         return ok;
209     }
210 
211     /**
212      * Enforce the context has android.Manifest.permission.BLUETOOTH_ADMIN permission. A
213      * {@link SecurityException} would be thrown if neither the calling process or the application
214      * does not have BLUETOOTH_ADMIN permission.
215      *
216      * @param context Context for the permission check.
217      */
enforceAdminPermission(ContextWrapper context)218     public static void enforceAdminPermission(ContextWrapper context) {
219         context.enforceCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_ADMIN,
220                 "Need BLUETOOTH_ADMIN permission");
221     }
222 
223     /**
224      * Converts {@code millisecond} to unit. Each unit is 0.625 millisecond.
225      */
millsToUnit(int milliseconds)226     public static int millsToUnit(int milliseconds) {
227         return (int) (TimeUnit.MILLISECONDS.toMicros(milliseconds) / MICROS_PER_UNIT);
228     }
229 }
230