1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.messaging.sms; 18 19 import android.content.res.Resources; 20 21 import com.android.messaging.Factory; 22 import com.android.messaging.R; 23 import com.android.messaging.datamodel.SyncManager; 24 import com.android.messaging.util.BugleGservices; 25 import com.android.messaging.util.BugleGservicesKeys; 26 import com.android.messaging.util.LogUtil; 27 28 import java.util.regex.Matcher; 29 import java.util.regex.Pattern; 30 31 /** 32 * Class handling message cleanup when storage is low 33 */ 34 public class SmsReleaseStorage { 35 /** 36 * Class representing a time duration specified by Gservices 37 */ 38 public static class Duration { 39 // Time duration unit types 40 public static final int UNIT_WEEK = 'w'; 41 public static final int UNIT_MONTH = 'm'; 42 public static final int UNIT_YEAR = 'y'; 43 44 // Number of units 45 public final int mCount; 46 // Unit type: week, month or year 47 public final int mUnit; 48 Duration(final int count, final int unit)49 public Duration(final int count, final int unit) { 50 mCount = count; 51 mUnit = unit; 52 } 53 } 54 55 private static final String TAG = LogUtil.BUGLE_TAG; 56 57 private static final Duration DEFAULT_DURATION = new Duration(1, Duration.UNIT_MONTH); 58 59 private static final Pattern DURATION_PATTERN = Pattern.compile("([1-9]+\\d*)(w|m|y)"); 60 /** 61 * Parse message retaining time duration specified by Gservices 62 * 63 * @return The parsed time duration from Gservices 64 */ parseMessageRetainingDuration()65 public static Duration parseMessageRetainingDuration() { 66 final String smsAutoDeleteMessageRetainingDuration = 67 BugleGservices.get().getString( 68 BugleGservicesKeys.SMS_STORAGE_PURGING_MESSAGE_RETAINING_DURATION, 69 BugleGservicesKeys.SMS_STORAGE_PURGING_MESSAGE_RETAINING_DURATION_DEFAULT); 70 final Matcher matcher = DURATION_PATTERN.matcher(smsAutoDeleteMessageRetainingDuration); 71 try { 72 if (matcher.matches()) { 73 return new Duration( 74 Integer.parseInt(matcher.group(1)), 75 matcher.group(2).charAt(0)); 76 } 77 } catch (final NumberFormatException e) { 78 // Nothing to do 79 } 80 LogUtil.e(TAG, "SmsAutoDelete: invalid duration " + 81 smsAutoDeleteMessageRetainingDuration); 82 return DEFAULT_DURATION; 83 } 84 85 /** 86 * Get string representation of the time duration 87 * 88 * @param duration 89 * @return 90 */ getMessageRetainingDurationString(final Duration duration)91 public static String getMessageRetainingDurationString(final Duration duration) { 92 final Resources resources = Factory.get().getApplicationContext().getResources(); 93 switch (duration.mUnit) { 94 case Duration.UNIT_WEEK: 95 return resources.getQuantityString( 96 R.plurals.week_count, duration.mCount, duration.mCount); 97 case Duration.UNIT_MONTH: 98 return resources.getQuantityString( 99 R.plurals.month_count, duration.mCount, duration.mCount); 100 case Duration.UNIT_YEAR: 101 return resources.getQuantityString( 102 R.plurals.year_count, duration.mCount, duration.mCount); 103 } 104 throw new IllegalArgumentException( 105 "SmsAutoDelete: invalid duration unit " + duration.mUnit); 106 } 107 108 // Time conversations 109 private static final long WEEK_IN_MILLIS = 7 * 24 * 3600 * 1000L; 110 private static final long MONTH_IN_MILLIS = 30 * 24 * 3600 * 1000L; 111 private static final long YEAR_IN_MILLIS = 365 * 24 * 3600 * 1000L; 112 113 /** 114 * Convert time duration to time in milliseconds 115 * 116 * @param duration 117 * @return 118 */ durationToTimeInMillis(final Duration duration)119 public static long durationToTimeInMillis(final Duration duration) { 120 switch (duration.mUnit) { 121 case Duration.UNIT_WEEK: 122 return duration.mCount * WEEK_IN_MILLIS; 123 case Duration.UNIT_MONTH: 124 return duration.mCount * MONTH_IN_MILLIS; 125 case Duration.UNIT_YEAR: 126 return duration.mCount * YEAR_IN_MILLIS; 127 } 128 return -1L; 129 } 130 131 /** 132 * Delete message actions: 133 * 0: delete media messages 134 * 1: delete old messages 135 * 136 * @param actionIndex The index of the delete action to perform 137 * @param durationInMillis The time duration for retaining messages 138 */ deleteMessages(final int actionIndex, final long durationInMillis)139 public static void deleteMessages(final int actionIndex, final long durationInMillis) { 140 int deleted = 0; 141 switch (actionIndex) { 142 case 0: { 143 // Delete media 144 deleted = MmsUtils.deleteMediaMessages(); 145 break; 146 } 147 case 1: { 148 // Delete old messages 149 final long now = System.currentTimeMillis(); 150 final long cutOffTimestampInMillis = now - durationInMillis; 151 // Delete messages from telephony provider 152 deleted = MmsUtils.deleteMessagesOlderThan(cutOffTimestampInMillis); 153 break; 154 } 155 default: { 156 LogUtil.e(TAG, "SmsStorageStatusManager: invalid action " + actionIndex); 157 break; 158 } 159 } 160 161 if (deleted > 0) { 162 // Kick off a sync to update local db. 163 SyncManager.sync(); 164 } 165 } 166 } 167