/** * 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 and this file only is also released under Apache license as an API file */ package com.csipsimple.api; import java.io.Serializable; import java.util.Comparator; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.database.DatabaseUtils; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; /** * Holder for a sip profile state.<br/> * It allows to unpack content values from registration/activation status of a {@link SipProfile}. */ public class SipProfileState implements Parcelable, Serializable{ /** * Primary key for serialization of the object. */ private static final long serialVersionUID = -3630993161572726153L; public int primaryKey = -1; private int databaseId; private int pjsuaId; private String wizard; private boolean active; private int statusCode; private String statusText; private int addedStatus; private int expires; private String displayName; private int priority; private String regUri = ""; /** * Account id.<br/> * Identifier of the SIP account associated. It's the identifier of the account for the API. * * @see SipProfile#FIELD_ID * @see Integer */ public final static String ACCOUNT_ID = "account_id"; /** * Identifier for underlying sip stack. <br/> * This is an internal identifier you normally don't need to use when using the api from an external application. * * @see Integer */ public final static String PJSUA_ID = "pjsua_id"; /** * Wizard key. <br/> * Wizard identifier associated to the account. This is a shortcut to not have to query {@link SipProfile} database * * @see String */ public final static String WIZARD = "wizard"; /** * Activation state.<br/> * Active state of the account. This is a shortcut to not have to query {@link SipProfile} database * * @see Boolean */ public final static String ACTIVE = "active"; /** * Status code of the latest registration.<br/> * SIP code of latest registration. * * @see Integer */ public final static String STATUS_CODE = "status_code"; /** * Status comment of latest registration.<br/> * Sip comment of latest registration. * * @see String */ public final static String STATUS_TEXT = "status_text"; /** * Status of sip stack adding of the account.<br/> * When the application adds the account to the stack it may fails if the sip profile is invalid. * * @see Integer */ public final static String ADDED_STATUS = "added_status"; /** * Latest know expires time. <br/> * Expires value of latest registration. It's actually usefull to detect that it was unregister testing 0 value. * Else it's not necessarily relevant information. * * @see Integer */ public final static String EXPIRES = "expires"; /** * Display name of the account.<br.> * This is a shortcut to not have to query {@link SipProfile} database */ public final static String DISPLAY_NAME = "display_name"; /** * Priority of the account.<br.> * This is a shortcut to not have to query {@link SipProfile} database */ public final static String PRIORITY = "priority"; /** * Registration uri of the account.<br.> * This is a shortcut to not have to query {@link SipProfile} database */ public final static String REG_URI = "reg_uri"; public static final String [] FULL_PROJECTION = new String[] { ACCOUNT_ID, PJSUA_ID, WIZARD, ACTIVE, STATUS_CODE, STATUS_TEXT, EXPIRES, DISPLAY_NAME, PRIORITY, REG_URI }; public SipProfileState(Parcel in) { readFromParcel(in); } /** * Should not be used for external use of the API. * Default constructor. */ public SipProfileState() { //Set default values addedStatus = -1; pjsuaId = -1; statusCode = -1; statusText = ""; expires = 0; } /** * Should not be used for external use of the API. * Constructor on the top of a sip account. * * @param account The sip profile to associate this wrapper info to. */ public SipProfileState(SipProfile account) { this(); databaseId = (int) account.id; wizard = account.wizard; active = account.active; displayName = account.display_name; priority = account.priority; regUri = account.reg_uri; } /** * Construct a sip state wrapper from a cursor retrieved with a * {@link ContentProvider} query on {@link SipProfile#ACCOUNT_STATUS_URI}. * * @param c the cursor to unpack */ public SipProfileState(Cursor c) { super(); createFromDb(c); } /** * @see Parcelable#describeContents() */ @Override public int describeContents() { return 0; } private final void readFromParcel(Parcel in) { primaryKey = in.readInt(); databaseId = in.readInt(); pjsuaId = in.readInt(); wizard = in.readString(); active = (in.readInt() == 1); statusCode = in.readInt(); statusText = in.readString(); addedStatus = in.readInt(); expires = in.readInt(); displayName = in.readString(); priority = in.readInt(); regUri = in.readString(); } /** * @see Parcelable#writeToParcel(Parcel, int) */ @Override public void writeToParcel(Parcel out, int arg1) { out.writeInt(primaryKey); out.writeInt(databaseId); out.writeInt(pjsuaId); out.writeString(wizard); out.writeInt( (active?1:0) ); out.writeInt(statusCode); out.writeString(statusText); out.writeInt(addedStatus); out.writeInt(expires); out.writeString(displayName); out.writeInt(priority); out.writeString(regUri); } /** * Parcelable creator. So that it can be passed as an argument of the aidl * interface */ public static final Parcelable.Creator<SipProfileState> CREATOR = new Parcelable.Creator<SipProfileState>() { public SipProfileState createFromParcel(Parcel in) { return new SipProfileState(in); } public SipProfileState[] newArray(int size) { return new SipProfileState[size]; } }; /** * Fill account state object from cursor. * @param c cursor on the database queried from {@link SipProfile#ACCOUNT_STATUS_URI} */ public final void createFromDb(Cursor c) { ContentValues args = new ContentValues(); DatabaseUtils.cursorRowToContentValues(c, args); createFromContentValue(args); } /** * Fill account state object from content values. * @param args content values to wrap. */ public final void createFromContentValue(ContentValues args) { Integer tmp_i; String tmp_s; Boolean tmp_b; tmp_i = args.getAsInteger(ACCOUNT_ID); if(tmp_i != null) { databaseId = tmp_i; } tmp_i = args.getAsInteger(PJSUA_ID); if(tmp_i != null) { pjsuaId = tmp_i; } tmp_s = args.getAsString(WIZARD); if(tmp_s != null) { wizard = tmp_s; } tmp_b = args.getAsBoolean(ACTIVE); if(tmp_b != null) { active = tmp_b; } tmp_i = args.getAsInteger(STATUS_CODE); if(tmp_i != null) { statusCode = tmp_i; } tmp_s = args.getAsString(STATUS_TEXT); if(tmp_s != null) { statusText = tmp_s; } tmp_i = args.getAsInteger(ADDED_STATUS); if(tmp_i != null) { addedStatus = tmp_i; } tmp_i = args.getAsInteger(EXPIRES); if(tmp_i != null) { expires = tmp_i; } tmp_s = args.getAsString(DISPLAY_NAME); if(tmp_s != null) { displayName = tmp_s; } tmp_s = args.getAsString(REG_URI); if(tmp_s != null) { regUri = tmp_s; } tmp_i = args.getAsInteger(PRIORITY); if(tmp_i != null) { priority = tmp_i; } } /** * Should not be used for external use of the API. * Produce content value from the wrapper. * * @return Complete content values from the current wrapper around sip * profile state. */ public ContentValues getAsContentValue() { ContentValues cv = new ContentValues(); cv.put(ACCOUNT_ID, databaseId); cv.put(ACTIVE, active); cv.put(ADDED_STATUS, addedStatus); cv.put(DISPLAY_NAME, displayName); cv.put(EXPIRES, expires); cv.put(PJSUA_ID, pjsuaId); cv.put(PRIORITY, priority); cv.put(REG_URI, regUri); cv.put(STATUS_CODE, statusCode); cv.put(STATUS_TEXT, statusText); cv.put(WIZARD, wizard); return cv; } /** * @param databaseId the databaseId to set */ public void setDatabaseId(int databaseId) { this.databaseId = databaseId; } /** * Get the identifier identifier of the account that this state is linked to. * @return the accountId identifier of the account : {@link #ACCOUNT_ID} */ public int getAccountId() { return databaseId; } /** * Should not be used for external use of the API. * @param pjsuaId the pjsuaId to set */ public void setPjsuaId(int pjsuaId) { this.pjsuaId = pjsuaId; } /** * Should not be used for external use of the API. * @return the pjsuaId {@link #PJSUA_ID} */ public int getPjsuaId() { return pjsuaId; } /** * Should not be used for external use of the API. * @param wizard the wizard to set */ public void setWizard(String wizard) { this.wizard = wizard; } /** * @return the wizard {@link #WIZARD} */ public String getWizard() { return wizard; } /** * Should not be used for external use of the API. * @param active the active to set */ public void setActive(boolean active) { this.active = active; } /** * @return the active {@link #ACTIVE} */ public boolean isActive() { return active; } /** * Should not be used for external use of the API. * @param statusCode the statusCode to set */ public void setStatusCode(int statusCode) { this.statusCode = statusCode; } /** * @return the statusCode {@link #STATUS_TEXT} */ public int getStatusCode() { return statusCode; } /** * Should not be used for external use of the API. * @param statusText the statusText to set */ public void setStatusText(String statusText) { this.statusText = statusText; } /** * @return the statusText {@link #STATUS_TEXT} */ public String getStatusText() { return statusText; } /** * Should not be used for external use of the API. * @param addedStatus the addedStatus to set */ public void setAddedStatus(int addedStatus) { this.addedStatus = addedStatus; } /** * @return the addedStatus {@link #ADDED_STATUS} */ public int getAddedStatus() { return addedStatus; } /** * Should not be used for external use of the API. * @param expires the expires to set */ public void setExpires(int expires) { this.expires = expires; } /** * @return the expires {@link #EXPIRES} */ public int getExpires() { return expires; } /** * @return the display name {@link #DISPLAY_NAME} */ public CharSequence getDisplayName() { return displayName; } /** * @return the priority {@link #PRIORITY} */ public int getPriority() { return priority; } /** * Should not be used for external use of the API. * @param priority */ public void setPriority(int priority) { this.priority = priority; } /** * Should not be used for external use of the API. * @param regUri the regUri to set */ public void setRegUri(String regUri) { this.regUri = regUri; } /** * @return the regUri {@link #REG_URI} */ public String getRegUri() { return regUri; } /** * Is the account added to sip stack yet? * @return true if the account has been added to sip stack and has a sip stack id. */ public boolean isAddedToStack() { return pjsuaId != -1; } /** * Is the account valid for sip calls? * @return true if it should be possible to make a call using the associated account. */ public boolean isValidForCall() { if(active) { if(TextUtils.isEmpty(getRegUri())) { return true; } return (isAddedToStack() && getStatusCode() == SipCallSession.StatusCode.OK && getExpires() > 0); } return false; } /** * Compare accounts profile states. * @return a comparator instance to compare profile states by priorities. */ public final static Comparator<SipProfileState> getComparator(){ return ACC_INFO_COMPARATOR; } private static final Comparator<SipProfileState> ACC_INFO_COMPARATOR = new Comparator<SipProfileState>() { @Override public int compare(SipProfileState infos1,SipProfileState infos2) { if (infos1 != null && infos2 != null) { int c1 = infos1.getPriority(); int c2 = infos2.getPriority(); if (c1 > c2) { return 1; } if (c1 < c2) { return -1; } } return 0; } }; }