Android Open Source - android_monitor Helpers






From Project

Back to project page android_monitor.

License

The source code is released under:

GNU General Public License

If you think the Android project android_monitor 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

/*******************************************************************************
 * Copyright (C) 2014 MUSE team Inria Paris - Rocquencourt
 * //from www.jav  a  2 s .  co  m
 * This file is part of UCNDataCollector.
 * 
 * UCNDataCollector is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * UCNDataCollector 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 Affero Public License for more details.
 * 
 * You should have received a copy of the GNU Affero Public License
 * along with UCNDataCollector.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package fr.inria.ucn;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.TimeZone;
import java.util.UUID;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

/**
 * Misc helper methods.
 * 
 * @author Anna-Kaisa Pietilainen <anna-kaisa.pietilainen@inria.fr>
 */
public final class Helpers {
  
  /* Hide the constructor, this class only has static methods */
  private Helpers() {};
  
  /* CPU wakelock for keeping the service alive on the background */
  private static PowerManager.WakeLock lock = null;
  
  /* Wifi wakelock for keeping the wifi device alive on the background */
  private static WifiManager.WifiLock wifilock = null;
  
  /**
   * Acquire the wakelock to keep the CPU running.
   * @param c
   */
  public static synchronized void acquireLock(Context c) {
    PowerManager mgr = (PowerManager)c.getSystemService(Context.POWER_SERVICE);
    if (lock==null) {
      lock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,Constants.CPU_WAKE_LOCK);    
      lock.setReferenceCounted(true);
    }
    Log.d(Constants.LOGTAG, "acquire lock");
    lock.acquire();
  }
  
  /**
   * Release the wakelock and let CPU sleep.
   */
  public static synchronized void releaseLock() {
    Log.d(Constants.LOGTAG, "release lock");
    if (lock!=null)
      lock.release();
  }

  /**
   * Acquire the wifi wakelock.
   * @param c
   */
  public static synchronized void acquireWifiLock(Context c) {
    WifiManager mgr = (WifiManager)c.getSystemService(Context.WIFI_SERVICE);
    if (wifilock==null) {
      wifilock = mgr.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "ucn");
      wifilock.setReferenceCounted(false);
    }
    Log.d(Constants.LOGTAG, "acquire wifilock");
    wifilock.acquire();
    acquireLock(c);
  }
  
  /**
   * Release the wifi wakelock.
   */
  public static synchronized void releaseWifiLock() {
    Log.d(Constants.LOGTAG, "release wifilock");
    if (wifilock!=null)
      wifilock.release();
    releaseLock();
  }
    
    /**
     * Retrieves a system property
     * @param key the property key
     * @param def the value to be returned if the key could not be resolved
     */
    public static String getSystemProperty(String key, String def) {
        try {
            Method getString = Build.class.getDeclaredMethod("getString", String.class);
            getString.setAccessible(true);
            return getString.invoke(null, key).toString();
        } catch (Exception ex) {
            return def;
        }
    }
    
  /**
   * Enable broadcast received component.
   * @param c
   * @param component
   */
  public static void enableReceiver(Context c, Class component) {
    ComponentName receiver = new ComponentName(c, component);
    PackageManager pm = c.getPackageManager();
    pm.setComponentEnabledSetting(
        receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);    
  }

  /**
   * Disable broadcast received component.
   * @param c
   * @param component
   */
  public static void disableReceiver(Context c, Class component) {    
    ComponentName receiver = new ComponentName(c, component);
    PackageManager pm = c.getPackageManager();
    pm.setComponentEnabledSetting(
        receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);    
  }

  /**
   * Collectors and Listeners should use this method to send the results to the service.
   * @param c
   * @param cid data collection id (maps to mongodb collection used to store the data)
   * @param ts  periodic collection timestamp or event time if triggered by timestamp
   * @param data 
   */
  @SuppressLint("SimpleDateFormat")
  public static void sendResultObj(Context c, String cid, long ts, JSONObject data) {
      try {
        
      // wrap the collected data object to a common object format
      JSONObject res = new JSONObject();
  
      // data collection in the backend db
      res.put("collection", cid);
      
      // store unique user id to each result object
      res.put("uid", getDeviceUuid(c));
      
      // app version to help to detect data format changes
      try {
        PackageManager manager = c.getPackageManager();
        PackageInfo info = manager.getPackageInfo(c.getPackageName(), 0);
        res.put("app_version_name", info.versionName);
        res.put("app_version_code", info.versionCode);
      } catch (NameNotFoundException e) {
      }
      
      // event and current time in UTC JSON date format
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
      sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
      res.put("ts_event", sdf.format(new Date(ts)));
      res.put("ts", sdf.format(new Date()));
      res.put("tz", TimeZone.getDefault().getID()); // devices current timezone
      res.put("tz_offset", TimeZone.getDefault().getOffset(ts)); // ts offset to this event
      
      // the data obj
      res.put("data", data);
      
      // ask the service to handle the data
      Intent intent = new Intent(c, CollectorService.class);
      intent.setAction(Constants.ACTION_DATA);
      intent.putExtra(Constants.INTENT_EXTRA_DATA, res.toString());
      c.startService(intent);
      
        Log.d(Constants.LOGTAG, res.toString(4));
        
      } catch (JSONException ex) {
      Log.w(Constants.LOGTAG, "failed to create json obj",ex);
      }
  }

  /**
   * 
   * @param type
   * @return
   */
  public static String getTelephonyPhoneType(int type) {
      switch (type) {
      case TelephonyManager.PHONE_TYPE_CDMA:
        return "CDMA";
      case TelephonyManager.PHONE_TYPE_GSM:
        return "GSM";
      case TelephonyManager.PHONE_TYPE_NONE:
        return "None";
      default:
        return "Unknown["+type+"]";
      }
  }
  
  /**
   * 
   * @param type
   * @return
   */
  public static String getTelephonyNetworkType(int type) {
    switch (type) {
      case TelephonyManager.NETWORK_TYPE_1xRTT:
        return "1xRTT";
      case TelephonyManager.NETWORK_TYPE_CDMA:
        return "CDMA";
      case TelephonyManager.NETWORK_TYPE_EDGE:
        return "EDGE";
      case TelephonyManager.NETWORK_TYPE_EVDO_0:
        return "EVDO_0";
      case TelephonyManager.NETWORK_TYPE_EVDO_A:
        return "EVDO_A";
      case TelephonyManager.NETWORK_TYPE_GPRS:
        return "GPRS";
      case TelephonyManager.NETWORK_TYPE_HSDPA:
        return "HSDPA";
      case TelephonyManager.NETWORK_TYPE_HSPA:
        return "HSPA";
      case TelephonyManager.NETWORK_TYPE_HSUPA:
        return "HSUPA";
      case TelephonyManager.NETWORK_TYPE_IDEN:
        return "IDEN";
      case TelephonyManager.NETWORK_TYPE_UMTS:
        return "UMTS";
      case TelephonyManager.NETWORK_TYPE_EVDO_B:
        return "EVDO_B";
      case TelephonyManager.NETWORK_TYPE_LTE:
        return "LTE";
      case TelephonyManager.NETWORK_TYPE_EHRPD:
        return "EHRPD";
      case TelephonyManager.NETWORK_TYPE_HSPAP:
        return "HSPAP";
      default: 
        return "UNKNOWN [" + type + "]";
    }
  }  
  
  // Source : http://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id
  private volatile static UUID uuid = null;
    private static final String ID_PREFS_FILE = "ucn_device_id.xml";
    private static final String ID_PREFS_DEVICE_ID = "ucn_device_id";
    private static final String BAD_UUID = "9774d56d682e549c";
  private static UUID getUuid(Context c) {
    final SharedPreferences prefs = c.getSharedPreferences(ID_PREFS_FILE, Context.MODE_PRIVATE);
    final String id = prefs.getString(ID_PREFS_DEVICE_ID, null);
    final UUID uuid;
    if (id != null) {
      uuid = UUID.fromString(id);
    } else {
      final String androidId = Secure.getString(c.getContentResolver(), Secure.ANDROID_ID);
      try {
        if (!BAD_UUID.equals(androidId)) {
          uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
        } else {
          final String deviceId = ((TelephonyManager)c.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
          if (deviceId != null)
            uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
          else
            uuid = UUID.randomUUID();
        }
      } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
      }
      prefs.edit().putString(ID_PREFS_DEVICE_ID, uuid.toString()).commit();
    }
    return uuid;
  }

  /**
   * Get a unique id for this device.
   * @param c
   * @return
   */
  public static UUID getDeviceUuid(Context c) {
    if (uuid==null) {
      synchronized (Helpers.class) {
        if (uuid==null)
          uuid = getUuid(c);        
      }
    }
    return uuid;
  }
  
  /**
   * 
   * @param c
   * @param uid
   * @return
   * @throws JSONException
   */
  public static JSONArray getPackagesForUid(Context c, int uid) throws JSONException {
    PackageManager pm = c.getPackageManager();
    JSONArray res = new JSONArray();
    String[] pkgs = pm.getPackagesForUid(uid);
    if (pkgs!=null) {
      for (int i = 0; i < pkgs.length; i++) {
        try {
          CharSequence appLabel = 
              pm.getApplicationLabel(
                  pm.getApplicationInfo(
                      pkgs[i], 
                      PackageManager.GET_META_DATA));
          JSONObject pkg = new JSONObject();
          pkg.put("package", pkgs[i]);
          pkg.put("app_label",appLabel.toString());
          res.put(pkg);
        } catch (NameNotFoundException e) {
        } catch (Exception e) {
        }
      }
    }
    return res;
  }
  
  /**
   * Check for the OpenVPN for Android app:
   * https://play.google.com/store/apps/details?id=de.blinkt.openvpn
   * @param c
   * @return
   */
  public static boolean isOpenVPNClientInstalled(Context c) {
    boolean res = false;
    PackageManager pm = c.getPackageManager();
    for (ApplicationInfo ai : pm.getInstalledApplications(PackageManager.GET_META_DATA)) {
      if (ai.packageName.contains("de.blinkt.openvpn")) {
        res = true;
        break;
      }
    }
    return res;
  }
  
  /**
   * Check for the Llama app.
   * @param c
   * @return
   */
  public static boolean isLlamaInstalled(Context c) {
    boolean res = false;
    PackageManager pm = c.getPackageManager();
    for (ApplicationInfo ai : pm.getInstalledApplications(PackageManager.GET_META_DATA)) {
      if (ai.packageName.contains("com.kebab.Llama")) {
        res = true;
        break;
      }
    }
    return res;    
  }
  
  /**
   * FIXME: remove once all servers have valid certificate
   * @return
   */
    public static boolean isCaCertInstalledHack(String match) {
      boolean res = false;
    try {
      KeyStore ks = KeyStore.getInstance("AndroidCAStore");
      ks.load(null, null);
      Enumeration<String> aliases = ks.aliases();
      while (aliases.hasMoreElements()) {
          String alias = aliases.nextElement();
          X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
          //Log.d(Constants.LOGTAG, "keystore: " + alias + "/" + cert.getIssuerDN().getName());
          if (cert.getIssuerDN().getName().contains(match)) {
            res = true;
            break;
          }
      }    
    } catch (KeyStoreException e) {
      Log.w(Constants.LOGTAG, "failed to check certificates", e);
    } catch (NoSuchAlgorithmException e) {
    } catch (CertificateException e) {
    } catch (IOException e) {
    }
    return res;
  }
    
    /**
     * Read a given file and return a list of lines.
     * @param file
     * @return
     */
    public static List<String> readProc(String file) {
    List<String> lines = new ArrayList<String>();
    BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(file), 500);
            String line;
      while ((line = in.readLine()) != null) {
        lines.add(line.trim());
      }
        } catch (FileNotFoundException e) {
          Log.w(Constants.LOGTAG, "could not find " + file, e);
        } catch (IOException e) {
          Log.w(Constants.LOGTAG, "could not read " + file, e);
        }
        if (in!=null)
      try {
        in.close();
      } catch (IOException e) {
      }
        return lines;
  }
    
    /**
     * Request data collection sample.
     *  
     * @param context
     * @param wl         Need wakelock?
     */
    public static void doSample(Context context, boolean wl) {
      if (wl)
      Helpers.acquireLock(context);
    Intent sintent = new Intent(context, CollectorService.class);
    sintent.setAction(Constants.ACTION_COLLECT);
    if (wl)
      sintent.putExtra(Constants.INTENT_EXTRA_RELEASE_WL, true); // request service to release the wl
    context.startService(sintent);
    }
    
    /**
     * Request data upload.
     *  
     * @param context
     * @param wl         Need wakelock?
     */
    public static void doUpload(Context context, boolean wl) {
      if (wl)
      Helpers.acquireLock(context);
    Intent sintent = new Intent(context, CollectorService.class);
    sintent.setAction(Constants.ACTION_UPLOAD);
    if (wl)
      sintent.putExtra(Constants.INTENT_EXTRA_RELEASE_WL, true); // request service to release the wl
    context.startService(sintent);
    }
    
    /**
     * Start (schedule) the data collector service.
     *  
     * @param context
     * @param wl         Need wakelock?
     */
    public static void startCollector(Context context, boolean wl) {
      if (wl)
      Helpers.acquireLock(context);
    Intent sintent = new Intent(context, CollectorService.class);
    sintent.setAction(Constants.ACTION_SCHEDULE);
    sintent.putExtra(Constants.INTENT_EXTRA_SCHEDULER_START, true);
    if (wl)
      sintent.putExtra(Constants.INTENT_EXTRA_RELEASE_WL, true); // request service to release the wl
    context.startService(sintent);
    }
    
    /**
     * Stop (schedule) the data collector service.
     *  
     * @param context
     * @param wl         Need wakelock?
     */
    public static void stopCollector(Context context, boolean wl) {
      if (wl)
      Helpers.acquireLock(context);
    Intent sintent = new Intent(context, CollectorService.class);
    sintent.setAction(Constants.ACTION_SCHEDULE);
    sintent.putExtra(Constants.INTENT_EXTRA_SCHEDULER_START, false);
    if (wl)
      sintent.putExtra(Constants.INTENT_EXTRA_RELEASE_WL, true); // request service to release the wl
    context.startService(sintent);      
    }

    /**
     * @param c
     * @return <code>True</code> if user has enabled the night-time mode and current time is
     * within night, else <code>False</code>.
     */
    public static boolean isNightTime(Context c) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
    if (!prefs.getBoolean(Constants.PREF_STOP_NIGHT, false))
      return false;
    
    int nstart = prefs.getInt(Constants.PREF_NIGHT_START, 23*3600);
    int nstop = prefs.getInt(Constants.PREF_NIGHT_STOP, 6*3600);
      
    Calendar nightstart = Calendar.getInstance();
    nightstart.roll(Calendar.HOUR_OF_DAY, -1*nightstart.get(Calendar.HOUR_OF_DAY));
    nightstart.roll(Calendar.MINUTE, -1*nightstart.get(Calendar.MINUTE));
    nightstart.roll(Calendar.SECOND, -1*nightstart.get(Calendar.SECOND));
    nightstart.roll(Calendar.MILLISECOND, -1*nightstart.get(Calendar.MILLISECOND));
    nightstart.add(Calendar.SECOND, nstart);

    Calendar nightstop = Calendar.getInstance();
    nightstop.roll(Calendar.HOUR_OF_DAY, -1*nightstop.get(Calendar.HOUR_OF_DAY));
    nightstop.roll(Calendar.MINUTE, -1*nightstop.get(Calendar.MINUTE));
    nightstop.roll(Calendar.SECOND, -1*nightstop.get(Calendar.SECOND));
    nightstop.roll(Calendar.MILLISECOND, -1*nightstop.get(Calendar.MILLISECOND));
    nightstop.add(Calendar.SECOND, nstop);
    if (nightstop.before(nightstart))
      nightstop.add(Calendar.HOUR, 24);
      
    Log.d(Constants.LOGTAG, "nightstart " + nstart + " -> " + nightstart.toString());
    Log.d(Constants.LOGTAG, "nightstop " + nstop + " -> " + nightstop.toString());
    
    Calendar now = Calendar.getInstance();    
    return (now.after(nightstart) && now.before(nightstop));
    }
    
    /**
     * 
     * @param c
     * @return -1 if not at night-time (or feature disabled), else milliseconds until morning.
     */
    public static long getNightEnd(Context c) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
    if (!prefs.getBoolean(Constants.PREF_STOP_NIGHT, false))
      return -1;
    
    int nstart = prefs.getInt(Constants.PREF_NIGHT_START, 23*3600);
    int nstop = prefs.getInt(Constants.PREF_NIGHT_STOP, 6*3600);
      
    Calendar nightstart = Calendar.getInstance();
    nightstart.roll(Calendar.HOUR_OF_DAY, -1*nightstart.get(Calendar.HOUR_OF_DAY));
    nightstart.roll(Calendar.MINUTE, -1*nightstart.get(Calendar.MINUTE));
    nightstart.roll(Calendar.SECOND, -1*nightstart.get(Calendar.SECOND));
    nightstart.roll(Calendar.MILLISECOND, -1*nightstart.get(Calendar.MILLISECOND));
    nightstart.add(Calendar.SECOND, nstart);

    Calendar nightstop = Calendar.getInstance();
    nightstop.roll(Calendar.HOUR_OF_DAY, -1*nightstop.get(Calendar.HOUR_OF_DAY));
    nightstop.roll(Calendar.MINUTE, -1*nightstop.get(Calendar.MINUTE));
    nightstop.roll(Calendar.SECOND, -1*nightstop.get(Calendar.SECOND));
    nightstop.roll(Calendar.MILLISECOND, -1*nightstop.get(Calendar.MILLISECOND));
    nightstop.add(Calendar.SECOND, nstop);
    if (nightstop.before(nightstart))
      nightstop.add(Calendar.HOUR, 24);
      
    Log.d(Constants.LOGTAG, "nightstart " + nstart + " -> " + nightstart.toString());
    Log.d(Constants.LOGTAG, "nightstop " + nstop + " -> " + nightstop.toString());
    
    Calendar now = Calendar.getInstance();    
    if (now.after(nightstart) && now.before(nightstop)) {
      return nightstop.getTimeInMillis();
    } else {
      return -1;
    }
    }    
}




Java Source Code List

fr.inria.ucn.CollectorException.java
fr.inria.ucn.CollectorService.java
fr.inria.ucn.Constants.java
fr.inria.ucn.DataStore.java
fr.inria.ucn.DataUploader.java
fr.inria.ucn.Helpers.java
fr.inria.ucn.OnBootReceiver.java
fr.inria.ucn.Scheduler.java
fr.inria.ucn.collectors.AppDataUsageCollector.java
fr.inria.ucn.collectors.Collector.java
fr.inria.ucn.collectors.DeviceInfoCollector.java
fr.inria.ucn.collectors.LlamaCollector.java
fr.inria.ucn.collectors.NetworkStateCollector.java
fr.inria.ucn.collectors.RunningAppsCollector.java
fr.inria.ucn.collectors.SocketsCollector.java
fr.inria.ucn.collectors.SysStateCollector.java
fr.inria.ucn.listeners.MyPhoneStateListener.java
fr.inria.ucn.listeners.SystemStateListener.java
fr.inria.ucn.ui.SettingsActivity.java
fr.inria.ucn.ui.SettingsFragment.java
fr.inria.ucn.ui.TimePreference.java