19e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn/*
29e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * Copyright (C) 2015 The Android Open Source Project
39e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn *
49e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * Licensed under the Apache License, Version 2.0 (the "License");
59e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * you may not use this file except in compliance with the License.
69e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * You may obtain a copy of the License at
79e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn *
89e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn *      http://www.apache.org/licenses/LICENSE-2.0
99e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn *
109e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * Unless required by applicable law or agreed to in writing, software
119e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * distributed under the License is distributed on an "AS IS" BASIS,
129e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * See the License for the specific language governing permissions and
149e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn * limitations under the License
159e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn */
169e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1769c182afb0e6d82a341a28b4317aa703af768906Gary Maipackage com.android.contacts.dialog;
189e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport android.animation.Animator;
2096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport android.animation.AnimatorListenerAdapter;
219e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.app.Activity;
229e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.content.Context;
239e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.content.Intent;
24a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunnimport android.content.SharedPreferences;
259e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.net.Uri;
269e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.os.Bundle;
27a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunnimport android.preference.PreferenceManager;
289467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunnimport android.telecom.PhoneAccount;
299e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.telecom.PhoneAccountHandle;
309e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.telecom.TelecomManager;
319e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.text.Editable;
32a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunnimport android.text.InputFilter;
339e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.text.TextUtils;
349e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.text.TextWatcher;
359e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.util.Log;
369e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.view.View;
379e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.view.ViewGroup;
3896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport android.view.ViewTreeObserver;
39a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunnimport android.view.inputmethod.InputMethodManager;
4096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport android.widget.AdapterView;
4196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport android.widget.ArrayAdapter;
429e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.widget.EditText;
4396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport android.widget.ListView;
449e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.widget.QuickContactBadge;
459e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunnimport android.widget.TextView;
469e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
470a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.CallUtil;
480a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.ContactPhotoManager;
493f6a2444e0134b7380cdb2e13abf4bf1163336d0Arthur Wangimport com.android.contacts.R;
5069c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.compat.CompatUtils;
5169c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.compat.PhoneAccountSdkCompat;
5269c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.compat.telecom.TelecomManagerCompat;
5369c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.util.UriUtils;
5496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnimport com.android.phone.common.animation.AnimUtils;
559e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
569467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunnimport java.nio.charset.Charset;
57a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunnimport java.util.ArrayList;
58a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunnimport java.util.List;
59a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
609e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn/**
6196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn * Implements a dialog which prompts for a call subject for an outgoing call.  The dialog includes
6296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn * a pop up list of historical call subjects.
639e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn */
6496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunnpublic class CallSubjectDialog extends Activity {
659e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private static final String TAG = "CallSubjectDialog";
669e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private static final int CALL_SUBJECT_LIMIT = 16;
67a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    private static final int CALL_SUBJECT_HISTORY_SIZE = 5;
68a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
69a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    private static final int REQUEST_SUBJECT = 1001;
70a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
71a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String PREF_KEY_SUBJECT_HISTORY_COUNT = "subject_history_count";
72a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String PREF_KEY_SUBJECT_HISTORY_ITEM = "subject_history_item";
739e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
749e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
7596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * Activity intent argument bundle keys:
769e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
77a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_PHOTO_ID = "PHOTO_ID";
78a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_PHOTO_URI = "PHOTO_URI";
79a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_CONTACT_URI = "CONTACT_URI";
80a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_NAME_OR_NUMBER = "NAME_OR_NUMBER";
81a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_IS_BUSINESS = "IS_BUSINESS";
82a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_NUMBER = "NUMBER";
83a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_DISPLAY_NUMBER = "DISPLAY_NUMBER";
84a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_NUMBER_LABEL = "NUMBER_LABEL";
85a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static final String ARG_PHONE_ACCOUNT_HANDLE = "PHONE_ACCOUNT_HANDLE";
869e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
8796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private int mAnimationDuration;
889467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn    private Charset mMessageEncoding;
8996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private View mBackgroundView;
9096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private View mDialogView;
919e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private QuickContactBadge mContactPhoto;
929e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private TextView mNameView;
939e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private TextView mNumberView;
949e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private EditText mCallSubjectView;
959e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private TextView mCharacterLimitView;
969e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private View mHistoryButton;
979e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private View mSendAndCallButton;
9896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private ListView mSubjectList;
999e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1009e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private int mLimit = CALL_SUBJECT_LIMIT;
1019e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private int mPhotoSize;
102a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    private SharedPreferences mPrefs;
103a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    private List<String> mSubjectHistory;
1049e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1059e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private long mPhotoID;
1069e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private Uri mPhotoUri;
1079e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private Uri mContactUri;
1089e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private String mNameOrNumber;
1099e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private boolean mIsBusiness;
1109e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private String mNumber;
1119e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private String mDisplayNumber;
1129e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private String mNumberLabel;
1139e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private PhoneAccountHandle mPhoneAccountHandle;
1149e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1159e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
1169e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Handles changes to the text in the subject box.  Ensures the character limit is updated.
1179e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
1189e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private final TextWatcher mTextWatcher = new TextWatcher() {
1199e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        @Override
1209e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
1219e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            // no-op
1229e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
1239e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1249e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        @Override
1259e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        public void onTextChanged(CharSequence s, int start, int before, int count) {
1269e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            updateCharacterLimit();
1279e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
1289e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1299e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        @Override
1309e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        public void afterTextChanged(Editable s) {
1319e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            // no-op
1329e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
1339e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    };
1349e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1359e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
13696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * Click listener which handles user clicks outside of the dialog.
13796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     */
13896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private View.OnClickListener mBackgroundListener = new View.OnClickListener() {
13996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        @Override
14096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        public void onClick(View v) {
14196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            finish();
14296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        }
14396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    };
14496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
14596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    /**
1469e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Handles displaying the list of past call subjects.
1479e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
1489e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private final View.OnClickListener mHistoryOnClickListener = new View.OnClickListener() {
1499e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        @Override
1509e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        public void onClick(View v) {
15196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            hideSoftKeyboard(CallSubjectDialog.this, mCallSubjectView);
15296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            showCallHistory(mSubjectList.getVisibility() == View.GONE);
1539e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
1549e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    };
1559e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1569e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
1579e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Handles starting a call with a call subject specified.
1589e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
1599e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private final View.OnClickListener mSendAndCallOnClickListener = new View.OnClickListener() {
1609e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        @Override
1619e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        public void onClick(View v) {
162a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            String subject = mCallSubjectView.getText().toString();
1639e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            Intent intent = CallUtil.getCallWithSubjectIntent(mNumber, mPhoneAccountHandle,
164a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                    subject);
1659e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
16678384189dc0d1e60379947ce9f878f80045f7e6cNancy Chen            TelecomManagerCompat.placeCall(
16778384189dc0d1e60379947ce9f878f80045f7e6cNancy Chen                    CallSubjectDialog.this,
16878384189dc0d1e60379947ce9f878f80045f7e6cNancy Chen                    (TelecomManager) getSystemService(Context.TELECOM_SERVICE),
16978384189dc0d1e60379947ce9f878f80045f7e6cNancy Chen                    intent);
170a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
171a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            mSubjectHistory.add(subject);
172a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            saveSubjectHistory(mSubjectHistory);
17396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            finish();
1749e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
1759e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    };
1769e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
1779e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
17896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * Handles auto-hiding the call history when user clicks in the call subject field to give it
17996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * focus.
18096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     */
18196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private final View.OnClickListener mCallSubjectClickListener = new View.OnClickListener() {
18296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        @Override
18396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        public void onClick(View v) {
18496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            if (mSubjectList.getVisibility() == View.VISIBLE) {
18596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                showCallHistory(false);
18696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            }
18796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        }
18896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    };
18996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
19096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    /**
19196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * Item click listener which handles user clicks on the items in the list view.  Dismisses
19296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * the activity, returning the subject to the caller and closing the activity with the
19396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * {@link Activity#RESULT_OK} result code.
19496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     */
19596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private AdapterView.OnItemClickListener mItemClickListener =
19696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            new AdapterView.OnItemClickListener() {
19796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                @Override
19896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
19996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    mCallSubjectView.setText(mSubjectHistory.get(position));
20096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    showCallHistory(false);
20196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                }
20296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            };
20396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
20496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    /**
20504538afa5f1e7968811ba014de0b9a39fa20d3f9Nancy Chen     * Show the call subject dialog given a phone number to dial (e.g. from the dialpad).
206a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     *
207a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @param activity The activity.
208a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @param number The number to dial.
209a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     */
210a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static void start(Activity activity, String number) {
211a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        start(activity,
212a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                -1 /* photoId */,
213a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                null /* photoUri */,
214a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                null /* contactUri */,
215a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                number /* nameOrNumber */,
216a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                false /* isBusiness */,
217a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                number /* number */,
218a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                null /* displayNumber */,
219a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                null /* numberLabel */,
220a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                null /* phoneAccountHandle */);
221a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    }
222a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
223a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    /**
2249e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Creates a call subject dialog.
2259e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     *
2269e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param activity The current activity.
2279e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param photoId The photo ID (used to populate contact photo).
2289e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param photoUri The photo Uri (used to populate contact photo).
2299e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param contactUri The Contact URI (used so quick contact can be invoked from contact photo).
2309e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param nameOrNumber The name or number of the callee.
2319e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param isBusiness {@code true} if a business is being called (used for contact photo).
2329e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param number The raw number to dial.
2339e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param displayNumber The number to dial, formatted for display.
2349e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param numberLabel The label for the number (if from a contact).
2359e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param phoneAccountHandle The phone account handle.
2369e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
2379e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    public static void start(Activity activity, long photoId, Uri photoUri, Uri contactUri,
2389e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            String nameOrNumber, boolean isBusiness, String number, String displayNumber,
2399e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            String numberLabel, PhoneAccountHandle phoneAccountHandle) {
2409e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        Bundle arguments = new Bundle();
2419e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putLong(ARG_PHOTO_ID, photoId);
2429e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putParcelable(ARG_PHOTO_URI, photoUri);
2439e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putParcelable(ARG_CONTACT_URI, contactUri);
2449e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putString(ARG_NAME_OR_NUMBER, nameOrNumber);
2459e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putBoolean(ARG_IS_BUSINESS, isBusiness);
2469e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putString(ARG_NUMBER, number);
2479e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putString(ARG_DISPLAY_NUMBER, displayNumber);
2489e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putString(ARG_NUMBER_LABEL, numberLabel);
2499e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        arguments.putParcelable(ARG_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
250a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        start(activity, arguments);
251a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    }
252a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
253a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    /**
254a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * Shows the call subject dialog given a Bundle containing all the arguments required to
255a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * display the dialog (e.g. from Quick Contacts).
256a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     *
257a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @param activity The activity.
258a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @param arguments The arguments bundle.
259a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     */
260a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static void start(Activity activity, Bundle arguments) {
26196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        Intent intent = new Intent(activity, CallSubjectDialog.class);
26296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        intent.putExtras(arguments);
26396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        activity.startActivity(intent);
2649e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    }
2659e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
2669e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
2679e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Creates the dialog, inflating the layout and populating it with the name and phone number.
2689e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     *
2699e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param savedInstanceState The last saved instance state of the Fragment,
2709e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * or null if this is a freshly created Fragment.
2719e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     *
2729e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @return Dialog instance.
2739e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
2749e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    @Override
27596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    public void onCreate(Bundle savedInstanceState) {
27696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        super.onCreate(savedInstanceState);
27796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mAnimationDuration = getResources().getInteger(R.integer.call_subject_animation_duration);
27896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
27996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mPhotoSize = getResources().getDimensionPixelSize(
2809e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                R.dimen.call_subject_dialog_contact_photo_size);
2819e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        readArguments();
2829467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        loadConfiguration();
283a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        mSubjectHistory = loadSubjectHistory(mPrefs);
2849e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
28596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        setContentView(R.layout.dialog_call_subject);
28696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
28796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                ViewGroup.LayoutParams.MATCH_PARENT);
28896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mBackgroundView = findViewById(R.id.call_subject_dialog);
28996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mBackgroundView.setOnClickListener(mBackgroundListener);
29096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mDialogView = findViewById(R.id.dialog_view);
29196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mContactPhoto = (QuickContactBadge) findViewById(R.id.contact_photo);
29296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mNameView = (TextView) findViewById(R.id.name);
29396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mNumberView = (TextView) findViewById(R.id.number);
29496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mCallSubjectView = (EditText) findViewById(R.id.call_subject);
2959e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mCallSubjectView.addTextChangedListener(mTextWatcher);
29696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mCallSubjectView.setOnClickListener(mCallSubjectClickListener);
297a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        InputFilter[] filters = new InputFilter[1];
298a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        filters[0] = new InputFilter.LengthFilter(mLimit);
299a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        mCallSubjectView.setFilters(filters);
30096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mCharacterLimitView = (TextView) findViewById(R.id.character_limit);
30196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mHistoryButton = findViewById(R.id.history_button);
3029e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mHistoryButton.setOnClickListener(mHistoryOnClickListener);
303a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        mHistoryButton.setVisibility(mSubjectHistory.isEmpty() ? View.GONE : View.VISIBLE);
30496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mSendAndCallButton = findViewById(R.id.send_and_call_button);
3059e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mSendAndCallButton.setOnClickListener(mSendAndCallOnClickListener);
30696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mSubjectList = (ListView) findViewById(R.id.subject_list);
30796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mSubjectList.setOnItemClickListener(mItemClickListener);
30896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        mSubjectList.setVisibility(View.GONE);
3099e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
3109e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        updateContactInfo();
3119e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        updateCharacterLimit();
3129e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    }
3139e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
3149e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
3159e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Populates the contact info fields based on the current contact information.
3169e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
3179e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private void updateContactInfo() {
318a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        if (mContactUri != null) {
319a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            setPhoto(mPhotoID, mPhotoUri, mContactUri, mNameOrNumber, mIsBusiness);
320a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        } else {
321a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            mContactPhoto.setVisibility(View.GONE);
322a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        }
3239e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mNameView.setText(mNameOrNumber);
3249e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        if (!TextUtils.isEmpty(mNumberLabel) && !TextUtils.isEmpty(mDisplayNumber)) {
3259e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            mNumberView.setVisibility(View.VISIBLE);
32696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            mNumberView.setText(getString(R.string.call_subject_type_and_number,
32796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    mNumberLabel, mDisplayNumber));
3289e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        } else {
3299e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            mNumberView.setVisibility(View.GONE);
3309e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            mNumberView.setText(null);
3319e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
3329e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    }
3339e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
3349e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
3359e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Reads arguments from the fragment arguments and populates the necessary instance variables.
3369e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
3379e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private void readArguments() {
33896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        Bundle arguments = getIntent().getExtras();
3399e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        if (arguments == null) {
3409e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            Log.e(TAG, "Arguments cannot be null.");
341a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            return;
3429e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
3439e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mPhotoID = arguments.getLong(ARG_PHOTO_ID);
3449e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mPhotoUri = arguments.getParcelable(ARG_PHOTO_URI);
3459e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mContactUri = arguments.getParcelable(ARG_CONTACT_URI);
3469e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mNameOrNumber = arguments.getString(ARG_NAME_OR_NUMBER);
3479e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mIsBusiness = arguments.getBoolean(ARG_IS_BUSINESS);
3489e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mNumber = arguments.getString(ARG_NUMBER);
3499e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mDisplayNumber = arguments.getString(ARG_DISPLAY_NUMBER);
3509e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mNumberLabel = arguments.getString(ARG_NUMBER_LABEL);
3519e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mPhoneAccountHandle = arguments.getParcelable(ARG_PHONE_ACCOUNT_HANDLE);
3529e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    }
3539e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
3549e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
3559e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Updates the character limit display, coloring the text RED when the limit is reached or
3569e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * exceeded.
3579e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
3589e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private void updateCharacterLimit() {
3599467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        String subjectText = mCallSubjectView.getText().toString();
3609467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        final int length;
3619467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
3629467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        // If a message encoding is specified, use that to count bytes in the message.
3639467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        if (mMessageEncoding != null) {
3649467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            length = subjectText.getBytes(mMessageEncoding).length;
3659467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        } else {
3669467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            // No message encoding specified, so just count characters entered.
3679467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            length = subjectText.length();
3689467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        }
3699467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
3709e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mCharacterLimitView.setText(
37196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                getString(R.string.call_subject_limit, length, mLimit));
3729e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        if (length >= mLimit) {
37396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            mCharacterLimitView.setTextColor(getResources().getColor(
3749e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                    R.color.call_subject_limit_exceeded));
3759e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        } else {
37696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            mCharacterLimitView.setTextColor(getResources().getColor(
3779e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                    R.color.dialtacts_secondary_text_color));
3789e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
3799e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    }
3809e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
3819e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    /**
3829e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * Sets the photo on the quick contact photo.
3839e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     *
3849e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param photoId
3859e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param photoUri
3869e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param contactUri
3879e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param displayName
3889e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     * @param isBusiness
3899e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn     */
3909e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    private void setPhoto(long photoId, Uri photoUri, Uri contactUri, String displayName,
3919e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            boolean isBusiness) {
3929e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        mContactPhoto.assignContactUri(contactUri);
39354ea4b140d3e82ab5a061c0f1c8aff2933871714Wenyi Wang        if (CompatUtils.isLollipopCompatible()) {
39454ea4b140d3e82ab5a061c0f1c8aff2933871714Wenyi Wang            mContactPhoto.setOverlay(null);
39554ea4b140d3e82ab5a061c0f1c8aff2933871714Wenyi Wang        }
3969e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
3979e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        int contactType;
3989e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        if (isBusiness) {
3999e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            contactType = ContactPhotoManager.TYPE_BUSINESS;
4009e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        } else {
4019e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            contactType = ContactPhotoManager.TYPE_DEFAULT;
4029e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
4039e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
4049e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        String lookupKey = null;
4059e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        if (contactUri != null) {
4069e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn            lookupKey = UriUtils.getLookupKeyFromUri(contactUri);
4079e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
4089e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
4099e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        ContactPhotoManager.DefaultImageRequest
4109e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                request = new ContactPhotoManager.DefaultImageRequest(
4119e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                displayName, lookupKey, contactType, true /* isCircular */);
4129e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn
4139e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        if (photoId == 0 && photoUri != null) {
41496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            ContactPhotoManager.getInstance(this).loadPhoto(mContactPhoto, photoUri,
4159e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                    mPhotoSize, false /* darkTheme */, true /* isCircular */, request);
4169e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        } else {
41796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            ContactPhotoManager.getInstance(this).loadThumbnail(mContactPhoto, photoId,
4189e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn                    false /* darkTheme */, true /* isCircular */, request);
4199e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn        }
4209e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn    }
421a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
422a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    /**
423a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * Loads the subject history from shared preferences.
424a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     *
425a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @param prefs Shared preferences.
426a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @return List of subject history strings.
427a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     */
428a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public static List<String> loadSubjectHistory(SharedPreferences prefs) {
429a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        int historySize = prefs.getInt(PREF_KEY_SUBJECT_HISTORY_COUNT, 0);
430a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        List<String> subjects = new ArrayList(historySize);
431a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
432a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        for (int ix = 0 ; ix < historySize; ix++) {
433a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            String historyItem = prefs.getString(PREF_KEY_SUBJECT_HISTORY_ITEM + ix, null);
434a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            if (!TextUtils.isEmpty(historyItem)) {
435a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                subjects.add(historyItem);
436a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            }
437a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        }
438a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
439a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        return subjects;
440a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    }
441a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
442a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    /**
443a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * Saves the subject history list to shared prefs, removing older items so that there are only
444a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * {@link #CALL_SUBJECT_HISTORY_SIZE} items at most.
445a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     *
446a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * @param history The history.
447a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     */
448a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    private void saveSubjectHistory(List<String> history) {
449a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        // Remove oldest subject(s).
450a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        while (history.size() > CALL_SUBJECT_HISTORY_SIZE) {
451a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            history.remove(0);
452a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        }
453a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
454a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        SharedPreferences.Editor editor = mPrefs.edit();
455a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        int historyCount = 0;
456a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        for (String subject : history) {
457a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            if (!TextUtils.isEmpty(subject)) {
458a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                editor.putString(PREF_KEY_SUBJECT_HISTORY_ITEM + historyCount,
459a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                        subject);
460a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                historyCount++;
461a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn            }
462a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        }
463a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        editor.putInt(PREF_KEY_SUBJECT_HISTORY_COUNT, historyCount);
464a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        editor.apply();
465a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    }
466a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
467a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    /**
468a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     * Hide software keyboard for the given {@link View}.
469a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     */
470a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    public void hideSoftKeyboard(Context context, View view) {
471a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        InputMethodManager imm = (InputMethodManager) context.getSystemService(
472a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn                Context.INPUT_METHOD_SERVICE);
473a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        if (imm != null) {
47496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
475a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        }
476a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    }
477a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn
478a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    /**
47996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * Hides or shows the call history list.
48096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     *
48196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn     * @param show {@code true} if the call history should be shown, {@code false} otherwise.
482a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn     */
48396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn    private void showCallHistory(final boolean show) {
48496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        // Bail early if the visibility has not changed.
48596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        if ((show && mSubjectList.getVisibility() == View.VISIBLE) ||
48696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                (!show && mSubjectList.getVisibility() == View.GONE)) {
48796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            return;
488a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn        }
48996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
49096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        final int dialogStartingBottom = mDialogView.getBottom();
49196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        if (show) {
49296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            // Showing the subject list; bind the list of history items to the list and show it.
49396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            ArrayAdapter<String> adapter = new ArrayAdapter<String>(CallSubjectDialog.this,
49496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    R.layout.call_subject_history_list_item, mSubjectHistory);
49596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            mSubjectList.setAdapter(adapter);
49696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            mSubjectList.setVisibility(View.VISIBLE);
49796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        } else {
49896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            // Hiding the subject list.
49996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn            mSubjectList.setVisibility(View.GONE);
50096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        }
50196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
50296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        // Use a ViewTreeObserver so that we can animate between the pre-layout and post-layout
50396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        // states.
50496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        final ViewTreeObserver observer = mBackgroundView.getViewTreeObserver();
50596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        observer.addOnPreDrawListener(
50696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                new ViewTreeObserver.OnPreDrawListener() {
50796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    @Override
50896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    public boolean onPreDraw() {
50996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        // We don't want to continue getting called.
51096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        if (observer.isAlive()) {
51196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            observer.removeOnPreDrawListener(this);
51296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        }
51396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
51496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        // Determine the amount the dialog has shifted due to the relayout.
51596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        int shiftAmount = dialogStartingBottom - mDialogView.getBottom();
51696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
51796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        // If the dialog needs to be shifted, do that now.
51896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        if (shiftAmount != 0) {
51996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            // Start animation in translated state and animate to translationY 0.
52096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            mDialogView.setTranslationY(shiftAmount);
52196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            mDialogView.animate()
52296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .translationY(0)
52396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setInterpolator(AnimUtils.EASE_OUT_EASE_IN)
52496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setDuration(mAnimationDuration)
52596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .start();
52696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        }
52796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
52896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        if (show) {
52996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            // Show the subhect list.
53096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            mSubjectList.setTranslationY(mSubjectList.getHeight());
53196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
53296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            mSubjectList.animate()
53396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .translationY(0)
53496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setInterpolator(AnimUtils.EASE_OUT_EASE_IN)
53596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setDuration(mAnimationDuration)
53696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setListener(new AnimatorListenerAdapter() {
53796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        @Override
53896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        public void onAnimationEnd(Animator animation) {
53996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                            super.onAnimationEnd(animation);
54096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        }
54196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
54296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        @Override
54396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        public void onAnimationStart(Animator animation) {
54496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                            super.onAnimationStart(animation);
54596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                            mSubjectList.setVisibility(View.VISIBLE);
54696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        }
54796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    })
54896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .start();
54996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        } else {
55096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            // Hide the subject list.
55196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            mSubjectList.setTranslationY(0);
55296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
55396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                            mSubjectList.animate()
55496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .translationY(mSubjectList.getHeight())
55596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setInterpolator(AnimUtils.EASE_OUT_EASE_IN)
55696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setDuration(mAnimationDuration)
55796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .setListener(new AnimatorListenerAdapter() {
55896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        @Override
55996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        public void onAnimationEnd(Animator animation) {
56096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                            super.onAnimationEnd(animation);
56196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                            mSubjectList.setVisibility(View.GONE);
56296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        }
56396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn
56496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        @Override
56596a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        public void onAnimationStart(Animator animation) {
56696a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                            super.onAnimationStart(animation);
56796a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                        }
56896a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    })
56996a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                                    .start();
57096a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        }
57196a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                        return true;
57296a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                    }
57396a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn                }
57496a121e7add6785ca22bc6342895382ea6f162f5Tyler Gunn        );
575a05f1535ab8dc7efa1d6454b5418259a6a513b64Tyler Gunn    }
5769467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
5779467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn    /**
5789467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn     * Loads the message encoding and maximum message length from the phone account extras for the
5799467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn     * current phone account.
5809467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn     */
5819467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn    private void loadConfiguration() {
5829467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        // Only attempt to load configuration from the phone account extras if the SDK is N or
5839467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        // later.  If we've got a prior SDK the default encoding and message length will suffice.
5849467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        int sdk = android.os.Build.VERSION.SDK_INT;
5859467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        if(sdk <= android.os.Build.VERSION_CODES.M) {
5869467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            return;
5879467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        }
5889467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
5899467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        if (mPhoneAccountHandle == null) {
5909467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            return;
5919467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        }
5929467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
5939467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        TelecomManager telecomManager =
5949467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn                (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
5959467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        final PhoneAccount account = telecomManager.getPhoneAccount(mPhoneAccountHandle);
5969467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
59759023c2f76136eb1cf402e1ee954a50c3f964168Ta-wei Yen        Bundle phoneAccountExtras = PhoneAccountSdkCompat.getExtras(account);
5989467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        if (phoneAccountExtras == null) {
5999467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            return;
6009467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        }
6019467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
6029467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        // Get limit, if provided; otherwise default to existing value.
60359023c2f76136eb1cf402e1ee954a50c3f964168Ta-wei Yen        mLimit = phoneAccountExtras
60459023c2f76136eb1cf402e1ee954a50c3f964168Ta-wei Yen                .getInt(PhoneAccountSdkCompat.EXTRA_CALL_SUBJECT_MAX_LENGTH, mLimit);
6059467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
6069467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        // Get charset; default to none (e.g. count characters 1:1).
6079467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        String charsetName = phoneAccountExtras.getString(
60859023c2f76136eb1cf402e1ee954a50c3f964168Ta-wei Yen                PhoneAccountSdkCompat.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING);
6099467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn
6109467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        if (!TextUtils.isEmpty(charsetName)) {
6119467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            try {
6129467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn                mMessageEncoding = Charset.forName(charsetName);
6139467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            } catch (java.nio.charset.UnsupportedCharsetException uce) {
6149467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn                // Character set was invalid; log warning and fallback to none.
6159467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn                Log.w(TAG, "Invalid charset: " + charsetName);
6169467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn                mMessageEncoding = null;
6179467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            }
6189467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        } else {
6199467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            // No character set specified, so count characters 1:1.
6209467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn            mMessageEncoding = null;
6219467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn        }
6229467b38d1a370b5d5a4c516096b1ccb3840bc80aTyler Gunn    }
6239e0c14e59650a45e31b60da254091d4ce13b3e49Tyler Gunn}
624