1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.ui;
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.app.Fragment;
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ActivityNotFoundException;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Intent;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.LayoutInflater;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.Menu;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.MenuInflater;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.MenuItem;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View.OnLayoutChangeListener;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.ViewGroup;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.ExpandableListAdapter;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.ExpandableListView;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.widget.ExpandableListView.OnChildClickListener;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R;
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DataModel;
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.MediaScratchFileProvider;
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.binding.Binding;
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.binding.BindingBase;
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.PersonItemData;
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.VCardContactItemData;
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.PersonItemData.PersonItemDataListener;
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert;
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.SafeAsyncTask;
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.UiUtils;
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.UriUtil;
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/**
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * A fragment that shows the content of a VCard that contains one or more contacts.
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class VCardDetailFragment extends Fragment implements PersonItemDataListener {
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final Binding<VCardContactItemData> mBinding =
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            BindingBase.createBinding(this);
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private ExpandableListView mListView;
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private VCardDetailAdapter mAdapter;
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Uri mVCardUri;
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * We need to persist the VCard in the scratch directory before letting the user view it.
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * We save this Uri locally, so that if the user cancels the action and re-perform the add
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * to contacts action we don't have to persist it again.
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private Uri mScratchSpaceUri;
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onCreate(final Bundle savedInstanceState) {
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.onCreate(savedInstanceState);
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        setHasOptionsMenu(true);
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Bundle savedInstanceState) {
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Assert.notNull(mVCardUri);
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final View view = inflater.inflate(R.layout.vcard_detail_fragment, container, false);
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mListView = (ExpandableListView) view.findViewById(R.id.list);
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mListView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public void onLayoutChange(final View v, final int left, final int top, final int right,
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final int bottom, final int oldLeft, final int oldTop, final int oldRight,
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    final int oldBottom) {
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mListView.setIndicatorBounds(mListView.getWidth() - getResources()
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        .getDimensionPixelSize(R.dimen.vcard_detail_group_indicator_width),
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        mListView.getWidth());
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mListView.setOnChildClickListener(new OnChildClickListener() {
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            @Override
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            public boolean onChildClick(ExpandableListView expandableListView, View clickedView,
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    int groupPosition, int childPosition, long childId) {
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (!(clickedView instanceof PersonItemView)) {
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return false;
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Intent intent = ((PersonItemView) clickedView).getClickIntent();
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                if (intent != null) {
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    try {
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        startActivity(intent);
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    } catch (ActivityNotFoundException e) {
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        return false;
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    return true;
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return false;
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        });
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mBinding.bind(DataModel.get().createVCardContactItemData(getActivity(), mVCardUri));
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mBinding.getData().setListener(this);
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return view;
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onDestroy() {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.onDestroy();
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mBinding.isBound()) {
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mBinding.unbind();
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mListView.setAdapter((ExpandableListAdapter) null);
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private boolean shouldShowAddToContactsItem() {
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return mBinding.isBound() && mBinding.getData().hasValidVCard();
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        super.onCreateOptionsMenu(menu, inflater);
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        inflater.inflate(R.menu.vcard_detail_fragment_menu, menu);
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final MenuItem addToContactsItem = menu.findItem(R.id.action_add_contact);
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        addToContactsItem.setVisible(shouldShowAddToContactsItem());
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public boolean onOptionsItemSelected(final MenuItem item) {
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        switch (item.getItemId()) {
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case R.id.action_add_contact:
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                mBinding.ensureBound();
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Uri vCardUri = mBinding.getData().getVCardUri();
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                // We have to do things in the background in case we need to copy the vcard data.
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                new SafeAsyncTask<Void, Void, Uri>() {
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    @Override
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    protected Uri doInBackgroundTimed(final Void... params) {
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // We can't delete the persisted vCard file because we don't know when to
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // delete it, since the app that uses it (contacts, dialer) may start or
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // shut down at any point. Therefore, we rely on the system to clean up
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        // the cache directory for us.
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        return mScratchSpaceUri != null ? mScratchSpaceUri :
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            UriUtil.persistContentToScratchSpace(vCardUri);
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    @Override
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    protected void onPostExecute(final Uri result) {
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        if (result != null) {
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            mScratchSpaceUri = result;
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            if (getActivity() != null) {
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                MediaScratchFileProvider.addUriToDisplayNameEntry(
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                        result, mBinding.getData().getDisplayName());
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                UIIntents.get().launchSaveVCardToContactsActivity(getActivity(),
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                        result);
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                            }
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        }
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    }
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                }.executeOnThreadPool();
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return true;
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            default:
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return super.onOptionsItemSelected(item);
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void setVCardUri(final Uri vCardUri) {
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Assert.isTrue(!mBinding.isBound());
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mVCardUri = vCardUri;
173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onPersonDataUpdated(final PersonItemData data) {
177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Assert.isTrue(data instanceof VCardContactItemData);
178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mBinding.ensureBound();
179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final VCardContactItemData vCardData = (VCardContactItemData) data;
180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        Assert.isTrue(vCardData.hasValidVCard());
181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mAdapter = new VCardDetailAdapter(getActivity(), vCardData.getVCardResource().getVCards());
182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mListView.setAdapter(mAdapter);
183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Expand the contact card if there's only one contact.
185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mAdapter.getGroupCount() == 1) {
186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mListView.expandGroup(0);
187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        getActivity().invalidateOptionsMenu();
189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void onPersonDataFailed(final PersonItemData data, final Exception exception) {
193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mBinding.ensureBound();
194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        UiUtils.showToastAtBottom(R.string.failed_loading_vcard);
195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        getActivity().finish();
196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
198