/*
*Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
*Redistribution and use in source and binary forms, with or without
*modification, are permitted provided that the following conditions are
*met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
*THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
*WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
*ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
*BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
*SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
*WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
*OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
*IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.android.server;
import android.os.Binder;
import android.os.PowerManager;
import android.os.Process;
import android.util.Slog;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public final class QCNsrmAlarmExtension {
static final String TAG = "QCNsrmAlarmExtn";
static final boolean localLOGV = false;
private AlarmManagerService almHandle;
//track the blocked and triggered uids in AlarmManagerService
private static final ArrayList<Integer> mTriggeredUids = new ArrayList<Integer>();
private static final ArrayList<Integer> mBlockedUids = new ArrayList<Integer>();
private static final int BLOCKED_UID_CHECK_INTERVAL = 1000; // 1 sec.
public QCNsrmAlarmExtension(AlarmManagerService handle) {
almHandle = handle;
}
//AlarmManagerService extension Methods
protected void processBlockedUids(int uid, boolean isBlocked, PowerManager.WakeLock mWakeLock ){
if (localLOGV) Slog.v(TAG, "UpdateBlockedUids: uid = " + uid +
" isBlocked = " + isBlocked);
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
if (localLOGV) Slog.v(TAG, "UpdateBlockedUids is not allowed");
return;
}
if(isBlocked) {
if (localLOGV) Slog.v(TAG, "updating alarmMgr mBlockedUids "+
"with uid " + uid);
mBlockedUids.add(new Integer(uid));
Timer checkBlockedUidTimer = new Timer();
checkBlockedUidTimer.schedule( new CheckBlockedUidTimerTask(
uid,
mWakeLock),
BLOCKED_UID_CHECK_INTERVAL);
} else {
if (localLOGV) Slog.v(TAG, "clearing alarmMgr mBlockedUids ");
mBlockedUids.clear();
}
}
protected void addTriggeredUid (int uid){
if (localLOGV) Slog.v(TAG, "adding uid to mTriggeredUids uid=" + uid);
mTriggeredUids.add(new Integer(uid));
}
protected void removeTriggeredUid (int uid) {
if (localLOGV) Slog.v(TAG, "removing uid from mTriggeredUids uid= " + uid);
mTriggeredUids.remove(new Integer(uid));
}
protected boolean hasBlockedUid (int uid) {
return mBlockedUids.contains(uid);
}
class CheckBlockedUidTimerTask extends TimerTask {
private int mUid;
PowerManager.WakeLock mWakeLock;
CheckBlockedUidTimerTask(int uid, PowerManager.WakeLock lWakeLock) {
mUid = uid;
mWakeLock = lWakeLock;
}
@Override
public void run(){
if (mBlockedUids.contains(mUid) && mTriggeredUids.contains(mUid)) {
synchronized(almHandle.mLock) {
if (mWakeLock.isHeld()) {
mWakeLock.release();
if (localLOGV)
Slog.v(TAG, "CheckBlockedUidTimerTask: AM "+
"WakeLock Released Internally!!");
}
}
return;
}
}
}
}