15ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee/* 25ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Copyright (C) 2009 The Android Open Source Project 35ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 45ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); 55ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * you may not use this file except in compliance with the License. 65ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * You may obtain a copy of the License at 75ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 85ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * http://www.apache.org/licenses/LICENSE-2.0 95ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 105ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Unless required by applicable law or agreed to in writing, software 115ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * distributed under the License is distributed on an "AS IS" BASIS, 125ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * See the License for the specific language governing permissions and 145ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * limitations under the License. 155ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 165ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 175ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leepackage com.android.contacts.common.util; 185ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 195ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.content.Context; 205ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.content.pm.PackageManager; 215ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.database.Cursor; 225ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.graphics.drawable.Drawable; 235ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.provider.ContactsContract.Data; 245ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.text.TextUtils; 255ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.text.format.DateUtils; 265ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 275ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport com.android.contacts.common.R; 285ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 295ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee/** 305ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Storage for a social status update. Holds a single update, but can use 315ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * {@link #possibleUpdate(Cursor)} to consider updating when a better status 325ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * exists. Statuses with timestamps, or with newer timestamps win. 335ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 345ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leepublic class DataStatus { 355ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private int mPresence = -1; 365ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private String mStatus = null; 375ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private long mTimestamp = -1; 385ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 395ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private String mResPackage = null; 405ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private int mIconRes = -1; 415ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private int mLabelRes = -1; 425ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 435ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public DataStatus() { 445ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 455ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 465ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public DataStatus(Cursor cursor) { 475ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // When creating from cursor row, fill normally 485ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee fromCursor(cursor); 495ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 505ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 515ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 525ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Attempt updating this {@link DataStatus} based on values at the 535ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * current row of the given {@link Cursor}. 545ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 555ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public void possibleUpdate(Cursor cursor) { 565ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final boolean hasStatus = !isNull(cursor, Data.STATUS); 575ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final boolean hasTimestamp = !isNull(cursor, Data.STATUS_TIMESTAMP); 585ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 595ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // Bail early when not valid status, or when previous status was 605ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // found and we can't compare this one. 615ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!hasStatus) return; 625ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (isValid() && !hasTimestamp) return; 635ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 645ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (hasTimestamp) { 655ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // Compare timestamps and bail if older status 665ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final long newTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1); 675ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (newTimestamp < mTimestamp) return; 685ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 695ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mTimestamp = newTimestamp; 705ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 715ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 725ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // Fill in remaining details from cursor 735ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee fromCursor(cursor); 745ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 755ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 765ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private void fromCursor(Cursor cursor) { 775ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mPresence = getInt(cursor, Data.PRESENCE, -1); 785ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mStatus = getString(cursor, Data.STATUS); 795ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1); 805ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mResPackage = getString(cursor, Data.STATUS_RES_PACKAGE); 815ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mIconRes = getInt(cursor, Data.STATUS_ICON, -1); 825ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mLabelRes = getInt(cursor, Data.STATUS_LABEL, -1); 835ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 845ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 855ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public boolean isValid() { 865ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return !TextUtils.isEmpty(mStatus); 875ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 885ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 895ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public int getPresence() { 905ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return mPresence; 915ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 925ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 935ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public CharSequence getStatus() { 945ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return mStatus; 955ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 965ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 975ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public long getTimestamp() { 985ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return mTimestamp; 995ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1005ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1015ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 1025ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Build any timestamp and label into a single string. 1035ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 1045ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public CharSequence getTimestampLabel(Context context) { 1055ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final PackageManager pm = context.getPackageManager(); 1065ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1075ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // Use local package for resources when none requested 1085ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (mResPackage == null) mResPackage = context.getPackageName(); 1095ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1105ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final boolean validTimestamp = mTimestamp > 0; 1115ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final boolean validLabel = mResPackage != null && mLabelRes != -1; 1125ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1135ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final CharSequence timeClause = validTimestamp ? DateUtils.getRelativeTimeSpanString( 1145ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee mTimestamp, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, 1155ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee DateUtils.FORMAT_ABBREV_RELATIVE) : null; 1165ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final CharSequence labelClause = validLabel ? pm.getText(mResPackage, mLabelRes, 1175ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee null) : null; 1185ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1195ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (validTimestamp && validLabel) { 1205ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return context.getString( 1215ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee R.string.contact_status_update_attribution_with_date, 1225ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee timeClause, labelClause); 1235ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } else if (validLabel) { 1245ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return context.getString( 1255ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee R.string.contact_status_update_attribution, 1265ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee labelClause); 1275ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } else if (validTimestamp) { 1285ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return timeClause; 1295ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } else { 1305ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return null; 1315ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1325ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1335ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1345ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public Drawable getIcon(Context context) { 1355ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final PackageManager pm = context.getPackageManager(); 1365ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1375ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee // Use local package for resources when none requested 1385ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (mResPackage == null) mResPackage = context.getPackageName(); 1395ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1405ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final boolean validIcon = mResPackage != null && mIconRes != -1; 1415ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return validIcon ? pm.getDrawable(mResPackage, mIconRes, null) : null; 1425ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1435ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1445ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static String getString(Cursor cursor, String columnName) { 1455ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return cursor.getString(cursor.getColumnIndex(columnName)); 1465ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1475ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1485ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static int getInt(Cursor cursor, String columnName) { 1495ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return cursor.getInt(cursor.getColumnIndex(columnName)); 1505ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1515ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1525ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static int getInt(Cursor cursor, String columnName, int missingValue) { 1535ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final int columnIndex = cursor.getColumnIndex(columnName); 1545ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return cursor.isNull(columnIndex) ? missingValue : cursor.getInt(columnIndex); 1555ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1565ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1575ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static long getLong(Cursor cursor, String columnName, long missingValue) { 1585ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee final int columnIndex = cursor.getColumnIndex(columnName); 1595ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return cursor.isNull(columnIndex) ? missingValue : cursor.getLong(columnIndex); 1605ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1615ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1625ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static boolean isNull(Cursor cursor, String columnName) { 1635ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return cursor.isNull(cursor.getColumnIndex(columnName)); 1645ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1655ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee} 166