1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/* 2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License. 6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at 7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * 10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and 14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License. 15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth; 18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 1937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport android.app.ActivityManager; 206654f5c903de510a70f9e72cd5ad7837b615d93ffredcimport android.bluetooth.BluetoothAdapter; 2174ae04c73312403e89db0f8e9bd9601d403b4783fredcimport android.bluetooth.BluetoothDevice; 2237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport android.os.Binder; 23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.ParcelUuid; 2437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xuimport android.os.UserHandle; 25c7a57f31515107366589bd6875c3cc4af1fc806efredcimport android.util.Log; 26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 27c7a57f31515107366589bd6875c3cc4af1fc806efredcimport java.io.IOException; 28c7a57f31515107366589bd6875c3cc4af1fc806efredcimport java.io.InputStream; 29c7a57f31515107366589bd6875c3cc4af1fc806efredcimport java.io.OutputStream; 30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.nio.ByteBuffer; 31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.nio.ByteOrder; 32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport java.util.UUID; 33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/** 35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * @hide 36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal public class Utils { 39c7a57f31515107366589bd6875c3cc4af1fc806efredc private static final String TAG = "BluetoothUtils"; 40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int BD_ADDR_LEN = 6; // bytes 41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int BD_UUID_LEN = 16; // bytes 42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static String getAddressStringFromByte(byte[] address) { 446654f5c903de510a70f9e72cd5ad7837b615d93ffredc if (address == null || address.length !=6) { 456654f5c903de510a70f9e72cd5ad7837b615d93ffredc return null; 466654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 476654f5c903de510a70f9e72cd5ad7837b615d93ffredc 48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return String.format("%02X:%02X:%02X:%02X:%02X:%02X", 49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh address[0], address[1], address[2], address[3], address[4], 50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh address[5]); 51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 5374ae04c73312403e89db0f8e9bd9601d403b4783fredc public static byte[] getByteAddress(BluetoothDevice device) { 5474ae04c73312403e89db0f8e9bd9601d403b4783fredc return getBytesFromAddress(device.getAddress()); 5574ae04c73312403e89db0f8e9bd9601d403b4783fredc } 5674ae04c73312403e89db0f8e9bd9601d403b4783fredc 57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static byte[] getBytesFromAddress(String address) { 58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int i, j = 0; 59ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh byte[] output = new byte[BD_ADDR_LEN]; 60ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 61ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh for (i = 0; i < address.length();i++) { 62ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (address.charAt(i) != ':') { 63ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh output[j] = (byte) Integer.parseInt(address.substring(i, i+2), 16); 64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh j++; 65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh i++; 66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return output; 70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static int byteArrayToInt(byte[] valueBuf) { 73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return byteArrayToInt(valueBuf, 0); 74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static short byteArrayToShort(byte[] valueBuf) { 77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ByteBuffer converter = ByteBuffer.wrap(valueBuf); 78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.order(ByteOrder.nativeOrder()); 79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return converter.getShort(); 80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static int byteArrayToInt(byte[] valueBuf, int offset) { 83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ByteBuffer converter = ByteBuffer.wrap(valueBuf); 84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.order(ByteOrder.nativeOrder()); 85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return converter.getInt(offset); 86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static byte[] intToByteArray(int value) { 89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ByteBuffer converter = ByteBuffer.allocate(4); 90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.order(ByteOrder.nativeOrder()); 91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.putInt(value); 92ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return converter.array(); 93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 94ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 95cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie public static byte[] uuidToByteArray(ParcelUuid pUuid) { 96cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie int length = BD_UUID_LEN; 97cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie ByteBuffer converter = ByteBuffer.allocate(length); 98cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie converter.order(ByteOrder.BIG_ENDIAN); 99cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie long msb, lsb; 100cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie UUID uuid = pUuid.getUuid(); 101cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie msb = uuid.getMostSignificantBits(); 102cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie lsb = uuid.getLeastSignificantBits(); 103cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie converter.putLong(msb); 104cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie converter.putLong(8, lsb); 105cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie return converter.array(); 106cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie } 107cc80b2261351dc74ad1bed237b0423c12d340514Matthew Xie 108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static byte[] uuidsToByteArray(ParcelUuid[] uuids) { 109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int length = uuids.length * BD_UUID_LEN; 110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ByteBuffer converter = ByteBuffer.allocate(length); 111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.order(ByteOrder.BIG_ENDIAN); 112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh UUID uuid; 113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh long msb, lsb; 114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh for (int i = 0; i < uuids.length; i++) { 115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh uuid = uuids[i].getUuid(); 116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh msb = uuid.getMostSignificantBits(); 117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh lsb = uuid.getLeastSignificantBits(); 118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.putLong(i * 16, msb); 119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.putLong(i * 16 + 8, lsb); 120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return converter.array(); 122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public static ParcelUuid[] byteArrayToUuid(byte[] val) { 125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int numUuids = val.length/BD_UUID_LEN; 126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ParcelUuid[] puuids = new ParcelUuid[numUuids]; 127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh UUID uuid; 128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh int offset = 0; 129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh ByteBuffer converter = ByteBuffer.wrap(val); 131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.order(ByteOrder.BIG_ENDIAN); 132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh for (int i = 0; i < numUuids; i++) { 134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh puuids[i] = new ParcelUuid(new UUID(converter.getLong(offset), 135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh converter.getLong(offset + 8))); 136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh offset += 16; 137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return puuids; 139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 1406654f5c903de510a70f9e72cd5ad7837b615d93ffredc 1416654f5c903de510a70f9e72cd5ad7837b615d93ffredc public static String debugGetAdapterStateString(int state) { 1426654f5c903de510a70f9e72cd5ad7837b615d93ffredc switch (state) { 1436654f5c903de510a70f9e72cd5ad7837b615d93ffredc case BluetoothAdapter.STATE_OFF : return "STATE_OFF"; 1446654f5c903de510a70f9e72cd5ad7837b615d93ffredc case BluetoothAdapter.STATE_ON : return "STATE_ON"; 1456654f5c903de510a70f9e72cd5ad7837b615d93ffredc case BluetoothAdapter.STATE_TURNING_ON : return "STATE_TURNING_ON"; 1466654f5c903de510a70f9e72cd5ad7837b615d93ffredc case BluetoothAdapter.STATE_TURNING_OFF : return "STATE_TURNING_OFF"; 1476654f5c903de510a70f9e72cd5ad7837b615d93ffredc default : return "UNKNOWN"; 1486654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 1496654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 150c7a57f31515107366589bd6875c3cc4af1fc806efredc 151c7a57f31515107366589bd6875c3cc4af1fc806efredc public static void copyStream(InputStream is, OutputStream os, int bufferSize) throws IOException { 152c7a57f31515107366589bd6875c3cc4af1fc806efredc if (is != null && os!=null) { 153c7a57f31515107366589bd6875c3cc4af1fc806efredc byte[] buffer = new byte[bufferSize]; 154c7a57f31515107366589bd6875c3cc4af1fc806efredc int bytesRead=0; 155c7a57f31515107366589bd6875c3cc4af1fc806efredc while ( (bytesRead = is.read(buffer))>=0) { 156c7a57f31515107366589bd6875c3cc4af1fc806efredc os.write(buffer,0,bytesRead); 157c7a57f31515107366589bd6875c3cc4af1fc806efredc } 158c7a57f31515107366589bd6875c3cc4af1fc806efredc } 159c7a57f31515107366589bd6875c3cc4af1fc806efredc } 160c7a57f31515107366589bd6875c3cc4af1fc806efredc 161c7a57f31515107366589bd6875c3cc4af1fc806efredc public static void safeCloseStream(InputStream is) { 162c7a57f31515107366589bd6875c3cc4af1fc806efredc if (is != null) { 163c7a57f31515107366589bd6875c3cc4af1fc806efredc try { 164c7a57f31515107366589bd6875c3cc4af1fc806efredc is.close(); 165c7a57f31515107366589bd6875c3cc4af1fc806efredc } catch (Throwable t) { 166c7a57f31515107366589bd6875c3cc4af1fc806efredc Log.d(TAG,"Error closing stream",t); 167c7a57f31515107366589bd6875c3cc4af1fc806efredc } 168c7a57f31515107366589bd6875c3cc4af1fc806efredc } 169c7a57f31515107366589bd6875c3cc4af1fc806efredc } 170c7a57f31515107366589bd6875c3cc4af1fc806efredc 171c7a57f31515107366589bd6875c3cc4af1fc806efredc public static void safeCloseStream(OutputStream os) { 172c7a57f31515107366589bd6875c3cc4af1fc806efredc if (os != null) { 173c7a57f31515107366589bd6875c3cc4af1fc806efredc try { 174c7a57f31515107366589bd6875c3cc4af1fc806efredc os.close(); 175c7a57f31515107366589bd6875c3cc4af1fc806efredc } catch (Throwable t) { 176c7a57f31515107366589bd6875c3cc4af1fc806efredc Log.d(TAG,"Error closing stream",t); 177c7a57f31515107366589bd6875c3cc4af1fc806efredc } 178c7a57f31515107366589bd6875c3cc4af1fc806efredc } 179c7a57f31515107366589bd6875c3cc4af1fc806efredc } 18037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 18137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu public static boolean checkCaller() { 18237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu boolean ok; 18337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu // Get the caller's user id then clear the calling identity 18437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu // which will be restored in the finally clause. 18537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu int callingUser = UserHandle.getCallingUserId(); 18637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu long ident = Binder.clearCallingIdentity(); 18737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu 18837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu try { 18937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu // With calling identity cleared the current user is the foreground user. 19037510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu int foregroundUser = ActivityManager.getCurrentUser(); 19137510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu ok = (foregroundUser == callingUser); 19237510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } catch (Exception ex) { 19337510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Log.e(TAG,"checkIfCallerIsSelfOrForegroundUser: Exception ex=" + ex); 19437510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu ok = false; 19537510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } finally { 19637510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu Binder.restoreCallingIdentity(ident); 19737510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 19837510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu return ok; 19937510150ee738ccfa5913f7120e28f25ae7768dfZhihai Xu } 200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 201