summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml25
-rw-r--r--src/com/android/providers/contacts/CallLogBackupAgent.java4
-rw-r--r--src/com/android/providers/contacts/CallLogProvider.java38
-rw-r--r--src/com/android/providers/contacts/ContactsDatabaseHelper.java23
-rw-r--r--src/com/android/providers/contacts/PhoneAccountRegistrationReceiver.java56
5 files changed, 125 insertions, 21 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bb8158a..bc8ddea 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3,18 +3,19 @@
android:sharedUserId="android.uid.shared"
android:sharedUserLabel="@string/sharedUserLabel">
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
- <uses-permission android:name="android.permission.READ_PROFILE" />
- <uses-permission android:name="android.permission.WRITE_PROFILE" />
- <uses-permission android:name="android.permission.GET_ACCOUNTS" />
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BIND_DIRECTORY_SEARCH" />
- <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
- <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.READ_PROFILE" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_PROFILE" />
<uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
<uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL" />
<uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL" />
@@ -71,6 +72,14 @@
</intent-filter>
</receiver>
+ <receiver android:name="PhoneAccountRegistrationReceiver"
+ android:permission="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION">
+ <!-- Broadcast sent after a phone account is registered in telecom. -->
+ <intent-filter>
+ <action android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED"/>
+ </intent-filter>
+ </receiver>
+
<receiver android:name="PackageIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
diff --git a/src/com/android/providers/contacts/CallLogBackupAgent.java b/src/com/android/providers/contacts/CallLogBackupAgent.java
index 8e160c8..6de5a5e 100644
--- a/src/com/android/providers/contacts/CallLogBackupAgent.java
+++ b/src/com/android/providers/contacts/CallLogBackupAgent.java
@@ -289,8 +289,8 @@ public class CallLogBackupAgent extends BackupAgent {
call.type = dataInput.readInt();
call.numberPresentation = dataInput.readInt();
call.accountComponentName = readString(dataInput, version);
- call.accountId = dataInput.readUTF();
- call.accountAddress = dataInput.readUTF();
+ call.accountId = readString(dataInput, version);
+ call.accountAddress = readString(dataInput, version);
call.dataUsage = dataInput.readLong();
call.features = dataInput.readInt();
}
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
index 6bf913e..1899393 100644
--- a/src/com/android/providers/contacts/CallLogProvider.java
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -39,6 +39,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
+import android.telecom.PhoneAccountHandle;
import android.text.TextUtils;
import android.util.Log;
@@ -46,7 +47,6 @@ import com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
import com.android.providers.contacts.util.SelectionBuilder;
import com.android.providers.contacts.util.UserUtils;
-
import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
@@ -60,12 +60,16 @@ public class CallLogProvider extends ContentProvider {
private static final String TAG = CallLogProvider.class.getSimpleName();
private static final int BACKGROUND_TASK_INITIALIZE = 0;
+ private static final int BACKGROUND_TASK_ADJUST_PHONE_ACCOUNT = 1;
/** Selection clause for selecting all calls that were made after a certain time */
private static final String MORE_RECENT_THAN_SELECTION = Calls.DATE + "> ?";
/** Selection clause to use to exclude voicemail records. */
private static final String EXCLUDE_VOICEMAIL_SELECTION = getInequalityClause(
Calls.TYPE, Calls.VOICEMAIL_TYPE);
+ /** Selection clause to exclude hidden records. */
+ private static final String EXCLUDE_HIDDEN_SELECTION = getEqualityClause(
+ Calls.PHONE_ACCOUNT_HIDDEN, 0);
@VisibleForTesting
static final String[] CALL_LOG_SYNC_PROJECTION = new String[] {
@@ -86,6 +90,10 @@ public class CallLogProvider extends ContentProvider {
private static final int CALLS_FILTER = 3;
+ private static final String ADJUST_FOR_NEW_PHONE_ACCOUNT_QUERY =
+ "UPDATE " + Tables.CALLS + " SET " + Calls.PHONE_ACCOUNT_HIDDEN + "=0 WHERE " +
+ Calls.PHONE_ACCOUNT_COMPONENT_NAME + "=? AND " + Calls.PHONE_ACCOUNT_ID + "=?;";
+
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(CallLog.AUTHORITY, "calls", CALLS);
@@ -109,6 +117,7 @@ public class CallLogProvider extends ContentProvider {
sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_COMPONENT_NAME, Calls.PHONE_ACCOUNT_COMPONENT_NAME);
sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_ID, Calls.PHONE_ACCOUNT_ID);
sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_ADDRESS, Calls.PHONE_ACCOUNT_ADDRESS);
+ sCallsProjectionMap.put(Calls.PHONE_ACCOUNT_HIDDEN, Calls.PHONE_ACCOUNT_HIDDEN);
sCallsProjectionMap.put(Calls.NEW, Calls.NEW);
sCallsProjectionMap.put(Calls.VOICEMAIL_URI, Calls.VOICEMAIL_URI);
sCallsProjectionMap.put(Calls.TRANSCRIPTION, Calls.TRANSCRIPTION);
@@ -155,13 +164,13 @@ public class CallLogProvider extends ContentProvider {
mBackgroundHandler = new Handler(mBackgroundThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
- performBackgroundTask(msg.what);
+ performBackgroundTask(msg.what, msg.obj);
}
};
mReadAccessLatch = new CountDownLatch(1);
- scheduleBackgroundTask(BACKGROUND_TASK_INITIALIZE);
+ scheduleBackgroundTask(BACKGROUND_TASK_INITIALIZE, null);
if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
Log.d(Constants.PERFORMANCE_TAG, "CallLogProvider.onCreate finish");
@@ -190,6 +199,7 @@ public class CallLogProvider extends ContentProvider {
final SelectionBuilder selectionBuilder = new SelectionBuilder(selection);
checkVoicemailPermissionAndAddRestriction(uri, selectionBuilder, true /*isQuery*/);
+ selectionBuilder.addClause(EXCLUDE_HIDDEN_SELECTION);
final int match = sURIMatcher.match(uri);
switch (match) {
@@ -357,6 +367,10 @@ public class CallLogProvider extends ContentProvider {
return getContext();
}
+ void adjustForNewPhoneAccount(PhoneAccountHandle handle) {
+ scheduleBackgroundTask(BACKGROUND_TASK_ADJUST_PHONE_ACCOUNT, handle);
+ }
+
/**
* Returns a {@link DatabaseModifier} that takes care of sending necessary notifications
* after the operation is performed.
@@ -467,6 +481,16 @@ public class CallLogProvider extends ContentProvider {
}
/**
+ * Un-hides any hidden call log entries that are associated with the specified handle.
+ *
+ * @param handle The handle to the newly registered {@link android.telecom.PhoneAccount}.
+ */
+ private void adjustForNewPhoneAccountInternal(PhoneAccountHandle handle) {
+ mDbHelper.getWritableDatabase().execSQL(ADJUST_FOR_NEW_PHONE_ACCOUNT_QUERY,
+ new String[] { handle.getComponentName().flattenToString(), handle.getId() });
+ }
+
+ /**
* @param cursor to copy call log entries from
*
* @return the timestamp of the last synced entry.
@@ -544,11 +568,11 @@ public class CallLogProvider extends ContentProvider {
}
}
- private void scheduleBackgroundTask(int task) {
- mBackgroundHandler.sendEmptyMessage(task);
+ private void scheduleBackgroundTask(int task, Object arg) {
+ mBackgroundHandler.obtainMessage(task, arg).sendToTarget();
}
- private void performBackgroundTask(int task) {
+ private void performBackgroundTask(int task, Object arg) {
if (task == BACKGROUND_TASK_INITIALIZE) {
try {
final Context context = getContext();
@@ -563,6 +587,8 @@ public class CallLogProvider extends ContentProvider {
mReadAccessLatch.countDown();
mReadAccessLatch = null;
}
+ } else if (task == BACKGROUND_TASK_ADJUST_PHONE_ACCOUNT) {
+ adjustForNewPhoneAccountInternal((PhoneAccountHandle) arg);
}
}
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index fc4d343..1fe874a 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -16,15 +16,14 @@
package com.android.providers.contacts;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.CharArrayBuffer;
import android.database.Cursor;
@@ -90,12 +89,12 @@ import com.android.providers.contacts.util.NeededForTesting;
import com.google.android.collect.Sets;
import com.google.common.annotations.VisibleForTesting;
+import libcore.icu.ICU;
+
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import libcore.icu.ICU;
-
/**
* Database helper for contacts. Designed as a singleton to make sure that all
* {@link android.content.ContentProvider} users get the same reference.
@@ -121,7 +120,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
* 1000-1100 M
* </pre>
*/
- static final int DATABASE_VERSION = 1003;
+ static final int DATABASE_VERSION = 1004;
public interface Tables {
public static final String CONTACTS = "contacts";
@@ -1519,6 +1518,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
Calls.PHONE_ACCOUNT_COMPONENT_NAME + " TEXT," +
Calls.PHONE_ACCOUNT_ID + " TEXT," +
Calls.PHONE_ACCOUNT_ADDRESS + " TEXT," +
+ Calls.PHONE_ACCOUNT_HIDDEN + " INTEGER NOT NULL DEFAULT 0," +
Calls.SUB_ID + " INTEGER DEFAULT -1," +
Calls.NEW + " INTEGER," +
Calls.CACHED_NAME + " TEXT," +
@@ -2881,6 +2881,11 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
oldVersion = 1003;
}
+ if (oldVersion < 1004) {
+ upgradeToVersion1004(db);
+ oldVersion = 1004;
+ }
+
if (upgradeViewsAndTriggers) {
createContactsViews(db);
createGroupsView(db);
@@ -4374,6 +4379,14 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
}
}
+ /**
+ * Add a "hidden" column for call log entries we want to hide after an upgrade until the user
+ * adds the right phone account to the device.
+ */
+ public void upgradeToVersion1004(SQLiteDatabase db) {
+ db.execSQL("ALTER TABLE calls ADD phone_account_hidden INTEGER NOT NULL DEFAULT 0;");
+ }
+
public String extractHandleFromEmailAddress(String email) {
Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email);
if (tokens.length == 0) {
diff --git a/src/com/android/providers/contacts/PhoneAccountRegistrationReceiver.java b/src/com/android/providers/contacts/PhoneAccountRegistrationReceiver.java
new file mode 100644
index 0000000..8a68889
--- /dev/null
+++ b/src/com/android/providers/contacts/PhoneAccountRegistrationReceiver.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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.providers.contacts;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.content.Intent;
+import android.provider.CallLog;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+/**
+ * This will be launched when a new phone account is registered in telecom. It is used by the call
+ * log to un-hide any entries which were previously hidden after a backup-restore until it's
+ * associated phone-account is registered with telecom.
+ *
+ * IOW, after a restore, we hide call log entries until the user inserts the corresponding SIM,
+ * registers the corresponding SIP account, or registers a corresponding alternative phone-account.
+ */
+public class PhoneAccountRegistrationReceiver extends BroadcastReceiver {
+ static final String TAG = "PhoneAccountReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // We are now running with the system up, but no apps started,
+ // so can do whatever cleanup after an upgrade that we want.
+ if (TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED.equals(intent.getAction())) {
+
+ PhoneAccountHandle handle = (PhoneAccountHandle) intent.getParcelableExtra(
+ TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+
+ IContentProvider iprovider =
+ context.getContentResolver().acquireProvider(CallLog.AUTHORITY);
+ ContentProvider provider = ContentProvider.coerceToLocalContentProvider(iprovider);
+ if (provider instanceof CallLogProvider) {
+ ((CallLogProvider) provider).adjustForNewPhoneAccount(handle);
+ }
+ }
+ }
+}