/*
 * 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.common.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.common.R;
import com.android.contacts.common.activity.RequestImportVCardPermissionsActivity;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.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.common.vcard.LOCAL_TMP_FILE_NAME";

    private static final String SOURCE_URI_DISPLAY_NAME =
            "com.android.contacts.common.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();
            }
        });
    }
}
