DataStatus.java revision b7da2d0f30e012f786686bedea065af01f20a4e2
1624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey/*
2624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * Copyright (C) 2009 The Android Open Source Project
3624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey *
4624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * you may not use this file except in compliance with the License.
6624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * You may obtain a copy of the License at
7624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey *
8624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey *
10624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * See the License for the specific language governing permissions and
14624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * limitations under the License.
15624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey */
16624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
17624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeypackage com.android.contacts.util;
18624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
19624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.content.Context;
20624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.content.pm.PackageManager;
21624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.database.Cursor;
22624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.graphics.drawable.Drawable;
23624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.provider.ContactsContract.Data;
24624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.text.TextUtils;
25624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeyimport android.text.format.DateUtils;
26624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
27624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey/**
28624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * Storage for a social status update. Holds a single update, but can use
29624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * {@link #possibleUpdate(Cursor)} to consider updating when a better status
30624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey * exists. Statuses with timestamps, or with newer timestamps win.
31624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey */
32624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkeypublic class DataStatus {
33624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private int mPresence = -1;
34624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private String mStatus = null;
35624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private long mTimestamp = -1;
36624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
37624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private String mResPackage = null;
38624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private int mIconRes = -1;
39624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private int mLabelRes = -1;
40624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
41624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public DataStatus() {
42624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
43624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
44624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public DataStatus(Cursor cursor) {
45624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        // When creating from cursor row, fill normally
46624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        fromCursor(cursor);
47624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
48624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
49624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    /**
50624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey     * Attempt updating this {@link DataStatus} based on values at the
51624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey     * current row of the given {@link Cursor}.
52624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey     */
53624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public void possibleUpdate(Cursor cursor) {
54624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final boolean hasStatus = !isNull(cursor, Data.STATUS);
55624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final boolean hasTimestamp = !isNull(cursor, Data.STATUS_TIMESTAMP);
56624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
57624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        // Bail early when not valid status, or when previous status was
58624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        // found and we can't compare this one.
59624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        if (!hasStatus) return;
60624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        if (isValid() && !hasTimestamp) return;
61624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
62624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        if (hasTimestamp) {
63624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            // Compare timestamps and bail if older status
64624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            final long newTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1);
65624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            if (newTimestamp < mTimestamp) return;
66624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
67624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            mTimestamp = newTimestamp;
68624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        }
69624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
70624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        // Fill in remaining details from cursor
71624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        fromCursor(cursor);
72624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
73624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
74624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private void fromCursor(Cursor cursor) {
75624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        mPresence = getInt(cursor, Data.PRESENCE, -1);
76624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        mStatus = getString(cursor, Data.STATUS);
77624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        mTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1);
78624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        mResPackage = getString(cursor, Data.STATUS_RES_PACKAGE);
79624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        mIconRes = getInt(cursor, Data.STATUS_ICON, -1);
80624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        mLabelRes = getInt(cursor, Data.STATUS_LABEL, -1);
81624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
82624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
83624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public boolean isValid() {
84624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return !TextUtils.isEmpty(mStatus);
85624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
86624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
87624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public int getPresence() {
88624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return mPresence;
89624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
90624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
91624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public CharSequence getStatus() {
92624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return mStatus;
93624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
94624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
95624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    /**
96624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey     * Build any timestamp and label into a single string.
97624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey     */
98624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public CharSequence getTimestampLabel(Context context) {
99624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final PackageManager pm = context.getPackageManager();
100624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
101b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey        // Use local package for resources when none requested
102b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey        if (mResPackage == null) mResPackage = context.getPackageName();
103b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey
104624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final boolean validTimestamp = mTimestamp > 0;
105624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final boolean validLabel = mResPackage != null && mLabelRes != -1;
106624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
107624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final CharSequence timeClause = validTimestamp ? DateUtils.getRelativeTimeSpanString(
108624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                mTimestamp, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS,
109624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                DateUtils.FORMAT_ABBREV_RELATIVE) : null;
110624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final CharSequence labelClause = validLabel ? pm.getText(mResPackage, mLabelRes,
111624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                null) : null;
112624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
113624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        if (validTimestamp && validLabel) {
114624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            return context.getString(
115624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                    com.android.internal.R.string.contact_status_update_attribution_with_date,
116624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                    timeClause, labelClause);
117624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        } else if (validLabel) {
118624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            return context.getString(
119624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                    com.android.internal.R.string.contact_status_update_attribution,
120624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey                    labelClause);
121624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        } else if (validTimestamp) {
122624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            return timeClause;
123624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        } else {
124624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey            return null;
125624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        }
126624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
127624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
128624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    public Drawable getIcon(Context context) {
129624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final PackageManager pm = context.getPackageManager();
130b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey
131b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey        // Use local package for resources when none requested
132b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey        if (mResPackage == null) mResPackage = context.getPackageName();
133b7da2d0f30e012f786686bedea065af01f20a4e2Jeff Sharkey
134624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final boolean validIcon = mResPackage != null && mIconRes != -1;
135624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return validIcon ? pm.getDrawable(mResPackage, mIconRes, null) : null;
136624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
137624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
138624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private static String getString(Cursor cursor, String columnName) {
139624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return cursor.getString(cursor.getColumnIndex(columnName));
140624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
141624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
142624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private static int getInt(Cursor cursor, String columnName) {
143624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return cursor.getInt(cursor.getColumnIndex(columnName));
144624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
145624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
146624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private static int getInt(Cursor cursor, String columnName, int missingValue) {
147624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final int columnIndex = cursor.getColumnIndex(columnName);
148624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return cursor.isNull(columnIndex) ? missingValue : cursor.getInt(columnIndex);
149624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
150624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
151624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private static long getLong(Cursor cursor, String columnName, long missingValue) {
152624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        final int columnIndex = cursor.getColumnIndex(columnName);
153624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return cursor.isNull(columnIndex) ? missingValue : cursor.getLong(columnIndex);
154624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
155624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey
156624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    private static boolean isNull(Cursor cursor, String columnName) {
157624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey        return cursor.isNull(cursor.getColumnIndex(columnName));
158624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey    }
159624ddc3cce02e3d9216e87564766fd86e814675dJeff Sharkey}
160