blob: 9ca82fc495678e54650ec9a7dc514a74be4b3a35 [file] [log] [blame]
/*
* 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.ArrayList;
import java.util.List;
import android.content.ServiceConnection;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.os.Parcel;
import com.android.ims.internal.uce.presence.IPresenceListener;
import com.android.ims.internal.uce.presence.PresCmdId;
import com.android.ims.internal.uce.presence.PresCmdStatus;
import com.android.ims.internal.uce.presence.PresPublishTriggerType;
import com.android.ims.internal.uce.presence.PresResInfo;
import com.android.ims.internal.uce.presence.PresRlmiInfo;
import com.android.ims.internal.uce.presence.PresSipResponse;
import com.android.ims.internal.uce.presence.PresTupleInfo;
import com.android.ims.internal.uce.common.StatusCode;
import com.android.ims.internal.uce.common.StatusCode;
import com.android.ims.RcsManager;
import com.android.ims.RcsManager.ResultCode;
import com.android.ims.RcsPresence;
import com.android.ims.RcsPresenceInfo;
import com.android.ims.IRcsPresenceListener;
import com.android.ims.internal.Logger;
import com.android.service.ims.TaskManager;
import com.android.service.ims.Task;
import com.android.service.ims.RcsStackAdaptor;
public class StackListener extends Handler{
/*
* The logger
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
Context mContext;
private PresencePublication mPresencePublication = null;
private PresenceSubscriber mPresenceSubscriber = null;
// RCS stack notify the AP to publish the presence.
private static final short PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER = 1;
// PUBLISH CMD status changed
private static final short PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS = 2;
// Received the SIP response for publish
private static final short PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE = 3;
// Received the presence for single contact
private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE = 4;
// Received the presence for contacts.
private static final short PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE = 5;
// Received the CMD status for capability/availability request
private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS = 6;
// Received the SIP response for capability/availability request
private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE = 7;
private final Object mSyncObj = new Object();
public StackListener(Context context, Looper looper) {
super(looper);
mContext = context;
}
public void setPresencePublication(PresencePublication presencePublication){
mPresencePublication = presencePublication;
}
public void setPresenceSubscriber(PresenceSubscriber presenceSubscriber){
mPresenceSubscriber = presenceSubscriber;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
logger.debug( "Thread=" + Thread.currentThread().getName() + " received "
+ msg);
if(msg == null){
logger.error("msg=null");
return;
}
switch (msg.what) {
// RCS stack notify the AP to publish the presence.
case PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER:
{
PresPublishTriggerType val = (PresPublishTriggerType) msg.obj;
if(mPresencePublication == null || val == null){
logger.error("mPresencePublication=" + mPresencePublication + " val=" + val);
return;
}
mPresencePublication.invokePublish(val);
break;
}
// RCS stack tell AP that the CMD status changed.
case PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS:
{
PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
if(mPresencePublication == null || pCmdStatus == null){
logger.error("mPresencePublication=" + mPresencePublication +
" pCmdStatus=" + pCmdStatus);
return;
}
mPresencePublication.handleCmdStatus(pCmdStatus);
}
break;
// RCS stack tells AP that the CMD status changed.
case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS:
{
PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
if(mPresenceSubscriber == null || pCmdStatus == null){
logger.error("mPresenceSubcriber=" + mPresenceSubscriber +
" pCmdStatus=" + pCmdStatus);
return;
}
mPresenceSubscriber.handleCmdStatus(pCmdStatus);
break;
}
// RCS stack tells AP that the SIP response has been received.
case PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE:
{
PresSipResponse pSipResponse = (PresSipResponse) msg.obj;
if(mPresencePublication == null || pSipResponse == null){
logger.error("mPresencePublication=" + mPresencePublication +
"pSipResponse=" +pSipResponse);
return;
}
mPresencePublication.handleSipResponse(pSipResponse);
break;
}
// RCS stack tells AP that the SIP response has been received.
case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE:
{
PresSipResponse pSipResponse = (PresSipResponse) msg.obj;
if(mPresenceSubscriber == null || pSipResponse == null){
logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
" pSipResponse=" + pSipResponse);
return;
}
mPresenceSubscriber.handleSipResponse(pSipResponse);
break;
}
// RCS stack tells AP that the presence data has been received.
case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE:
{
NotifyData notifyData = (NotifyData) msg.obj;
if(mPresenceSubscriber == null || notifyData == null){
logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
" notifyData=" + notifyData);
return;
}
mPresenceSubscriber.updatePresence(notifyData.getUri(),
notifyData.getTupleInfo());
break;
}
case PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE:
{
NotifyListData notifyListData = (NotifyListData) msg.obj;
logger.debug("Received PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE");
if(mPresenceSubscriber==null || notifyListData == null){
logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
" notifyListData=" + notifyListData);
return;
}
mPresenceSubscriber.updatePresences(notifyListData.getRlmiInfo(),
notifyListData.getResInfo());
break;
}
default:
logger.debug("Unknown mesg " + msg.what + " recieved.");
}
}
public class NotifyData{
private String mUri;
private PresTupleInfo[] mTupleInfo;
NotifyData(){
mUri = null;
mTupleInfo = null;
}
NotifyData(String uri, PresTupleInfo[] pTupleInfo){
mUri = uri;
mTupleInfo = pTupleInfo;
}
public String getUri(){
return mUri;
}
public PresTupleInfo[] getTupleInfo(){
return mTupleInfo;
}
}
public class NotifyListData{
private PresRlmiInfo mRlmiInfo;
private PresResInfo[] mResInfo;
NotifyListData(){
mRlmiInfo = null;
mResInfo = null;
}
NotifyListData(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo){
mRlmiInfo = pRlmiInfo;
mResInfo = pResInfo;
}
public PresRlmiInfo getRlmiInfo(){
return mRlmiInfo;
}
public PresResInfo[] getResInfo(){
return mResInfo;
}
}
public IPresenceListener mPresenceListener = new IPresenceListener.Stub() {
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException{
try{
return super.onTransact(code, data, reply, flags);
} catch (RemoteException e) {
Log.w("ListenerHandler", "Unexpected remote exception", e);
e.printStackTrace();
throw e;
}
}
public void getVersionCb(String pVersion) {
logger.debug("pVersion=" + pVersion);
}
public void sipResponseReceived(PresSipResponse pSipResponse) throws RemoteException {
synchronized(mSyncObj){
if(pSipResponse == null){
logger.error("ISipResponseReceived pSipResponse=null");
return;
}
logger.debug("pSipResponse.getCmdId() "+
pSipResponse.getCmdId().getCmdId());
logger.debug("getReasonPhrase() "+pSipResponse.getReasonPhrase());
logger.debug("getsRequestID() "+pSipResponse.getRequestId());
logger.debug("getsSipResponseCode() "+pSipResponse.getSipResponseCode());
switch (pSipResponse.getCmdId().getCmdId()) {
case PresCmdId.UCE_PRES_CMD_PUBLISHMYCAP:
{
Message updateMesgSipPub = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE,
pSipResponse);
StackListener.this.sendMessage(updateMesgSipPub);
break;
}
case PresCmdId.UCE_PRES_CMD_GETCONTACTCAP:
case PresCmdId.UCE_PRES_CMD_GETCONTACTLISTCAP:
{
Message updateMesgSipPub = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE,
pSipResponse);
StackListener.this.sendMessage(updateMesgSipPub);
break;
}
case PresCmdId.UCE_PRES_CMD_SETNEWFEATURETAG:
{
logger.debug("UCE_PRES_CMD_SETNEWFEATURETAG, doesn't care it");
break;
}
default:
logger.debug("CMD ID for unknown value=" +
pSipResponse.getCmdId().getCmdId());
}
}
}
public void serviceUnAvailable(StatusCode statusCode) throws RemoteException {
synchronized(mSyncObj){
if(statusCode == null){
logger.error("statusCode=null");
}else{
logger.debug("IServiceUnAvailable statusCode " +
statusCode.getStatusCode());
}
logger.debug("QPresListener_ServiceUnAvailable");
RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
if (rcsStackAdaptor != null) {
rcsStackAdaptor.setImsEnableState(false);
}
Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_UNAVAILABLE);
mContext.sendBroadcast(intent,
"com.android.ims.rcs.permission.STATUS_CHANGED");
}
}
public void serviceAvailable(StatusCode statusCode) throws RemoteException {
synchronized(mSyncObj){
if(statusCode == null){
logger.error("statusCode=null");
}else{
logger.debug("IServiceAvailable statusCode " +
statusCode.getStatusCode());
}
logger.debug("QPresListener_ServiceAvailable");
RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
if (rcsStackAdaptor != null) {
rcsStackAdaptor.setImsEnableState(true);
}
// Handle the cached trigger which got from stack
if(mPresencePublication != null && mPresencePublication.getHasCachedTrigger()){
logger.debug("publish for cached trigger");
mPresencePublication.invokePublish(
PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
}
Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_AVAILABLE);
mContext.sendBroadcast(intent,
"com.android.ims.rcs.permission.STATUS_CHANGED");
}
}
public void publishTriggering(PresPublishTriggerType publishTrigger)
throws RemoteException {
if(publishTrigger == null){
logger.error("publishTrigger=null");
}else{
logger.debug("getPublishTrigeerType() "+
publishTrigger.getPublishTrigeerType());
}
logger.debug("ListenerHandler : PublishTriggering");
Message publishTrigerMsg = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER, publishTrigger);
StackListener.this.sendMessage(publishTrigerMsg);
}
public void listCapInfoReceived(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo)
throws RemoteException {
if(pRlmiInfo == null || pResInfo == null){
logger.error("pRlmiInfo=" + pRlmiInfo + " pResInfo=" + pResInfo);
}else{
logger.debug("pRlmiInfo.getListName "+pRlmiInfo.getListName());
logger.debug("pRlmiInfo.isFullState "+pRlmiInfo.isFullState());
logger.debug("pRlmiInfo.getUri "+pRlmiInfo.getUri());
logger.debug("pRlmiInfo.getVersion "+pRlmiInfo.getVersion());
logger.debug("pRlmiInfo.getSubscriptionTerminatedReason " +
pRlmiInfo.getSubscriptionTerminatedReason());
logger.debug("pRlmiInfo.getPresSubscriptionState " +
pRlmiInfo.getPresSubscriptionState());
logger.debug("pRlmiInfo.getRequestID=" + pRlmiInfo.getRequestId());
for(int i=0; i < pResInfo.length; i++ ){
if(pResInfo[i] == null){
logger.debug("ignoring, pResInfo[" + i + "]=null");
continue;
}
logger.debug(".getDisplayName() "+pResInfo[i].getDisplayName());
logger.debug("getResUri() "+pResInfo[i].getResUri());
if(pResInfo[i].getInstanceInfo() != null){
logger.debug("getInstanceInfo().getPresentityUri() "+
pResInfo[i].getInstanceInfo().getPresentityUri());
logger.debug("getInstanceInfo().getResId() "+
pResInfo[i].getInstanceInfo().getResId());
logger.debug("getInstanceInfo().getsReason() "+
pResInfo[i].getInstanceInfo().getReason());
logger.debug("getInstanceInfo().getResInstanceState() "+
pResInfo[i].getInstanceInfo().getResInstanceState());
if(pResInfo[i].getInstanceInfo().getTupleInfo() == null){
logger.debug("pResInfo[" + i +"].getInstanceInfo().getTupleInfo()=null");
continue;
}
logger.debug("getTupleInfo().length "+
pResInfo[i].getInstanceInfo().getTupleInfo().length);
if(pResInfo[i].getInstanceInfo().getTupleInfo() != null){
for(int j = 0; j < pResInfo[i].getInstanceInfo().getTupleInfo().length;
j++)
{
if(pResInfo[i].getInstanceInfo().getTupleInfo() == null){
logger.debug("ignoring, pResInfo[" + i +
"].getInstanceInfo().getTupleInfo()[" +j + "]");
continue;
}
logger.debug("getFeatureTag "+
pResInfo[i].getInstanceInfo().getTupleInfo()[j].
getFeatureTag());
logger.debug("getsContactUri "+
pResInfo[i].getInstanceInfo().getTupleInfo()[j].
getContactUri());
logger.debug("getsTimestamp "+
pResInfo[i].getInstanceInfo().getTupleInfo()[j].
getTimestamp());
}
}
}
}
}
Message notifyListReceivedMsg = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE,
new NotifyListData(pRlmiInfo, pResInfo));
logger.debug("Send PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE");
StackListener.this.sendMessage(notifyListReceivedMsg);
}
public void capInfoReceived(String presentityURI, PresTupleInfo[] pTupleInfo)
throws RemoteException {
logger.debug("ListenerHandler : CapInfoReceived");
if(presentityURI == null || presentityURI == null){
logger.error("presentityURI=null or presentityURI=null");
return;
}
logger.debug("ListenerHandler : CapInfoReceived : presentityURI "+ presentityURI);
Message notifyReceivedMsg = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_NOTIFY_UPDATE,
new NotifyData(presentityURI, pTupleInfo));
StackListener.this.sendMessage(notifyReceivedMsg);
}
public void cmdStatus(PresCmdStatus pCmdStatus) throws RemoteException {
synchronized(mSyncObj){
if(pCmdStatus == null || pCmdStatus.getCmdId() == null){
logger.debug( "ICMDStatus error, pCmdStatus="+ pCmdStatus);
return;
}
logger.debug("ListenerHandler : CMDStatus");
logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getRequestID() "+
pCmdStatus.getRequestId());
logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getUserData() "+
pCmdStatus.getUserData());
logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getCmdId() "+
pCmdStatus.getCmdId().getCmdId());
if(pCmdStatus.getStatus() != null){
logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getStatus() "+
pCmdStatus.getStatus().getStatusCode());
}
switch (pCmdStatus.getCmdId().getCmdId()) {
case PresCmdId.UCE_PRES_CMD_PUBLISHMYCAP:
Message publishCmdMsg = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS,
pCmdStatus);
StackListener.this.sendMessage(publishCmdMsg);
break;
case PresCmdId.UCE_PRES_CMD_GETCONTACTCAP:
case PresCmdId.UCE_PRES_CMD_GETCONTACTLISTCAP:
Message notifyUpdateCmdMsg = StackListener.this.obtainMessage(
PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS,
pCmdStatus);
StackListener.this.sendMessage(notifyUpdateCmdMsg);
break;
case PresCmdId.UCE_PRES_CMD_SETNEWFEATURETAG:
logger.debug("UCE_PRES_CMD_SETNEWFEATURETAG: app does not care it");
break;
default:
logger.debug("CMD ID for unknown value=" +
pCmdStatus.getCmdId().getCmdId());
}
}
}
public void unpublishMessageSent() {
logger.debug("unpublishMessageSent()");
}
};
}