| /************************************************************************************ |
| * |
| * Copyright (C) 2009-2012 Broadcom Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ************************************************************************************/ |
| package com.android.bluetooth.pbap; |
| |
| import android.content.Context; |
| import android.os.SystemProperties; |
| import android.util.Log; |
| |
| import com.android.bluetooth.Utils; |
| import com.android.bluetooth.pbap.BluetoothPbapService; |
| import com.android.vcard.VCardComposer; |
| import com.android.vcard.VCardConfig; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| |
| import android.content.Context; |
| import android.content.res.AssetFileDescriptor; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.provider.ContactsContract.Contacts; |
| import android.provider.ContactsContract.Profile; |
| import android.provider.ContactsContract.RawContactsEntity; |
| |
| |
| import com.android.vcard.VCardComposer; |
| import com.android.vcard.VCardConfig; |
| |
| |
| public class BluetoothPbapUtils { |
| |
| private static final String TAG = "FilterUtils"; |
| private static final boolean V = BluetoothPbapService.VERBOSE; |
| |
| public static int FILTER_PHOTO = 3; |
| public static int FILTER_TEL = 7; |
| public static int FILTER_NICKNAME = 23; |
| |
| public static boolean hasFilter(byte[] filter) { |
| return filter != null && filter.length > 0; |
| } |
| |
| public static boolean isNameAndNumberOnly(byte[] filter) { |
| // For vcard 2.0: VERSION,N,TEL is mandatory |
| // For vcard 3.0, VERSION,N,FN,TEL is mandatory |
| // So we only need to make sure that no other fields except optionally |
| // NICKNAME is set |
| |
| // Check that an explicit filter is not set. If not, this means |
| // return everything |
| if (!hasFilter(filter)) { |
| Log.v(TAG, "No filter set. isNameAndNumberOnly=false"); |
| return false; |
| } |
| |
| // Check bytes 0-4 are all 0 |
| for (int i = 0; i <= 4; i++) { |
| if (filter[i] != 0) { |
| return false; |
| } |
| } |
| // On byte 5, only BIT_NICKNAME can be set, so make sure |
| // rest of bits are not set |
| if ((filter[5] & 0x7F) > 0) { |
| return false; |
| } |
| |
| // Check byte 6 is not set |
| if (filter[6] != 0) { |
| return false; |
| } |
| |
| // Check if bit#3-6 is set. Return false if so. |
| if ((filter[7] & 0x78) > 0) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| public static boolean isFilterBitSet(byte[] filter, int filterBit) { |
| if (hasFilter(filter)) { |
| int byteNumber = 7 - filterBit / 8; |
| int bitNumber = filterBit % 8; |
| if (byteNumber < filter.length) { |
| return (filter[byteNumber] & (1 << bitNumber)) > 0; |
| } |
| } |
| return false; |
| } |
| |
| public static VCardComposer createFilteredVCardComposer(final Context ctx, |
| final int vcardType, final byte[] filter) { |
| int vType = vcardType; |
| /* |
| boolean isNameNumberOnly = isNameAndNumberOnly(filter); |
| if (isNameNumberOnly) { |
| if (V) |
| Log.v(TAG, "Creating Name/Number only VCardComposer..."); |
| vType |= VCardConfig.FLAG_NAME_NUMBER_ONLY_EXPORT; |
| } else { |
| */ |
| boolean includePhoto = BluetoothPbapConfig.includePhotosInVcard() |
| && (!hasFilter(filter) || isFilterBitSet(filter, FILTER_PHOTO)); |
| if (!includePhoto) { |
| if (V) Log.v(TAG, "Excluding images from VCardComposer..."); |
| vType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; |
| } |
| //} |
| return new VCardComposer(ctx, vType, true); |
| } |
| |
| public static boolean isProfileSet(Context context) { |
| Cursor c = context.getContentResolver().query( |
| Profile.CONTENT_VCARD_URI, new String[] { Profile._ID }, null, |
| null, null); |
| boolean isSet = (c != null && c.getCount() > 0); |
| if (c != null) { |
| c.close(); |
| } |
| return isSet; |
| } |
| |
| public static String getProfileName(Context context) { |
| Cursor c = context.getContentResolver().query( |
| Profile.CONTENT_URI, new String[] { Profile.DISPLAY_NAME}, null, |
| null, null); |
| String ownerName =null; |
| if (c!= null && c.moveToFirst()) { |
| ownerName = c.getString(0); |
| } |
| if (c != null) { |
| c.close(); |
| } |
| return ownerName; |
| } |
| public static final String createProfileVCard(Context ctx, final int vcardType,final byte[] filter) { |
| VCardComposer composer = null; |
| String vcard = null; |
| try { |
| composer = createFilteredVCardComposer(ctx, vcardType, filter); |
| if (composer |
| .init(Profile.CONTENT_URI, null, null, null, null, Uri |
| .withAppendedPath(Profile.CONTENT_URI, |
| RawContactsEntity.CONTENT_URI |
| .getLastPathSegment()))) { |
| vcard = composer.createOneEntry(); |
| } else { |
| Log.e(TAG, |
| "Unable to create profile vcard. Error initializing composer: " |
| + composer.getErrorReason()); |
| } |
| } catch (Throwable t) { |
| Log.e(TAG, "Unable to create profile vcard.", t); |
| } |
| if (composer != null) { |
| try { |
| composer.terminate(); |
| } catch (Throwable t) { |
| |
| } |
| } |
| return vcard; |
| } |
| |
| public static boolean createProfileVCardFile(File file, Context context) { |
| // File defaultFile = new |
| // File(OppApplicationConfig.OPP_OWNER_VCARD_PATH); |
| FileInputStream is = null; |
| FileOutputStream os = null; |
| boolean success = true; |
| try { |
| AssetFileDescriptor fd = context.getContentResolver() |
| .openAssetFileDescriptor(Profile.CONTENT_VCARD_URI, "r"); |
| |
| if(fd == null) |
| { |
| return false; |
| } |
| is = fd.createInputStream(); |
| os = new FileOutputStream(file); |
| Utils.copyStream(is, os, 200); |
| } catch (Throwable t) { |
| Log.e(TAG, "Unable to create default contact vcard file", t); |
| success = false; |
| } |
| Utils.safeCloseStream(is); |
| Utils.safeCloseStream(os); |
| return success; |
| } |
| } |