summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortnmy-cyngn <tlnu@cyngn.com>2016-04-15 02:46:22 +0530
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-04-22 12:56:22 -0700
commit22d92d6675a139bf63613788f19f06ed59449315 (patch)
treec104e47243cbcb05e6c039ca8c4d2f2a67b28040
parent98df70d4e4210517bc810df59e7a956a5688f9b0 (diff)
downloadpackages_apps_Messaging-22d92d6675a139bf63613788f19f06ed59449315.zip
packages_apps_Messaging-22d92d6675a139bf63613788f19f06ed59449315.tar.gz
packages_apps_Messaging-22d92d6675a139bf63613788f19f06ed59449315.tar.bz2
Text/Multimedia message limit feature
Porting feature from 12.1 to 13.1 Feature to set/configure SMS and MMS limits per conversation. Bug: PAELLA-194,PAELLA-195 Change-Id: Ib1bd15f58a3d33572484d8c28de42e481c66f6b0
-rw-r--r--res/layout/number_picker_dialog.xml59
-rw-r--r--res/values/cm_strings.xml12
-rw-r--r--res/xml-v21/preferences_application.xml26
-rw-r--r--res/xml-v23/preferences_application.xml26
-rw-r--r--res/xml/preferences_application.xml26
-rw-r--r--src/android/support/v7/mms/CarrierConfigValuesLoader.java20
-rw-r--r--src/com/android/messaging/datamodel/BugleDatabaseOperations.java63
-rw-r--r--src/com/android/messaging/datamodel/action/InsertNewMessageAction.java4
-rw-r--r--src/com/android/messaging/datamodel/action/MessageRecyclerAction.java131
-rw-r--r--src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java1
-rw-r--r--src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java3
-rw-r--r--src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java2
-rw-r--r--src/com/android/messaging/datamodel/action/SyncMessageBatch.java3
-rwxr-xr-xsrc/com/android/messaging/sms/MmsConfig.java36
-rw-r--r--src/com/android/messaging/sms/MmsUtils.java33
-rw-r--r--src/com/android/messaging/ui/NumberPickerDialog.java139
-rw-r--r--src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java59
-rw-r--r--src/com/cyanogenmod/messaging/util/PrefsUtils.java48
18 files changed, 685 insertions, 6 deletions
diff --git a/res/layout/number_picker_dialog.xml b/res/layout/number_picker_dialog.xml
new file mode 100644
index 0000000..b94f9ad
--- /dev/null
+++ b/res/layout/number_picker_dialog.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, Google Inc.
+**
+** 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.
+*/
+-->
+
+<!--
+This layout file is used by the AlertDialog when displaying a list of items.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent" >
+
+ <TextView
+ android:id="@+id/header"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="1dip" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingTop="10dip"
+ android:orientation="horizontal">
+
+ <NumberPicker
+ android:id="@+id/number_picker"
+ android:layout_width="100dip"
+ android:layout_height="150dip" />
+
+ <TextView
+ android:id="@+id/unit"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="10dp"
+ android:layout_gravity="center_vertical"
+ android:visibility="gone" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 674e3ec..4ad47e2 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -46,6 +46,18 @@
<string name="priority_normal">Normal</string>
<string name="priority_high">High</string>
+ <!-- Storage specific Settings -->
+ <string name="sms_storage_pref_title">Storage</string>
+ <string name="pref_summary_auto_delete">Delete old messages as limits are reached</string>
+ <string name="auto_delete_pref_title">Delete old messages</string>
+ <string name="pref_summary_delete_limit"><xliff:g id="count">%1$s</xliff:g> messages per conversation</string>
+ <string name="sms_delete_pref_title">Text message limit</string>
+ <string name="mms_delete_pref_title">Multimedia message limit</string>
+ <string name="set">Set</string>
+ <string name="no">Cancel</string>
+ <string name="pref_messages_to_save">Set number of messages to save</string>
+
+
<!-- Swipe to delete conversation -->
<string name="swipe_to_delete_conversation_pref_title">Swipe to delete</string>
<string name="swipe_to_delete_conversation_pref_summary">Swipe to the right to delete a conversation</string>
diff --git a/res/xml-v21/preferences_application.xml b/res/xml-v21/preferences_application.xml
index 8acbae1..4d39999 100644
--- a/res/xml-v21/preferences_application.xml
+++ b/res/xml-v21/preferences_application.xml
@@ -119,6 +119,32 @@
android:defaultValue="false"
android:persistent="true" />
+ <!--Storage Preferences-->
+ <PreferenceCategory
+ android:title="@string/sms_storage_pref_title"
+ android:key="storage_settings_pref_key">
+
+ <SwitchPreference
+ android:defaultValue="true"
+ android:key="auto_delete_pref_key"
+ android:summary="@string/pref_summary_auto_delete"
+ android:title="@string/auto_delete_pref_title" />
+
+ <Preference
+ android:key="sms_delete_limit_pref_key"
+ android:dependency="auto_delete_pref_key"
+ android:persistent="false"
+ android:summary="@string/pref_summary_delete_limit"
+ android:title="@string/sms_delete_pref_title" />
+
+ <Preference
+ android:key="mms_delete_limit_pref_key"
+ android:dependency="auto_delete_pref_key"
+ android:persistent="false"
+ android:summary="@string/pref_summary_delete_limit"
+ android:title="@string/mms_delete_pref_title" />
+ </PreferenceCategory>
+
<!-- QuickMessage settings -->
<PreferenceCategory android:title="@string/pref_quickmessage">
diff --git a/res/xml-v23/preferences_application.xml b/res/xml-v23/preferences_application.xml
index 29a5a91..95ba3c3 100644
--- a/res/xml-v23/preferences_application.xml
+++ b/res/xml-v23/preferences_application.xml
@@ -121,6 +121,32 @@
android:defaultValue="false"
android:persistent="true" />
+ <!--Storage Preferences-->
+ <PreferenceCategory
+ android:title="@string/sms_storage_pref_title"
+ android:key="storage_settings_pref_key">
+
+ <SwitchPreference
+ android:defaultValue="true"
+ android:key="auto_delete_pref_key"
+ android:summary="@string/pref_summary_auto_delete"
+ android:title="@string/auto_delete_pref_title" />
+
+ <Preference
+ android:key="sms_delete_limit_pref_key"
+ android:dependency="auto_delete_pref_key"
+ android:persistent="false"
+ android:summary="@string/pref_summary_delete_limit"
+ android:title="@string/sms_delete_pref_title" />
+
+ <Preference
+ android:key="mms_delete_limit_pref_key"
+ android:dependency="auto_delete_pref_key"
+ android:persistent="false"
+ android:summary="@string/pref_summary_delete_limit"
+ android:title="@string/mms_delete_pref_title" />
+ </PreferenceCategory>
+
<!-- QuickMessage settings -->
<PreferenceCategory android:title="@string/pref_quickmessage">
diff --git a/res/xml/preferences_application.xml b/res/xml/preferences_application.xml
index 0e8aa45..64bc7e2 100644
--- a/res/xml/preferences_application.xml
+++ b/res/xml/preferences_application.xml
@@ -119,6 +119,32 @@
android:defaultValue="false"
android:persistent="true" />
+ <!--Storage Preferences-->
+ <PreferenceCategory
+ android:title="@string/sms_storage_pref_title"
+ android:key="storage_settings_pref_key">
+
+ <SwitchPreference
+ android:defaultValue="true"
+ android:key="auto_delete_pref_key"
+ android:summary="@string/pref_summary_auto_delete"
+ android:title="@string/auto_delete_pref_title" />
+
+ <Preference
+ android:key="sms_delete_limit_pref_key"
+ android:dependency="auto_delete_pref_key"
+ android:persistent="false"
+ android:summary="@string/pref_summary_delete_limit"
+ android:title="@string/sms_delete_pref_title" />
+
+ <Preference
+ android:key="mms_delete_limit_pref_key"
+ android:dependency="auto_delete_pref_key"
+ android:persistent="false"
+ android:summary="@string/pref_summary_delete_limit"
+ android:title="@string/mms_delete_pref_title" />
+ </PreferenceCategory>
+
<!-- QuickMessage settings -->
<PreferenceCategory android:title="@string/pref_quickmessage">
diff --git a/src/android/support/v7/mms/CarrierConfigValuesLoader.java b/src/android/support/v7/mms/CarrierConfigValuesLoader.java
index ad94fb2..e9798d2 100644
--- a/src/android/support/v7/mms/CarrierConfigValuesLoader.java
+++ b/src/android/support/v7/mms/CarrierConfigValuesLoader.java
@@ -195,4 +195,24 @@ public interface CarrierConfigValuesLoader {
*/
public static final String CONFIG_NAI_SUFFIX = "naiSuffix";
public static final String CONFIG_NAI_SUFFIX_DEFAULT = null;
+ /**
+ * Integer value: default limit for number of SMS per conversation
+ */
+ public static final String CONFIG_SMS_MESSAGES_PER_THREAD = "defaultSMSMessagesPerThread";
+ public static final int CONFIG_SMS_MESSAGES_PER_THREAD_DEFAULT = 10000;
+ /**
+ * Integer value: default limit for number of MMS per conversation
+ */
+ public static final String CONFIG_MMS_MESSAGES_PER_THREAD = "defaultMMSMessagesPerThread";
+ public static final int CONFIG_MMS_MESSAGES_PER_THREAD_DEFAULT = 1000;
+ /**
+ * Integer value: minimum limit for number of messages per conversation
+ */
+ public static final String CONFIG_MIN_MESSAGE_COUNT_PER_THREAD = "minMessageCountPerThread";
+ public static final int CONFIG_MIN_MESSAGE_COUNT_PER_THREAD_DEFAULT = 10;
+ /**
+ * Integer value: maximum limit for number of messages per conversation
+ */
+ public static final String CONFIG_MAX_MESSAGE_COUNT_PER_THREAD = "maxMessageCountPerThread";
+ public static final int CONFIG_MAX_MESSAGE_COUNT_PER_THREAD_DEFAULT = 10000;
}
diff --git a/src/com/android/messaging/datamodel/BugleDatabaseOperations.java b/src/com/android/messaging/datamodel/BugleDatabaseOperations.java
index 9faf3d5..f80abdf 100644
--- a/src/com/android/messaging/datamodel/BugleDatabaseOperations.java
+++ b/src/com/android/messaging/datamodel/BugleDatabaseOperations.java
@@ -1939,4 +1939,67 @@ public class BugleDatabaseOperations {
Assert.inRange(count, 0, 1);
return (count >= 0);
}
+
+ @DoesNotRunOnMainThread
+ public static boolean deleteConversationByProtocol(final DatabaseWrapper dbWrapper,
+ final String conversationId, final long cutoffTimestamp, final int protocol) {
+ if (protocol != MessageData.PROTOCOL_SMS && protocol != MessageData.PROTOCOL_MMS) {
+ return false;
+ }
+
+ Assert.isNotMainThread();
+ dbWrapper.beginTransaction();
+ boolean conversationDeleted = false;
+ boolean conversationMessagesDeleted;
+ try {
+ // Delete all messages prior to the cutoff
+ dbWrapper.delete(DatabaseHelper.MESSAGES_TABLE,
+ MessageColumns.CONVERSATION_ID + "=? AND "
+ + MessageColumns.RECEIVED_TIMESTAMP + "<=? AND "
+ + MessageColumns.PROTOCOL + "=?",
+ new String[] { conversationId, Long.toString(cutoffTimestamp),
+ Integer.toString(protocol) });
+ // Check to see if there are any messages left in the conversation
+ final long count = dbWrapper.queryNumEntries(DatabaseHelper.MESSAGES_TABLE,
+ MessageColumns.CONVERSATION_ID + "=?", new String[] { conversationId });
+ conversationMessagesDeleted = (count <= 0);
+
+ if (conversationMessagesDeleted) {
+ // Delete conversation row
+ final int conversationCount = dbWrapper.delete(DatabaseHelper.CONVERSATIONS_TABLE,
+ ConversationColumns._ID + "=?", new String[] { conversationId });
+ conversationDeleted = (conversationCount > 0);
+ }
+ dbWrapper.setTransactionSuccessful();
+ } finally {
+ dbWrapper.endTransaction();
+ }
+ return conversationDeleted;
+ }
+
+ public static long getCutOffTimeStampFromLimit(final String conversationId,
+ final int maxLimit, final int protocol) {
+ final DatabaseWrapper db = DataModel.get().getDatabase();
+ db.beginTransaction();
+ Cursor cursor = null;
+ Long cutoffTimeStamp = Long.MIN_VALUE;
+ try {
+ cursor = db.query(DatabaseHelper.MESSAGES_TABLE,
+ new String[]{ MessageColumns.RECEIVED_TIMESTAMP },
+ MessageColumns.CONVERSATION_ID + "=? AND " + MessageColumns.PROTOCOL + "=?",
+ new String[]{ conversationId, Integer.toString(protocol) }, null, null,
+ MessageColumns.RECEIVED_TIMESTAMP + " DESC", null);
+ if (cursor != null && cursor.getCount() > maxLimit) {
+ cursor.moveToPosition(maxLimit);
+ cutoffTimeStamp = cursor.getLong(0);
+ }
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return cutoffTimeStamp;
+ }
}
diff --git a/src/com/android/messaging/datamodel/action/InsertNewMessageAction.java b/src/com/android/messaging/datamodel/action/InsertNewMessageAction.java
index 2567ca9..6f8dd82 100644
--- a/src/com/android/messaging/datamodel/action/InsertNewMessageAction.java
+++ b/src/com/android/messaging/datamodel/action/InsertNewMessageAction.java
@@ -334,6 +334,7 @@ public class InsertNewMessageAction extends Action implements Parcelable {
}
MessagingContentProvider.notifyMessagesChanged(conversationId);
MessagingContentProvider.notifyPartsChanged();
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_SMS);
} else {
// Ignore error as we only really care about the individual messages?
LogUtil.e(TAG,
@@ -412,6 +413,7 @@ public class InsertNewMessageAction extends Action implements Parcelable {
}
MessagingContentProvider.notifyMessagesChanged(conversationId);
MessagingContentProvider.notifyPartsChanged();
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_SMS);
} else {
LogUtil.e(TAG, "InsertNewMessageAction: No uri for SMS inserted into telephony DB");
}
@@ -452,7 +454,7 @@ public class InsertNewMessageAction extends Action implements Parcelable {
}
MessagingContentProvider.notifyMessagesChanged(conversationId);
MessagingContentProvider.notifyPartsChanged();
-
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_MMS);
return message;
}
diff --git a/src/com/android/messaging/datamodel/action/MessageRecyclerAction.java b/src/com/android/messaging/datamodel/action/MessageRecyclerAction.java
new file mode 100644
index 0000000..86da6aa
--- /dev/null
+++ b/src/com/android/messaging/datamodel/action/MessageRecyclerAction.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 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.datamodel.action;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+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.data.MessageData;
+import com.android.messaging.sms.MmsUtils;
+import com.android.messaging.util.LogUtil;
+import com.cyanogenmod.messaging.util.PrefsUtils;
+
+/*
+ * Action used to delete a messages based on limit specified by user/config.
+ */
+
+
+public class MessageRecyclerAction extends Action implements Parcelable {
+ private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG;
+
+ public static void deleteMessagesOverLimit(final String conversationId, int protocol) {
+
+ if (!PrefsUtils.isAutoDeleteEnabled() || (protocol != MessageData.PROTOCOL_SMS
+ && protocol != MessageData.PROTOCOL_MMS)) {
+ return;
+ }
+
+ int cutOffLimit = PrefsUtils.getMessagesPerThreadLimitByProtocol(protocol);
+ long cutOffTimeStampFromLimit = BugleDatabaseOperations.
+ getCutOffTimeStampFromLimit(conversationId, cutOffLimit, MessageData.PROTOCOL_SMS);
+
+ if (cutOffTimeStampFromLimit > Long.MIN_VALUE) {
+ deleteMessages(conversationId, protocol, cutOffTimeStampFromLimit);
+ }
+ }
+
+ public static void deleteMessages(final String conversationId,
+ final int protocol, final long cutOffTimeStamp) {
+ final MessageRecyclerAction action =
+ new MessageRecyclerAction(conversationId, protocol, cutOffTimeStamp);
+ action.start();
+ }
+
+ private static final String KEY_CONVERSATION_ID = "key_conversation_id";
+ private static final String KEY_PROTOCOL = "key_protocol";
+ private static final String KEY_CUTOFF_TIMESTAMP = "key_cutoff_timestamp";
+
+ private MessageRecyclerAction(final String conversationId,
+ final int protocol, final long cutOffTimeStamp) {
+ super();
+ actionParameters.putString(KEY_CONVERSATION_ID, conversationId);
+ actionParameters.putInt(KEY_PROTOCOL, protocol);
+ actionParameters.putLong(KEY_CUTOFF_TIMESTAMP, cutOffTimeStamp);
+ }
+
+ @Override
+ protected Bundle doBackgroundWork() {
+ final DatabaseWrapper db = DataModel.get().getDatabase();
+
+ final String conversationId = actionParameters.getString(KEY_CONVERSATION_ID);
+ final int protocol = actionParameters.getInt(KEY_PROTOCOL);
+ final long cutOffTimeStamp = actionParameters.getLong(KEY_CUTOFF_TIMESTAMP);
+
+ if (!TextUtils.isEmpty(conversationId)) {
+ // Delete from local DB
+ BugleDatabaseOperations.
+ deleteConversationByProtocol(db, conversationId, cutOffTimeStamp, protocol);
+
+ // We may have changed the conversation list
+ MessagingContentProvider.notifyMessagesChanged(conversationId);
+ MessagingContentProvider.notifyConversationListChanged();
+
+ int count = MmsUtils.deleteMessagesOlderThanByProtocol(cutOffTimeStamp, protocol);
+ if (count > 0) {
+ LogUtil.i(TAG, "MessageRecyclerAction: Deleted telephony messages "
+ + count);
+ } else {
+ LogUtil.w(TAG, "MessageRecyclerAction: Could not delete message from telephony");
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected Object executeAction() {
+ requestBackgroundWork();
+ return null;
+ }
+
+ private MessageRecyclerAction(final Parcel in) {
+ super(in);
+ }
+
+ public static final Creator<MessageRecyclerAction> CREATOR
+ = new Creator<MessageRecyclerAction>() {
+ @Override
+ public MessageRecyclerAction createFromParcel(final Parcel in) {
+ return new MessageRecyclerAction(in);
+ }
+
+ @Override
+ public MessageRecyclerAction[] newArray(final int size) {
+ return new MessageRecyclerAction[size];
+ }
+ };
+
+ @Override
+ public void writeToParcel(final Parcel parcel, final int flags) {
+ writeActionToParcel(parcel, flags);
+ }
+}
diff --git a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java b/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java
index 757ea05..93f738f 100644
--- a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java
+++ b/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java
@@ -545,6 +545,7 @@ public class ProcessDownloadedMmsAction extends Action {
}
MessagingContentProvider.notifyMessagesChanged(notificationConversationId);
MessagingContentProvider.notifyPartsChanged();
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_MMS);
return message;
}
diff --git a/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java b/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java
index 6794b17..4ebc8b4 100644
--- a/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java
+++ b/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java
@@ -134,7 +134,8 @@ public class ReceiveMmsMessageAction extends Action implements Parcelable {
if (!autoDownload) {
MessagingContentProvider.notifyMessagesChanged(message.getConversationId());
MessagingContentProvider.notifyPartsChanged();
-
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId,
+ MessageData.PROTOCOL_MMS);
// Show a notification to let the user know a new message has arrived
BugleNotifications.update(false/*silent*/, conversationId,
BugleNotifications.UPDATE_ALL);
diff --git a/src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java b/src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java
index 5ffb35d..b8c97b9 100644
--- a/src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java
+++ b/src/com/android/messaging/datamodel/action/ReceiveSmsMessageAction.java
@@ -170,7 +170,7 @@ public class ReceiveSmsMessageAction extends Action implements Parcelable {
MessagingContentProvider.notifyMessagesChanged(conversationId);
MessagingContentProvider.notifyPartsChanged();
-
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_SMS);
return message;
}
diff --git a/src/com/android/messaging/datamodel/action/SyncMessageBatch.java b/src/com/android/messaging/datamodel/action/SyncMessageBatch.java
index 972d691..87e7448 100644
--- a/src/com/android/messaging/datamodel/action/SyncMessageBatch.java
+++ b/src/com/android/messaging/datamodel/action/SyncMessageBatch.java
@@ -192,6 +192,7 @@ class SyncMessageBatch {
+ message.getReceivedTimeStamp());
}
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_SMS);
// Keep track of updated conversation for later updating the conversation snippet, etc.
mConversationsToUpdate.add(conversationId);
}
@@ -281,7 +282,7 @@ class SyncMessageBatch {
+ " for MMS " + message.getSmsMessageUri() + " received at "
+ message.getReceivedTimeStamp());
}
-
+ MessageRecyclerAction.deleteMessagesOverLimit(conversationId, MessageData.PROTOCOL_MMS);
// Keep track of updated conversation for later updating the conversation snippet, etc.
mConversationsToUpdate.add(conversationId);
}
diff --git a/src/com/android/messaging/sms/MmsConfig.java b/src/com/android/messaging/sms/MmsConfig.java
index f13d785..56898cf 100755
--- a/src/com/android/messaging/sms/MmsConfig.java
+++ b/src/com/android/messaging/sms/MmsConfig.java
@@ -90,6 +90,12 @@ public class MmsConfig {
sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_HTTP_PARAMS, KEY_TYPE_STRING);
sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_EMAIL_GATEWAY_NUMBER, KEY_TYPE_STRING);
sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_NAI_SUFFIX, KEY_TYPE_STRING);
+ sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MIN_MESSAGE_COUNT_PER_THREAD,
+ KEY_TYPE_INT);
+ sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_SMS_MESSAGES_PER_THREAD, KEY_TYPE_INT);
+ sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MMS_MESSAGES_PER_THREAD, KEY_TYPE_INT);
+ sKeyTypeMap.put(CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_COUNT_PER_THREAD,
+ KEY_TYPE_INT);
}
// A map that stores all MmsConfigs, one per active subscription. For pre-LMSim, this will
@@ -187,6 +193,36 @@ public class MmsConfig {
CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_SIZE_DEFAULT);
}
+ public static int getMaxOfTheConfigValues(String configName, int defaultValue) {
+ int max = 0;
+ for (MmsConfig config : sSubIdToMmsConfigMap.values()) {
+ max = Math.max(max, config.mValues.getInt(configName, 0));
+ }
+ return (max > 0) ? max : defaultValue;
+ }
+
+ public static int getMinMessageCountPerThread() {
+ return getMaxOfTheConfigValues(
+ CarrierConfigValuesLoader.CONFIG_MIN_MESSAGE_COUNT_PER_THREAD,
+ CarrierConfigValuesLoader.CONFIG_MIN_MESSAGE_COUNT_PER_THREAD_DEFAULT);
+ }
+
+ public static int getMaxMessageCountPerThread() {
+ return getMaxOfTheConfigValues(
+ CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_COUNT_PER_THREAD,
+ CarrierConfigValuesLoader.CONFIG_MAX_MESSAGE_COUNT_PER_THREAD_DEFAULT);
+ }
+
+ public static int getSMSMessagesPerThread() {
+ return getMaxOfTheConfigValues(CarrierConfigValuesLoader.CONFIG_SMS_MESSAGES_PER_THREAD,
+ CarrierConfigValuesLoader.CONFIG_SMS_MESSAGES_PER_THREAD_DEFAULT);
+ }
+
+ public static int getMMSMessagesPerThread() {
+ return getMaxOfTheConfigValues(CarrierConfigValuesLoader.CONFIG_MMS_MESSAGES_PER_THREAD,
+ CarrierConfigValuesLoader.CONFIG_MMS_MESSAGES_PER_THREAD_DEFAULT);
+ }
+
/**
* Return the largest MaxMessageSize for any subid
*/
diff --git a/src/com/android/messaging/sms/MmsUtils.java b/src/com/android/messaging/sms/MmsUtils.java
index c91747b..1fd811f 100644
--- a/src/com/android/messaging/sms/MmsUtils.java
+++ b/src/com/android/messaging/sms/MmsUtils.java
@@ -1386,6 +1386,39 @@ public class MmsUtils {
return deleted;
}
+ public static int deleteMessagesOlderThanByProtocol(final long cutOffTimestampInMillis,
+ final int protocol) {
+ Uri uri;
+ String selectionSql;
+ String dateField;
+
+ switch (protocol) {
+ case MessageData.PROTOCOL_SMS:
+ uri = Sms.CONTENT_URI;
+ selectionSql = getSmsTypeSelectionSql();
+ dateField = Sms.DATE;
+ break;
+ case MessageData.PROTOCOL_MMS:
+ uri = Mms.CONTENT_URI;
+ selectionSql = getMmsTypeSelectionSql();
+ dateField = Mms.DATE;
+ break;
+ default:
+ return 0;
+ }
+ final ContentResolver resolver =
+ Factory.get().getApplicationContext().getContentResolver();
+ final String selection = String.format(
+ Locale.US,
+ "%s AND (%s<=%d)",
+ selectionSql,
+ dateField,
+ cutOffTimestampInMillis);
+ int deleted = resolver.delete(uri, selection, null);
+
+ return deleted;
+ }
+
/**
* Update the read status of SMS/MMS messages by thread and timestamp
*
diff --git a/src/com/android/messaging/ui/NumberPickerDialog.java b/src/com/android/messaging/ui/NumberPickerDialog.java
new file mode 100644
index 0000000..755bc81
--- /dev/null
+++ b/src/com/android/messaging/ui/NumberPickerDialog.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2007 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.messaging.ui;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.NumberPicker;
+import android.widget.TextView;
+
+import com.android.messaging.R;
+/**
+ * A dialog that prompts the user for the message deletion limits.
+ */
+public class NumberPickerDialog extends AlertDialog implements OnClickListener {
+ private static final String NUMBER = "number";
+
+ /**
+ * The callback interface used to indicate the user is done filling in
+ * the time (they clicked on the 'Set' button).
+ */
+ public interface OnNumberSetListener {
+
+ /**
+ * @param number The number that was set.
+ */
+ void onNumberSet(int number);
+ }
+
+ private final NumberPicker mNumberPicker;
+ private final OnNumberSetListener mCallback;
+
+ /**
+ * @param context Parent.
+ * @param callBack How parent is notified.
+ * @param number The initial number.
+ */
+ public NumberPickerDialog(Context context,
+ OnNumberSetListener callBack,
+ int number,
+ int rangeMin,
+ int rangeMax,
+ int title,
+ int header) {
+ this(context, callBack, number, rangeMin, rangeMax, title, header, 0);
+ }
+
+ /**
+ * @param context Parent.
+ * @param callBack How parent is notified.
+ * @param number The initial number.
+ */
+ public NumberPickerDialog(Context context,
+ OnNumberSetListener callBack,
+ int number,
+ int rangeMin,
+ int rangeMax,
+ int title,
+ int header,
+ int unit) {
+ super(context);
+ mCallback = callBack;
+
+ setTitle(title);
+
+ setButton(DialogInterface.BUTTON_POSITIVE, context.getText(R.string.set), this);
+ setButton(DialogInterface.BUTTON_NEGATIVE, context.getText(R.string.no),
+ (OnClickListener) null);
+
+ LayoutInflater inflater =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view = inflater.inflate(R.layout.number_picker_dialog, null);
+ setView(view);
+ mNumberPicker = (NumberPicker) view.findViewById(R.id.number_picker);
+
+ TextView headerView = (TextView) view.findViewById(R.id.header);
+ if (header != 0) {
+ headerView.setText(header);
+ headerView.setVisibility(View.VISIBLE);
+ } else {
+ headerView.setVisibility(View.GONE);
+ }
+ TextView unitView = (TextView) view.findViewById(R.id.unit);
+ if (unit != 0) {
+ unitView.setText(unit);
+ unitView.setVisibility(View.VISIBLE);
+ } else {
+ unitView.setVisibility(View.GONE);
+ }
+
+ // initialize state
+ mNumberPicker.setMinValue(rangeMin);
+ mNumberPicker.setMaxValue(rangeMax);
+ mNumberPicker.setValue(number);
+ mNumberPicker.setOnLongPressUpdateInterval(100); // make the repeat rate three times as fast
+ // as normal since the range is so large.
+ mNumberPicker.setWrapSelectorWheel(false); // don't wrap from min->max
+ }
+
+ public void onClick(DialogInterface dialog, int which) {
+ if (mCallback != null) {
+ mNumberPicker.clearFocus();
+ mCallback.onNumberSet(mNumberPicker.getValue());
+ dialog.dismiss();
+ }
+ }
+
+ @Override
+ public Bundle onSaveInstanceState() {
+ Bundle state = super.onSaveInstanceState();
+ state.putInt(NUMBER, mNumberPicker.getValue());
+ return state;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ int number = savedInstanceState.getInt(NUMBER);
+ mNumberPicker.setValue(number);
+ }
+}
diff --git a/src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java b/src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java
index 81993a2..b91cc6c 100644
--- a/src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java
+++ b/src/com/android/messaging/ui/appsettings/ApplicationSettingsActivity.java
@@ -38,13 +38,16 @@ import android.view.Menu;
import android.view.MenuItem;
import com.android.messaging.R;
+import com.android.messaging.sms.MmsConfig;
import com.android.messaging.ui.BugleActionBarActivity;
import com.android.messaging.ui.LicenseActivity;
+import com.android.messaging.ui.NumberPickerDialog;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.util.BuglePrefs;
import com.android.messaging.util.DebugUtils;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PhoneUtils;
+import com.cyanogenmod.messaging.util.PrefsUtils;
public class ApplicationSettingsActivity extends BugleActionBarActivity {
@Override
@@ -104,6 +107,8 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
private ListPreference mSmsValidityPref;
private ListPreference mSmsValidityCard1Pref;
private ListPreference mSmsValidityCard2Pref;
+ private Preference mSmsLimitPref;
+ private Preference mMmsLimitPref;
public ApplicationSettingsFragment() {
@@ -132,6 +137,8 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
mSmsValidityPref = (ListPreference) findPreference("pref_key_sms_validity_period");
mSmsValidityCard1Pref = (ListPreference) findPreference("pref_key_sms_validity_period_slot1");
mSmsValidityCard2Pref = (ListPreference) findPreference("pref_key_sms_validity_period_slot2");
+ mSmsLimitPref = findPreference("sms_delete_limit_pref_key");
+ mMmsLimitPref = findPreference("mms_delete_limit_pref_key");
if (getResources().getBoolean(R.bool.config_sms_validity)) {
if (PhoneUtils.getDefault().isMultiSimEnabledMms()) {
@@ -172,6 +179,8 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
// the parent SettingsActivity.
getPreferenceScreen().removePreference(advancedScreen);
}
+ setSmsDisplayLimit();
+ setMmsDisplayLimit();
}
@Override
@@ -180,6 +189,28 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
if (preference.getKey() == mSmsDisabledPrefKey ||
preference.getKey() == mSmsEnabledPrefKey) {
mIsSmsPreferenceClicked = true;
+ } else if (getActivity() != null &&
+ preference.getKey().equals(mSmsLimitPref.getKey())) {
+
+ new NumberPickerDialog(getActivity(),
+ mSmsLimitListener,
+ PrefsUtils.getSMSMessagesPerThreadLimit(),
+ MmsConfig.getMinMessageCountPerThread(),
+ MmsConfig.getMaxMessageCountPerThread(),
+ R.string.sms_delete_pref_title,
+ R.string.pref_messages_to_save).show();
+
+ } else if(getActivity() != null &&
+ preference.getKey().equals(mMmsLimitPref.getKey())) {
+
+ new NumberPickerDialog(getActivity(),
+ mMmsLimitListener,
+ PrefsUtils.getMMSMessagesPerThreadLimit(),
+ MmsConfig.getMinMessageCountPerThread(),
+ MmsConfig.getMaxMessageCountPerThread(),
+ R.string.mms_delete_pref_title,
+ R.string.pref_messages_to_save).show();
+
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@@ -286,5 +317,33 @@ public class ApplicationSettingsActivity extends BugleActionBarActivity {
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
+
+ private void setSmsDisplayLimit() {
+ mSmsLimitPref.setSummary(
+ getString(R.string.pref_summary_delete_limit,
+ PrefsUtils.getSMSMessagesPerThreadLimit()));
+ }
+
+ private void setMmsDisplayLimit() {
+ mMmsLimitPref.setSummary(
+ getString(R.string.pref_summary_delete_limit,
+ PrefsUtils.getMMSMessagesPerThreadLimit()));
+ }
+
+ NumberPickerDialog.OnNumberSetListener mSmsLimitListener =
+ new NumberPickerDialog.OnNumberSetListener() {
+ public void onNumberSet(int limit) {
+ PrefsUtils.setSMSMessagesPerThreadLimit(limit);
+ setSmsDisplayLimit();
+ }
+ };
+
+ NumberPickerDialog.OnNumberSetListener mMmsLimitListener =
+ new NumberPickerDialog.OnNumberSetListener() {
+ public void onNumberSet(int limit) {
+ PrefsUtils.setMMSMessagesPerThreadLimit(limit);
+ setMmsDisplayLimit();
+ }
+ };
}
}
diff --git a/src/com/cyanogenmod/messaging/util/PrefsUtils.java b/src/com/cyanogenmod/messaging/util/PrefsUtils.java
index 4afbb6d..7af4c06 100644
--- a/src/com/cyanogenmod/messaging/util/PrefsUtils.java
+++ b/src/com/cyanogenmod/messaging/util/PrefsUtils.java
@@ -17,13 +17,14 @@
package com.cyanogenmod.messaging.util;
import android.content.Context;
-import android.content.SharedPreferences;
-
import com.android.messaging.Factory;
import com.android.messaging.R;
+import com.android.messaging.datamodel.data.MessageData;
+import com.android.messaging.sms.MmsConfig;
import com.android.messaging.util.BuglePrefs;
import com.android.messaging.util.UnicodeFilter;
import com.android.messaging.util.PhoneUtils;
+import java.lang.IllegalArgumentException;
public class PrefsUtils {
@@ -32,6 +33,13 @@ public class PrefsUtils {
public static final String QM_CLOSE_ALL_ENABLED = "pref_key_close_all";
public static final String SHOW_EMOTICONS_ENABLED = "pref_show_emoticons";
+ //Storage Limits
+ public static final String PREF_STORAGE_AUTO_DELETE = "auto_delete_pref_key";
+ public static final String PREF_SMS_MESSAGES_PER_THREAD = "sms_delete_limit_pref_key";
+ public static final String PREF_MMS_MESSAGES_PER_THREAD = "mms_delete_limit_pref_key";
+
+ public static final boolean PREF_STORAGE_AUTO_DELETE_DEFAULT = false;
+
private PrefsUtils() {
//Don't instantiate
}
@@ -100,4 +108,40 @@ public class PrefsUtils {
return (validityPeriod == null) ? -1 : Integer.parseInt(validityPeriod);
}
+ public static boolean isAutoDeleteEnabled() {
+ final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
+ return prefs.getBoolean(PREF_STORAGE_AUTO_DELETE, PREF_STORAGE_AUTO_DELETE_DEFAULT);
+ }
+
+ public static void setSMSMessagesPerThreadLimit(int limit) {
+ final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
+ prefs.putInt(PREF_SMS_MESSAGES_PER_THREAD, limit);
+ }
+
+ public static void setMMSMessagesPerThreadLimit(int limit) {
+ final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
+ prefs.putInt(PREF_MMS_MESSAGES_PER_THREAD, limit);
+ }
+
+ public static int getSMSMessagesPerThreadLimit() {
+ final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
+ return prefs.getInt(PREF_SMS_MESSAGES_PER_THREAD, MmsConfig.getSMSMessagesPerThread());
+ }
+
+ public static int getMMSMessagesPerThreadLimit() {
+ final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
+ return prefs.getInt(PREF_MMS_MESSAGES_PER_THREAD, MmsConfig.getMMSMessagesPerThread());
+ }
+
+ public static int getMessagesPerThreadLimitByProtocol(int protocol) {
+ if(protocol == MessageData.PROTOCOL_SMS) {
+ return getSMSMessagesPerThreadLimit();
+ } else if(protocol == MessageData.PROTOCOL_MMS) {
+ return getMMSMessagesPerThreadLimit();
+ }
+
+ throw new IllegalArgumentException("Invalid Protocol protocol ="
+ + Integer.toString(protocol));
+ }
+
}