package kr.co.icontrols.homeautomation; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.util.Log; import com.artncore.WallPadDataMgr.WallpadStatusData; import com.artncore.commons.define; import java.util.List; public class HomeAutomation_Call { private static final String TAG = "HomeAutomation_Call"; Context context; /** BR Action Name
* 본 Action Name을 BroadcastReceiver에 getAction 후 문자열 비교 등록 후 일치 시 사용해야 한다. * **/ public static final String BR_ACTION_NAME = "HOME_AUTOMATION_CALL"; public static final String BR_ACTION_NAME_OPTION = "HOME_AUTOMATION_CALL_OPTION"; /** BR Data Type **/ public static final String BR_DEVICE = "DEVICE"; public static final String BR_TYPE_CALL = "TYPE_CALL"; public static final String BR_ID_DONG = "ID_DONG"; public static final String BR_ID_HO = "ID_HO"; public static final String BR_BLOCK_NEWCALL = "BLOCK_NEWCALL"; public static final String BR_BLOCK_NEWCALL_RELEASESEC = "BLOCK_NEWCALL_RELEASESEC"; /** BR APP Name **/ public static final String APP_NAME_WALLPADDEVSERVICE = "WallPadDevService"; public static final String APP_NAME_WALLPADCALL = "WallPadCall"; /** Device Define **/ public static final int DEVICE_NONE = 0; public static final int DEVICE_GUARD = 1; public static final int DEVICE_LOBBY = 2; public static final int DEVICE_NEIBOR = 3; /** Call Type Define **/ public static final int CALLTYPE_NONE = 0; public static final int CALLTYPE_RECEIVE_CALL_REQUEST = 1; //통화 요청 받음(수신) public static final int CALLTYPE_SEND_CALL_ACK = 2; //통화 요청 응답 public static final int CALLTYPE_SEND_CALL_ACK_FAIL = 3; //통화 중 또는 통화 거절 응답 public static final int CALLTYPE_SEND_CALL_START = 4; //통화 시작 보냄 public static final int CALLTYPE_RECEIVE_CALL_END = 5; //통화 종료 받음 public static final int CALLTYPE_SEND_CALL_END = 6; //통화 종료 보냄 public static final int CALLTYPE_SEND_CALL_REQUEST = 7; //통화 요청 보냄(발신) public static final int CALLTYPE_RECEIVE_CALL_ACK = 8; //통화 응답 받음 public static final int CALLTYPE_RECEIVE_CALL_ACK_FAIL = 9; //통화 중 또는 통화 거절 받음 public static final int CALLTYPE_RECEIVE_CALL_START = 10; //통화 시작 받음 public static final int CALLTYPE_SEND_DOOR_OPEN = 11; //문열림 요청 public static final int CALLTYPE_RECEIVE_DOOR_OPEN_ACK = 12; //문열림 응답 (응답 수신 후, 통화 종료 BR Send 해야 함, 그리고 통화 APP 종료) public class Call_Info { /** 기기 종류 **/ public int Type_Device; /** 통화 구분자 **/ public int Type_Call; /** 동 정보 * 경비인 경우 0사용 **/ public int ID_Dong; /** 호 정보 * 로비, 경비인 경우는 ID로 사용됨**/ public int ID_Ho; public Call_Info() { Type_Device = DEVICE_NONE; Type_Call = CALLTYPE_NONE; ID_Dong = 0; ID_Ho = 0; } } /** * 생성자 * **/ public HomeAutomation_Call(Context ctx) { context = ctx; Log.d(TAG, "HomeAutomation_Call API Start"); } /** * @description * 홈오토 통화 관련 BR 파싱 함수 * * @return Call_Info Class (null인지 비교하고 사용) * * @param intent -> 수신 받은 intent 원형 * @param AppName -> 본 함수 사용하는 APP의 Name ("WallPadDevService or WallPadCall") * **/ int m_nCallType = 0; public Call_Info BR_Parsing(Intent intent, String AppName) { Log.e(TAG, "[BR_Parsing] AppName : " + AppName); Call_Info call_info = null; // 1. 디바이스 정보 범위 체크 int Device = intent.getIntExtra(BR_DEVICE, DEVICE_NONE); if ((Device < DEVICE_NONE) || (Device > DEVICE_NEIBOR)) { Log.e(TAG, "BR_Parsing - Device is error : " + Device); return null; } // 2. 통화 정보 범위 체크 int CallType = intent.getIntExtra(BR_TYPE_CALL, CALLTYPE_NONE); if ((CallType < CALLTYPE_NONE) || (CALLTYPE_RECEIVE_DOOR_OPEN_ACK < CallType)) { Log.e(TAG, "BR_Parsing - CallType is error : " + CallType); return null; } // 2.1 WallPadDevService 일 경우 받은 BR 종류 범위 체크 if (AppName.equalsIgnoreCase(APP_NAME_WALLPADDEVSERVICE) == true) { switch (CallType) { case CALLTYPE_SEND_CALL_ACK: case CALLTYPE_SEND_CALL_ACK_FAIL: case CALLTYPE_SEND_CALL_START: case CALLTYPE_SEND_CALL_END: case CALLTYPE_SEND_CALL_REQUEST: case CALLTYPE_SEND_DOOR_OPEN: break; default: Log.e(TAG, "BR_Parsing - " + APP_NAME_WALLPADDEVSERVICE + " - CallType is error : " + CallType); return null; } } // 2.2 WallPadCall 일 경우 받은 BR 종류 범위 체크 if (AppName.equalsIgnoreCase(APP_NAME_WALLPADCALL) == true) { switch (CallType) { case CALLTYPE_RECEIVE_CALL_REQUEST: case CALLTYPE_RECEIVE_CALL_END: case CALLTYPE_RECEIVE_CALL_ACK: case CALLTYPE_RECEIVE_CALL_ACK_FAIL: case CALLTYPE_RECEIVE_CALL_START: case CALLTYPE_RECEIVE_DOOR_OPEN_ACK: break; default: Log.e(TAG, "BR_Parsing - " + APP_NAME_WALLPADCALL + " - CallType is error : " + CallType); return null; } } // 3. 동 정보 범위 체크 int Dong = intent.getIntExtra(BR_ID_DONG, -1); if ((Dong < 0) || (Dong > 9999)) { Log.e(TAG, "BR_Parsing - Dong is error : " + Dong); return null; } if (Device == DEVICE_GUARD) { if (Dong != 0) { Log.e(TAG, "BR_Parsing - Dong is error : " + Dong + "(DEVICE_GUARD)"); return null; } } // 4. 호 정보 범위 체크 int Ho = intent.getIntExtra(BR_ID_HO, -1); if ((Ho < 0) || (Ho > 9999)) { Log.e(TAG, "BR_Parsing - Ho is error : " + Ho); return null; } // 5. 데이터 응답 call_info = new Call_Info(); call_info.Type_Device = Device; call_info.Type_Call = CallType; call_info.ID_Dong = Dong; call_info.ID_Ho = Ho; Log.d(TAG, "BR_Parsing - call_info.Type_Device : " + call_info.Type_Device); Log.d(TAG, "BR_Parsing - call_info.Type_Call : " + call_info.Type_Call); Log.d(TAG, "BR_Parsing - call_info.ID_Dong : " + call_info.ID_Dong); Log.d(TAG, "BR_Parsing - call_info.ID_Ho : " + call_info.ID_Ho); return call_info; } /** * @description * 홈오토 통화 관련 BR 송신 * * @return boolean -> true(정상), false(송신 실패) * * @param DeviceType -> 디바이스 종류 * @param CallType -> 통화 종류 * @param ID_Dong -> 동 ID (경비실인 경우는 무시) * @param ID_Ho -> 호 ID (로비, 경비인 경우는 ID로 사용됨) * **/ public boolean BR_Send(int DeviceType, int CallType, int ID_Dong, int ID_Ho) { /** param check **/ /* if(CallType == CALLTYPE_SEND_CALL_END || CallType == CALLTYPE_SEND_CALL_ACK_FAIL || CallType == CALLTYPE_RECEIVE_CALL_END || CallType == CALLTYPE_RECEIVE_CALL_ACK_FAIL || CallType == CALLTYPE_SEND_DOOR_OPEN || CallType == CALLTYPE_RECEIVE_DOOR_OPEN_ACK) { m_nCallType = 0; } else { m_nCallType = CallType; } */ // 1. 디바이스 정보 범위 체크 if ((DeviceType < DEVICE_NONE) || (DeviceType > DEVICE_NEIBOR)) { Log.e(TAG, "BR_Send - DeviceType is error : " + DeviceType); //m_nCallType = 0; return false; } // 2. 통화 정보 범위 체크 if ((CallType < CALLTYPE_NONE) || (CallType > CALLTYPE_RECEIVE_DOOR_OPEN_ACK)) { Log.e(TAG, "BR_Send - CallType is error : " + CallType); //m_nCallType = 0; return false; } // 3. 동 정보 범위 체크 if ((ID_Dong < 0) || (ID_Dong > 9999)) { Log.e(TAG, "BR_Send - ID_Dong is error : " + ID_Dong); //m_nCallType = 0; return false; } if (DeviceType == DEVICE_GUARD) { if (ID_Dong != 0) { Log.e(TAG, "BR_Send - ID_Dong is error : " + ID_Dong + "(DEVICE_GUARD)"); //m_nCallType = 0; return false; } } // 4. 호 정보 범위 체크 if ((ID_Ho < 0) || (ID_Ho > 9999)) { Log.e(TAG, "BR_Send - ID_Dong is error : " + ID_Ho); //m_nCallType = 0; return false; } Log.d(TAG, "BR_Send - DeviceType : " + DeviceType); Log.d(TAG, "BR_Send - CallType : " + CallType); Log.d(TAG, "BR_Send - ID_Dong : " + ID_Dong); Log.d(TAG, "BR_Send - ID_Ho : " + ID_Ho); //5. Broadcast 전송 sendCallBR(DeviceType, CallType, ID_Dong, ID_Ho); /* if(CallType == CALLTYPE_SEND_CALL_END || CallType == CALLTYPE_SEND_CALL_ACK_FAIL || CallType == CALLTYPE_RECEIVE_CALL_END || CallType == CALLTYPE_RECEIVE_CALL_ACK_FAIL || CallType == CALLTYPE_SEND_DOOR_OPEN || CallType == CALLTYPE_RECEIVE_DOOR_OPEN_ACK) { m_nCallType = 0; } else { m_nCallType = CallType; } */ //Log.d(TAG, "BR_Send - CallType1 : " + m_nCallType); // Intent mIntent = new Intent(); // mIntent.setAction(BR_ACTION_NAME); // mIntent.putExtra(BR_DEVICE, DeviceType); // mIntent.putExtra(BR_TYPE_CALL, ID_Dong); // mIntent.putExtra(BR_ID_DONG, nDong); // mIntent.putExtra(BR_ID_HO, ID_Ho); // context.sendBroadcast(mIntent); return true; } public void setCallStaus(int nStatus) { m_nCallType = nStatus; Log.d(TAG, "BR_Send - CallType1 : " + m_nCallType); } public void sendCallBR(int nCallType, int nEventType, int nDong, int nHo) { try { Log.i(TAG, "[sendCallBR] nCallType [" + nCallType + "], nEventType [" + nEventType + "], nDong [" + nDong + "], nHo [" + nHo + "]"); // 통화관련 BR을 전송하기 전에 신규호출과 관련된 내용이면, 통화어플이 동작중인지 확인하여 // 통화어플이 동작중이면 BR을 전송하고, // 동작중이 아니면, 통화어플을 구동한다. if (nEventType == CALLTYPE_RECEIVE_CALL_REQUEST) { receiveNewCall(nCallType, nEventType, nDong, nHo); } else { Intent mIntent = new Intent(); mIntent.setAction(BR_ACTION_NAME); mIntent.putExtra(BR_DEVICE, nCallType); mIntent.putExtra(BR_TYPE_CALL, nEventType); mIntent.putExtra(BR_ID_DONG, nDong); mIntent.putExtra(BR_ID_HO, nHo); context.sendBroadcast(mIntent); } } catch (Exception e) { Log.e(TAG, "[Exception] sendCallBR(int nCallType, int nEventType, int nDong, int nHo)"); e.printStackTrace(); } } public void sendBlockCallFalg(boolean bBlock, int nAutoReleaseSec) { try { Log.i(TAG, "[sendBlockCallFalg] bBlock [" + bBlock + "], nAutoReleaseSec [" + nAutoReleaseSec + "]"); Intent mIntent = new Intent(); mIntent.setAction(BR_ACTION_NAME_OPTION); mIntent.putExtra(BR_BLOCK_NEWCALL, bBlock); mIntent.putExtra(BR_BLOCK_NEWCALL_RELEASESEC, nAutoReleaseSec); context.sendBroadcast(mIntent); } catch (Exception e) { Log.e(TAG, "[Exception] sendBlockCallFalg(boolean bBlock, int nAutoReleaseSec)"); e.printStackTrace(); } } //String strWallPadAnalogCallPakageName = "kr.co.icontrols.wallpadanalogcall"; String strWallPadAnalogCallPakageName = "kr.co.icontrols.wallpadcall"; public void receiveNewCall(int nCallType, int nEventType, int nDong, int nHo) { try { Log.i(TAG, "[receiveNewCall] nCallType [" + nCallType + "], nEventType [" + nEventType + "], nDong [" + nDong + "], nHo [" + nHo + "]" + "], m_nCallType [" + m_nCallType + "]"); CALLEVENTTYPE eEventType = CALLEVENTTYPE.RECEIVE_CALL; CALLTYPE eCallType = CALLTYPE.NONE; if (nCallType == DEVICE_LOBBY) eCallType = CALLTYPE.LOBBY; else if (nCallType == DEVICE_GUARD) eCallType = CALLTYPE.GUARD; else if (nCallType == DEVICE_NEIBOR) eCallType = CALLTYPE.RESIDENCE; else { Log.e(TAG, "[receiveNewCall] SIPID is not correct!!!"); return; } //if (isCallAppRunning()) { if (m_nCallType == 0) { // 통화어플을 실행시킨다. //m_nCallType = 1; Log.w(TAG, "[runCallMainActivity] ########## START ##########"); WallpadStatusData mWallpadStatusData = new WallpadStatusData(context); int nAlramStatus = mWallpadStatusData.GetAlarmStatus(); mWallpadStatusData.closeDB(); if (nAlramStatus != WallpadStatusData.GUARD_OUT) sendBR_AppFinish(context); // 통화어플 실행 후, ACK 전송시 타임아웃 되는 경우가 있어서 통화어플이 실행중이지 않는 경우에는 API에서 바로 ACK를 전송한다. sendDirectACKBR(nCallType, CALLTYPE_SEND_CALL_ACK, nDong, nHo); //ComponentName mComponentName = new ComponentName("kr.co.icontrols.wallpadanalogcall", "kr.co.icontrols.wallpadanalogcall.MainActivity"); ComponentName mComponentName = new ComponentName("kr.co.icontrols.wallpadcall", "kr.co.icontrols.wallpadcall.MainActivity"); Intent mIntent = new Intent(Intent.ACTION_MAIN); // mIntent.addCategory(Intent.CATEGORY_LAUNCHER); mIntent.putExtra(CALLTRIGGER.CALLOWNER, CALLOWNER.NONE.toString()); mIntent.putExtra(CALLTRIGGER.CALLEVENTTYPE, eEventType.toString()); mIntent.putExtra(CALLTRIGGER.CALLTYPE, eCallType.toString()); mIntent.putExtra(CALLTRIGGER.REMOTEINFO_DONG, nDong); mIntent.putExtra(CALLTRIGGER.REMOTEINFO_HO, nHo); mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mIntent.setComponent(mComponentName); context.startActivity(mIntent); // Thread.sleep(500); // Call app이 실행되는 시간을 기다려준다. (빨리 띄우면 이벤트를 수신 못함) } else { Log.w(TAG, "[runCallMainActivity] wallpadcall is already running!!"); Log.e(TAG, "[runCallMainActivity] ############################## RUNNING ##############################"); Intent mIntent = new Intent(); mIntent.setAction(BR_ACTION_NAME); mIntent.putExtra(BR_DEVICE, nCallType); mIntent.putExtra(BR_TYPE_CALL, nEventType); mIntent.putExtra(BR_ID_DONG, nDong); mIntent.putExtra(BR_ID_HO, nHo); context.sendBroadcast(mIntent); } } catch (Exception e) { Log.e(TAG, "[Exception] runCallMainActivity()"); e.printStackTrace(); } } private boolean isCallAppRunning() { try { for (int i = 0; i < 5; i++) { Log.w(TAG, "[isCallAppRunning] Check Count [" + i + "]"); if (!getTopActivity().equals(strWallPadAnalogCallPakageName)) { return true; } Thread.sleep(100); } return false; } catch (Exception e) { Log.e(TAG, "[Exception] isCallAppRunning()"); e.printStackTrace(); return false; } } private void sendDirectACKBR(int nCallType, int nEventType, int nDong, int nHo) { try { Log.i(TAG, "[sendDirectACKBR] nCallType [" + nCallType + "], nEventType [" + nEventType + "], nDong [" + nDong + "], nHo [" + nHo + "]"); // Thread.sleep(500); Intent mIntent = new Intent(); mIntent.setAction(BR_ACTION_NAME); mIntent.putExtra(BR_DEVICE, nCallType); mIntent.putExtra(BR_TYPE_CALL, nEventType); mIntent.putExtra(BR_ID_DONG, nDong); mIntent.putExtra(BR_ID_HO, nHo); context.sendBroadcast(mIntent); } catch (Exception e) { Log.e(TAG, "[Exception] sendDirectACKBR(int nCallType, int nEventType, int nDong, int nHo)"); e.printStackTrace(); } } private String getTopActivity() { try { // ActivityManager mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); ActivityManager mActivityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); List mTaskInfo = mActivityManager.getRunningTasks(1); Log.i(TAG, "[getTopActivity] getClassName = " + mTaskInfo.get(0).topActivity.getClassName()); ComponentName mComponentName = mTaskInfo.get(0).topActivity; Log.i(TAG, "[getTopActivity] getPackageName = " + mComponentName.getPackageName()); return mComponentName.getPackageName(); } catch (Exception e) { Log.e(TAG, "[Exception] getTopActivity()"); e.printStackTrace(); return null; } } private void sendBR_AppFinish(Context context) { try { Log.w(TAG, "[sendBR_AppFinish] Send App Finish!!"); Intent mIntent = new Intent(); mIntent.setAction(define.BR_APP_FINISH); context.sendBroadcast(mIntent); } catch (Exception e) { Log.e(TAG, "[Exception] sendBR_AppFinish(Context context)"); e.printStackTrace(); } } public static class CALLTRIGGER { public static String CALLOWNER = "CALLOWNER"; public static String CALLEVENTTYPE = "CALLEVENTTYPE"; public static String CALLTYPE = "CALLTYPE"; public static String REMOTEINFO = "REMOTEINFO"; public static String REMOTEINFO_DONG = "REMOTEINFO_DONG"; public static String REMOTEINFO_HO = "REMOTEINFO_HO"; public enum SOURCE { USER, CALL_RECEIVE, SUBPHONE } public enum TYPE { MENU, FRONT, LOBBY, GUARD, RESIDENCE, PSTN } } // 통화상태정보를 다루는 enum public enum CALLTYPE { NONE, FRONT, RESIDENCE, LOBBY, GUARD, PSTN, IHUB, HISTORY_CALL, HISTORY_VISITORPIC, ERROR; public static CALLTYPE getCALLTYPE(String value) { try { if (value.equals(NONE.toString())) { return NONE; } else if (value.equals(FRONT.toString())) { return FRONT; } else if (value.equals(RESIDENCE.toString())) { return RESIDENCE; } else if (value.equals(LOBBY.toString())) { return LOBBY; } else if (value.equals(GUARD.toString())) { return GUARD; } else if (value.equals(PSTN.toString())) { return PSTN; } else if (value.equals(IHUB.toString())) { return IHUB; } else if (value.equals(HISTORY_CALL.toString())) { return HISTORY_CALL; } else if (value.equals(HISTORY_VISITORPIC.toString())) { return HISTORY_VISITORPIC; } else if (value.equals(ERROR.toString())) { return ERROR; } else { return null; } } catch (Exception e) { Log.e(TAG, "[Exception] getCALLTYPE()"); e.printStackTrace(); return null; } } } public enum CALLEVENTTYPE { RECEIVE_CALL, // 호출 수신 (호출 수신) TRYING_CALL, // 호출 시도중 (호출 발신) RECEIVE_CALL_2ND, // 멀티콜 수신 (호출 수신) RECEIVE_CALL_ACK, // 호출응답 수신 (호출 발신) REQUEST_FRONT_MONITORING, // 호출응답 수신 (호출 발신) CONNECT_CALL, // 통화 시작 TERMINATE_CALL, // 통화 종료 CANCEL_CALL, // 호출 취소 CANCEL_CALL_2ND, // 멀티콜 호출 취소 REJECT_CALL, // 호출수신 거절 REJECT_BUSY_CALL, // 통화중 호출수신 거절 FORWARD_CALL, // 착신전환 설정 CALLERID, // Caller ID TIMEOUT_1STCALL, // 1st Call Timeout TIMEOUT_2NDCALL, // 2nd Call Timeout TIMEOUT_3RDCALL, // 3rd Call Timeout MOIP_VIDEO_SET, // MoIP 영상통화 설정 DOOR_OPEN, // 문열림 설정 PSTN_RING, // PSTN ARS동작을 위해, UI에서 Ring을 카운트 하기위한 이벤트 PSTN_DTMF, // PSTN DTMF 수신 NONE; public static CALLEVENTTYPE getCALLEVENTTYPE(String value) { try { if (value.equals(RECEIVE_CALL.toString())) { return RECEIVE_CALL; } else if (value.equals(TRYING_CALL.toString())) { return TRYING_CALL; } else if (value.equals(RECEIVE_CALL_2ND.toString())) { return RECEIVE_CALL_2ND; } else if (value.equals(RECEIVE_CALL_ACK.toString())) { return RECEIVE_CALL_ACK; } else if (value.equals(REQUEST_FRONT_MONITORING.toString())) { return REQUEST_FRONT_MONITORING; } else if (value.equals(CONNECT_CALL.toString())) { return CONNECT_CALL; } else if (value.equals(TERMINATE_CALL.toString())) { return TERMINATE_CALL; } else if (value.equals(CANCEL_CALL.toString())) { return CANCEL_CALL; } else if (value.equals(REJECT_CALL.toString())) { return REJECT_CALL; } else if (value.equals(REJECT_BUSY_CALL.toString())) { return REJECT_BUSY_CALL; } else if (value.equals(FORWARD_CALL.toString())) { return FORWARD_CALL; } else if (value.equals(CALLERID.toString())) { return CALLERID; } else if (value.equals(TIMEOUT_1STCALL.toString())) { return TIMEOUT_1STCALL; } else if (value.equals(TIMEOUT_2NDCALL.toString())) { return TIMEOUT_2NDCALL; } else if (value.equals(TIMEOUT_3RDCALL.toString())) { return TIMEOUT_3RDCALL; } else if (value.equals(MOIP_VIDEO_SET.toString())) { return MOIP_VIDEO_SET; } else if (value.equals(DOOR_OPEN.toString())) { return DOOR_OPEN; } else if (value.equals(PSTN_RING.toString())) { return PSTN_RING; } else if (value.equals(PSTN_DTMF.toString())) { return PSTN_DTMF; } else if (value.equals(NONE.toString())) { return NONE; } else { return null; } } catch (Exception e) { Log.e(TAG, "[Exception] getCALLEVENTTYPE()"); e.printStackTrace(); return null; } } } public enum CALLOWNER { NONE, WALLPAD, SUB_WALLPAD, KITCHEN_TV, BATH_PHONE, BATH_TV, UNIVERSAL_DEVICE, ERROR; public static CALLOWNER getCALLOWNER(String value) { try { if (value.equals(NONE.toString())) { return NONE; } else if (value.equals(WALLPAD.toString())) { return WALLPAD; } else if (value.equals(SUB_WALLPAD.toString())) { return SUB_WALLPAD; } else if (value.equals(KITCHEN_TV.toString())) { return KITCHEN_TV; } else if (value.equals(BATH_PHONE.toString())) { return BATH_PHONE; } else if (value.equals(BATH_TV.toString())) { return BATH_TV; } else if (value.equals(UNIVERSAL_DEVICE.toString())) { return UNIVERSAL_DEVICE; } else if (value.equals(ERROR.toString())) { return ERROR; } else { return null; } } catch (Exception e) { Log.e(TAG, "[Exception] getCALLOWNER()"); e.printStackTrace(); return null; } } } }