Home | History | Annotate | Download | only in contacts
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * 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, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License
     15  */
     16 package com.android.providers.contacts;
     17 
     18 import android.content.ContentValues;
     19 import android.content.Context;
     20 import android.database.Cursor;
     21 import android.database.sqlite.SQLiteDatabase;
     22 import android.provider.ContactsContract.CommonDataKinds.Phone;
     23 import android.telephony.PhoneNumberUtils;
     24 import android.text.TextUtils;
     25 
     26 import com.android.providers.contacts.ContactsDatabaseHelper.PhoneLookupColumns;
     27 import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
     28 import com.android.providers.contacts.SearchIndexManager.IndexBuilder;
     29 import com.android.providers.contacts.aggregation.ContactAggregator;
     30 
     31 /**
     32  * Handler for phone number data rows.
     33  */
     34 public class DataRowHandlerForPhoneNumber extends DataRowHandlerForCommonDataKind {
     35 
     36     public DataRowHandlerForPhoneNumber(Context context,
     37             ContactsDatabaseHelper dbHelper, ContactAggregator aggregator) {
     38         super(context, dbHelper, aggregator, Phone.CONTENT_ITEM_TYPE, Phone.TYPE, Phone.LABEL);
     39     }
     40 
     41     @Override
     42     public long insert(SQLiteDatabase db, TransactionContext txContext, long rawContactId,
     43             ContentValues values) {
     44         fillNormalizedNumber(values);
     45 
     46         final long dataId = super.insert(db, txContext, rawContactId, values);
     47         if (values.containsKey(Phone.NUMBER)) {
     48             final String number = values.getAsString(Phone.NUMBER);
     49             final String normalizedNumber = values.getAsString(Phone.NORMALIZED_NUMBER);
     50             updatePhoneLookup(db, rawContactId, dataId, number, normalizedNumber);
     51             mContactAggregator.updateHasPhoneNumber(db, rawContactId);
     52             fixRawContactDisplayName(db, txContext, rawContactId);
     53 
     54             triggerAggregation(txContext, rawContactId);
     55         }
     56         return dataId;
     57     }
     58 
     59     @Override
     60     public boolean update(SQLiteDatabase db, TransactionContext txContext, ContentValues values,
     61             Cursor c, boolean callerIsSyncAdapter) {
     62         fillNormalizedNumber(values);
     63 
     64         if (!super.update(db, txContext, values, c, callerIsSyncAdapter)) {
     65             return false;
     66         }
     67 
     68         if (values.containsKey(Phone.NUMBER)) {
     69             long dataId = c.getLong(DataUpdateQuery._ID);
     70             long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID);
     71             updatePhoneLookup(db, rawContactId, dataId,
     72                     values.getAsString(Phone.NUMBER),
     73                     values.getAsString(Phone.NORMALIZED_NUMBER));
     74             mContactAggregator.updateHasPhoneNumber(db, rawContactId);
     75             fixRawContactDisplayName(db, txContext, rawContactId);
     76 
     77             triggerAggregation(txContext, rawContactId);
     78         }
     79 
     80         return true;
     81     }
     82 
     83     private void fillNormalizedNumber(ContentValues values) {
     84         // No NUMBER? Also ignore NORMALIZED_NUMBER
     85         if (!values.containsKey(Phone.NUMBER)) {
     86             values.remove(Phone.NORMALIZED_NUMBER);
     87             return;
     88         }
     89 
     90         // NUMBER is given. Try to extract NORMALIZED_NUMBER from it, unless it is also given
     91         final String number = values.getAsString(Phone.NUMBER);
     92         final String numberE164 = values.getAsString(Phone.NORMALIZED_NUMBER);
     93         if (number != null && numberE164 == null) {
     94             final String newNumberE164 = PhoneNumberUtils.formatNumberToE164(number,
     95                     mDbHelper.getCurrentCountryIso());
     96             values.put(Phone.NORMALIZED_NUMBER, newNumberE164);
     97         }
     98     }
     99 
    100     @Override
    101     public int delete(SQLiteDatabase db, TransactionContext txContext, Cursor c) {
    102         long dataId = c.getLong(DataDeleteQuery._ID);
    103         long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID);
    104 
    105         int count = super.delete(db, txContext, c);
    106 
    107         updatePhoneLookup(db, rawContactId, dataId, null, null);
    108         mContactAggregator.updateHasPhoneNumber(db, rawContactId);
    109         fixRawContactDisplayName(db, txContext, rawContactId);
    110         triggerAggregation(txContext, rawContactId);
    111         return count;
    112     }
    113 
    114     private void updatePhoneLookup(SQLiteDatabase db, long rawContactId, long dataId,
    115             String number, String numberE164) {
    116         mSelectionArgs1[0] = String.valueOf(dataId);
    117         db.delete(Tables.PHONE_LOOKUP, PhoneLookupColumns.DATA_ID + "=?", mSelectionArgs1);
    118         if (number != null) {
    119             String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
    120             if (!TextUtils.isEmpty(normalizedNumber)) {
    121                 ContentValues phoneValues = new ContentValues();
    122                 phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId);
    123                 phoneValues.put(PhoneLookupColumns.DATA_ID, dataId);
    124                 phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
    125                 phoneValues.put(PhoneLookupColumns.MIN_MATCH,
    126                         PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber));
    127                 db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
    128 
    129                 if (numberE164 != null && !numberE164.equals(normalizedNumber)) {
    130                     phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164);
    131                     phoneValues.put(PhoneLookupColumns.MIN_MATCH,
    132                             PhoneNumberUtils.toCallerIDMinMatch(numberE164));
    133                     db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
    134                 }
    135             }
    136         }
    137     }
    138 
    139     @Override
    140     protected int getTypeRank(int type) {
    141         switch (type) {
    142             case Phone.TYPE_MOBILE: return 0;
    143             case Phone.TYPE_WORK: return 1;
    144             case Phone.TYPE_HOME: return 2;
    145             case Phone.TYPE_PAGER: return 3;
    146             case Phone.TYPE_CUSTOM: return 4;
    147             case Phone.TYPE_OTHER: return 5;
    148             case Phone.TYPE_FAX_WORK: return 6;
    149             case Phone.TYPE_FAX_HOME: return 7;
    150             default: return 1000;
    151         }
    152     }
    153 
    154     @Override
    155     public boolean containsSearchableColumns(ContentValues values) {
    156         return values.containsKey(Phone.NUMBER);
    157     }
    158 
    159     @Override
    160     public void appendSearchableData(IndexBuilder builder) {
    161         String number = builder.getString(Phone.NUMBER);
    162         if (TextUtils.isEmpty(number)) {
    163             return;
    164         }
    165 
    166         String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
    167         if (TextUtils.isEmpty(normalizedNumber)) {
    168             return;
    169         }
    170 
    171         builder.appendToken(normalizedNumber);
    172 
    173         String numberE164 = PhoneNumberUtils.formatNumberToE164(
    174                 number, mDbHelper.getCurrentCountryIso());
    175         if (numberE164 != null && !numberE164.equals(normalizedNumber)) {
    176             builder.appendToken(numberE164);
    177         }
    178     }
    179 }
    180