1 /* 2 * Copyright (c) 2015, Motorola Mobility LLC 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * - Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * - Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * - Neither the name of Motorola Mobility nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 26 * DAMAGE. 27 */ 28 29 package com.android.service.ims.presence; 30 31 import java.io.FileNotFoundException; 32 33 import android.content.ContentUris; 34 import android.content.ContentValues; 35 import android.content.Intent; 36 import android.content.UriMatcher; 37 import android.database.Cursor; 38 import android.database.SQLException; 39 import android.database.sqlite.SQLiteDatabase; 40 import android.database.sqlite.SQLiteQueryBuilder; 41 import android.net.Uri; 42 import android.os.ParcelFileDescriptor; 43 import android.provider.BaseColumns; 44 import android.provider.ContactsContract.Contacts; 45 import android.content.ComponentName; 46 47 import com.android.ims.internal.ContactNumberUtils; 48 import com.android.ims.RcsPresenceInfo; 49 import com.android.ims.internal.EABContract; 50 import com.android.ims.internal.Logger; 51 52 /** 53 * @author Vishal Patil (A22809) 54 */ 55 56 public class EABProvider extends DatabaseContentProvider{ 57 private Logger logger = Logger.getLogger(this.getClass().getName()); 58 59 private static final String EAB_DB_NAME = "rcseab.db"; 60 61 private static final int EAB_DB_VERSION = 4; 62 63 private static final int EAB_TABLE = 1; 64 65 private static final int EAB_TABLE_ID = 2; 66 67 private static final int EAB_GROUPITEMS_TABLE = 3; 68 69 private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH) { 70 { 71 addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME, EAB_TABLE); 72 addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME + "/#", EAB_TABLE_ID); 73 addURI(EABContract.AUTHORITY, EABContract.EABColumns.GROUPITEMS_NAME, 74 EAB_GROUPITEMS_TABLE); 75 } 76 }; 77 78 /* Statement to create VMM Album table. */ 79 private static final String EAB_CREATE_STATEMENT = "create table if not exists " 80 + EABContract.EABColumns.TABLE_NAME 81 + "(" 82 + EABContract.EABColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " 83 + EABContract.EABColumns.CONTACT_NAME + " TEXT, " 84 + EABContract.EABColumns.CONTACT_NUMBER + " TEXT, " 85 + EABContract.EABColumns.RAW_CONTACT_ID + " LONG, " 86 + EABContract.EABColumns.CONTACT_ID + " LONG, " 87 + EABContract.EABColumns.DATA_ID + " LONG, " 88 + EABContract.EABColumns.ACCOUNT_TYPE + " TEXT, " 89 + EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, " 90 + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " INTEGER, " 91 + EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP + " LONG, " 92 + EABContract.EABColumns.VOLTE_CALL_AVAILABILITY + " INTEGER, " 93 + EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP + " LONG, " 94 + EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, " 95 + EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " INTEGER, " 96 + EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP + " LONG, " 97 + EABContract.EABColumns.VIDEO_CALL_AVAILABILITY + " INTEGER, " 98 + EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP + " LONG, " 99 + EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP + " LONG " 100 + ");"; 101 102 private static final String EAB_DROP_STATEMENT = "drop table if exists " 103 + EABContract.EABColumns.TABLE_NAME + ";"; 104 EABProvider()105 public EABProvider() { 106 super(EAB_DB_NAME, EAB_DB_VERSION); 107 } 108 109 @Override bootstrapDatabase(SQLiteDatabase db)110 public void bootstrapDatabase(SQLiteDatabase db) { 111 logger.info("Enter: bootstrapDatabase() Creating new EAB database"); 112 upgradeDatabase(db, 0, EAB_DB_VERSION); 113 logger.debug("Exit: bootstrapDatabase()"); 114 } 115 116 /* 117 * In upgradeDatabase, 118 * oldVersion - the current version of Provider on the phone. 119 * newVersion - the version of Provider where the phone will be upgraded to. 120 */ 121 @Override upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion)122 public boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) { 123 logger.info("Enter: upgradeDatabase() - oldVersion = " + oldVersion + 124 " newVersion = " + newVersion); 125 126 boolean needsEabResetBroadcast = false; 127 128 if (oldVersion == newVersion) { 129 logger.info("upgradeDatabase oldVersion == newVersion, No Upgrade Required"); 130 return true; 131 } 132 133 try { 134 if (oldVersion == 0) { 135 db.execSQL(EAB_CREATE_STATEMENT); 136 137 oldVersion++; 138 logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion); 139 } 140 if (oldVersion == 1) { 141 addColumn(db, EABContract.EABColumns.TABLE_NAME, 142 EABContract.EABColumns.VOLTE_STATUS, "INTEGER NOT NULL DEFAULT -1"); 143 144 oldVersion++; 145 logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion); 146 } 147 if (oldVersion == 2) { 148 // Add new column to EABPresence table to handle special numbers *67 and *82. 149 addColumn(db, EABContract.EABColumns.TABLE_NAME, 150 EABContract.EABColumns.FORMATTED_NUMBER, "TEXT DEFAULT NULL"); 151 152 // Delete all records from EABPresence table. 153 db.execSQL("DELETE FROM " + EABContract.EABColumns.TABLE_NAME); 154 needsEabResetBroadcast = true; 155 156 oldVersion++; 157 logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion); 158 } 159 if (oldVersion == 3) { 160 // Delete all records from EABPresence table. A bug in the previous version caused 161 // invalid rows to be created. This version removes all rows to allow the DB to 162 // repopulate. 163 db.execSQL("DELETE FROM " + EABContract.EABColumns.TABLE_NAME); 164 needsEabResetBroadcast = true; 165 166 oldVersion++; 167 logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion); 168 } 169 // add further upgrade code above this 170 } catch (SQLException exception) { 171 logger.error("Exception during upgradeDatabase. " + exception.getMessage()); 172 // If exception occured during upgrade database, then drop EABPresence 173 // and recreate it. Please note in this case, all information stored in 174 // table is lost. 175 db.execSQL(EAB_DROP_STATEMENT); 176 upgradeDatabase(db, 0, EAB_DB_VERSION); 177 needsEabResetBroadcast = true; 178 logger.debug("Dropped and created new EABPresence table."); 179 } 180 181 if (needsEabResetBroadcast) { 182 sendEabResetBroadcast(); 183 } 184 185 if (oldVersion == newVersion) { 186 logger.debug("DB upgrade complete : to " + newVersion); 187 } 188 189 logger.debug("Exit: upgradeDatabase()"); 190 return true; 191 } 192 193 @Override downgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion)194 protected boolean downgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) { 195 logger.info("Enter: downgradeDatabase()"); 196 // Drop and recreate EABPresence table as there should not be a scenario 197 // where EAB table version is greater than EAB_DB_VERSION. 198 db.execSQL(EAB_DROP_STATEMENT); 199 upgradeDatabase(db, 0, EAB_DB_VERSION); 200 sendEabResetBroadcast(); 201 logger.debug("Dropped and created new EABPresence table."); 202 logger.debug("Exit: downgradeDatabase()"); 203 return true; 204 } 205 206 @Override deleteInternal(SQLiteDatabase db, Uri uri, String selection, String[] selectionArgs)207 protected int deleteInternal(SQLiteDatabase db, Uri uri, String selection, 208 String[] selectionArgs) { 209 logger.debug("Enter: deleteInternal()"); 210 final int match = URI_MATCHER.match(uri); 211 String table = null; 212 switch (match) { 213 case EAB_TABLE_ID: 214 if (selection == null) { 215 selection = "_id=?"; 216 selectionArgs = new String[] {uri.getPathSegments().get(1)}; 217 } 218 case EAB_TABLE: 219 table = EABContract.EABColumns.TABLE_NAME; 220 break; 221 default: 222 logger.debug("No match for " + uri); 223 logger.debug("Exit: deleteInternal()"); 224 return 0; 225 } 226 logger.debug("Deleting from the table" + table + " selection= " + selection); 227 printDeletingValues(uri, selection, selectionArgs); 228 logger.debug("Exit: deleteInternal()"); 229 return db.delete(table, selection, selectionArgs); 230 } 231 232 @Override insertInternal(SQLiteDatabase db, Uri uri, ContentValues values)233 protected Uri insertInternal(SQLiteDatabase db, Uri uri, ContentValues values) { 234 logger.debug("Enter: insertInternal()"); 235 final int match = URI_MATCHER.match(uri); 236 String table = null; 237 String nullColumnHack = null; 238 switch (match) { 239 case EAB_TABLE: 240 table = EABContract.EABColumns.TABLE_NAME; 241 break; 242 default: 243 logger.warn("No match for " + uri); 244 logger.debug("Exit: insertInternal() with null"); 245 return null; 246 } 247 values = verifyIfMdnExists(values); 248 // Do the insert. 249 logger.debug("Inserting to the table" + table + " values=" + values.toString()); 250 251 final long id = db.insert(table, nullColumnHack, values); 252 if (id > 0) { 253 String contactNumber = values.getAsString(EABContract.EABColumns.CONTACT_NUMBER); 254 sendInsertBroadcast(contactNumber); 255 logger.debug("Exit: insertInternal()"); 256 return ContentUris.withAppendedId(uri, id); 257 } else { 258 logger.debug("Exit: insertInternal() with null"); 259 return null; 260 } 261 } 262 263 @Override queryInternal(SQLiteDatabase db, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)264 protected Cursor queryInternal(SQLiteDatabase db, Uri uri, String[] projection, 265 String selection, String[] selectionArgs, String sortOrder) { 266 logger.debug("Enter: queryInternal()"); 267 final int match = URI_MATCHER.match(uri); 268 269 switch (match) { 270 case EAB_TABLE_ID: 271 long id = ContentUris.parseId(uri); 272 logger.debug("queryInternal id=" + id); 273 String idSelection = BaseColumns._ID + "=" + id; 274 if(null != selection) { 275 selection = "((" + idSelection + ") AND (" + selection + "))"; 276 } else { 277 selection = idSelection; 278 } 279 break; 280 case EAB_GROUPITEMS_TABLE: 281 SQLiteQueryBuilder sqb = new SQLiteQueryBuilder(); 282 sqb.setTables(EABContract.EABColumns.TABLE_NAME); 283 String rawquery = "select DISTINCT " + EABContract.EABColumns.CONTACT_ID 284 + " from " + EABContract.EABColumns.TABLE_NAME 285 + " where " + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " >'" + 286 RcsPresenceInfo.ServiceState.OFFLINE+"' AND " 287 + EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " >'" 288 + RcsPresenceInfo.ServiceState.OFFLINE + "'"; 289 StringBuffer sb = new StringBuffer(); 290 Cursor cursor = db.rawQuery(rawquery, null); 291 if (cursor != null && cursor.moveToFirst()) { 292 do { 293 if (sb.length() != 0) sb.append(","); 294 String contactId = cursor.getString(cursor 295 .getColumnIndex(EABContract.EABColumns.CONTACT_ID)); 296 sb.append(contactId); 297 } while (cursor.moveToNext()); 298 } 299 if (cursor != null) cursor.close(); 300 String contactSel = Contacts._ID + " IN ( " + sb.toString() + ")"; 301 return getContext().getContentResolver().query(Contacts.CONTENT_URI, projection, 302 contactSel, null, sortOrder); 303 } 304 305 SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 306 307 String groupBy = uri.getQueryParameter("groupby"); 308 String having = null; 309 310 switch (match) { 311 case EAB_TABLE: 312 case EAB_TABLE_ID: 313 qb.setTables(EABContract.EABColumns.TABLE_NAME); 314 break; 315 default: 316 logger.warn("No match for " + uri); 317 logger.debug("Exit: queryInternal()"); 318 return null; 319 } 320 logger.debug("Exit: queryInternal()"); 321 return qb.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder); 322 } 323 324 @Override updateInternal(SQLiteDatabase db, Uri uri, ContentValues values, String selection, String[] selectionArgs)325 protected int updateInternal(SQLiteDatabase db, Uri uri, ContentValues values, 326 String selection, String[] selectionArgs) { 327 logger.debug("Enter: updateInternal()"); 328 int result = 0; 329 final int match = URI_MATCHER.match(uri); 330 331 switch (match) { 332 case EAB_TABLE_ID: 333 long id = ContentUris.parseId(uri); 334 logger.debug("updateInternal id=" + id); 335 String idSelection = BaseColumns._ID + "=" + id; 336 if(null != selection){ 337 selection = "((" + idSelection + ") AND (" + selection + "))"; 338 } else { 339 selection = idSelection; 340 } 341 break; 342 } 343 344 String table = null; 345 switch (match) { 346 case EAB_TABLE: 347 case EAB_TABLE_ID: 348 table = EABContract.EABColumns.TABLE_NAME; 349 break; 350 default: 351 logger.warn("No match for " + uri); 352 break; 353 } 354 355 if (table != null && values != null) { 356 logger.debug("Updating the table " + table + " values= " + values.toString()); 357 result = db.update(table, values, selection, selectionArgs); 358 } 359 logger.debug("Exit: updateInternal()"); 360 return result; 361 } 362 363 @Override getType(Uri uri)364 public String getType(Uri uri) { 365 logger.debug("Enter: getType()"); 366 final int match = URI_MATCHER.match(uri); 367 switch (match) { 368 case EAB_TABLE: 369 return EABContract.EABColumns.CONTENT_TYPE; 370 case EAB_TABLE_ID: 371 return EABContract.EABColumns.CONTENT_ITEM_TYPE; 372 default: 373 throw (new IllegalArgumentException("EABProvider URI: " + uri)); 374 } 375 } 376 377 @Override openFile(Uri uri, String mode)378 public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 379 return null; 380 } 381 sendInsertBroadcast(String contactNumber)382 private void sendInsertBroadcast(String contactNumber) { 383 Intent intent = new Intent(com.android.service.ims.presence.Contacts 384 .ACTION_NEW_CONTACT_INSERTED); 385 ComponentName component = new ComponentName("com.android.service.ims.presence", 386 "com.android.service.ims.presence.AlarmBroadcastReceiver"); 387 intent.setComponent(component); 388 389 intent.putExtra(com.android.service.ims.presence.Contacts.NEW_PHONE_NUMBER, contactNumber); 390 getContext().sendBroadcast(intent); 391 } 392 sendEabResetBroadcast()393 private void sendEabResetBroadcast() { 394 logger.info("Enter: sendEabResetBroadcast()"); 395 Intent intent = new Intent(com.android.service.ims.presence.Contacts 396 .ACTION_EAB_DATABASE_RESET); 397 getContext().sendBroadcast(intent, "com.android.ims.permission.PRESENCE_ACCESS"); 398 } 399 verifyIfMdnExists(ContentValues cvalues)400 private ContentValues verifyIfMdnExists(ContentValues cvalues) { 401 String formattedNumber = null; 402 String phoneNumber = null; 403 if (cvalues.containsKey(EABContract.EABColumns.CONTACT_NUMBER) 404 && cvalues.containsKey(EABContract.EABColumns.FORMATTED_NUMBER)) { 405 phoneNumber = cvalues.getAsString(EABContract.EABColumns.CONTACT_NUMBER); 406 formattedNumber = cvalues.getAsString(EABContract.EABColumns.FORMATTED_NUMBER); 407 } else { 408 return cvalues; 409 } 410 if (null == formattedNumber) { 411 return cvalues; 412 } 413 String[] projection = new String[] { 414 EABContract.EABColumns.FORMATTED_NUMBER, 415 EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS, 416 EABContract.EABColumns.VOLTE_CALL_CAPABILITY, 417 EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP, 418 EABContract.EABColumns.VOLTE_CALL_AVAILABILITY, 419 EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP, 420 EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS, 421 EABContract.EABColumns.VIDEO_CALL_CAPABILITY, 422 EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP, 423 EABContract.EABColumns.VIDEO_CALL_AVAILABILITY, 424 EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP}; 425 String whereClause = "PHONE_NUMBERS_EQUAL(" 426 + EABContract.EABColumns.FORMATTED_NUMBER + ", ?, 0)"; 427 String[] selectionArgs = new String[] { formattedNumber }; 428 Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI, 429 projection, whereClause, selectionArgs, null); 430 if ((null != cursor) && (cursor.getCount() > 0)) { 431 logger.debug("Cursor count is " + cursor.getCount()); 432 // Update data only from first valid cursor element. 433 while (cursor.moveToNext()) { 434 ContactNumberUtils contactNumberUtils = ContactNumberUtils.getDefault(); 435 String eabFormattedNumber = cursor.getString( 436 cursor.getColumnIndex(EABContract.EABColumns.FORMATTED_NUMBER)); 437 438 // Use contactNumberUtils.format() to format both formattedNumber and 439 // eabFormattedNumber and then check if they are equal. 440 if(contactNumberUtils.format(formattedNumber).equals( 441 contactNumberUtils.format(eabFormattedNumber))) { 442 logger.debug("phoneNumber : "+ phoneNumber +" is already stored in EAB DB. " 443 + " Hence inserting another copy."); 444 cvalues.put(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS, 445 cursor.getString(cursor.getColumnIndex( 446 EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS))); 447 cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY, cursor.getString( 448 cursor.getColumnIndex( 449 EABContract.EABColumns.VOLTE_CALL_CAPABILITY))); 450 cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP, 451 cursor.getLong(cursor.getColumnIndex( 452 EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP))); 453 cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY, 454 cursor.getString(cursor.getColumnIndex( 455 EABContract.EABColumns.VOLTE_CALL_AVAILABILITY))); 456 cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP, 457 cursor.getLong(cursor.getColumnIndex( 458 EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP))); 459 cvalues.put(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS, 460 cursor.getString(cursor.getColumnIndex( 461 EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS))); 462 cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY, 463 cursor.getString(cursor.getColumnIndex( 464 EABContract.EABColumns.VIDEO_CALL_CAPABILITY))); 465 cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP, 466 cursor.getLong(cursor.getColumnIndex( 467 EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP))); 468 cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY, 469 cursor.getString(cursor.getColumnIndex( 470 EABContract.EABColumns.VIDEO_CALL_AVAILABILITY))); 471 cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP, 472 cursor.getLong(cursor.getColumnIndex( 473 EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP))); 474 cvalues.put(EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP, 0); 475 break; 476 } 477 } 478 } 479 if (null != cursor) { 480 cursor.close(); 481 } 482 return cvalues; 483 } 484 printDeletingValues(Uri uri, String selection, String[] selectionArgs)485 private void printDeletingValues(Uri uri, String selection, String[] selectionArgs) { 486 String[] projection = new String[] { 487 EABContract.EABColumns.CONTACT_NUMBER, 488 EABContract.EABColumns.CONTACT_NAME, 489 EABContract.EABColumns.RAW_CONTACT_ID, 490 EABContract.EABColumns.CONTACT_ID, 491 EABContract.EABColumns.DATA_ID}; 492 Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI, 493 projection, selection, selectionArgs, null); 494 if ((null != cursor) && (cursor.getCount() > 0)) { 495 logger.debug("Before deleting the cursor count is " + cursor.getCount()); 496 // Update data only from first cursor element. 497 while (cursor.moveToNext()) { 498 long dataId = cursor.getLong(cursor.getColumnIndex( 499 EABContract.EABColumns.DATA_ID)); 500 long contactId = cursor.getLong(cursor.getColumnIndex( 501 EABContract.EABColumns.CONTACT_ID)); 502 long rawContactId = cursor.getLong(cursor.getColumnIndex( 503 EABContract.EABColumns.RAW_CONTACT_ID)); 504 String phoneNumber = cursor.getString(cursor.getColumnIndex( 505 EABContract.EABColumns.CONTACT_NUMBER)); 506 String displayName = cursor.getString(cursor.getColumnIndex( 507 EABContract.EABColumns.CONTACT_NAME)); 508 logger.debug("Deleting : dataId : " + dataId + " contactId :" + contactId + 509 " rawContactId :" + rawContactId + " phoneNumber :" + phoneNumber + 510 " displayName :" + displayName); 511 } 512 } else { 513 logger.error("cursor is null!"); 514 } 515 if (null != cursor) { 516 cursor.close(); 517 } 518 } 519 } 520