Android Open Source - HeadphoneController H C Config Adapter






From Project

Back to project page HeadphoneController.

License

The source code is released under:

GNU General Public License

If you think the Android project HeadphoneController listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package ca.mbabic.headphonecontroller.configuration;
//  w  w  w . ja  v a 2 s .c o m
import static ca.mbabic.headphonecontroller.configuration.HCConfigConstants.*;

import java.util.ArrayList;
import java.util.Arrays;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.telephony.TelephonyManager;
import android.util.Log;
import ca.mbabic.headphonecontroller.commands.HCCommand;
import ca.mbabic.headphonecontroller.commands.HCCommandContext;
import ca.mbabic.headphonecontroller.commands.HCCommandFactory;
import ca.mbabic.headphonecontroller.models.HCCmd;
import ca.mbabic.headphonecontroller.models.HCInputSequence;

/**
 * Defines methods allowing other classes access to configuration settings.
 * 
 * @author Marko Babic
 * 
 */
public class HCConfigAdapter {

  /**
   * Class specific logging tag.
   */
  private static final String TAG = ".configuration.HCConfigAdapter";

  /**
   * Reference to shared preferences object storing configuration details.
   */
  private SharedPreferences prefs;

  /**
   * Reference to telephonyManager instance such that call state (i.e., if the
   * phone is ringing, if a call is ongoing, etc.) can be queried.
   */
  private TelephonyManager telephonyManager;

  /**
   * @param prefs
   *            Shared preferences object from which preferences can be
   *            retrieved.
   * @param prefs
   *            Application context such that reference to TelephonyManager
   *            can be retrieved.
   */
  public HCConfigAdapter(SharedPreferences sharedPrefs, Context cxt) {

    prefs = sharedPrefs;

    telephonyManager = (TelephonyManager) cxt
        .getSystemService(Context.TELEPHONY_SERVICE);
  }

  
  /**
   * Returns State object associated with the given state key or null if no
   * such object exists.
   * @param stateKey
   *     The key of the state to be retrieved from configuration store.
   */
  public HCInputSequence getState(String stateKey) {

    String[] cmds;
    HCCmd idleCmd, offHookCmd, ringingCmd;
    String idleCmdKey, offHookCmdKey, ringingCmdKey, stateName, 
    idleCmdName, offHookCmdName, ringingCmdName, cmdStr;  
    
    if (!isValidStateKey(stateKey)) return null;
    
    cmdStr = prefs.getString(stateKey, "");
    
    cmds = cmdStr.split(COMMAND_DELIMITER);
    
    idleCmdKey     = cmds[TelephonyManager.CALL_STATE_IDLE];
    offHookCmdKey   = cmds[TelephonyManager.CALL_STATE_OFFHOOK];
    ringingCmdKey   = cmds[TelephonyManager.CALL_STATE_RINGING];
    
    idleCmdName   = HCConfigAdapter.keyToName(idleCmdKey);
    offHookCmdName   = HCConfigAdapter.keyToName(offHookCmdKey);
    ringingCmdName   = HCConfigAdapter.keyToName(ringingCmdKey);
    
    idleCmd     = new HCCmd(idleCmdKey, idleCmdName);
    offHookCmd     = new HCCmd(offHookCmdKey, offHookCmdName);
    ringingCmd     = new HCCmd(ringingCmdKey, ringingCmdName);
    
    stateName     = HCConfigAdapter.keyToName(stateKey);
    
    return new HCInputSequence(stateKey, stateName, idleCmd, offHookCmd, ringingCmd);
  }
  
  /**
   * Get collection of state objects from configuration file.
   */
  public ArrayList<HCInputSequence> getStates() {

    ArrayList<HCInputSequence> ret;
    String stateKey;
    int i;

    ret = new ArrayList<HCInputSequence>();    
    
    for (i = 0; i < INPUTSEQUENCE_KEYS.length; i++) {

      stateKey = INPUTSEQUENCE_KEYS[i];
      
      ret.add(getState(stateKey));            
    }
    
    return ret;
  }
  
  /**
   * Get collection of all possible commands from the configuration file
   * by call state.
   * 
   * @param callState
   *     The call state for which all possible commands are to be retrieved.
   * @return
   *     ArrayList of command objects.
   * @throws Exception
   *     Throws exception if given invalid call state.
   */
  public ArrayList<HCCmd> getCommands(int callState) throws Exception {
    
    ArrayList<HCCmd> ret;
    
    if (!isValidCallState(callState)) {
      throw new Exception("Invalid call state value.");
    }
    
    ret = new ArrayList<HCCmd>();
    
    for (String cmdKey : CMD_KEYS) {
      
      // Search for callState in validCallStates -- if it is in there,
      // then we construct a new command object and add it to the array
      // to be returned.  isValidCommandKey() does this work for us.
      if (isValidCommandKey(cmdKey, callState)) {
        
        ret.add(new HCCmd(cmdKey, keyToName(cmdKey)));
        
      }  
    }
    
    return ret;
  }

  /**
   * Converts the given command or state key to a String representing the name
   * of that command or state.
   * 
   * @param key
   *    The state key from which the state name is to be derived.
   * @return
   *     The name of the state specified by the given key.
   */
  public static String keyToName(String key) {

    String[] splitKey;
    String name, ret = "";
    int i;
    char c;

    splitKey = key.split(".");

    name = splitKey[splitKey.length - 1];

    for (i = 0; i < name.length(); i++) {

      c = name.charAt(i);
      
      if (Character.isUpperCase(c) && i > 0) {
        ret += " ";
      }
      
      ret += c;
    }

    return ret;
  }

  /**
   * 
   * Set the command to be executed in the given HCStateMachine state 
   * in the given call state.
   * 
   * Command string stored in format:
   * CMD_FOR_CALL_IDLE::CMD_FOR_CALL_RINGING::CMD_FOR_CALL_OFFHOOK
   * 
   * @param stateKey
   *     The key of the HCStateMachine state in which the command is to
   *     executed.
   * @param cmdKey
   *     The key of the command to be executed.
   * @param callState
   *     The call state to which the command applies.
   * @throws Exception
   *    Throws exception if passed invalid state or command key.
   */
  public void setStateCommand(String stateKey, String cmdKey, int callState)
      throws Exception {

    String[] cmds;
    String cmdStr, newCmdStr;
    int i;

    // Ensure that given stateKey, cmdKey and callState are valid.
    // TODO: throw better exception type, break into separate cases for more
    // informative exception message.
    if (!isValidStateKey(stateKey) || !isValidCommandKey(cmdKey, callState)) {

      throw new Exception("Invalid state or command key.");

    }

    cmdStr = prefs.getString(stateKey, null);

    if (cmdStr == null) {

      // No preferences thus far set for this command.
      // TODO: can this happen/should this be allowed to happen?

    }

    cmds = cmdStr.split(COMMAND_DELIMITER);

    // Construct the new string to be stored.
    newCmdStr = "";
    for (i = 0; i < N_CALL_STATES; i++) {

      if (i != callState) {
        newCmdStr += cmds[i];
      } else {
        newCmdStr += cmdKey;
      }

      // Put delimiter between the first/second and second/third
      // commands.
      if (i < N_CALL_STATES - 1) {
        newCmdStr += COMMAND_DELIMITER;
      }
    }

    // Store and commit changes to shared preferences object.
    prefs.edit().putString(stateKey, newCmdStr).commit();

  }

  /**
   * Given a State class, constructs a HCCommandContext object from which
   * the appropriate command can be invoked.   * 
   * TODO: should this really be the responsibility of HCConfigAdapter?
   * Consider refactoring so that HCConfigAdapter class does not need 
   * reference to TelephonyManager to view state.
   * @param state
   * @return
   */
  @SuppressWarnings("rawtypes")
  public HCCommandContext getCommandContext(Class state) {

    HCCommand cmd;
    String[] cmds;
    String storedCmdStr, cmdStr;

    Log.d(TAG, "getCommandContext called with state = " + state.getName());

    storedCmdStr = prefs.getString(state.getName(), null);

    Log.d(TAG, "storedCmdStr = " + storedCmdStr);

    cmds = storedCmdStr.split(COMMAND_DELIMITER);

    Log.d(TAG, "cmds[0], cmds[1], cmds[2] = " + cmds[0] + ", " + cmds[1]
        + ", " + cmds[2]);

    cmdStr = cmds[telephonyManager.getCallState()];

    Log.d(TAG, "cmdStr = " + cmdStr);

    try {

      cmd = HCCommandFactory.createInstance(cmdStr);

      return new HCCommandContext(cmd);

    } catch (Exception e) {

      Log.e(TAG, e.getMessage());

    }

    // Got here only if exception was thrown, return null and let
    // program crash as this implies fatal error anyway.
    return null;

  }

  /**
   * Writes the default configuration values to the SharedPreferences object.
   */
  public void writeDefaultConfigurationValues() {

    Editor edit;
    String cmdStr;

    edit = prefs.edit();

    // Write default values for OnePressState.
    cmdStr = PLAYPAUSE_CMD_KEY + COMMAND_DELIMITER + NO_OP_CMD_KEY
        + COMMAND_DELIMITER + NO_OP_CMD_KEY;
    edit.putString(ONE_PRESS_KEY, cmdStr).commit();

    // Write default values for TwoPressState.
    cmdStr = SKIP_CMD_KEY + COMMAND_DELIMITER + NO_OP_CMD_KEY
        + COMMAND_DELIMITER + NO_OP_CMD_KEY;
    edit.putString(TWO_PRESS_KEY, cmdStr).commit();

    // Write default values for ThreePressState.
    cmdStr = PREVIOUS_CMD_KEY + COMMAND_DELIMITER + NO_OP_CMD_KEY
        + COMMAND_DELIMITER + NO_OP_CMD_KEY;
    edit.putString(THREE_PRESS_KEY, cmdStr).commit();

    // Write default values for FourPressState.
    cmdStr = MUTE_MUSIC_CMD_KEY + COMMAND_DELIMITER + NO_OP_CMD_KEY
        + COMMAND_DELIMITER + NO_OP_CMD_KEY;
    edit.putString(FOUR_PRESS_KEY, cmdStr).commit();

  }

  /**
   * Retrieve the value of the "hasRunBefore" key from the shared preferences
   * object.
   */
  public boolean hasApplicationRunBefore() {
    return prefs.getBoolean(HAS_RUN_BEFORE_KEY, false);
  }

  /**
   * Set the value of the "hasRunBefore" key in the shared preferences object
   * to be true.
   */
  public void setHasRunBefore() {
    prefs.edit().putBoolean(HAS_RUN_BEFORE_KEY, true);
  }

  // Validation functions
  /**
   * Inspects the validity of the given string as a key for a stored state.
   * 
   * @param key
   *            The state key whose validity is to be established.
   * @return True if valid, false otherwise.
   */
  private boolean isValidStateKey(String key) {
    return Arrays.asList(INPUTSEQUENCE_KEYS).contains(key);
  }

  /**
   * Inspects the validity of the given string as a key for a stored state.
   * 
   * @param key
   *            Command string to be validated.
   * 
   * @param callState
   *            The call state associated with the command.
   * 
   * @return True if valid, false otherwise.
   */
  private boolean isValidCommandKey(String key, int callState) {

    // Ensure key is valid.
    if (Arrays.binarySearch(CMD_KEYS, key) == -1)
      return false;

    // Ensure that command can be invoked in the specified call state.
    Arrays.sort(VALID_CMD_STATES.get(key));
    if (Arrays.binarySearch(VALID_CMD_STATES.get(key), callState) == -1)
      return false;

    return true;
  }
  
  /**
   * Determines if the given callState is of a valid value.
   * @param callState
   *     The call state whose validity is to be determined.
   * @return
   *     True if the call state is valid, false otherwise.
   */
  private boolean isValidCallState(int callState) {
    if   (  
        callState != TelephonyManager.CALL_STATE_IDLE     &&
        callState != TelephonyManager.CALL_STATE_OFFHOOK  &&
        callState != TelephonyManager.CALL_STATE_RINGING
    ) {
      return false;
    }
    
    return true;
  }

}




Java Source Code List

ca.mbabic.headphonecontroller.ConfigurationFragment.java
ca.mbabic.headphonecontroller.HCApplication.java
ca.mbabic.headphonecontroller.HomeActivity.java
ca.mbabic.headphonecontroller.SelectCommandActivity.java
ca.mbabic.headphonecontroller.commands.CommandExecutor.java
ca.mbabic.headphonecontroller.commands.HCCommandContext.java
ca.mbabic.headphonecontroller.commands.HCCommandFactory.java
ca.mbabic.headphonecontroller.commands.HCCommand.java
ca.mbabic.headphonecontroller.commands.MuteMusicCommand.java
ca.mbabic.headphonecontroller.commands.NoOpCommand.java
ca.mbabic.headphonecontroller.commands.PlayPauseCommand.java
ca.mbabic.headphonecontroller.commands.PreviousCommand.java
ca.mbabic.headphonecontroller.commands.SkipCommand.java
ca.mbabic.headphonecontroller.configuration.HCConfigAdapter.java
ca.mbabic.headphonecontroller.configuration.HCConfigConstants.java
ca.mbabic.headphonecontroller.db.DbHelper.java
ca.mbabic.headphonecontroller.db.HCCallStateTable.java
ca.mbabic.headphonecontroller.db.HCCommandCallStateTable.java
ca.mbabic.headphonecontroller.db.HCCommandTable.java
ca.mbabic.headphonecontroller.db.HCDbAdapter.java
ca.mbabic.headphonecontroller.db.HCDbHelper.java
ca.mbabic.headphonecontroller.db.HCDbTable.java
ca.mbabic.headphonecontroller.db.HCInputSequenceCommandsTable.java
ca.mbabic.headphonecontroller.db.HCInputSequenceTable.java
ca.mbabic.headphonecontroller.models.HCCmd.java
ca.mbabic.headphonecontroller.models.HCInputSequence.java
ca.mbabic.headphonecontroller.services.MediaButtonListenerService.java
ca.mbabic.headphonecontroller.services.MediaButtonReceiver.java
ca.mbabic.headphonecontroller.services.MediaStateChangeReceiver.java
ca.mbabic.headphonecontroller.statemachine.FourPressState.java
ca.mbabic.headphonecontroller.statemachine.HCStateMachine.java
ca.mbabic.headphonecontroller.statemachine.HCState.java
ca.mbabic.headphonecontroller.statemachine.InactiveState.java
ca.mbabic.headphonecontroller.statemachine.OnePressState.java
ca.mbabic.headphonecontroller.statemachine.ThreePressState.java
ca.mbabic.headphonecontroller.statemachine.TwoPressState.java
ca.mbabic.headphonecontroller.views.CommandAdapter.java