diff options
author | gkipnis <gkipnis@cyngn.com> | 2015-11-13 15:03:34 -0800 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2015-12-08 14:52:47 -0800 |
commit | dbcecc682dcde13911e8373056d933762e8aefca (patch) | |
tree | 87e17b44fb5d868ffffb43b7a0cc454eab5907da | |
parent | 3d4deaf5320efb43600e2f5fff783f07b9f244b4 (diff) | |
download | packages_apps_Messaging-dbcecc682dcde13911e8373056d933762e8aefca.zip packages_apps_Messaging-dbcecc682dcde13911e8373056d933762e8aefca.tar.gz packages_apps_Messaging-dbcecc682dcde13911e8373056d933762e8aefca.tar.bz2 |
Added local blacklist and framework blacklist database synchronization
Local blacklist DB acts as a WriteThrough cache of the FW blacklist DB.
1. At the App startup time, the local DB is initialized with FW DB values.
2. A ContentObserver is registered to monitor FW Blacklist DB
3. Updates to local DB are also passed to the FW DB
Change-Id: I56e1965884c383782710c90563940d75a17a7264
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | AndroidManifest.xml | 5 | ||||
-rw-r--r-- | src/com/android/messaging/BugleApplication.java | 23 | ||||
-rw-r--r-- | src/com/android/messaging/datamodel/BugleDatabaseOperations.java | 29 | ||||
-rw-r--r-- | src/com/android/messaging/util/BlacklistObserver.java | 106 | ||||
-rw-r--r-- | src/com/android/messaging/util/BlacklistSync.java | 90 |
6 files changed, 252 insertions, 3 deletions
@@ -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; + } +} |