/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.contacts.vcard;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.provider.OpenableColumns;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.android.contacts.R;
import com.android.contacts.activities.RequestImportVCardPermissionsActivity;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contactsbind.FeedbackHelper;
import com.android.vcard.VCardEntryCounter;
import com.android.vcard.VCardParser;
import com.android.vcard.VCardParser_V21;
import com.android.vcard.VCardParser_V30;
import com.android.vcard.VCardSourceDetector;
import com.android.vcard.exception.VCardException;
import com.android.vcard.exception.VCardNestedException;
import com.android.vcard.exception.VCardVersionException;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * The class letting users to import vCard. This includes the UI part for letting them select
 * an Account and posssibly a file if there's no Uri is given from its caller Activity.
 *
 * Note that this Activity assumes that the instance is a "one-shot Activity", which will be
 * finished (with the method {@link Activity#finish()}) after the import and never reuse
 * any Dialog in the instance. So this code is careless about the management around managed
 * dialogs stuffs (like how onCreateDialog() is used).
 */
public class ImportVCardActivity extends Activity implements ImportVCardDialogFragment.Listener {
    private static final String LOG_TAG = "VCardImport";

    private static final int SELECT_ACCOUNT = 0;

    /* package */ final static int VCARD_VERSION_AUTO_DETECT = 0;
    /* package */ final static int VCARD_VERSION_V21 = 1;
    /* package */ final static int VCARD_VERSION_V30 = 2;

    private static final int REQUEST_OPEN_DOCUMENT = 100;

    /**
     * Notification id used when error happened before sending an import request to VCardServer.
     */
    private static final int FAILURE_NOTIFICATION_ID = 1;

    private static final String LOCAL_TMP_FILE_NAME_EXTRA =
            "com.android.contacts.vcard.LOCAL_TMP_FILE_NAME";

    private static final String SOURCE_URI_DISPLAY_NAME =
            "com.android.contacts.vcard.SOURCE_URI_DISPLAY_NAME";

    private static final String STORAGE_VCARD_URI_PREFIX = "file:///storage";

    private AccountWithDataSet mAccount;

    private ProgressDialog mProgressDialogForCachingVCard;

    private VCardCacheThread mVCardCacheThread;
    private ImportRequestConnection mConnection;
    /* package */ VCardImportExportListener mListener;

    private String mErrorMessage;

    private Handler mHandler = new Handler();

    // Runs on the UI thread.
    private class DialogDisplayer implements Runnable {
        private final int mResId;
        public DialogDisplayer(int resId) {
            mResId = resId;
        }
        public DialogDisplayer(String errorMessage) {
            mResId = R.id.dialog_error_with_message;
            mErrorMessage = errorMessage;
        }
        @Override
        public void run() {
            if (!isFinishing()) {
                showDialog(mResId);
            }
        }
    }

    private class CancelListener
        implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            finish();
        }
        @Override
        public void onCancel(DialogInterface dialog) {
            finish();
        }
    }

    private CancelListener mCancelListener = new CancelListener();

    private class ImportRequestConnection implements ServiceConnection {
        private VCardService mService;

        public void sendImportRequest(final List<ImportRequest> requests) {
            Log.i(LOG_TAG, "Send an import request");
            mService.handleImportRequest(requests, mListener);
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            mService = ((VCardService.MyBinder) binder).getService();
            Log.i(LOG_TAG,
                    String.format("Connected to VCardService. Kick a vCard cache thread (uri: %s)",
                            Arrays.toString(mVCardCacheThread.getSourceUris())));
            mVCardCacheThread.start();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(LOG_TAG, "Disconnected from VCardService");
        }
    }

    /**
     * Caches given vCard files into a local directory, and sends actual import request to
     * {@link VCardService}.
     *
     * We need to cache given files into local storage. One of reasons is that some data (as Uri)
     * may have special permissions. Callers may allow only this Activity to access that content,
     * not what this Activity launched (like {@link VCardService}).
     */
    private class VCardCacheThread extends Thread
            implements DialogInterface.OnCancelListener {
        private boolean mCanceled;
        private PowerManager.WakeLock mWakeLock;
        private VCardParser mVCardParser;
        private final Uri[] mSourceUris;  // Given from a caller.
        private final String[] mSourceDisplayNames; // Display names for each Uri in mSourceUris.
        private final byte[] mSource;
        private final String mDisplayName;

        public VCardCacheThread(final Uri[] sourceUris, String[] sourceDisplayNames) {
            mSourceUris = sourceUris;
            mSourceDisplayNames = sourceDisplayNames;
            mSource = null;
            final Context context = ImportVCardActivity.this;
            final PowerManager powerManager =
                    (PowerManager)context.getSystemService(Context.POWER_SERVICE);
            mWakeLock = powerManager.newWakeLock(
                    PowerManager.SCREEN_DIM_WAKE_LOCK |
                    PowerManager.ON_AFTER_RELEASE, LOG_TAG);
            mDisplayName = null;
        }

        @Override
        public void finalize() {
            if (mWakeLock != null && mWakeLock.isHeld()) {
                Log.w(LOG_TAG, "WakeLock is being held.");
                mWakeLock.release();
            }
        }

        @Override
        public void run() {
            Log.i(LOG_TAG, "vCard cache thread starts running.");
            if (mConnection == null) {
                throw new NullPointerException("vCard cache thread must be launched "
                        + "after a service connection is established");
            }

            mWakeLock.acquire();
            try {
                if (mCanceled == true) {
                    Log.i(LOG_TAG, "vCard cache operation is canceled.");
                    return;
                }

                final Context context = ImportVCardActivity.this;
                // Uris given from caller applications may not be opened twice: consider when
                // it is not from local storage (e.g. "file:///...") but from some special
                // provider (e.g. "content://...").
                // Thus we have to once copy the content of Uri into local storage, and read
                // it after it.
                //
                // We may be able to read content of each vCard file during copying them
                // to local storage, but currently vCard code does not allow us to do so.
                int cache_index = 0;
                ArrayList<ImportRequest> requests = new ArrayList<ImportRequest>();
                if (mSource != null) {
                    try {
                        requests.add(constructImportRequest(mSource, null, mDisplayName));
                    } catch (VCardException e) {
                        FeedbackHelper.sendFeedback(ImportVCardActivity.this, LOG_TAG,
                                "Failed to cache vcard", e);
                        showFailureNotification(R.string.fail_reason_not_supported);
                        return;
                    }
                } else {
                    int i = 0;
                    for (Uri sourceUri : mSourceUris) {
                        if (mCanceled) {
                            Log.i(LOG_TAG, "vCard cache operation is canceled.");
                            break;
                        }

                        String sourceDisplayName = mSourceDisplayNames[i++];

                        final ImportRequest request;
                        try {
                            request = constructImportRequest(null, sourceUri, sourceDisplayName);
                        } catch (VCardException e) {
                            FeedbackHelper.sendFeedback(ImportVCardActivity.this, LOG_TAG,
                                    "Failed to cache vcard", e);
                            showFailureNotification(R.string.fail_reason_not_supported);
                            return;
                        } catch (IOException e) {
                            FeedbackHelper.sendFeedback(ImportVCardActivity.this, LOG_TAG,
                                    "Failed to cache vcard", e);
                            showFailureNotification(R.string.fail_reason_io_error);
                            return;
                        }
                        if (mCanceled) {
                            Log.i(LOG_TAG, "vCard cache operation is canceled.");
                            return;
                        }
                        requests.add(request);
                    }
                }
                if (!requests.isEmpty()) {
                    mConnection.sendImportRequest(requests);
                } else {
                    Log.w(LOG_TAG, "Empty import requests. Ignore it.");
                }
            } catch (OutOfMemoryError e) {
                FeedbackHelper.sendFeedback(ImportVCardActivity.this, LOG_TAG,
                        "OutOfMemoryError occured during caching vCard", e);
                System.gc();
                runOnUiThread(new DialogDisplayer(
                        getString(R.string.fail_reason_low_memory_during_import)));
            } catch (IOException e) {
                FeedbackHelper.sendFeedback(ImportVCardActivity.this, LOG_TAG,
                        "IOException during caching vCard", e);
                runOnUiThread(new DialogDisplayer(
                        getString(R.string.fail_reason_io_error)));
            } finally {
                Log.i(LOG_TAG, "Finished caching vCard.");
                mWakeLock.release();
                try {
                    unbindService(mConnection);
                } catch (IllegalArgumentException e) {
                    FeedbackHelper.sendFeedback(ImportVCardActivity.this, LOG_TAG,
                            "Cannot unbind service connection", e);
                }
                mProgressDialogForCachingVCard.dismiss();
                mProgressDialogForCachingVCard = null;
                finish();
            }
        }

        /**
         * Reads localDataUri (possibly multiple times) and constructs {@link ImportRequest} from
         * its content.
         *
         * @arg localDataUri Uri actually used for the import. Should be stored in
         * app local storage, as we cannot guarantee other types of Uris can be read
         * multiple times. This variable populates {@link ImportRequest#uri}.
         * @arg displayName Used for displaying information to the user. This variable populates
         * {@link ImportRequest#displayName}.
         */
        private ImportRequest constructImportRequest(final byte[] data,
                final Uri localDataUri, final String displayName)
                throws IOException, VCardException {
            final ContentResolver resolver = ImportVCardActivity.this.getContentResolver();
            VCardEntryCounter counter = null;
            VCardSourceDetector detector = null;
            int vcardVersion = VCARD_VERSION_V21;
            try {
                boolean shouldUseV30 = false;
                InputStream is;
                if (data != null) {
                    is = new ByteArrayInputStream(data);
                } else {
                    is = resolver.openInputStream(localDataUri);
                }
                mVCardParser = new VCardParser_V21();
                try {
                    counter = new VCardEntryCounter();
                    detector = new VCardSourceDetector();
                    mVCardParser.addInterpreter(counter);
                    mVCardParser.addInterpreter(detector);
                    mVCardParser.parse(is);
                } catch (VCardVersionException e1) {
                    try {
                        is.close();
                    } catch (IOException e) {
                    }

                    shouldUseV30 = true;
                    if (data != null) {
                        is = new ByteArrayInputStream(data);
                    } else {
                        is = resolver.openInputStream(localDataUri);
                    }
                    mVCardParser = new VCardParser_V30();
                    try {
                        counter = new VCardEntryCounter();
                        detector = new VCardSourceDetector();
                        mVCardParser.addInterpreter(counter);
                        mVCardParser.addInterpreter(detector);
                        mVCardParser.parse(is);
                    } catch (VCardVersionException e2) {
                        throw new VCardException("vCard with unspported version.");
                    }
                } finally {
                    if (is != null) {
                        try {
                            is.close();
                        } catch (IOException e) {
                        }
                    }
                }

                vcardVersion = shouldUseV30 ? VCARD_VERSION_V30 : VCARD_VERSION_V21;
            } catch (VCardNestedException e) {
                Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive).");
                // Go through without throwing the Exception, as we may be able to detect the
                // version before it
            }
            return new ImportRequest(mAccount,
                    data, localDataUri, displayName,
                    detector.getEstimatedType(),
                    detector.getEstimatedCharset(),
                    vcardVersion, counter.getCount());
        }

        public Uri[] getSourceUris() {
            return mSourceUris;
        }

        public void cancel() {
            mCanceled = true;
            if (mVCardParser != null) {
                mVCardParser.cancel();
            }
        }

        @Override
        public void onCancel(DialogInterface dialog) {
            Log.i(LOG_TAG, "Cancel request has come. Abort caching vCard.");
            cancel();
        }
    }

    private void importVCard(final Uri uri, final String sourceDisplayName) {
        importVCard(new Uri[] {uri}, new String[] {sourceDisplayName});
    }

    private void importVCard(final Uri[] uris, final String[] sourceDisplayNames) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!isFinishing()) {
                    mVCardCacheThread = new VCardCacheThread(uris, sourceDisplayNames);
                    mListener = new NotificationImportExportListener(ImportVCardActivity.this);
                    showDialog(R.id.dialog_cache_vcard);
                }
            }
        });
    }

    private String getDisplayName(Uri sourceUri) {
        if (sourceUri == null) {
            return null;
        }
        final ContentResolver resolver = ImportVCardActivity.this.getContentResolver();
        String displayName = null;
        Cursor cursor = null;
        // Try to get a display name from the given Uri. If it fails, we just
        // pick up the last part of the Uri.
        try {
            cursor = resolver.query(sourceUri,
                    new String[] { OpenableColumns.DISPLAY_NAME },
                    null, null, null);
            if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) {
                if (cursor.getCount() > 1) {
                    Log.w(LOG_TAG, "Unexpected multiple rows: "
                            + cursor.getCount());
                }
                int index = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                if (index >= 0) {
                    displayName = cursor.getString(index);
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        if (TextUtils.isEmpty(displayName)){
            displayName = sourceUri.getLastPathSegment();
        }
        return displayName;
    }

    /**
     * Copy the content of sourceUri to the destination.
     */
    private Uri copyTo(final Uri sourceUri, String filename) throws IOException {
        Log.i(LOG_TAG, String.format("Copy a Uri to app local storage (%s -> %s)",
                sourceUri, filename));
        final Context context = ImportVCardActivity.this;
        final ContentResolver resolver = context.getContentResolver();
        ReadableByteChannel inputChannel = null;
        WritableByteChannel outputChannel = null;
        Uri destUri = null;
        try {
            inputChannel = Channels.newChannel(resolver.openInputStream(sourceUri));
            destUri = Uri.parse(context.getFileStreamPath(filename).toURI().toString());
            outputChannel = context.openFileOutput(filename, Context.MODE_PRIVATE).getChannel();
            final ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
            while (inputChannel.read(buffer) != -1) {
                buffer.flip();
                outputChannel.write(buffer);
                buffer.compact();
            }
            buffer.flip();
            while (buffer.hasRemaining()) {
                outputChannel.write(buffer);
            }
        } finally {
            if (inputChannel != null) {
                try {
                    inputChannel.close();
                } catch (IOException e) {
                    Log.w(LOG_TAG, "Failed to close inputChannel.");
                }
            }
            if (outputChannel != null) {
                try {
                    outputChannel.close();
                } catch(IOException e) {
                    Log.w(LOG_TAG, "Failed to close outputChannel");
                }
            }
        }
        return destUri;
    }

    /**
     * Reads the file from {@param sourceUri} and copies it to local cache file.
     * Returns the local file name which stores the file from sourceUri.
     */
    private String readUriToLocalFile(Uri sourceUri) {
        // Read the uri to local first.
        int cache_index = 0;
        String localFilename = null;
        // Note: caches are removed by VCardService.
        while (true) {
            localFilename = VCardService.CACHE_FILE_PREFIX + cache_index + ".vcf";
            final File file = getFileStreamPath(localFilename);
            if (!file.exists()) {
                break;
            } else {
                if (cache_index == Integer.MAX_VALUE) {
                    throw new RuntimeException("Exceeded cache limit");
                }
                cache_index++;
            }
        }
        try {
            copyTo(sourceUri, localFilename);
        } catch (IOException|SecurityException e) {
            FeedbackHelper.sendFeedback(this, LOG_TAG, "Failed to copy vcard to local file", e);
            showFailureNotification(R.string.fail_reason_io_error);
            return null;
        }

        if (localFilename == null) {
            Log.e(LOG_TAG, "Cannot load uri to local storage.");
            showFailureNotification(R.string.fail_reason_io_error);
            return null;
        }

        return localFilename;
    }

    private Uri readUriToLocalUri(Uri sourceUri) {
        final String fileName = readUriToLocalFile(sourceUri);
        if (fileName == null) {
            return null;
        }
        return Uri.parse(getFileStreamPath(fileName).toURI().toString());
    }

    // Returns true if uri is from Storage.
    private boolean isStorageUri(Uri uri) {
        return uri != null && uri.toString().startsWith(STORAGE_VCARD_URI_PREFIX);
    }

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        Uri sourceUri = getIntent().getData();

        // Reading uris from non-storage needs the permission granted from the source intent,
        // instead of permissions from RequestImportVCardPermissionActivity. So skipping requesting
        // permissions from RequestImportVCardPermissionActivity for uris from non-storage source.
        if (isStorageUri(sourceUri) && RequestImportVCardPermissionsActivity
                .startPermissionActivity(this, isCallerSelf(this))) {
            return;
        }

        String sourceDisplayName = null;
        if (sourceUri != null) {
            // Read the uri to local first.
            String localTmpFileName = getIntent().getStringExtra(LOCAL_TMP_FILE_NAME_EXTRA);
            sourceDisplayName = getIntent().getStringExtra(SOURCE_URI_DISPLAY_NAME);
            if (TextUtils.isEmpty(localTmpFileName)) {
                localTmpFileName = readUriToLocalFile(sourceUri);
                sourceDisplayName = getDisplayName(sourceUri);
                if (localTmpFileName == null) {
                    Log.e(LOG_TAG, "Cannot load uri to local storage.");
                    showFailureNotification(R.string.fail_reason_io_error);
                    return;
                }
                getIntent().putExtra(LOCAL_TMP_FILE_NAME_EXTRA, localTmpFileName);
                getIntent().putExtra(SOURCE_URI_DISPLAY_NAME, sourceDisplayName);
            }
            sourceUri = Uri.parse(getFileStreamPath(localTmpFileName).toURI().toString());
        }

        // Always request required permission for contacts before importing the vcard.
        if (RequestImportVCardPermissionsActivity.startPermissionActivity(this,
                isCallerSelf(this))) {
            return;
        }

        String accountName = null;
        String accountType = null;
        String dataSet = null;
        final Intent intent = getIntent();
        if (intent != null) {
            accountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
            accountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
            dataSet = intent.getStringExtra(SelectAccountActivity.DATA_SET);
        } else {
            Log.e(LOG_TAG, "intent does not exist");
        }

        if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
            mAccount = new AccountWithDataSet(accountName, accountType, dataSet);
        } else {
            final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
            final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
            if (accountList.size() == 0) {
                mAccount = null;
            } else if (accountList.size() == 1) {
                mAccount = accountList.get(0);
            } else {
                startActivityForResult(new Intent(this, SelectAccountActivity.class),
                        SELECT_ACCOUNT);
                return;
            }
        }

        if (isCallerSelf(this)) {
            startImport(sourceUri, sourceDisplayName);
        } else {
            ImportVCardDialogFragment.show(this, sourceUri, sourceDisplayName);
        }
    }

    private static boolean isCallerSelf(Activity activity) {
        // {@link Activity#getCallingActivity()} is a safer alternative to
        // {@link Activity#getCallingPackage()} that works around a
        // framework bug where getCallingPackage() can sometimes return null even when the
        // current activity *was* in fact launched via a startActivityForResult() call.
        //
        // (The bug happens if the task stack needs to be re-created by the framework after
        // having been killed due to memory pressure or by the "Don't keep activities"
        // developer option; see bug 7494866 for the full details.)
        //
        // Turns out that {@link Activity#getCallingActivity()} *does* return correct info
        // even in the case where getCallingPackage() is broken, so the workaround is simply
        // to get the package name from getCallingActivity().getPackageName() instead.
        final ComponentName callingActivity = activity.getCallingActivity();
        if (callingActivity == null) return false;
        final String packageName = callingActivity.getPackageName();
        if (packageName == null) return false;
        return packageName.equals(activity.getApplicationContext().getPackageName());
    }

    @Override
    public void onImportVCardConfirmed(Uri sourceUri, String sourceDisplayName) {
        startImport(sourceUri, sourceDisplayName);
    }

    @Override
    public void onImportVCardDenied() {
        finish();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == SELECT_ACCOUNT) {
            if (resultCode == Activity.RESULT_OK) {
                mAccount = new AccountWithDataSet(
                        intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME),
                        intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE),
                        intent.getStringExtra(SelectAccountActivity.DATA_SET));
                final Uri sourceUri = getIntent().getData();
                if (sourceUri == null) {
                    startImport(sourceUri, /* sourceDisplayName =*/ null);
                } else {
                    final String sourceDisplayName = getIntent().getStringExtra(
                            SOURCE_URI_DISPLAY_NAME);
                    final String localFileName = getIntent().getStringExtra(
                            LOCAL_TMP_FILE_NAME_EXTRA);
                    final Uri localUri = Uri.parse(
                            getFileStreamPath(localFileName).toURI().toString());
                    startImport(localUri, sourceDisplayName);
                }
            } else {
                if (resultCode != Activity.RESULT_CANCELED) {
                    Log.w(LOG_TAG, "Result code was not OK nor CANCELED: " + resultCode);
                }
                finish();
            }
        } else if (requestCode == REQUEST_OPEN_DOCUMENT) {
            if (resultCode == Activity.RESULT_OK) {
                final ClipData clipData = intent.getClipData();
                if (clipData != null) {
                    final ArrayList<Uri> uris = new ArrayList<>();
                    final ArrayList<String> sourceDisplayNames = new ArrayList<>();
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        final Uri uri = item.getUri();
                        if (uri != null) {
                            final Uri localUri = readUriToLocalUri(uri);
                            if (localUri != null) {
                                final String sourceDisplayName = getDisplayName(uri);
                                uris.add(localUri);
                                sourceDisplayNames.add(sourceDisplayName);
                            }
                        }
                    }
                    if (uris.isEmpty()) {
                        Log.w(LOG_TAG, "No vCard was selected for import");
                        finish();
                    } else {
                        Log.i(LOG_TAG, "Multiple vCards selected for import: " + uris);
                        importVCard(uris.toArray(new Uri[0]),
                                sourceDisplayNames.toArray(new String[0]));
                    }
                } else {
                    final Uri uri = intent.getData();
                    if (uri != null) {
                        Log.i(LOG_TAG, "vCard selected for import: " + uri);
                        final Uri localUri = readUriToLocalUri(uri);
                        if (localUri != null) {
                            final String sourceDisplayName = getDisplayName(uri);
                            importVCard(localUri, sourceDisplayName);
                        } else {
                            Log.w(LOG_TAG, "No local URI for vCard import");
                            finish();
                        }
                    } else {
                        Log.w(LOG_TAG, "No vCard was selected for import");
                        finish();
                    }
                }
            } else {
                if (resultCode != Activity.RESULT_CANCELED) {
                    Log.w(LOG_TAG, "Result code was not OK nor CANCELED" + resultCode);
                }
                finish();
            }
        }
    }

    private void startImport(Uri uri, String sourceDisplayName) {
        // Handle inbound files
        if (uri != null) {
            Log.i(LOG_TAG, "Starting vCard import using Uri " + uri);
            importVCard(uri, sourceDisplayName);
        } else {
            Log.i(LOG_TAG, "Start vCard without Uri. The user will select vCard manually.");
            final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType(VCardService.X_VCARD_MIME_TYPE);
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
            startActivityForResult(intent, REQUEST_OPEN_DOCUMENT);
        }
    }

    @Override
    protected Dialog onCreateDialog(int resId, Bundle bundle) {
        if (resId == R.id.dialog_cache_vcard) {
            if (mProgressDialogForCachingVCard == null) {
                final String title = getString(R.string.caching_vcard_title);
                final String message = getString(R.string.caching_vcard_message);
                mProgressDialogForCachingVCard = new ProgressDialog(this);
                mProgressDialogForCachingVCard.setTitle(title);
                mProgressDialogForCachingVCard.setMessage(message);
                mProgressDialogForCachingVCard.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                mProgressDialogForCachingVCard.setOnCancelListener(mVCardCacheThread);
                startVCardService();
            }
            return mProgressDialogForCachingVCard;
        } else if (resId == R.id.dialog_error_with_message) {
            String message = mErrorMessage;
            if (TextUtils.isEmpty(message)) {
                Log.e(LOG_TAG, "Error message is null while it must not.");
                message = getString(R.string.fail_reason_unknown);
            }
            final AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle(getString(R.string.reading_vcard_failed_title))
                .setIconAttribute(android.R.attr.alertDialogIcon)
                .setMessage(message)
                .setOnCancelListener(mCancelListener)
                .setPositiveButton(android.R.string.ok, mCancelListener);
            return builder.create();
        }

        return super.onCreateDialog(resId, bundle);
    }

    /* package */ void startVCardService() {
        mConnection = new ImportRequestConnection();

        Log.i(LOG_TAG, "Bind to VCardService.");
        // We don't want the service finishes itself just after this connection.
        Intent intent = new Intent(this, VCardService.class);
        startService(intent);
        bindService(new Intent(this, VCardService.class),
                mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if (mProgressDialogForCachingVCard != null) {
            Log.i(LOG_TAG, "Cache thread is still running. Show progress dialog again.");
            showDialog(R.id.dialog_cache_vcard);
        }
    }

    /* package */ void showFailureNotification(int reasonId) {
        final NotificationManager notificationManager =
                (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        final Notification notification =
                NotificationImportExportListener.constructImportFailureNotification(
                        ImportVCardActivity.this,
                        getString(reasonId));
        notificationManager.notify(NotificationImportExportListener.FAILURE_NOTIFICATION_TAG,
                FAILURE_NOTIFICATION_ID, notification);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(ImportVCardActivity.this,
                        getString(R.string.vcard_import_failed), Toast.LENGTH_LONG).show();
            }
        });
    }
}
