Home | History | Annotate | Download | only in sms
      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 
     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      */
     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      */
     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      */
    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      */
    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