blob: 48502d3eee1b5362deedab6ef5ce1f3b909bce5e [file] [log] [blame]
/*
* Copyright (C) 2008 Esmertec AG.
* Copyright (C) 2008 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.mms.util;
import com.google.android.mms.util.SqliteWrapper;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.provider.Telephony.Mms.Rate;
import android.util.Config;
import android.util.Log;
public class RateController {
private static final String TAG = "RateController";
private static final boolean DEBUG = false;
private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
private static final int RATE_LIMIT = 100;
private static final long ONE_HOUR = 1000 * 60 * 60;
private static final int NO_ANSWER = 0;
private static final int ANSWER_YES = 1;
private static final int ANSWER_NO = 2;
public static final int ANSWER_TIMEOUT = 20000;
public static final String RATE_LIMIT_SURPASSED_ACTION =
"com.android.mms.RATE_LIMIT_SURPASSED";
public static final String RATE_LIMIT_CONFIRMED_ACTION =
"com.android.mms.RATE_LIMIT_CONFIRMED";
private static RateController sInstance;
private static boolean sMutexLock;
private final Context mContext;
private int mAnswer;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (LOCAL_LOGV) {
Log.v(TAG, "Intent received: " + intent);
}
if (RATE_LIMIT_CONFIRMED_ACTION.equals(intent.getAction())) {
synchronized (this) {
mAnswer = intent.getBooleanExtra("answer", false)
? ANSWER_YES : ANSWER_NO;
notifyAll();
}
}
}
};
private RateController(Context context) {
mContext = context;
}
public static void init(Context context) {
if (LOCAL_LOGV) {
Log.v(TAG, "RateController.init()");
}
if (sInstance != null) {
Log.w(TAG, "Already initialized.");
}
sInstance = new RateController(context);
}
public static RateController getInstance() {
if (sInstance == null) {
throw new IllegalStateException("Uninitialized.");
}
return sInstance;
}
public final void update() {
ContentValues values = new ContentValues(1);
values.put(Rate.SENT_TIME, System.currentTimeMillis());
SqliteWrapper.insert(mContext, mContext.getContentResolver(),
Rate.CONTENT_URI, values);
}
public final boolean isLimitSurpassed() {
long oneHourAgo = System.currentTimeMillis() - ONE_HOUR;
Cursor c = SqliteWrapper.query(mContext, mContext.getContentResolver(),
Rate.CONTENT_URI, new String[] { "COUNT(*) AS rate" },
Rate.SENT_TIME + ">" + oneHourAgo, null, null);
if (c != null) {
try {
if (c.moveToFirst()) {
return c.getInt(0) >= RATE_LIMIT;
}
} finally {
c.close();
}
}
return false;
}
synchronized public boolean isAllowedByUser() {
while (sMutexLock) {
try {
wait();
} catch (InterruptedException _) {
// Ignore it.
}
}
sMutexLock = true;
mContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(RATE_LIMIT_CONFIRMED_ACTION));
mAnswer = NO_ANSWER;
try {
Intent intent = new Intent(RATE_LIMIT_SURPASSED_ACTION);
// Using NEW_TASK here is necessary because we're calling
// startActivity from outside an activity.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
return waitForAnswer() == ANSWER_YES;
} finally {
mContext.unregisterReceiver(mBroadcastReceiver);
sMutexLock = false;
notifyAll();
}
}
synchronized private int waitForAnswer() {
for (int t = 0; (mAnswer == NO_ANSWER) && (t < ANSWER_TIMEOUT); t += 1000) {
try {
if (LOCAL_LOGV) {
Log.v(TAG, "Waiting for answer..." + t / 1000);
}
wait(1000L);
} catch (InterruptedException _) {
// Ignore it.
}
}
return mAnswer;
}
}