Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.contacts.util;
     18 
     19 import android.content.Context;
     20 import android.content.pm.PackageManager;
     21 import android.database.Cursor;
     22 import android.graphics.drawable.Drawable;
     23 import android.provider.ContactsContract.Data;
     24 import android.text.TextUtils;
     25 import android.text.format.DateUtils;
     26 
     27 import com.android.contacts.R;
     28 
     29 /**
     30  * Storage for a social status update. Holds a single update, but can use
     31  * {@link #possibleUpdate(Cursor)} to consider updating when a better status
     32  * exists. Statuses with timestamps, or with newer timestamps win.
     33  */
     34 public class DataStatus {
     35     private int mPresence = -1;
     36     private String mStatus = null;
     37     private long mTimestamp = -1;
     38 
     39     private String mResPackage = null;
     40     private int mIconRes = -1;
     41     private int mLabelRes = -1;
     42 
     43     public DataStatus() {
     44     }
     45 
     46     public DataStatus(Cursor cursor) {
     47         // When creating from cursor row, fill normally
     48         fromCursor(cursor);
     49     }
     50 
     51     /**
     52      * Attempt updating this {@link DataStatus} based on values at the
     53      * current row of the given {@link Cursor}.
     54      */
     55     public void possibleUpdate(Cursor cursor) {
     56         final boolean hasStatus = !isNull(cursor, Data.STATUS);
     57         final boolean hasTimestamp = !isNull(cursor, Data.STATUS_TIMESTAMP);
     58 
     59         // Bail early when not valid status, or when previous status was
     60         // found and we can't compare this one.
     61         if (!hasStatus) return;
     62         if (isValid() && !hasTimestamp) return;
     63 
     64         if (hasTimestamp) {
     65             // Compare timestamps and bail if older status
     66             final long newTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1);
     67             if (newTimestamp < mTimestamp) return;
     68 
     69             mTimestamp = newTimestamp;
     70         }
     71 
     72         // Fill in remaining details from cursor
     73         fromCursor(cursor);
     74     }
     75 
     76     private void fromCursor(Cursor cursor) {
     77         mPresence = getInt(cursor, Data.PRESENCE, -1);
     78         mStatus = getString(cursor, Data.STATUS);
     79         mTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1);
     80         mResPackage = getString(cursor, Data.STATUS_RES_PACKAGE);
     81         mIconRes = getInt(cursor, Data.STATUS_ICON, -1);
     82         mLabelRes = getInt(cursor, Data.STATUS_LABEL, -1);
     83     }
     84 
     85     public boolean isValid() {
     86         return !TextUtils.isEmpty(mStatus);
     87     }
     88 
     89     public int getPresence() {
     90         return mPresence;
     91     }
     92 
     93     public CharSequence getStatus() {
     94         return mStatus;
     95     }
     96 
     97     public long getTimestamp() {
     98         return mTimestamp;
     99     }
    100 
    101     /**
    102      * Build any timestamp and label into a single string.
    103      */
    104     public CharSequence getTimestampLabel(Context context) {
    105         final PackageManager pm = context.getPackageManager();
    106 
    107         // Use local package for resources when none requested
    108         if (mResPackage == null) mResPackage = context.getPackageName();
    109 
    110         final boolean validTimestamp = mTimestamp > 0;
    111         final boolean validLabel = mResPackage != null && mLabelRes != -1;
    112 
    113         final CharSequence timeClause = validTimestamp ? DateUtils.getRelativeTimeSpanString(
    114                 mTimestamp, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS,
    115                 DateUtils.FORMAT_ABBREV_RELATIVE) : null;
    116         final CharSequence labelClause = validLabel ? pm.getText(mResPackage, mLabelRes,
    117                 null) : null;
    118 
    119         if (validTimestamp && validLabel) {
    120             return context.getString(
    121                     R.string.contact_status_update_attribution_with_date,
    122                     timeClause, labelClause);
    123         } else if (validLabel) {
    124             return context.getString(
    125                     R.string.contact_status_update_attribution,
    126                     labelClause);
    127         } else if (validTimestamp) {
    128             return timeClause;
    129         } else {
    130             return null;
    131         }
    132     }
    133 
    134     public Drawable getIcon(Context context) {
    135         final PackageManager pm = context.getPackageManager();
    136 
    137         // Use local package for resources when none requested
    138         if (mResPackage == null) mResPackage = context.getPackageName();
    139 
    140         final boolean validIcon = mResPackage != null && mIconRes != -1;
    141         return validIcon ? pm.getDrawable(mResPackage, mIconRes, null) : null;
    142     }
    143 
    144     private static String getString(Cursor cursor, String columnName) {
    145         return cursor.getString(cursor.getColumnIndex(columnName));
    146     }
    147 
    148     private static int getInt(Cursor cursor, String columnName) {
    149         return cursor.getInt(cursor.getColumnIndex(columnName));
    150     }
    151 
    152     private static int getInt(Cursor cursor, String columnName, int missingValue) {
    153         final int columnIndex = cursor.getColumnIndex(columnName);
    154         return cursor.isNull(columnIndex) ? missingValue : cursor.getInt(columnIndex);
    155     }
    156 
    157     private static long getLong(Cursor cursor, String columnName, long missingValue) {
    158         final int columnIndex = cursor.getColumnIndex(columnName);
    159         return cursor.isNull(columnIndex) ? missingValue : cursor.getLong(columnIndex);
    160     }
    161 
    162     private static boolean isNull(Cursor cursor, String columnName) {
    163         return cursor.isNull(cursor.getColumnIndex(columnName));
    164     }
    165 }
    166