/**
* Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
* This file is part of CSipSimple.
*
* CSipSimple is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* If you own a pjsip commercial license you can also redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as an android library.
*
* CSipSimple is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CSipSimple. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* This file contains relicensed code from Apache copyright of
* Copyright (C) 2008 The Android Open Source Project
*/
package com.csipsimple.ui.incall.locker;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.RelativeLayout;
import com.csipsimple.api.SipCallSession;
import com.csipsimple.api.SipConfigManager;
import com.csipsimple.ui.incall.IOnCallActionTrigger;
import com.csipsimple.ui.incall.locker.buttons.AlternateUnlocker;
import com.csipsimple.ui.incall.locker.multiwaveview.GlowPadView;
import com.csipsimple.ui.incall.locker.slidingtab.SlidingTab;
import com.csipsimple.utils.Compatibility;
import com.csipsimple.utils.Log;
import com.csipsimple.utils.Theme;
import com.csipsimple.utils.accessibility.AccessibilityWrapper;
public class InCallAnswerControls extends RelativeLayout implements IOnLeftRightChoice {
private static final String THIS_FILE = "InCallAnswerControls";
private static final int LOCKER_SLIDINGTAB = 1;
private static final int LOCKER_BUTTON = 2;
private static final int LOCKER_GLOWPAD = 3;
private int lockerWidgetType;
private IOnLeftRightProvider lockerWidget;
private static final int MODE_LOCKER = 0;
private static final int MODE_NO_ACTION = 1;
private int controlMode;
private SipCallSession currentCall;
private IOnCallActionTrigger onTriggerListener;
public InCallAnswerControls(Context context) {
this(context, null, 0);
}
public InCallAnswerControls(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InCallAnswerControls(Context context, AttributeSet attrs, int style) {
super(context, attrs, style);
lockerWidgetType = LOCKER_GLOWPAD;
setGravity(Gravity.CENTER_VERTICAL);
if(!isInEditMode()) {
int unlockerType = SipConfigManager.getPreferenceIntegerValue(context, SipConfigManager.UNLOCKER_TYPE, 0);
if(unlockerType <= 0 || unlockerType > 3) {
AccessibilityWrapper accessibilityManager = AccessibilityWrapper.getInstance();
accessibilityManager.init(getContext());
if(accessibilityManager.isEnabled()) {
lockerWidgetType = LOCKER_BUTTON;
}
if (Compatibility.isTabletScreen(getContext())
&& !Compatibility.isCompatible(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) {
lockerWidgetType = LOCKER_BUTTON;
}
}else {
lockerWidgetType = unlockerType;
}
if(lockerWidgetType == LOCKER_GLOWPAD && !Compatibility.isCompatible(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) {
lockerWidgetType = LOCKER_SLIDINGTAB;
}
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// Finalize object style
controlMode = MODE_NO_ACTION;
}
private void setCallLockerVisibility(int visibility) {
controlMode = visibility == View.VISIBLE ? MODE_LOCKER : MODE_NO_ACTION;
setVisibility(visibility);
if(visibility == View.VISIBLE) {
// Inflate sub views only if display is requested
if(lockerWidget == null) {
switch (lockerWidgetType) {
case LOCKER_SLIDINGTAB:
lockerWidget = new SlidingTab(getContext());
break;
case LOCKER_BUTTON:
lockerWidget = new AlternateUnlocker(getContext());
break;
case LOCKER_GLOWPAD:
lockerWidget = new GlowPadView(getContext());
break;
default:
break;
}
lockerWidget.setOnLeftRightListener(this);
lockerWidget.setTypeOfLock(TypeOfLock.CALL);
LayoutParams lp = new LayoutParams(lockerWidget.getLayoutingWidth(), lockerWidget.getLayoutingHeight());
if(lockerWidget.getLayoutingHeight() == LayoutParams.WRAP_CONTENT ||
lockerWidget.getLayoutingWidth() == LayoutParams.WRAP_CONTENT) {
lp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
}
this.addView((View) lockerWidget, lp);
}
}
if(lockerWidget != null) {
lockerWidget.setVisibility(visibility);
lockerWidget.resetView();
}
}
public void setCallState(SipCallSession callInfo) {
currentCall = callInfo;
if(currentCall == null) {
setCallLockerVisibility(GONE);
return;
}
int state = currentCall.getCallState();
switch (state) {
case SipCallSession.InvState.INCOMING:
setCallLockerVisibility(VISIBLE);
break;
case SipCallSession.InvState.CALLING:
case SipCallSession.InvState.CONNECTING:
case SipCallSession.InvState.CONFIRMED:
case SipCallSession.InvState.NULL:
case SipCallSession.InvState.DISCONNECTED:
setCallLockerVisibility(GONE);
break;
case SipCallSession.InvState.EARLY:
default:
if (currentCall.isIncoming()) {
setCallLockerVisibility(VISIBLE);
} else {
setCallLockerVisibility(GONE);
}
break;
}
}
/**
* Registers a callback to be invoked when the user triggers an event.
*
* @param listener
* the OnTriggerListener to attach to this view
*/
public void setOnTriggerListener(IOnCallActionTrigger listener) {
onTriggerListener = listener;
}
private void dispatchTriggerEvent(int whichHandle) {
if (onTriggerListener != null) {
onTriggerListener.onTrigger(whichHandle, currentCall);
}
}
@Override
public void onLeftRightChoice(int whichHandle) {
Log.d(THIS_FILE, "Call controls receive info from slider " + whichHandle);
if (controlMode != MODE_LOCKER) {
// Oups we are not in locker mode and we get a trigger from
// locker...
// Should not happen... but... to be sure
return;
}
switch (whichHandle) {
case LEFT_HANDLE:
Log.d(THIS_FILE, "We take the call");
dispatchTriggerEvent(IOnCallActionTrigger.TAKE_CALL);
break;
case RIGHT_HANDLE:
Log.d(THIS_FILE, "We clear the call");
dispatchTriggerEvent(IOnCallActionTrigger.DONT_TAKE_CALL);
default:
break;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d(THIS_FILE, "Hey you hit the key : " + keyCode);
if (controlMode == MODE_LOCKER) {
switch (keyCode) {
case KeyEvent.KEYCODE_CALL:
dispatchTriggerEvent(IOnCallActionTrigger.TAKE_CALL);
return true;
case KeyEvent.KEYCODE_ENDCALL:
//case KeyEvent.KEYCODE_POWER:
dispatchTriggerEvent(IOnCallActionTrigger.REJECT_CALL);
return true;
default:
break;
}
}
return super.onKeyDown(keyCode, event);
}
public void applyTheme(Theme t) {
// TODO
}
}