/**
* Copyright (c) 2013, Sana
* 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 the Sana 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 Sana 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 org.sana.android.content;
import java.util.HashMap;
import java.util.Map;
import org.sana.android.util.Logf;
import android.content.Intent;
import android.text.TextUtils;
import android.util.SparseArray;
/**
*
* @author Sana Development
*
*/
public final class Intents{
private static final String TAG = Intents.class.getSimpleName();
protected static final int ACTION_WIDTH = 16;
protected static final int ACTION_MASK = ((1 << ACTION_WIDTH) - 1);
/** The bit width of the intent descriptor */
public static final int DESCRIPTOR_WIDTH = 32;
//-------------------------------------------------------------------------
// Base action codes
//-------------------------------------------------------------------------
public static final int NULL = -1;
public static final int MAIN = 1;
public static final int RUN = 2;
public static final int INSERT = 4 ;
public static final int INSERT_OR_EDIT = 8;
public static final int VIEW = 16;
public static final int EDIT = 32;
public static final int DELETE = 64;
public static final int PICK = 128;
public static final int ATTACH_DATA = 256;
public static final int CHOOSER = 512;
public static final int GET_CONTENT = 512;
public static final int DIAL = 1024;
public static final int CALL = 2048;
public static final int SEND = 4096;
public static final int SENDTO = 8192;
public static final int ANSWER = 16384;
public static final int SYNC = 32768;
public static final int PICK_ACTIVITY = 65536;
public static final int SEARCH = 131072;
public static final int WEB_SEARCH = 262144;
//-------------------------------------------------------------------------
// Request Codes
//-------------------------------------------------------------------------
/** Intent request code for picking a procedure */
public static final int PICK_PROCEDURE = PICK | Uris.PROCEDURE_DIR;
/** Intent request code for picking a saved procedure */
public static final int PICK_ENCOUNTER = PICK | Uris.ENCOUNTER_DIR;
/** Intent request code for picking a notification */
public static final int PICK_NOTIFICATION = PICK | Uris.NOTIFICATION_DIR;
/** Intent request code to start running a procedure */
public static final int RUN_PROCEDURE = RUN | Uris.PROCEDURE_DIR;
/** Intent request code to resume running a saved procedure*/
public static final int RESUME_PROCEDURE = EDIT | Uris.PROCEDURE_DIR;
/** Intent request code to start running a procedure */
public static final int EXECUTE_ENCOUNTER_TASK = RUN | Uris.ENCOUNTER_TASK_DIR;
/** INtent request code to view settings */
//public static final int SETTINGS = PICK | Uris.SETTINGS_DIR;
/** Intent request code for creating a new patient. */
public static final int CREATE_PATIENT = INSERT | Uris.SUBJECT_DIR;
/** Intent request code for viewing all patients. */
public static final int PICK_PATIENT = PICK | Uris.SUBJECT_DIR;
/** Intent request code for creating a new patient. */
//public static final int INSERT_SESSION = INSERT | Uris.SESSION_DIR;
//-------------------------------------------------------------------------
// Activity action strings
//-------------------------------------------------------------------------
/** Effectively an action to indicate a call to Activity.finish() */
public static final String ACTION_RESPOND_SUCCESS = "org.sana.intent.action.RESPOND_SUCCES";
public static final String ACTION_RESPOND_FAIL = "org.sana.intent.action.RESPOND_FAIL";
public static final String ACTION_FINISH = "org.sana.android.intent.action.FINISH";
public static final String ACTION_CANCEL = "org.sana.android.intent.action.CANCEL";
public static final String ACTION_OK = "org.sana.android.intent.action.OK";
/** Intent action string for picking the activity to run next. */
public static final String ACTION_PICK_ACTIVITY = "org.sana.android.intent.action.PICK_ACTIVITY";
/** Intent action string for picking a procedure */
public static final String ACTION_PICK_PROCEDURE = "org.sana.android.intent.action.PICK_PROCEDURE";
/** Intent action string for picking a saved procedure */
public static final String ACTION_PICK_ENCOUNTER = "org.sana.android.intent.action.PICK_ENCOUNTER";
/** Intent action string for picking a notification */
public static final String ACTION_PICK_NOTIFICATION = "org.sana.android.intent.action.PICK_NOTIFICATION";
/** Intent action string for picking a saved procedure */
public static final String ACTION_PICK_OBSERVER = "org.sana.android.intent.action.PICK_OBSERVER";
/** Intent action string to start running a procedure */
public static final String ACTION_RUN_PROCEDURE = "org.sana.android.intent.action.RUN_PROCEDURE";
/** Intent action string to resume running a saved procedure*/
public static final String ACTION_RESUME_PROCEDURE = "org.sana.android.intent.action.EDIT_PROCEDURE";
/** Intent action string to view settings */
public static final String ACTION_SETTINGS = "org.sana.android.intent.action.EDIT_SETTINGS";
/** Intent action string for creating a new patient. */
public static final String ACTION_INSERT_SUBJECT = "org.sana.android.intent.action.INSERT_SUBJECT";
/** Intent action string for viewing all patients. */
public static final String ACTION_PICK_SUBJECT = "org.sana.android.intent.action.PICK_SUBJECT";
/** Intent action string for creating a new patient. */
public static final String ACTION_INSERT_SESSION = "org.sana.android.intent.action.INSERT_SESSION";
/** Intent action string for creating a new patient. */
public static final String ACTION_VIEW_SESSION = "org.sana.android.intent.action.VIEW_SESSION";
/** Intent action string for creating a new patient. */
public static final String ACTION_UPDATE_SESSION = "org.sana.android.intent.action.UPDATE_SESSION";
/** Intent action string for creating a new patient. */
public static final String ACTION_DELETE_SESSION = "org.sana.android.intent.action.DELETE_SESSION";
/** Intent action string for the main activity. */
public static final String ACTION_MAIN = "org.sana.android.intent.action.MAIN";
//-------------------------------------------------------------------------
// CRUD action strings for the dispatcher
//-------------------------------------------------------------------------
/** Indicates data has been created and should be pushed upstream as necessary */
public static final String ACTION_CREATE = "org.sana.intent.action.CREATE";
/** Indicates data needs to be read or fetched from upstream as necessary */
public static final String ACTION_READ = "org.sana.intent.action.READ";
/** Indicates data has been updated and should be pushed upstream as necessary */
public static final String ACTION_UPDATE = "org.sana.intent.action.UPDATE";
/** Indicates data has been removed and should be removed upstream as anecessary */
public static final String ACTION_DELETE = "org.sana.intent.action.DELETE";
/** General action to indicate the action is intended to complete a predefined task */
public static final String ACTION_EXECUTE_TASK = "org.sana.intent.action.EXECUTE_TASK";
private static final Map<String, Integer> sActionCodes = new HashMap<String, Integer>(18);
static{
sActionCodes.put(Intent.ACTION_MAIN, MAIN);
sActionCodes.put(Intent.ACTION_RUN,RUN);
sActionCodes.put(Intent.ACTION_INSERT,INSERT);
sActionCodes.put(Intent.ACTION_INSERT_OR_EDIT,INSERT_OR_EDIT);
sActionCodes.put(Intent.ACTION_VIEW, VIEW);
sActionCodes.put(Intent.ACTION_EDIT,EDIT);
sActionCodes.put(Intent.ACTION_DELETE,DELETE);
sActionCodes.put(Intent.ACTION_PICK,PICK);
sActionCodes.put(Intent.ACTION_ATTACH_DATA,ATTACH_DATA);
sActionCodes.put(Intent.ACTION_CHOOSER,CHOOSER);
sActionCodes.put(Intent.ACTION_GET_CONTENT,GET_CONTENT);
sActionCodes.put(Intent.ACTION_DIAL,DIAL);
sActionCodes.put(Intent.ACTION_CALL,CALL);
sActionCodes.put(Intent.ACTION_SEND,SEND);
sActionCodes.put(Intent.ACTION_SENDTO,SENDTO);
sActionCodes.put(Intent.ACTION_ANSWER,ANSWER);
sActionCodes.put(Intent.ACTION_SYNC,SYNC);
sActionCodes.put(Intents.ACTION_PICK_ACTIVITY,PICK_ACTIVITY);
sActionCodes.put(Intent.ACTION_SEARCH,SEARCH);
sActionCodes.put(Intent.ACTION_WEB_SEARCH,WEB_SEARCH);
// CRUD Actions - these are essentially synonyms for others
sActionCodes.put(ACTION_CREATE, INSERT);
sActionCodes.put(ACTION_READ, VIEW);
sActionCodes.put(ACTION_UPDATE, EDIT);
sActionCodes.put(ACTION_DELETE, DELETE);
// Additional sana defined actions
sActionCodes.put(ACTION_EXECUTE_TASK, MAIN);
}
//-------------------------------------------------------------------------
// Activity category strings
//-------------------------------------------------------------------------
public static final String CATEGORY_AUTHENTICATE = "org.sana.android.intent.category.AUTHENTICATE";
public static final String CATEGORY_OBSERVABLE = "org.sana.android.intent.category.OBSERVABLE";
public static final String CATEGORY_LEXICAL = "org.sana.android.intent.category.LEXICAL";
public static final String CATEGORY_TASK = "org.sana.android.intent.category.TASK";
public static final String CATEGORY_TASK_COMPLETE = "org.sana.intent.category.TASK_COMPLETE";
//-------------------------------------------------------------------------
// Intent extra keys
//-------------------------------------------------------------------------
/** The int value of the original request code used when starting an Activity. */
public static final String EXTRA_REQUEST_CODE = "org.sana.android.intent.REQUEST_CODE";
/** The int value of the original request code used when starting an Activity. */
public static final String EXTRA_TOKEN = "org.sana.android.intent.TOKEN";
/** A string unique key value for an unvalidated session instance. */
public static final String EXTRA_INSTANCE = "org.sana.android.intent.extra.INSTANCE";
/** A unique string value for a validated session. */
public static final String EXTRA_SESSION = "org.sana.android.intent.extra.SESSION";
/** An Intent representing the previous state or request that was sent */
public static final String EXTRA_REQUEST = "org.sana.android.intent.extra.REQUEST";
/** A content: Uri holding the current concept */
public static final String EXTRA_CONCEPT = "org.sana.android.intent.extra.CONCEPT";
/** A content: Uri holding the current encounter */
public static final String EXTRA_ENCOUNTER = "org.sana.android.intent.extra.ENCOUNTER";
/** A content: Uri holding the current event */
public static final String EXTRA_EVENT = "org.sana.android.intent.extra.EVENT";
/** A content: Uri holding the current instruction */
public static final String EXTRA_INSTRUCTION = "org.sana.android.intent.extra.INSTRUCTION";
/** A content: Uri holding the current notification */
public static final String EXTRA_NOTIFICATION = "org.sana.android.intent.extra.NOTIFICATION";
/** A content: Uri holding the current observation */
public static final String EXTRA_OBSERVATION = "org.sana.android.intent.extra.OBSERVATION";
/** A content: Uri holding the current observer */
public static final String EXTRA_OBSERVER = "org.sana.android.intent.extra.OBSERVER";
/** A content: Uri holding the current procedure */
public static final String EXTRA_PROCEDURE = "org.sana.android.intent.extra.PROCEDURE";
public static final String EXTRA_PROCEDURE_ID = "org.sana.android.intent" +
".extra.PROCEDURE_ID";
/** A content: Uri holding the current subject */
public static final String EXTRA_SUBJECT = "org.sana.android.intent.extra.SUBJECT";
/** A content: Uri holding a task */
public static final String EXTRA_TASK = "org.sana.android.intent.extra.TASK";
/** An array of content Uris holding zero or more tasks */
public static final String EXTRA_TASKS = "org.sana.android.intent.extra.TASKS";
/** A content: Uri holding the current encounter task */
public static final String EXTRA_TASK_ENCOUNTER = "org.sana.android.intent.extra.task.ENCOUNTER";
/** A content: Uri holding the current observation task */
public static final String EXTRA_TASK_OBSERVATION = "org.sana.android.intent.extra.task.OBSERVATION";
/** */
public static final String EXTRA_ON_COMPLETE = "org.sana.android.intent" +
".extra.ON_COMPLETE";
public static final String SERVICE_DISPATCH = "org.sana.service.START_DISPATCH";
//-------------------------------------------------------------------------
// Intent flags
//-------------------------------------------------------------------------
/** Indicates message should be placed into the retry queue on failure */
public static final int FLAG_RETRY_ON_FAIL = 1;
/** Indicates message should be placed into the retry queue on failure */
public static final int FLAG_REPLACE = 2;
/** Set to indicate notifications should be sent */
public static final int FLAG_NOTIFY = 4;
/** Set to indicate notifications should be sent when the action of the intent has been started */
public static final int FLAG_NOTIFY_TASK_INIT = 8;
/** Set to indicate notifications should be sent after the action of the intent has completed */
public static final int FLAG_NOTIFY_TASK_COMPLETE = 16;
/**
* Copies an intent into a new one including all data, type, extras, and
* categories.
*
* @param intent the Intent to copy.
* @return A copy of the original Intent.
*/
public static Intent copyOf(Intent intent){
Intent newIntent = new Intent();
newIntent.fillIn(intent, Intent.FILL_IN_ACTION);
newIntent.fillIn(intent, Intent.FILL_IN_CATEGORIES);
newIntent.fillIn(intent, Intent.FILL_IN_DATA);
if(intent.getExtras() != null)
newIntent.putExtras(intent.getExtras());
return newIntent;
}
/**
* Returns an int descriptor code for an intent by checking whether it first
* has a an Intent extra keyed to {@link #NULL} and then by the action String
* if set.
*
* @param intent The intent to check for a recognized action descriptor.
* @return The descriptor or {@link #NULL} if not recognized.
* @throws NullPointerException if <code>intent</code> is null.
*/
public static int parseActionDescriptor(Intent intent){
Integer code = intent.getIntExtra(Intents.EXTRA_REQUEST_CODE, Intents.NULL);
// if the code was explicitly set as part of the extra as in the case
// where we are preserving the original action as part of a request code
if(code == Intents.NULL){
String action = intent.getAction();
if(!TextUtils.isEmpty(action)){
code = sActionCodes.get(action);
Logf.D(TAG, "getActionDescriptor(Intent)",
"'action' : " + action + ", 'code': " + code);
// indexOf method returns a negative number if not found
// set code to standard null value of -1 if not found.
code = (code != null)? code: Intents.NULL;
} else
Logf.D(TAG, "getActionDescriptor(Intent)", "'action' : null");
}
return code;
}
/**
* Returns whether an Intent with an action String can reasonably be
* expected to return a result. If the intent doesn't refer to an Activity
* this is meaningless.
*
* @param intent
* @return true if a data Uri should be returned.
*/
public static boolean startForResult(Intent intent){
final int descriptor = Intents.parseActionDescriptor(intent);
Logf.D(TAG, "startForResult(Intent)", "descriptor");
switch(descriptor){
case PICK:
case EDIT:
case INSERT:
case INSERT_OR_EDIT:
case GET_CONTENT:
case PICK_ACTIVITY:
return true;
default:
return false;
}
}
}