10c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng/*
20c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * Copyright (C) 2012 The Android Open Source Project
30c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng *
40c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
50c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * you may not use this file except in compliance with the License.
60c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * You may obtain a copy of the License at
70c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng *
80c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
90c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng *
100c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * Unless required by applicable law or agreed to in writing, software
110c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
120c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * See the License for the specific language governing permissions and
140c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * limitations under the License
150c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng */
160c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
170c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Chengpackage com.android.contacts.common;
180c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
197dfb24822010e130fa31612e5a488cbc4e9a798dYorke Leeimport com.google.i18n.phonenumbers.NumberParseException;
207dfb24822010e130fa31612e5a488cbc4e9a798dYorke Leeimport com.google.i18n.phonenumbers.PhoneNumberUtil;
21b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner
2263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.Context;
23d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Chengimport android.content.Intent;
2463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.graphics.Rect;
25d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Chengimport android.net.Uri;
260c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Chengimport android.provider.ContactsContract;
270c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Chengimport android.telephony.PhoneNumberUtils;
280c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Chengimport android.text.TextUtils;
2963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.view.View;
3063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.widget.TextView;
310c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
32d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Chengimport com.android.contacts.common.model.account.AccountType;
33d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng
340c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng/**
350c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng * Shared static contact utility methods.
360c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng */
370c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Chengpublic class MoreContactUtils {
380c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
39b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner    private static final String WAIT_SYMBOL_AS_STRING = String.valueOf(PhoneNumberUtils.WAIT);
40b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner
410c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng    /**
420c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng     * Returns true if two data with mimetypes which represent values in contact entries are
430c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng     * considered equal for collapsing in the GUI. For caller-id, use
440c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng     * {@link android.telephony.PhoneNumberUtils#compare(android.content.Context, String, String)}
450c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng     * instead
460c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng     */
470c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng    public static boolean shouldCollapse(CharSequence mimetype1, CharSequence data1,
48b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner              CharSequence mimetype2, CharSequence data2) {
490c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        // different mimetypes? don't collapse
500c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        if (!TextUtils.equals(mimetype1, mimetype2)) return false;
510c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
520c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        // exact same string? good, bail out early
530c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        if (TextUtils.equals(data1, data2)) return true;
540c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
550c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        // so if either is null, these two must be different
560c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        if (data1 == null || data2 == null) return false;
570c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
580c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        // if this is not about phone numbers, we know this is not a match (of course, some
590c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        // mimetypes could have more sophisticated matching is the future, e.g. addresses)
600c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        if (!TextUtils.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
610c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng                mimetype1)) {
620c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng            return false;
630c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        }
640c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
650c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        return shouldCollapsePhoneNumbers(data1.toString(), data2.toString());
660c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng    }
670c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
6845d8dd98608fe7dc65becf1b5e34e7ec8c097371Paul Soulos    // TODO: Move this to PhoneDataItem.shouldCollapse override
69b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner    private static boolean shouldCollapsePhoneNumbers(String number1, String number2) {
70b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        // Now do the full phone number thing. split into parts, separated by waiting symbol
71b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        // and compare them individually
72b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        final String[] dataParts1 = number1.split(WAIT_SYMBOL_AS_STRING);
73b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        final String[] dataParts2 = number2.split(WAIT_SYMBOL_AS_STRING);
74b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        if (dataParts1.length != dataParts2.length) return false;
75b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        final PhoneNumberUtil util = PhoneNumberUtil.getInstance();
76b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        for (int i = 0; i < dataParts1.length; i++) {
77b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            // Match phone numbers represented by keypad letters, in which case prefer the
78b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            // phone number with letters.
79b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            final String dataPart1 = PhoneNumberUtils.convertKeypadLettersToDigits(dataParts1[i]);
80b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            final String dataPart2 = dataParts2[i];
810c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
82b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            // substrings equal? shortcut, don't parse
83b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            if (TextUtils.equals(dataPart1, dataPart2)) continue;
840c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng
85b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            // do a full parse of the numbers
86939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng            final PhoneNumberUtil.MatchType result = util.isNumberMatch(dataPart1, dataPart2);
87939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng            switch (result) {
88b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                case NOT_A_NUMBER:
89b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    // don't understand the numbers? let's play it safe
90b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    return false;
91b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                case NO_MATCH:
92b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    return false;
93b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                case EXACT_MATCH:
94b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    break;
95b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                case NSN_MATCH:
96b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    try {
97b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                        // For NANP phone numbers, match when one has +1 and the other does not.
98b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                        // In this case, prefer the +1 version.
99b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                        if (util.parse(dataPart1, null).getCountryCode() == 1) {
100939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // At this point, the numbers can be either case 1 or 2 below....
101939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
102939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // case 1)
103939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // +14155551212    <--- country code 1
104939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //  14155551212    <--- 1 is trunk prefix, not country code
105939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
106939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // and
107939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
108939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // case 2)
109939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // +14155551212
110939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //   4155551212
111939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
112939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // From b/7519057, case 2 needs to be equal.  But also that bug, case 3
113939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // below should not be equal.
114939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
115939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // case 3)
116939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // 14155551212
117939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //  4155551212
118939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
119939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // So in order to make sure transitive equality is valid, case 1 cannot
120939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // be equal.  Otherwise, transitive equality breaks and the following
121939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // would all be collapsed:
122939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //   4155551212  |
123939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //  14155551212  |---->   +14155551212
124939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // +14155551212  |
125939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //
126939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // With transitive equality, the collapsed values should be:
127939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //   4155551212  |         14155551212
128939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            //  14155551212  |---->   +14155551212
129939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // +14155551212  |
130939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng
131939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // Distinguish between case 1 and 2 by checking for trunk prefix '1'
132939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // at the start of number 2.
133939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            if (dataPart2.trim().charAt(0) == '1') {
134939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                                // case 1
135939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                                return false;
136939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            }
137b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                            break;
138b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                        }
139b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    } catch (NumberParseException e) {
140939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // This is the case where the first number does not have a country code.
141939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // examples:
142939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // (123) 456-7890   &   123-456-7890  (collapse)
143939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // 0049 (8092) 1234   &   +49/80921234  (unit test says do not collapse)
144939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng
145939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // Check the second number.  If it also does not have a country code, then
146939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // we should collapse.  If it has a country code, then it's a different
147939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // number and we should not collapse (this conclusion is based on an
148939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        // existing unit test).
149939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        try {
150939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            util.parse(dataPart2, null);
151939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        } catch (NumberParseException e2) {
152939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            // Number 2 also does not have a country.  Collapse.
153939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                            break;
154939837d76f33abdd3b44ce986329293d808ed41cChiao Cheng                        }
155b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    }
156b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    return false;
157b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                case SHORT_NSN_MATCH:
158b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    return false;
159b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                default:
160b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                    throw new IllegalStateException("Unknown result value from phone number " +
161b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner                            "library");
162b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner            }
1630c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng        }
164b2c826a4c935a42f458ab187b257cd0b6a47bfb4Jay Shrauner        return true;
1650c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng    }
16663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
16763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
16863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns the {@link android.graphics.Rect} with left, top, right, and bottom coordinates
16963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * that are equivalent to the given {@link android.view.View}'s bounds. This is equivalent to
17063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * how the target {@link android.graphics.Rect} is calculated in
17163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * {@link android.provider.ContactsContract.QuickContact#showQuickContact}.
17263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
173039b4d46787bd06f2faeaac8c332459c86f3cffeYorke Lee    public static Rect getTargetRectFromView(View view) {
17463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        final int[] pos = new int[2];
17563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        view.getLocationOnScreen(pos);
17663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
17763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        final Rect rect = new Rect();
178039b4d46787bd06f2faeaac8c332459c86f3cffeYorke Lee        rect.left = pos[0];
179039b4d46787bd06f2faeaac8c332459c86f3cffeYorke Lee        rect.top = pos[1];
180039b4d46787bd06f2faeaac8c332459c86f3cffeYorke Lee        rect.right = pos[0] + view.getWidth();
181039b4d46787bd06f2faeaac8c332459c86f3cffeYorke Lee        rect.bottom = pos[1] + view.getHeight();
18263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        return rect;
18363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
18463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng
18563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    /**
18663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * Returns a header view based on the R.layout.list_separator, where the
18763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     * containing {@link android.widget.TextView} is set using the given textResourceId.
18863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng     */
1893c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    public static TextView createHeaderView(Context context, int textResourceId) {
1903c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        final TextView textView = (TextView) View.inflate(context, R.layout.list_separator, null);
19163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng        textView.setText(context.getString(textResourceId));
1923c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        return textView;
19363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng    }
194d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng
195d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng    /**
1963c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell     * Set the top padding on the header view dynamically, based on whether the header is in
1973c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell     * the first row or not.
1983c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell     */
1993c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    public static void setHeaderViewBottomPadding(Context context, TextView textView,
2003c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell            boolean isFirstRow) {
2013c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        final int topPadding;
2023c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        if (isFirstRow) {
2033c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell            topPadding = (int) context.getResources().getDimension(
2043c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell                    R.dimen.frequently_contacted_title_top_margin_when_first_row);
2053c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        } else {
2063c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell            topPadding = (int) context.getResources().getDimension(
2073c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell                    R.dimen.frequently_contacted_title_top_margin);
2083c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        }
2093c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell        textView.setPaddingRelative(textView.getPaddingStart(), topPadding,
2103c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell                textView.getPaddingEnd(), textView.getPaddingBottom());
2113c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    }
2123c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell
2133c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell
2143c4e8501b8fe4a6f508a256fd133004e1f1936a4Brian Attwell    /**
215d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng     * Returns the intent to launch for the given invitable account type and contact lookup URI.
216d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng     * This will return null if the account type is not invitable (i.e. there is no
217d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng     * {@link AccountType#getInviteContactActivityClassName()} or
218d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng     * {@link AccountType#syncAdapterPackageName}).
219d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng     */
220d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng    public static Intent getInvitableIntent(AccountType accountType, Uri lookupUri) {
221d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        String syncAdapterPackageName = accountType.syncAdapterPackageName;
222d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        String className = accountType.getInviteContactActivityClassName();
223d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        if (TextUtils.isEmpty(syncAdapterPackageName) || TextUtils.isEmpty(className)) {
224d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng            return null;
225d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        }
226d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        Intent intent = new Intent();
227d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        intent.setClassName(syncAdapterPackageName, className);
228d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng
229d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        intent.setAction(ContactsContract.Intents.INVITE_CONTACT);
230d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng
231d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        // Data is the lookup URI.
232d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        intent.setData(lookupUri);
233d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng        return intent;
234d305a6e633b7315cdd1ce4711c0d3a2b18b3c05fChiao Cheng    }
2350c355f691e91ff0d6dfd3765bf72b04cce8a1cebChiao Cheng}
236