blob: 1aae276369dde2e18ecfd57513ca162c32c15248 [file] [log] [blame]
/************************************************************************************
*
* 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;
}
}