blob: f2676150390e026e3e367e3633b7a409d398074b [file] [log] [blame]
Yorke Lee2644d942013-10-28 11:05:43 -07001/*
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
Gary Mai69c182a2016-12-05 13:07:03 -080017package com.android.contacts.util;
Yorke Lee2644d942013-10-28 11:05:43 -070018
19import android.content.Context;
20import android.content.pm.PackageManager;
21import android.database.Cursor;
22import android.graphics.drawable.Drawable;
23import android.provider.ContactsContract.Data;
24import android.text.TextUtils;
25import android.text.format.DateUtils;
26
Arthur Wang3f6a2442016-12-05 14:51:59 -080027import com.android.contacts.R;
Yorke Lee2644d942013-10-28 11:05:43 -070028
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 */
34public 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}