summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk2
-rw-r--r--AndroidManifest.xml5
-rw-r--r--src/com/android/messaging/BugleApplication.java23
-rw-r--r--src/com/android/messaging/datamodel/BugleDatabaseOperations.java29
-rw-r--r--src/com/android/messaging/util/BlacklistObserver.java106
-rw-r--r--src/com/android/messaging/util/BlacklistSync.java90
6 files changed, 252 insertions, 3 deletions
diff --git a/Android.mk b/Android.mk
index 725c89d..46b90ce 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,6 +32,8 @@ LOCAL_RESOURCE_DIR += frameworks/opt/colorpicker/res
LOCAL_RESOURCE_DIR += frameworks/opt/photoviewer/res
LOCAL_RESOURCE_DIR += frameworks/opt/photoviewer/activity/res
+LOCAL_JAVA_LIBRARIES += telephony-common
+
LOCAL_STATIC_JAVA_LIBRARIES := android-common
LOCAL_STATIC_JAVA_LIBRARIES += android-common-framesequence
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8fe8fae..3266bd2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -48,6 +48,11 @@
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.READ_PHONE_BLACKLIST" />
+ <uses-permission android:name="android.permission.CHANGE_PHONE_BLACKLIST" />
+
+
+
<!-- Optional features -->
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
diff --git a/src/com/android/messaging/BugleApplication.java b/src/com/android/messaging/BugleApplication.java
index a5aea9f..756864a 100644
--- a/src/com/android/messaging/BugleApplication.java
+++ b/src/com/android/messaging/BugleApplication.java
@@ -22,13 +22,23 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
+import android.provider.Telephony;
import android.support.v7.mms.CarrierConfigValuesLoader;
import android.support.v7.mms.MmsManager;
import android.telephony.CarrierConfigManager;
+import android.util.Log;
+import com.android.messaging.datamodel.BugleDatabaseOperations;
import com.android.messaging.datamodel.DataModel;
+import com.android.messaging.datamodel.DatabaseWrapper;
+import com.android.messaging.datamodel.MessagingContentProvider;
+import com.android.messaging.datamodel.action.UpdateConversationArchiveStatusAction;
+import com.android.messaging.datamodel.action.UpdateDestinationBlockedAction;
import com.android.messaging.receiver.SmsReceiver;
import com.android.messaging.sms.ApnDatabase;
import com.android.messaging.sms.BugleApnSettingsLoader;
@@ -44,6 +54,8 @@ import com.android.messaging.util.LogUtil;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PhoneUtils;
import com.android.messaging.util.Trace;
+import com.android.messaging.util.BlacklistObserver;
+import com.android.messaging.util.BlacklistSync;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
@@ -83,8 +95,19 @@ public class BugleApplication extends Application implements UncaughtExceptionHa
LogUtil.e(TAG, "BugleApplication.onCreate: FactoryImpl.register skipped for test run");
}
+ BlacklistObserver observer = new BlacklistObserver(new Handler(), getContentResolver());
+ // TODO - need to extract URI from TelephonyProvider
+ Uri CONTENT_URI = Uri.parse("content://blacklist");
+ getContentResolver().registerContentObserver(CONTENT_URI, true, observer);
+
+ BlacklistSync blacklistSync = new BlacklistSync(getApplicationContext());
+ blacklistSync.execute();
+
+
sSystemUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
+
+
Trace.endSection();
}
diff --git a/src/com/android/messaging/datamodel/BugleDatabaseOperations.java b/src/com/android/messaging/datamodel/BugleDatabaseOperations.java
index 8c40177..9faf3d5 100644
--- a/src/com/android/messaging/datamodel/BugleDatabaseOperations.java
+++ b/src/com/android/messaging/datamodel/BugleDatabaseOperations.java
@@ -25,7 +25,9 @@ import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.support.v4.util.ArrayMap;
import android.support.v4.util.SimpleArrayMap;
+import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import com.android.internal.telephony.util.BlacklistUtils;
import com.android.messaging.Factory;
import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns;
@@ -48,6 +50,7 @@ import com.android.messaging.util.LogUtil;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PhoneUtils;
import com.android.messaging.util.UriUtil;
+import com.android.messaging.util.BlacklistSync;
import com.android.messaging.widget.WidgetConversationProvider;
import com.google.common.annotations.VisibleForTesting;
@@ -1768,16 +1771,36 @@ public class BugleDatabaseOperations {
}
@DoesNotRunOnMainThread
- public static void updateDestination(final DatabaseWrapper dbWrapper,
- final String destination, final boolean blocked) {
+ public static int updateDestination(final DatabaseWrapper dbWrapper,
+ final String destination, final boolean blocked) {
+ // by default, the framework DB is updated
+ int updateCount;
+ updateCount = updateDestination(dbWrapper, destination, blocked, true);
+ return updateCount;
+ }
+
+ @DoesNotRunOnMainThread
+ public static int updateDestination(final DatabaseWrapper dbWrapper,
+ final String destination, final boolean blocked, final boolean frameworkDb) {
Assert.isNotMainThread();
final ContentValues values = new ContentValues();
values.put(ParticipantColumns.BLOCKED, blocked ? 1 : 0);
- dbWrapper.update(DatabaseHelper.PARTICIPANTS_TABLE, values,
+ int updateCount = dbWrapper.update(DatabaseHelper.PARTICIPANTS_TABLE, values,
ParticipantColumns.NORMALIZED_DESTINATION + "=? AND " +
ParticipantColumns.SUB_ID + "=?",
new String[] { destination, Integer.toString(
ParticipantData.OTHER_THAN_SELF_SUB_ID) });
+
+ // update framework database in addition to the local database
+ if (frameworkDb) {
+ // update the framework database with the blacklisting information
+ String nn = PhoneNumberUtils.normalizeNumber(destination);
+ BlacklistUtils.addOrUpdate(dbWrapper.getContext(), nn,
+ blocked ? (BlacklistUtils.BLOCK_MESSAGES | BlacklistUtils.BLOCK_CALLS) : 0,
+ BlacklistUtils.BLOCK_MESSAGES | BlacklistUtils.BLOCK_CALLS);
+ }
+
+ return updateCount;
}
@DoesNotRunOnMainThread
diff --git a/src/com/android/messaging/util/BlacklistObserver.java b/src/com/android/messaging/util/BlacklistObserver.java
new file mode 100644
index 0000000..626a525
--- /dev/null
+++ b/src/com/android/messaging/util/BlacklistObserver.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.messaging.util;
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.util.Log;
+import com.android.messaging.BugleApplication;
+import com.android.messaging.datamodel.BugleDatabaseOperations;
+import com.android.messaging.datamodel.DataModel;
+import com.android.messaging.datamodel.DatabaseWrapper;
+import com.android.messaging.datamodel.MessagingContentProvider;
+import com.android.messaging.datamodel.action.UpdateConversationArchiveStatusAction;
+import com.android.messaging.util.LogUtil;
+
+
+// ContentObserver class to monitor changes to the Framework Blacklist DB
+public class BlacklistObserver extends ContentObserver {
+
+ private static final String TAG = BlacklistObserver.class.getSimpleName();
+ private ContentResolver mResolver;
+
+ public BlacklistObserver(Handler handler, ContentResolver resolver) {
+ super(handler);
+ mResolver = resolver;
+ }
+
+ @Override
+ public void onChange(boolean selfChange, final Uri uri) {
+ // depending on the Thread in which the handler was created, this function
+ // may or may not run on the UI thread, to be sure that it doesn't, launch
+ // it via AsyncTask
+ new SafeAsyncTask<Void, Void, Void>() {
+
+ @Override
+ protected Void doInBackgroundTimed(Void... params) {
+ if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
+ Log.i(TAG, "BlacklistObserver: onChange: Uri:" + uri.toString());
+ }
+
+ // we need to find the phone number being blacklisted and add/update it
+ // in the bugle database
+ Cursor cursor = null;
+ try {
+ cursor = mResolver.query(uri, null, null, null, null);
+ int normalizedNumberIndex = cursor.getColumnIndex("normalized_number");
+ int blockedIndex = cursor.getColumnIndex("message");
+
+ // if the column indices are not valid, don't perform the queries
+ if (normalizedNumberIndex < 0 || blockedIndex < 0) {
+ if (cursor != null) {
+ cursor.close();
+ }
+ return null;
+ }
+
+ DatabaseWrapper db = DataModel.get().getDatabase();
+
+ while(cursor.moveToNext()) {
+ String number = cursor.getString(normalizedNumberIndex);
+ String blocked = cursor.getString(blockedIndex);
+ boolean isBlocked = blocked.compareTo("1") == 0;
+
+ // don't update the framework db - the 'false' argument
+ BugleDatabaseOperations.updateDestination(db, number, isBlocked, false);
+ String conversationId = BugleDatabaseOperations
+ .getConversationFromOtherParticipantDestination(db, number);
+ if (conversationId != null) {
+ if (isBlocked) {
+ UpdateConversationArchiveStatusAction.archiveConversation(conversationId);
+ } else {
+ UpdateConversationArchiveStatusAction.unarchiveConversation(conversationId);
+ }
+ MessagingContentProvider.notifyParticipantsChanged(conversationId);
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "BlacklistObserver: onChange: " + e.getMessage());
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return null;
+ }
+ }.execute();
+
+ }
+} \ No newline at end of file
diff --git a/src/com/android/messaging/util/BlacklistSync.java b/src/com/android/messaging/util/BlacklistSync.java
new file mode 100644
index 0000000..9cc611e
--- /dev/null
+++ b/src/com/android/messaging/util/BlacklistSync.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.messaging.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.format.Time;
+import android.util.Log;
+import com.android.messaging.datamodel.BugleDatabaseOperations;
+import com.android.messaging.datamodel.DataModel;
+import com.android.messaging.datamodel.DatabaseWrapper;
+import com.android.messaging.datamodel.data.ParticipantData;
+import com.android.messaging.util.LogUtil;
+
+public class BlacklistSync extends AsyncTask<Void, Void, Void> {
+ private Context mContext;
+
+ private static final String TAG = BlacklistSync.class.getSimpleName();
+
+ public BlacklistSync(Context context) {
+ mContext = context;
+
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ // TODO - need to extract URI from TelephonyProvider
+ Uri CONTENT_URI = Uri.parse("content://blacklist");
+ Cursor cursor;
+
+ // need to update local blacklist database - we are simply overwriting the
+ // local database with the framework database - the local database is used
+ // as a WriteThrough Cache of the Framework Database
+ cursor = mContext.getContentResolver().query(CONTENT_URI, null, null, null, null);
+ if (cursor != null && cursor.getCount() > 0) {
+ int normalizedNumberIndex = cursor.getColumnIndex("normalized_number");
+ int blockedIndex = cursor.getColumnIndex("message");
+ int updateCount;
+ if (normalizedNumberIndex < 0 || blockedIndex < 0) {
+ cursor.close();
+ return null;
+ }
+
+ DatabaseWrapper db = DataModel.get().getDatabase();
+
+ while(cursor.moveToNext()) {
+ String number = cursor.getString(normalizedNumberIndex);
+ String blocked = cursor.getString(blockedIndex);
+ boolean isBlocked = blocked.compareTo("1") == 0;
+ updateCount = BugleDatabaseOperations.updateDestination(db, number, isBlocked,
+ false);
+ if (updateCount == 0) {
+ // there was no phone number in the local participants database that was
+ // blacklisted in the framework blacklist database, create a new participant
+ // and insert him into the local participants database
+ ParticipantData participant = ParticipantData
+ .getFromRawPhoneBySystemLocale(number);
+ BugleDatabaseOperations.getOrCreateParticipantInTransaction(db,
+ participant);
+ BugleDatabaseOperations.updateDestination(db, number,
+ isBlocked, false);
+ }
+ }
+ }
+ if (cursor != null) {
+ cursor.close();
+ }
+
+ return null;
+ }
+}