ChargingLEDLib.java :  » UnTagged » netmeterled » com » britoso » cpustatusled » utilclasses » Android Open Source

Android Open Source » UnTagged » netmeterled 
netmeterled » com » britoso » cpustatusled » utilclasses » ChargingLEDLib.java
package com.britoso.cpustatusled.utilclasses;

import java.io.DataOutputStream;
import java.io.File;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.britoso.cpustatusled.CPUStatusLEDActivity;
import com.britoso.cpustatusled.utilclasses.ShellCommand.CommandResult;

/**
 * This library offers methods to set the charging LED color.
 *
 * @author britoso
 *
 *         color combinations: green+blue= sky blue blue+amber= pink
 */
public class ChargingLEDLib
{
  //data
  public final static int MAX_SUPPORTED_COLORS = 4;
  private final static String ECHO_0 = "echo 0 > ";
  private final static String ECHO_1 = "echo 1 > ";
  public final static String ROOT_SHELL = "su";
  private final static String NORMAL_SHELL = "sh";
  private static final String COLOR_BLUE = "blue", COLOR_GREEN = "green", COLOR_AMBER = "amber", COLOR_RED = "red";
  private final static String TAG = "CPUStatusLED";
  public static final String PREFS_NAME = "CPUStatusLED.prefs";


  //reused
  public final static boolean DEBUG = true;
  // keep the console used to issue commands open. more efficient
  private static Process console = null;
  private static DataOutputStream os = null;
  static CPUStatusLEDActivity gui1;
  static int lastThreshhold = 0;
  public static boolean noLEDs = false;
  public static boolean canSU=false;//used to warn the user



  //prefs
  public static int [] thresholds =
  {
      3,
      15,
      40,
      75
  };
  public static String shellOpenCommand;
  private static String colorOrder[] = new String[MAX_SUPPORTED_COLORS];
  public static String ledpaths[] = new String[MAX_SUPPORTED_COLORS];
  public static String availableLEDs[];//used to populate the dropdown/spinner

  public ChargingLEDLib()
  {
  }

  private void initialize()
  {
    Log.i(TAG, "Phone Model=" + android.os.Build.MODEL);

    //leds
    String ledpathsononeline = detectLEDpaths();
    int ledcount = 0;
    ledpaths = ledpathsononeline.trim().split("\n");

    String temp[] = new String[20];//large enough
    for (int i = 0; i < ledpaths.length; i++)
    {
      if (ledpaths[i].indexOf(COLOR_RED) > -1 || ledpaths[i].indexOf(COLOR_GREEN) > -1 || ledpaths[i].indexOf(COLOR_BLUE) > -1
          || ledpaths[i].indexOf(COLOR_AMBER) > -1)
      {
        if (ledpaths[i].indexOf(COLOR_RED) > -1) temp[ledcount] = COLOR_RED;
        if (ledpaths[i].indexOf(COLOR_GREEN) > -1) temp[ledcount] = COLOR_GREEN;
        if (ledpaths[i].indexOf(COLOR_BLUE) > -1) temp[ledcount] = COLOR_BLUE;
        if (ledpaths[i].indexOf(COLOR_AMBER) > -1) temp[ledcount] = COLOR_AMBER;
        ledcount++;
      }
    }
    availableLEDs = new String[ledcount];
    for (int i = 0; i < ledcount; i++)
      availableLEDs[i] = temp[i];

    Log.i(TAG, "Found " + ledcount + " LEDs!");

    //set colorOrder;
    setDefaultColorOrder(ledcount, ledpathsononeline);

    if (colorOrder[0] == null ||ledpaths==null || ledpaths.length==0)
    {
      ChargingLEDLib.noLEDs=true;
    }

    //uses sets ledpaths based on the colorOrder
    if(ChargingLEDLib.noLEDs==false)
      assignPathsBasedOnColorOrder();

    if (ledpaths.length > 0)
    {
      if (isWriteable(ledpaths[0]))
      {
        shellOpenCommand = NORMAL_SHELL;
      }
      else
      {
        shellOpenCommand = ROOT_SHELL;
      }
    }
    Log.i(TAG, "Shell = " + shellOpenCommand);
    if (shellOpenCommand == ROOT_SHELL)checkIfSUWorks();//set canSU

  }

  private void checkIfSUWorks()
  {
    if(shellOpenCommand.equals(ROOT_SHELL) && canSU==false)
    {
      ShellCommand sc = new ShellCommand();
      canSU=sc.canSU(true);//force
    }
  }

  private void setDefaultColorOrder(int ledcount, String ledpathsononeline)
  {
    //set default color order. 4 positions.
    int colorsused = 0;
    boolean blue = false, green = false, amber = false, red = false;
    while (colorsused < ledcount && colorsused < MAX_SUPPORTED_COLORS)
    {
      if (blue == false)
      {
        if (ledpathsononeline.indexOf(COLOR_BLUE) > -1)
        {
          colorOrder[colorsused++] = COLOR_BLUE;
          blue = true;//used
        }
        else
        {
          if (ledpathsononeline.indexOf(COLOR_GREEN) > -1)
          {
            colorOrder[colorsused++] = COLOR_GREEN;
            green = true;
          }
        }
        continue;
      }
      if (green == false)
      {
        if (ledpathsononeline.indexOf(COLOR_GREEN) > -1)
        {
          colorOrder[colorsused++] = COLOR_GREEN;
          green = true;//used
        }
        else
        {
          if (ledpathsononeline.indexOf(COLOR_AMBER) > -1)
          {
            colorOrder[colorsused++] = COLOR_AMBER;
            amber = true;
          }
        }
        continue;
      }
      if (amber == false)
      {
        if (ledpathsononeline.indexOf(COLOR_AMBER) > -1)
        {
          colorOrder[colorsused++] = COLOR_AMBER;
          amber = true;//used
        }
        else
        {
          if (ledpathsononeline.indexOf(COLOR_RED) > -1)
          {
            colorOrder[colorsused++] = COLOR_RED;
            red = true;
          }
        }
        continue;
      }
      if (red == false)
      {
        if (ledpathsononeline.indexOf(COLOR_RED) > -1)
        {
          colorOrder[colorsused++] = COLOR_RED;
          red = true;//used
        }
        continue;
      }
    }//while

    //use the last color for all the remaining slots, i.e for the Hero it will be: Green, Amber  +Amber+Amber
    for (int i = 1; i < colorOrder.length; i++)
    {
      if (colorOrder[i] == null)
      {
        colorOrder[i] = colorOrder[i - 1];
      }
    }
    if (DEBUG)
    {
      Log.i(TAG, "Colors= " + colorOrder[0] + " " + colorOrder[1] + " " + colorOrder[2] + " " + colorOrder[3] + " ");
    }
  }

  private void assignPathsBasedOnColorOrder()
  {
    //assign paths corresponding to ColorOrder
    String temp[] = new String[colorOrder.length];
    for (int j = 0; j < colorOrder.length; j++)
    {
      for (int i = 0; i < ledpaths.length; i++)
      {
        if (ledpaths[i].indexOf(colorOrder[j]) > -1)
        {
          temp[j] = ledpaths[i];
          break;
        }
      }
    }
    ledpaths = temp;

    if (DEBUG)
    {
      for (int i = 0; i < ledpaths.length; i++)
        Log.i(TAG, "Color[" + i + "]=" + colorOrder[i] + "\tpath[" + i + "] =" + ledpaths[i] + "\n");
    }
  }

  private boolean isWriteable(String file)
  {
    File f = new File(file);
    return f.canWrite();
  }

  private String detectLEDpaths()
  {
    String result = "";

    if(android.os.Build.MODEL.equalsIgnoreCase("HTC Desire"))
    {
      //su not needed, but cant run find!
      return "/sys/devices/platform/leds-microp/leds/green/brightness\n/sys/devices/platform/leds-microp/leds/blue/brightness\n/sys/devices/platform/leds-microp/leds/amber/brightness";      
    }
    ShellCommand cmd = new ShellCommand();
    CommandResult r = cmd.sh.runWaitFor("find /sys/devices/ -name \"brightness\"");

    if (!r.success())
    {
      //try su. need root to run find on some phones!
      ShellCommand sc= new ShellCommand();
      if(sc.canSU())
      {
        CommandResult r1 = cmd.su.runWaitFor("find /sys/devices/ -name \"brightness\"");
        if (!r1.success())
        {
          Log.d(TAG, "Error in detectLEDs: " + r.stderr);
        }
        else
        {
          result = r1.stdout;
        }
      }
    }
    else
    {
      //Log.d(TAG, "Successfully executed. Result: " + r.stdout);
      result = r.stdout;
    }
    return result;
  }

  /**
   * turn off all known LEDs
   */
  public void turnOffAllLEDs()
  {
    if (ChargingLEDLib.noLEDs) return;
    for (int i = 0; i < ledpaths.length; i++)
      runShellCommand(ECHO_0 + ledpaths[i]);
  }

  /**
   * set the charging LED color appropriately
   *
   * @author britoso
   * @param totalCPUInt
   *            the cpu usage percent
   */
  public void setLEDColor(int totalCPUInt)
  {
    if (CPUStatusLEDActivity.disabledLEDs || ChargingLEDLib.noLEDs) return;//dont do anything

    if (DEBUG) Log.d(TAG, "CPU=" + totalCPUInt);

    //workaround for bug causing the ledpaths to be null.
    if (ledpaths == null || ledpaths.length == 0 ||ledpaths[0].length()==0)
    {
      readPrefs();
    }

    int threshhold = getThreshHold(totalCPUInt);

    if (threshhold != lastThreshhold)
    {
      if (lastThreshhold >= 0)
      {
        runShellCommand(ECHO_0 + ledpaths[lastThreshhold]);
      }
      if (threshhold >= 0)
      {
        runShellCommand(ECHO_1 + ledpaths[threshhold]);
      }
      lastThreshhold = threshhold;
    }

  }

  private int getThreshHold(int totalCPUInt)
  {
    if (totalCPUInt <= thresholds[0])
    {
      return -1;//off
    }
    else if (totalCPUInt > thresholds[0] && totalCPUInt < thresholds[1])
    {
      return 0;
    }
    else if (totalCPUInt >= thresholds[1] && totalCPUInt < thresholds[2])
    {
      return 1;
    }
    else if (totalCPUInt >= thresholds[2] && totalCPUInt < thresholds[3])
    {
      return 2;
    }
    else if (totalCPUInt >= thresholds[3])
    {
      return 3;
    }
    return -1;
  }

  private boolean runShellCommand(String command)
  {
    try
    {
      // check if we have the console created.
      if (console == null || os == null)
      {
        console = Runtime.getRuntime().exec(shellOpenCommand);
        os = new DataOutputStream(console.getOutputStream());
      }
      if (DEBUG) Log.d(TAG, "Running command: " + command);
      os.writeBytes(command + "\n");
      os.flush();
    }
    catch (Exception e)
    {
      Log.d(TAG, "Unexpected error running system command: " + command + " Error:" + e.getMessage());
      if (e instanceof java.io.IOException && e.getMessage().equalsIgnoreCase("Broken pipe"))
      {
        //we may have lost our shell, force a retry next time.
        os = null;
      }
      return false;
    }
    return true;
  }

  public String [] getColorOrder()
  {
    return colorOrder;
  }

  public void setColorOrder(String [] colorOrder)
  {
    ChargingLEDLib.colorOrder = colorOrder;
    assignPathsBasedOnColorOrder();
  }

  public static Context context;
  //private static boolean prefsRead=false;

  /*read shared preferences, fall back to initialize() which auto-detects*/
  public void readPrefs()
  {
    //if (prefsRead) return;
    SharedPreferences settings=null;
    try
    {
      settings = PreferenceManager.getDefaultSharedPreferences(context);
    }
    catch(Exception e)
    {
      Log.i(TAG,"No saved preferences found");
    }
    if(settings==null)
    {
      initialize();
      return;//prefs dont exist, stop reading.
    }
    //read shellOpenCommand, thresholds, colorOrder, ledpaths, availableLEDs
    String shell = settings.getString("shell", null);
    if (shell != null)
    {
      ChargingLEDLib.shellOpenCommand = shell;
      if (ChargingLEDLib.DEBUG) Log.i(TAG, "Read: shell=" + shell);
      if (shellOpenCommand == ROOT_SHELL)checkIfSUWorks();//set canSU
    }
    else
    {
      initialize();
      return;//prefs dont exist, stop reading.
    }

    int i = 0;
    int availLEDCount = 0;
    String colorOrder[] = new String[ChargingLEDLib.MAX_SUPPORTED_COLORS];
    String [] tempLEDColor = new String[10];
    //try to read 4 values
    while (i < ChargingLEDLib.MAX_SUPPORTED_COLORS)
    {
      String color, ledpath;
      int threshold;
      color = settings.getString("color" + i, null);
      if (color != null) colorOrder[i] = color;

      threshold = settings.getInt("threshold" + i, -1);
      if (threshold >= 0) ChargingLEDLib.thresholds[i] = threshold;

      ledpath = settings.getString("ledpath" + i, null);
      if (ledpath != null) ChargingLEDLib.ledpaths[i] = ledpath;

      String availLED = settings.getString("availableLED" + i, null);
      if (availLED != null)
      {
        tempLEDColor[availLEDCount++] = availLED;
      }

      i++;
    }
    setColorOrder(colorOrder);
    if (ChargingLEDLib.DEBUG) Log.i(TAG, "Read: colorOrder=" + colorOrder[0] + "  " + colorOrder[1] + "  " + colorOrder[2] + "  " + colorOrder[3]);
    if (ChargingLEDLib.DEBUG) Log.i(TAG, "Read: ledpaths=" + ChargingLEDLib.ledpaths[0] + "  " + ChargingLEDLib.ledpaths[1] + "  "
        + ChargingLEDLib.ledpaths[2] + "  " + ChargingLEDLib.ledpaths[3]);
    if (ChargingLEDLib.DEBUG) Log.i(TAG, "Read: thresholds=" + ChargingLEDLib.thresholds[0] + "  " + ChargingLEDLib.thresholds[1] + "  "
        + ChargingLEDLib.thresholds[2] + "  " + ChargingLEDLib.thresholds[3]);
    ChargingLEDLib.availableLEDs = new String[availLEDCount];
    for (int j = 0; j < availLEDCount; j++)
    {
      ChargingLEDLib.availableLEDs[j] = tempLEDColor[j];
      if (ChargingLEDLib.DEBUG) Log.i(TAG, "Read: availableLED=" + ChargingLEDLib.availableLEDs[j]);
    }
    turnOffAllLEDs();
    //prefsRead=true;
  }

  /**
   * Save to sharedPrerefences: shellOpenCommand, thresholds, colorOrder,
   * ledpaths, availableLEDs
   */
  public void writePrefs()
  {
    //SharedPreferences settings = getPreferences(MODE_PRIVATE );
    SharedPreferences settings =PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor e = settings.edit();

    e.putString("shell", ChargingLEDLib.shellOpenCommand);
    for (int i = 0; i < colorOrder.length; i++)
    {
      e.putString("color" + i, colorOrder[i]);
      e.putInt("threshold" + i, ChargingLEDLib.thresholds[i]);
      e.putString("ledpath" + i, ChargingLEDLib.ledpaths[i]);
    }
    for (int i = 0; i < ChargingLEDLib.availableLEDs.length; i++)
    {
      e.putString("availableLED" + i, ChargingLEDLib.availableLEDs[i]);
    }
    e.commit();
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.