Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2008 Esmertec AG.
      3  * Copyright (C) 2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mms.util;
     19 
     20 import com.android.mms.LogTag;
     21 
     22 import android.content.BroadcastReceiver;
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.database.Cursor;
     28 import android.database.sqlite.SqliteWrapper;
     29 import android.provider.Telephony.Mms.Rate;
     30 import android.util.Log;
     31 
     32 public class RateController {
     33     private static final String TAG = LogTag.TAG;
     34     private static final boolean DEBUG = false;
     35     private static final boolean LOCAL_LOGV = false;
     36 
     37     private static final int RATE_LIMIT = 100;
     38     private static final long ONE_HOUR = 1000 * 60 * 60;
     39 
     40     private static final int NO_ANSWER  = 0;
     41     private static final int ANSWER_YES = 1;
     42     private static final int ANSWER_NO  = 2;
     43 
     44     public static final int ANSWER_TIMEOUT = 20000;
     45     public static final String RATE_LIMIT_SURPASSED_ACTION =
     46         "com.android.mms.RATE_LIMIT_SURPASSED";
     47     public static final String RATE_LIMIT_CONFIRMED_ACTION =
     48         "com.android.mms.RATE_LIMIT_CONFIRMED";
     49 
     50     private static RateController sInstance;
     51     private static boolean sMutexLock;
     52 
     53     private final Context mContext;
     54     private int mAnswer;
     55 
     56     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
     57         @Override
     58         public void onReceive(Context context, Intent intent) {
     59             if (LOCAL_LOGV) {
     60                 Log.v(TAG, "Intent received: " + intent);
     61             }
     62 
     63             if (RATE_LIMIT_CONFIRMED_ACTION.equals(intent.getAction())) {
     64                 synchronized (this) {
     65                     mAnswer = intent.getBooleanExtra("answer", false)
     66                                             ? ANSWER_YES : ANSWER_NO;
     67                     notifyAll();
     68                 }
     69             }
     70         }
     71     };
     72 
     73     private RateController(Context context) {
     74         mContext = context;
     75     }
     76 
     77     public static void init(Context context) {
     78         if (LOCAL_LOGV) {
     79             Log.v(TAG, "RateController.init()");
     80         }
     81 
     82         if (sInstance != null) {
     83             Log.w(TAG, "Already initialized.");
     84             return;
     85         }
     86         sInstance = new RateController(context);
     87     }
     88 
     89     public static RateController getInstance() {
     90         if (sInstance == null) {
     91             throw new IllegalStateException("Uninitialized.");
     92         }
     93         return sInstance;
     94     }
     95 
     96     public final void update() {
     97         ContentValues values = new ContentValues(1);
     98         values.put(Rate.SENT_TIME, System.currentTimeMillis());
     99         SqliteWrapper.insert(mContext, mContext.getContentResolver(),
    100                              Rate.CONTENT_URI, values);
    101     }
    102 
    103     public final boolean isLimitSurpassed() {
    104         long oneHourAgo = System.currentTimeMillis() - ONE_HOUR;
    105         Cursor c = SqliteWrapper.query(mContext, mContext.getContentResolver(),
    106                 Rate.CONTENT_URI, new String[] { "COUNT(*) AS rate" },
    107                 Rate.SENT_TIME + ">" + oneHourAgo, null, null);
    108         if (c != null) {
    109             try {
    110                 if (c.moveToFirst()) {
    111                     return c.getInt(0) >= RATE_LIMIT;
    112                 }
    113             } finally {
    114                 c.close();
    115             }
    116         }
    117         return false;
    118     }
    119 
    120     synchronized public boolean isAllowedByUser() {
    121         while (sMutexLock) {
    122             try {
    123                 wait();
    124             } catch (InterruptedException _) {
    125                  // Ignore it.
    126             }
    127         }
    128         sMutexLock = true;
    129 
    130         mContext.registerReceiver(mBroadcastReceiver,
    131                 new IntentFilter(RATE_LIMIT_CONFIRMED_ACTION));
    132 
    133         mAnswer = NO_ANSWER;
    134         try {
    135             Intent intent = new Intent(RATE_LIMIT_SURPASSED_ACTION);
    136             // Using NEW_TASK here is necessary because we're calling
    137             // startActivity from outside an activity.
    138             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    139             mContext.startActivity(intent);
    140             return waitForAnswer() == ANSWER_YES;
    141         } finally {
    142             mContext.unregisterReceiver(mBroadcastReceiver);
    143             sMutexLock = false;
    144             notifyAll();
    145         }
    146     }
    147 
    148     synchronized private int waitForAnswer() {
    149         for (int t = 0; (mAnswer == NO_ANSWER) && (t < ANSWER_TIMEOUT); t += 1000) {
    150             try {
    151                 if (LOCAL_LOGV) {
    152                     Log.v(TAG, "Waiting for answer..." + t / 1000);
    153                 }
    154                 wait(1000L);
    155             } catch (InterruptedException _) {
    156                  // Ignore it.
    157             }
    158         }
    159         return mAnswer;
    160     }
    161 }
    162