OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / packages / apps / Mms / src / com / android / mms / util / RateController.java
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 android.database.sqlite.SqliteWrapper;
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.provider.Telephony.Mms.Rate;
29 import android.util.Config;
30 import android.util.Log;
31
32 public class RateController {
33     private static final String TAG = "RateController";
34     private static final boolean DEBUG = false;
35     private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
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         }
85         sInstance = new RateController(context);
86     }
87
88     public static RateController getInstance() {
89         if (sInstance == null) {
90             throw new IllegalStateException("Uninitialized.");
91         }
92         return sInstance;
93     }
94
95     public final void update() {
96         ContentValues values = new ContentValues(1);
97         values.put(Rate.SENT_TIME, System.currentTimeMillis());
98         SqliteWrapper.insert(mContext, mContext.getContentResolver(),
99                              Rate.CONTENT_URI, values);
100     }
101
102     public final boolean isLimitSurpassed() {
103         long oneHourAgo = System.currentTimeMillis() - ONE_HOUR;
104         Cursor c = SqliteWrapper.query(mContext, mContext.getContentResolver(),
105                 Rate.CONTENT_URI, new String[] { "COUNT(*) AS rate" },
106                 Rate.SENT_TIME + ">" + oneHourAgo, null, null);
107         if (c != null) {
108             try {
109                 if (c.moveToFirst()) {
110                     return c.getInt(0) >= RATE_LIMIT;
111                 }
112             } finally {
113                 c.close();
114             }
115         }
116         return false;
117     }
118
119     synchronized public boolean isAllowedByUser() {
120         while (sMutexLock) {
121             try {
122                 wait();
123             } catch (InterruptedException _) {
124                  // Ignore it.
125             }
126         }
127         sMutexLock = true;
128
129         mContext.registerReceiver(mBroadcastReceiver,
130                 new IntentFilter(RATE_LIMIT_CONFIRMED_ACTION));
131
132         mAnswer = NO_ANSWER;
133         try {
134             Intent intent = new Intent(RATE_LIMIT_SURPASSED_ACTION);
135             // Using NEW_TASK here is necessary because we're calling
136             // startActivity from outside an activity.
137             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
138             mContext.startActivity(intent);
139             return waitForAnswer() == ANSWER_YES;
140         } finally {
141             mContext.unregisterReceiver(mBroadcastReceiver);
142             sMutexLock = false;
143             notifyAll();
144         }
145     }
146
147     synchronized private int waitForAnswer() {
148         for (int t = 0; (mAnswer == NO_ANSWER) && (t < ANSWER_TIMEOUT); t += 1000) {
149             try {
150                 if (LOCAL_LOGV) {
151                     Log.v(TAG, "Waiting for answer..." + t / 1000);
152                 }
153                 wait(1000L);
154             } catch (InterruptedException _) {
155                  // Ignore it.
156             }
157         }
158         return mAnswer;
159     }
160 }