Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 450a6057 authored by Sarmad Hashmi's avatar Sarmad Hashmi
Browse files

Add voicemail_archive_table to dialer database.

Stores the voicemail content and call log information for all the
voicemails that have been archived.

BUG=22797391

Change-Id: I1b5d98ab17d3d6f32d6797c2c51b50bcd29cd5fa
(cherry picked from commit ca67dbe4)
parent f0bf4ca8
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -343,5 +343,12 @@
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

        <provider
            android:name=".database.VoicemailArchiveProvider"
            android:authorities="com.android.dialer.database.voicemailarchiveprovider"
            android:exported="false"
            android:multiprocess="false"
            />
    </application>
</manifest>
+48 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.util.Log;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.util.StopWatch;
import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns;
import com.android.dialer.database.VoicemailArchiveContract.VoicemailArchive;
import com.android.dialer.R;
import com.android.dialer.dialpad.SmartDialNameMatcher;
import com.android.dialer.dialpad.SmartDialPrefix;
@@ -75,7 +76,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
     *   0-98   KitKat
     * </pre>
     */
    public static final int DATABASE_VERSION = 8;
    public static final int DATABASE_VERSION = 9;
    public static final String DATABASE_NAME = "dialer.db";

    /**
@@ -94,6 +95,8 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
        static final String SMARTDIAL_TABLE = "smartdial_table";
        /** Saves all possible prefixes to refer to a contacts.*/
        static final String PREFIX_TABLE = "prefix_table";
        /** Saves all archived voicemail information. */
        static final String VOICEMAIL_ARCHIVE_TABLE = "voicemail_archive_table";
        /** Database properties for internal use */
        static final String PROPERTIES = "properties";
    }
@@ -434,6 +437,8 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
                + FilteredNumberColumns.TYPE + " INTEGER,"
                + FilteredNumberColumns.SOURCE + " INTEGER"
                + ");");

        createVoicemailArchiveTable(db);
        setProperty(db, DATABASE_VERSION_PROPERTY, String.valueOf(DATABASE_VERSION));
        if (!mIsTestInstance) {
            resetSmartDialLastUpdatedTime();
@@ -445,6 +450,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
        db.execSQL("DROP TABLE IF EXISTS " + Tables.SMARTDIAL_TABLE);
        db.execSQL("DROP TABLE IF EXISTS " + Tables.PROPERTIES);
        db.execSQL("DROP TABLE IF EXISTS " + Tables.FILTERED_NUMBER_TABLE);
        db.execSQL("DROP TABLE IF EXISTS " + Tables.VOICEMAIL_ARCHIVE_TABLE);
    }

    @Override
@@ -486,6 +492,12 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
            oldVersion = 8;
        }

        if (oldVersion < 9) {
            db.execSQL("DROP TABLE IF EXISTS " + Tables.VOICEMAIL_ARCHIVE_TABLE);
            createVoicemailArchiveTable(db);
            oldVersion = 9;
        }

        if (oldVersion != DATABASE_VERSION) {
            throw new IllegalStateException(
                    "error upgrading the database to version " + DATABASE_VERSION);
@@ -652,6 +664,41 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper {
                SmartDialDbColumns.LAST_SMARTDIAL_UPDATE_TIME + " > " + last_update_time, null);
    }

    /**
     * All columns excluding MIME_TYPE, _DATA, ARCHIVED, SERVER_ID, are the same as
     *  the columns in the {@link android.provider.CallLog.Calls} table.
     *
     *  @param db Database pointer to the dialer database.
     */
    private void createVoicemailArchiveTable(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + Tables.VOICEMAIL_ARCHIVE_TABLE + " ("
                + VoicemailArchive._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + VoicemailArchive.NUMBER + " TEXT,"
                + VoicemailArchive.DATE + " LONG,"
                + VoicemailArchive.DURATION + " LONG,"
                + VoicemailArchive.MIME_TYPE + " TEXT,"
                + VoicemailArchive.COUNTRY_ISO + " TEXT,"
                + VoicemailArchive._DATA + " TEXT,"
                + VoicemailArchive.GEOCODED_LOCATION + " TEXT,"
                + VoicemailArchive.CACHED_NAME + " TEXT,"
                + VoicemailArchive.CACHED_NUMBER_TYPE + " INTEGER,"
                + VoicemailArchive.CACHED_NUMBER_LABEL + " TEXT,"
                + VoicemailArchive.CACHED_LOOKUP_URI + " TEXT,"
                + VoicemailArchive.CACHED_MATCHED_NUMBER + " TEXT,"
                + VoicemailArchive.CACHED_NORMALIZED_NUMBER + " TEXT,"
                + VoicemailArchive.CACHED_PHOTO_ID + " LONG,"
                + VoicemailArchive.CACHED_FORMATTED_NUMBER + " TEXT,"
                + VoicemailArchive.ARCHIVED + " INTEGER,"
                + VoicemailArchive.NUMBER_PRESENTATION + " INTEGER,"
                + VoicemailArchive.ACCOUNT_COMPONENT_NAME + " TEXT,"
                + VoicemailArchive.ACCOUNT_ID + " TEXT,"
                + VoicemailArchive.FEATURES + " INTEGER,"
                + VoicemailArchive.SERVER_ID + " INTEGER,"
                + VoicemailArchive.TRANSCRIPTION + " TEXT,"
                + VoicemailArchive.CACHED_PHOTO_URI + " TEXT"
                + ");");
    }

    /**
     * Removes all entries in the smartdial contact database.
     */
+201 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.dialer.database;

import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.CallLog;
import android.provider.OpenableColumns;

/**
 * Contains definitions for the supported URIs and columns for the voicemail archive table.
 * All the fields excluding MIME_TYPE, _DATA, ARCHIVED, SERVER_ID, mirror the fields in the
 * contract provided in {@link CallLog.Calls}.
 */
public final class VoicemailArchiveContract {

    /** The authority used by the voicemail archive provider. */
    public static final String AUTHORITY = "com.android.dialer.database.voicemailarchiveprovider";

    /** A content:// style uri for the voicemail archive provider */
    public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);

    public static final class VoicemailArchive implements BaseColumns, OpenableColumns {

        public static final String VOICEMAIL_ARCHIVE_TABLE = "voicemail_archive_table";

        public static final Uri CONTENT_URI = Uri.withAppendedPath(
                AUTHORITY_URI,
                VOICEMAIL_ARCHIVE_TABLE);

        /**
         * @see android.provider.CallLog.Calls#NUMBER
         * TYPE: TEXT
         */
        public static final String NUMBER = CallLog.Calls.NUMBER;

        /**
         * @see android.provider.CallLog.Calls#DATE
         * TYPE: LONG
         */
        public static final String DATE = CallLog.Calls.DATE;

        /**
         * @see android.provider.CallLog.Calls#DURATION
         * TYPE: LONG
         */
        public static final String DURATION =  CallLog.Calls.DURATION;

        /**
         * The mime type of the archived voicemail file.
         * TYPE: TEXT
         */
        public static final String MIME_TYPE = "mime_type";

        /**
         * @see android.provider.CallLog.Calls#COUNTRY_ISO
         * TYPE: LONG
         */
        public static final String COUNTRY_ISO = CallLog.Calls.COUNTRY_ISO;

        /**
         * The path of the archived voicemail file.
         * TYPE: TEXT
         */
        public static final String _DATA = "_data";

        /**
         * @see android.provider.CallLog.Calls#GEOCODED_LOCATION
         * TYPE: TEXT
         */
        public static final String GEOCODED_LOCATION = CallLog.Calls.GEOCODED_LOCATION;

        /**
         * @see android.provider.CallLog.Calls#CACHED_NAME
         * TYPE: TEXT
         */
        public static final String CACHED_NAME = CallLog.Calls.CACHED_NAME;

        /**
         * @see android.provider.CallLog.Calls#CACHED_NUMBER_TYPE
         * TYPE: INTEGER
         */
        public static final String CACHED_NUMBER_TYPE = CallLog.Calls.CACHED_NUMBER_TYPE;

        /**
         * @see android.provider.CallLog.Calls#CACHED_NUMBER_LABEL
         * TYPE: TEXT
         */
        public static final String CACHED_NUMBER_LABEL = CallLog.Calls.CACHED_NUMBER_LABEL;

        /**
         * @see android.provider.CallLog.Calls#CACHED_LOOKUP_URI
         * TYPE: TEXT
         */
        public static final String CACHED_LOOKUP_URI = CallLog.Calls.CACHED_LOOKUP_URI;

        /**
         * @see android.provider.CallLog.Calls#CACHED_MATCHED_NUMBER
         * TYPE: TEXT
         */
        public static final String CACHED_MATCHED_NUMBER = CallLog.Calls.CACHED_MATCHED_NUMBER;

        /**
         * @see android.provider.CallLog.Calls#CACHED_NORMALIZED_NUMBER
         * TYPE: TEXT
         */
        public static final String CACHED_NORMALIZED_NUMBER =
                CallLog.Calls.CACHED_NORMALIZED_NUMBER;

        /**
         * @see android.provider.CallLog.Calls#CACHED_PHOTO_ID
         * TYPE: LONG
         */
        public static final String CACHED_PHOTO_ID = CallLog.Calls.CACHED_PHOTO_ID;

        /**
         * @see android.provider.CallLog.Calls#CACHED_FORMATTED_NUMBER
         * TYPE: TEXT
         */
        public static final String CACHED_FORMATTED_NUMBER = CallLog.Calls.CACHED_FORMATTED_NUMBER;

        /**
         * If the voicemail was archived by the user by pressing the archive button, this is set to
         * 1 (true). If the voicemail was archived for the purpose of forwarding to other
         * applications, this is set to 0 (false).
         * TYPE: INTEGER
         */
        public static final String ARCHIVED = "archived_by_user";

        /**
         * @see android.provider.CallLog.Calls#NUMBER_PRESENTATION
         * TYPE: INTEGER
         */
        public static final String NUMBER_PRESENTATION = CallLog.Calls.NUMBER_PRESENTATION;

        /**
         * @see android.provider.CallLog.Calls#PHONE_ACCOUNT_COMPONENT_NAME
         * TYPE: TEXT
         */
        public static final String ACCOUNT_COMPONENT_NAME =
                CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME;

        /**
         * @see android.provider.CallLog.Calls#PHONE_ACCOUNT_ID
         * TYPE: TEXT
         */
        public static final String ACCOUNT_ID = CallLog.Calls.PHONE_ACCOUNT_ID;

        /**
         * @see android.provider.CallLog.Calls#FEATURES
         * TYPE: INTEGER
         */
        public static final String FEATURES = CallLog.Calls.FEATURES;

        /**
         * The id of the voicemail on the server.
         * TYPE: INTEGER
         */
        public static final String SERVER_ID = "server_id";

        /**
         * @see android.provider.CallLog.Calls#TRANSCRIPTION
         * TYPE: TEXT
         */
        public static final String TRANSCRIPTION = CallLog.Calls.TRANSCRIPTION;

        /**
         * @see android.provider.CallLog.Calls#CACHED_PHOTO_URI
         * TYPE: TEXT
         */
        public static final String CACHED_PHOTO_URI = CallLog.Calls.CACHED_PHOTO_URI;

        /**
         * The MIME type of a {@link #CONTENT_URI} single voicemail.
         */
        public static final String CONTENT_ITEM_TYPE =
                "vnd.android.cursor.item/voicmail_archive_table";

        public static final Uri buildWithId(int id) {
            return Uri.withAppendedPath(CONTENT_URI, Integer.toString(id));
        }

        /** Not instantiable. */
        private VoicemailArchive() {
        }
    }
}
+211 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.dialer.database;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.android.dialerbind.DatabaseHelperManager;
import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * An implementation of the Voicemail Archive content provider. This class performs
 * all database level operations on the voicemail_archive_table.
 */
public class VoicemailArchiveProvider extends ContentProvider {
    private static final String TAG = "VMArchiveProvider";
    private static final int VOICEMAIL_ARCHIVE_TABLE = 1;
    private static final int VOICEMAIL_ARCHIVE_TABLE_ID = 2;
    private static final String VOICEMAIL_FOLDER = "voicemails";

    private DialerDatabaseHelper mDialerDatabaseHelper;
    private final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    @Override
    public boolean onCreate() {
         mDialerDatabaseHelper = getDatabaseHelper(getContext());
         if (mDialerDatabaseHelper == null) {
             return false;
         }
        mUriMatcher.addURI(VoicemailArchiveContract.AUTHORITY,
                 VoicemailArchiveContract.VoicemailArchive.VOICEMAIL_ARCHIVE_TABLE,
                 VOICEMAIL_ARCHIVE_TABLE);
        mUriMatcher.addURI(VoicemailArchiveContract.AUTHORITY,
                 VoicemailArchiveContract.VoicemailArchive.VOICEMAIL_ARCHIVE_TABLE + "/#",
                 VOICEMAIL_ARCHIVE_TABLE_ID);
         return true;
    }

    @VisibleForTesting
    protected DialerDatabaseHelper getDatabaseHelper(Context context) {
        return DatabaseHelperManager.getDatabaseHelper(context);
    }

    /**
     * Used by the test class because it extends {@link android.test.ProviderTestCase2} in which the
     * {@link android.test.IsolatedContext} returns /dev/null when getFilesDir() is called.
     *
     * @see android.test.IsolatedContext#getFilesDir
     */
    @VisibleForTesting
    protected File getFilesDir() {
        return getContext().getFilesDir();
    }

    @Nullable
    @Override
    public Cursor query(Uri uri,
                        @Nullable String[] projection,
                        @Nullable String selection,
                        @Nullable String[] selectionArgs,
                        @Nullable String sortOrder) {
        SQLiteDatabase db = mDialerDatabaseHelper.getReadableDatabase();
        SQLiteQueryBuilder queryBuilder = getQueryBuilder(uri);
        Cursor cursor = queryBuilder
                .query(db, projection, selection, selectionArgs, null, null, sortOrder);
        if (cursor != null) {
            cursor.setNotificationUri(getContext().getContentResolver(),
                    VoicemailArchiveContract.VoicemailArchive.CONTENT_URI);
        }
        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        return VoicemailArchiveContract.VoicemailArchive.CONTENT_ITEM_TYPE;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = mDialerDatabaseHelper.getWritableDatabase();
        long id = db.insert(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE,
                null, values);
        if (id < 0) {
            return null;
        }
        notifyChange(uri);
        // Create the directory for archived voicemails if it doesn't already exist
        File directory = new File(getFilesDir(), VOICEMAIL_FOLDER);
        directory.mkdirs();

        // Update the row's _data column with a file path in the voicemails folder
        Uri newUri = ContentUris.withAppendedId(uri, id);
        File voicemailFile = new File(directory, Long.toString(id));
        values.put(VoicemailArchiveContract.VoicemailArchive._DATA, voicemailFile.getPath());
        update(newUri, values, null, null);
        return newUri;
    }


    @Override
    public int delete(Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        SQLiteDatabase db = mDialerDatabaseHelper.getWritableDatabase();
        SQLiteQueryBuilder queryBuilder = getQueryBuilder(uri);
        Cursor cursor = queryBuilder.query(db, null, selection, selectionArgs, null, null, null);

        // Delete all the voicemail files related to the selected rows
        while (cursor.moveToNext()) {
            deleteFile(cursor.getString(cursor.getColumnIndex(
                    VoicemailArchiveContract.VoicemailArchive._DATA)));
        }

        int rows = db.delete(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE,
                getSelectionWithId(selection, uri),
                selectionArgs);
        if (rows > 0) {
            notifyChange(uri);
        }
        return rows;
    }

    @Override
    public int update(Uri uri,
                      ContentValues values,
                      @Nullable String selection,
                      @Nullable String[] selectionArgs) {
        SQLiteDatabase db = mDialerDatabaseHelper.getWritableDatabase();
        selection = getSelectionWithId(selection, uri);
        int rows = db.update(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE,
                values,
                selection,
                selectionArgs);
        if (rows > 0) {
            notifyChange(uri);
        }
        return rows;
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        if (mUriMatcher.match(uri) != VOICEMAIL_ARCHIVE_TABLE_ID) {
            throw new IllegalArgumentException("URI Invalid.");
        }
        return openFileHelper(uri, mode);
    }

    private void deleteFile(@Nullable String path) {
        if (TextUtils.isEmpty(path)) {
            return;
        }
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        }
    }

    private SQLiteQueryBuilder getQueryBuilder(Uri uri) {
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        queryBuilder.setTables(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE);
        String selectionWithId = getSelectionWithId(null, uri);
        if (!TextUtils.isEmpty(selectionWithId)) {
            queryBuilder.appendWhere(selectionWithId);
        }
        return queryBuilder;
    }

    private String getSelectionWithId(String selection, Uri uri) {
        int match = mUriMatcher.match(uri);
        switch (match) {
            case VOICEMAIL_ARCHIVE_TABLE:
                return selection;
            case VOICEMAIL_ARCHIVE_TABLE_ID:
                String idStr = VoicemailArchiveContract.VoicemailArchive._ID + "=" +
                        ContentUris.parseId(uri);
                return TextUtils.isEmpty(selection) ? idStr : selection + " AND " + idStr;
            default:
                throw new IllegalArgumentException("Unknown uri: " + uri);
        }
    }

    private void notifyChange(Uri uri) {
        getContext().getContentResolver().notifyChange(uri, null);
    }
}
+266 −0

File added.

Preview size limit exceeded, changes collapsed.