BluetoothPbapUtils.java revision 6f1d727834316ee78c9c897965b254fa0316a065
1/************************************************************************************
2 *
3 *  Copyright (C) 2009-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ************************************************************************************/
18package com.android.bluetooth.pbap;
19
20import android.content.Context;
21import android.os.SystemProperties;
22import android.util.Log;
23
24import com.android.bluetooth.Utils;
25import com.android.bluetooth.pbap.BluetoothPbapService;
26import com.android.vcard.VCardComposer;
27import com.android.vcard.VCardConfig;
28
29import java.io.File;
30import java.io.FileInputStream;
31import java.io.FileOutputStream;
32
33import android.content.Context;
34import android.content.res.AssetFileDescriptor;
35import android.database.Cursor;
36import android.net.Uri;
37import android.provider.ContactsContract.Contacts;
38import android.provider.ContactsContract.Profile;
39import android.provider.ContactsContract.RawContactsEntity;
40
41
42import com.android.vcard.VCardComposer;
43import com.android.vcard.VCardConfig;
44
45
46public class BluetoothPbapUtils {
47
48    private static final String TAG = "FilterUtils";
49    private static final boolean V = BluetoothPbapService.VERBOSE;
50
51    public static int FILTER_PHOTO = 3;
52    public static int FILTER_TEL = 7;
53    public static int FILTER_NICKNAME = 23;
54
55    public static boolean hasFilter(byte[] filter) {
56        return filter != null && filter.length > 0;
57    }
58
59    public static boolean isNameAndNumberOnly(byte[] filter) {
60        // For vcard 2.0: VERSION,N,TEL is mandatory
61        // For vcard 3.0, VERSION,N,FN,TEL is mandatory
62        // So we only need to make sure that no other fields except optionally
63        // NICKNAME is set
64
65        // Check that an explicit filter is not set. If not, this means
66        // return everything
67        if (!hasFilter(filter)) {
68            Log.v(TAG, "No filter set. isNameAndNumberOnly=false");
69            return false;
70        }
71
72        // Check bytes 0-4 are all 0
73        for (int i = 0; i <= 4; i++) {
74            if (filter[i] != 0) {
75                return false;
76            }
77        }
78        // On byte 5, only BIT_NICKNAME can be set, so make sure
79        // rest of bits are not set
80        if ((filter[5] & 0x7F) > 0) {
81            return false;
82        }
83
84        // Check byte 6 is not set
85        if (filter[6] != 0) {
86            return false;
87        }
88
89        // Check if bit#3-6 is set. Return false if so.
90        if ((filter[7] & 0x78) > 0) {
91            return false;
92        }
93
94        return true;
95    }
96
97    public static boolean isFilterBitSet(byte[] filter, int filterBit) {
98        if (hasFilter(filter)) {
99            int byteNumber = 7 - filterBit / 8;
100            int bitNumber = filterBit % 8;
101            if (byteNumber < filter.length) {
102                return (filter[byteNumber] & (1 << bitNumber)) > 0;
103            }
104        }
105        return false;
106    }
107
108    public static VCardComposer createFilteredVCardComposer(final Context ctx,
109            final int vcardType, final byte[] filter) {
110        int vType = vcardType;
111        /*
112        boolean isNameNumberOnly = isNameAndNumberOnly(filter);
113        if (isNameNumberOnly) {
114            if (V)
115                Log.v(TAG, "Creating Name/Number only VCardComposer...");
116            vType |= VCardConfig.FLAG_NAME_NUMBER_ONLY_EXPORT;
117        } else {
118        */
119        boolean includePhoto = BluetoothPbapConfig.includePhotosInVcard()
120                    && (!hasFilter(filter) || isFilterBitSet(filter, FILTER_PHOTO));
121        if (!includePhoto) {
122            if (V) Log.v(TAG, "Excluding images from VCardComposer...");
123            vType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT;
124        }
125        //}
126        return new VCardComposer(ctx, vType, true);
127    }
128
129    public static boolean isProfileSet(Context context) {
130        Cursor c = context.getContentResolver().query(
131                Profile.CONTENT_VCARD_URI, new String[] { Profile._ID }, null,
132                null, null);
133        boolean isSet = (c != null && c.getCount() > 0);
134        if (c != null) {
135            c.close();
136            c = null;
137        }
138        return isSet;
139    }
140
141    public static String getProfileName(Context context) {
142        Cursor c = context.getContentResolver().query(
143                Profile.CONTENT_URI, new String[] { Profile.DISPLAY_NAME}, null,
144                null, null);
145        String ownerName =null;
146        if (c!= null && c.moveToFirst()) {
147            ownerName = c.getString(0);
148        }
149        if (c != null) {
150            c.close();
151            c = null;
152        }
153        return ownerName;
154    }
155    public static final String createProfileVCard(Context ctx, final int vcardType,final byte[] filter) {
156        VCardComposer composer = null;
157        String vcard = null;
158        try {
159            composer = createFilteredVCardComposer(ctx, vcardType, filter);
160            if (composer
161                    .init(Profile.CONTENT_URI, null, null, null, null, Uri
162                            .withAppendedPath(Profile.CONTENT_URI,
163                                    RawContactsEntity.CONTENT_URI
164                                            .getLastPathSegment()))) {
165                vcard = composer.createOneEntry();
166            } else {
167                Log.e(TAG,
168                        "Unable to create profile vcard. Error initializing composer: "
169                                + composer.getErrorReason());
170            }
171        } catch (Throwable t) {
172            Log.e(TAG, "Unable to create profile vcard.", t);
173        }
174        if (composer != null) {
175            try {
176                composer.terminate();
177            } catch (Throwable t) {
178
179            }
180        }
181        return vcard;
182    }
183
184    public static boolean createProfileVCardFile(File file, Context context) {
185        // File defaultFile = new
186        // File(OppApplicationConfig.OPP_OWNER_VCARD_PATH);
187        FileInputStream is = null;
188        FileOutputStream os = null;
189        boolean success = true;
190        try {
191            AssetFileDescriptor fd = context.getContentResolver()
192                    .openAssetFileDescriptor(Profile.CONTENT_VCARD_URI, "r");
193
194            if(fd == null)
195            {
196                return false;
197            }
198            is = fd.createInputStream();
199            os = new FileOutputStream(file);
200            Utils.copyStream(is, os, 200);
201        } catch (Throwable t) {
202            Log.e(TAG, "Unable to create default contact vcard file", t);
203            success = false;
204        }
205        Utils.safeCloseStream(is);
206        Utils.safeCloseStream(os);
207        return success;
208    }
209}
210