Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e55eacc authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Changing contact status to Presence-based

Change-Id: I35589e87f1e1743413d3f10509e9eccc333aa2fb
parent db9c3f2e
Loading
Loading
Loading
Loading
+65 −87
Original line number Diff line number Diff line
@@ -16,13 +16,14 @@

package com.android.internal.widget;

import com.android.internal.R;

import android.Manifest;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -31,13 +32,13 @@ import android.net.Uri;
import android.os.SystemClock;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Intents;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.Presence;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.SocialContract.Activities;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -47,8 +48,6 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.internal.R;

/**
 * Header used across system for displaying a title bar with contact info. You
 * can bind specific values on the header, or use helper methods like
@@ -68,6 +67,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
    private FasttrackBadgeWidget mPhotoView;
    private ImageView mPresenceView;
    private TextView mStatusView;
    private TextView mStatusDateView;
    private int mNoPhotoResource;
    private QueryHandler mQueryHandler;

@@ -87,31 +87,30 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList

    private ContactHeaderListener mListener;


    private interface ContactQuery {
        //Projection used for the summary info in the header.
    protected static final String[] HEADER_PROJECTION = new String[] {
        String[] COLUMNS = new String[] {
            Contacts._ID,
            Contacts.LOOKUP_KEY,
            Contacts.PHOTO_ID,
            Contacts.DISPLAY_NAME,
            Contacts.STARRED,
        Contacts.PHOTO_ID,
            Contacts.PRESENCE_STATUS,
        Contacts._ID,
        Contacts.LOOKUP_KEY,
            Contacts.PRESENCE_CUSTOM_STATUS,
            Contacts.PRESENCE_CUSTOM_STATUS_TIMESTAMP,
        };
    protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0;
        int _ID = 0;
        int LOOKUP_KEY = 1;
        int PHOTO_ID = 2;
        int DISPLAY_NAME = 3;
        //TODO: We need to figure out how we're going to get the phonetic name.
        //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX
    protected static final int HEADER_STARRED_COLUMN_INDEX = 1;
    protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2;
    protected static final int HEADER_PRESENCE_STATUS_COLUMN_INDEX = 3;
    protected static final int HEADER_CONTACT_ID_COLUMN_INDEX = 4;
    protected static final int HEADER_LOOKUP_KEY_COLUMN_INDEX = 5;

    //Projection used for finding the most recent social status.
    protected static final String[] SOCIAL_PROJECTION = new String[] {
        Activities.TITLE,
        Activities.PUBLISHED,
    };
    protected static final int SOCIAL_TITLE_COLUMN_INDEX = 0;
    protected static final int SOCIAL_PUBLISHED_COLUMN_INDEX = 1;
        int STARRED = 4;
        int PRESENCE_STATUS = 5;
        int PRESENCE_CUSTOM_STATUS = 6;
        int PRESENCE_CUSTOM_STATUS_TIMESTAMP = 7;
    }

    //Projection used for looking up contact id from phone number
    protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
@@ -135,10 +134,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
    protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0;

    private static final int TOKEN_CONTACT_INFO = 0;
    private static final int TOKEN_SOCIAL = 1;
    private static final int TOKEN_PHONE_LOOKUP = 2;
    private static final int TOKEN_EMAIL_LOOKUP = 3;
    private static final int TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY = 4;
    private static final int TOKEN_PHONE_LOOKUP = 1;
    private static final int TOKEN_EMAIL_LOOKUP = 2;

    public ContactHeaderWidget(Context context) {
        this(context, null);
@@ -171,7 +168,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
        mPresenceView = (ImageView) findViewById(R.id.presence);

        mStatusView = (TextView)findViewById(R.id.status);
        setSocialSnippet(null);
        mStatusDateView = (TextView)findViewById(R.id.status_date);

        // Set the photo with a random "no contact" image
        long now = SystemClock.elapsedRealtime();
@@ -229,11 +226,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
                        invalidate();
                        break;
                    }
                    case TOKEN_SOCIAL: {
                        bindSocial(cursor);
                        invalidate();
                        break;
                    }
                    case TOKEN_PHONE_LOOKUP: {
                        if (cursor != null && cursor.moveToFirst()) {
                            long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
@@ -260,13 +252,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
                        }
                        break;
                    }
                    case TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY: {
                        if (cursor != null && cursor.moveToFirst()) {
                            long contactId = cursor.getLong(CONTACT_LOOKUP_ID_COLUMN_INDEX);
                            startSocialQuery(ContentUris.withAppendedId(
                                    Activities.CONTENT_CONTACT_STATUS_URI, contactId));
                        }
                    }
                }
            } finally {
                if (cursor != null) {
@@ -370,11 +355,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
     */
    public void bindFromContactLookupUri(Uri contactLookupUri) {
        mContactUri = contactLookupUri;

        // Query for the contactId so we can do the social query.
        mQueryHandler.startQuery(TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY, null, contactLookupUri,
                CONTACT_LOOKUP_PROJECTION, null, null, null);

        startContactQuery(contactLookupUri);
    }

@@ -389,8 +369,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
        long contactId = ContentUris.parseId(contactUri);

        startContactQuery(contactUri);
        startSocialQuery(ContentUris.withAppendedId(
                Activities.CONTENT_CONTACT_STATUS_URI, contactId));
    }

    /**
@@ -421,13 +399,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
                PHONE_LOOKUP_PROJECTION, null, null, null);
    }

    private void startSocialQuery(Uri contactSocial) {
        mQueryHandler.startQuery(TOKEN_SOCIAL, null, contactSocial, SOCIAL_PROJECTION, null, null,
                null);
    }

    private void startContactQuery(Uri contactUri) {
        mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, HEADER_PROJECTION,
        mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, ContactQuery.COLUMNS,
                null, null, null);
    }

@@ -438,17 +411,17 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
        if (c == null || !c.moveToFirst()) return;

        // TODO: Bring back phonetic name
        final String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX);
        final long contactId = c.getLong(HEADER_CONTACT_ID_COLUMN_INDEX);
        final String lookupKey = c.getString(HEADER_LOOKUP_KEY_COLUMN_INDEX);
        final String displayName = c.getString(ContactQuery.DISPLAY_NAME);
        final long contactId = c.getLong(ContactQuery._ID);
        final String lookupKey = c.getString(ContactQuery.LOOKUP_KEY);
        final String phoneticName = null;
        this.setDisplayName(displayName, null);

        final boolean starred = c.getInt(HEADER_STARRED_COLUMN_INDEX) != 0;
        final boolean starred = c.getInt(ContactQuery.STARRED) != 0;
        mStarredView.setChecked(starred);

        //Set the photo
        Bitmap photoBitmap = loadContactPhoto(c.getLong(HEADER_PHOTO_ID_COLUMN_INDEX), null);
        Bitmap photoBitmap = loadContactPhoto(c.getLong(ContactQuery.PHOTO_ID), null);
        if (photoBitmap == null) {
            photoBitmap = loadPlaceholderPhoto(null);
        }
@@ -456,22 +429,39 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
        mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));

        //Set the presence status
        if (!c.isNull(HEADER_PRESENCE_STATUS_COLUMN_INDEX)) {
            int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX);
        if (!c.isNull(ContactQuery.PRESENCE_STATUS)) {
            int presence = c.getInt(ContactQuery.PRESENCE_STATUS);
            mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
            mPresenceView.setVisibility(View.VISIBLE);
        } else {
            mPresenceView.setVisibility(View.GONE);
        }

        //Set the status update
        String status = c.getString(ContactQuery.PRESENCE_CUSTOM_STATUS);
        if (!TextUtils.isEmpty(status)) {
            mStatusView.setText(status);
            mStatusView.setVisibility(View.VISIBLE);

            if (!c.isNull(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP)) {
                long date = c.getLong(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP);

                // Set the date/time field by mixing relative and absolute
                // times.
                int flags = DateUtils.FORMAT_ABBREV_RELATIVE;

                mStatusDateView.setText(DateUtils.getRelativeTimeSpanString(date, System
                        .currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, flags));
                mStatusDateView.setVisibility(View.VISIBLE);
            } else {
                mStatusDateView.setVisibility(View.GONE);
            }
        } else {
            mStatusView.setVisibility(View.GONE);
            mStatusDateView.setVisibility(View.GONE);
        }

    /**
     * Bind the social data provided by the given {@link Cursor}.
     */
    protected void bindSocial(Cursor c) {
        if (c == null || !c.moveToFirst()) return;
        final String status = c.getString(SOCIAL_TITLE_COLUMN_INDEX);
        this.setSocialSnippet(status);
        // TODO add support for status update source, e.g. "via Google Talk"
    }

    public void onClick(View view) {
@@ -497,18 +487,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
        }
    }

    private Rect getTargetRect(View anchor) {
        final int[] location = new int[2];
        anchor.getLocationOnScreen(location);

        final Rect rect = new Rect();
        rect.left = location[0];
        rect.top = location[1];
        rect.right = rect.left + anchor.getWidth();
        rect.bottom = rect.top + anchor.getHeight();
        return rect;
    }

    private Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) {
        Cursor photoCursor = null;
        Bitmap photoBm = null;
+12 −3
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1"

        android:orientation="vertical"
        android:layout_gravity="center_vertical" >

@@ -61,9 +60,19 @@
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:maxLines="2"
            android:ellipsize="end"/>
            android:maxLines="1"
            android:ellipsize="end"
            android:layout_marginTop="-4dip"
        />

        <TextView android:id="@+id/status_date"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textSize="12sp"
            android:layout_marginTop="-2dip"
        />
    </LinearLayout>

    <ImageView