/* * Copyright (c) 2015, Motorola Mobility LLC * 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 Motorola Mobility 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC 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.service.ims.presence; import java.util.Set; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import android.content.Context; import android.content.Intent; import android.app.PendingIntent; import android.content.IntentFilter; import android.os.RemoteException; import android.app.AlarmManager; import android.os.SystemClock; import com.android.ims.internal.uce.presence.PresCmdStatus; import com.android.ims.RcsManager.ResultCode; import com.android.ims.RcsPresenceInfo; import com.android.ims.IRcsPresenceListener; import com.android.ims.internal.Logger; import com.android.service.ims.TaskManager; /** * PresenceCapabilityTask */ public class PresenceCapabilityTask extends PresenceTask{ /* * The logger */ private Logger logger = Logger.getLogger(this.getClass().getName()); public static final String ACTION_TASK_TIMEOUT_ALARM = "com.android.service.ims.presence.task.timeout"; private Context mContext = null; // The result code will be used for retry. public int mResultCode; // The alarm manager. static AlarmManager sAlarmManager = null; PendingIntent mAlarmIntent = null; boolean mTimerStarted = false; // it will be set to true after got sip response. public boolean mWaitingForNotify; // The time when created the task. private long mCreatedTimeStamp; private long mTimeout; public PresenceCapabilityTask(Context context, int taskId, int cmdId, IRcsPresenceListener listener, String[] contacts, long timeout){ super(taskId, cmdId, listener, contacts); mContext = context; mWaitingForNotify = false; mCreatedTimeStamp = System.currentTimeMillis(); mTimeout = timeout; if(mTimeout <=0){ // The terminal notification may be received shortly after the time limit of // the subscription due to network delays or retransmissions. // Device shall wait for 3sec after the end of the subscription period in order to // accept such notifications without returning spurious errors (e.g. SIP 481). mTimeout = 36000; } if(listener != null){ startTimer(); } //else it will be removed after got sip response. } public String toString(){ return super.toString() + " mCreatedTimeStamp=" + mCreatedTimeStamp + " mTimeout=" + mTimeout; } private void startTimer(){ if(mContext == null){ logger.error("startTimer mContext is null"); return; } Intent intent = new Intent(ACTION_TASK_TIMEOUT_ALARM); intent.setClass(mContext, AlarmBroadcastReceiver.class); intent.putExtra("taskId", mTaskId); PendingIntent mAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT); if(sAlarmManager == null){ sAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); } long triggerAt = SystemClock.elapsedRealtime() + mTimeout; logger.debug("startTimer taskId=" + mTaskId + " mTimeout=" + mTimeout + " triggerAt=" + triggerAt + " mAlarmIntent=" + mAlarmIntent); sAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAt, mAlarmIntent); mTimerStarted = true; } public void cancelTimer(){ if(mTimerStarted){ logger.debug("cancelTimer, taskId=" + mTaskId); if(mAlarmIntent != null && sAlarmManager != null) { sAlarmManager.cancel(mAlarmIntent); } mTimerStarted = false; } } public void onTimeout(){ logger.debug("onTimeout, taskId=" + mTaskId); try{ if(mListener != null){ mListener.onTimeout(mTaskId); } }catch (RemoteException e){ logger.error("RemoteException", e); } TaskManager.getDefault().removeTask(mTaskId); } public void setWaitingForNotify(boolean waitingForNotify){ mWaitingForNotify = waitingForNotify; } public boolean isWaitingForNotify(){ return mWaitingForNotify; } public void onTerminated(String reason){ if(!mWaitingForNotify){ logger.debug("onTerminated mWaitingForNotify is false. task=" + this); return; } cancelTimer(); try{ if(mListener != null){ mListener.onFinish(mTaskId); } }catch (RemoteException e){ logger.error("RemoteException", e); } TaskManager.getDefault().removeTask(mTaskId); } };