/*
* Copyright (C) 2011-2012 asksven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asksven.android.common.privateapiproxies;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.asksven.android.common.privateapiproxies.StatElement;
import com.google.gson.annotations.SerializedName;
/**
* @author sven
* Value holder for alarms
*/
public class Alarm extends StatElement implements Comparable<Alarm>, Serializable
{
/**
* the tag for logging
*/
private static transient final String TAG = "Alarm";
/** The name of the app responsible for the alarm */
@SerializedName("package_name")
String m_strPackageName;
/** The number od wakeups */
@SerializedName("wakeups")
long m_nWakeups;
/** The total count */
@SerializedName("total_count")
long m_nTotalCount;
/** The details */
@SerializedName("items")
ArrayList<AlarmItem> m_items;
/**
* The default cctor
* @param strName
*/
public Alarm(String strName)
{
m_strPackageName = strName;
m_items = new ArrayList<AlarmItem>();
}
public Alarm clone()
{
Alarm clone = new Alarm(m_strPackageName);
clone.setWakeups(getWakeups());
clone.setTotalCount(m_nTotalCount);
for (int i=0; i < m_items.size(); i++)
{
clone.m_items.add(m_items.get(i).clone());
}
return clone;
}
/**
* Store the number of wakeups
* @param nCount
*/
public void setWakeups(long nCount)
{
m_nWakeups = nCount;
}
/**
* Set the total wakeup count for the sum of all alarms
* @param nCount
*/
public void setTotalCount(long nCount)
{
m_nTotalCount = nCount;
}
/**
* Return the max of all alarms (wakeups)
*/
public double getMaxValue()
{
return m_nTotalCount;
}
/* (non-Javadoc)
* @see com.asksven.android.common.privateapiproxies.StatElement#getName()
*/
public String getName()
{
return m_strPackageName;
}
/**
* Returns the number of wakeups
* @return
*/
public long getWakeups()
{
return m_nWakeups;
}
/**
* @see getWakeups
* @return
*/
long getCount()
{
return getWakeups();
}
/**
* Not supported for alarms
* @return 0
*/
long getDuration()
{
return 0;
}
/**
* returns the values of the data
*/
public double[] getValues()
{
double[] retVal = new double[2];
retVal[0] = getCount();
return retVal;
}
/**
* returns a string representation of the data
*/
public String getData()
{
String strRet = "";
strRet = "Wakeups: " + getCount();
return strRet;
}
/**
* returns a string representation of the detailed data (including children)
*/
public String getDetailedData()
{
String strRet = "";
strRet = "Wakeups: " + getCount() + "\n";
for (int i=0; i < m_items.size(); i++)
{
strRet += " " + m_items.get(i).getData() + "\n";
}
return strRet;
}
/**
* returns the representation of the data for file dump
*/
public String getDumpData(Context context)
{
return this.getName() + " (" + this.getFqn(context) + "): " + this.getDetailedData();
}
/**
* Adds an item
* @param nCount
* @param strIntent
*/
public void addItem(long nCount, String strIntent)
{
m_items.add(new AlarmItem(nCount, strIntent));
}
/**
* Retrieve the list of items
* @return
*/
public ArrayList<AlarmItem> getItems()
{
return m_items;
}
/**
* Substracts the values from a previous object
* found in myList from the current Process
* in order to obtain an object containing only the data since a referenc
* @param myList
*/
public void substractFromRef(List<StatElement> myList )
{
if (myList != null)
{
for (int i = 0; i < myList.size(); i++)
{
try
{
Alarm myRef = (Alarm) myList.get(i);
if (this.getName().equals(myRef.getName()))
{
// process main values
Log.i(TAG, "Substracting " + myRef.toString() + " from " + this.toString());
this.m_nWakeups -= myRef.getCount();
this.m_nTotalCount -= myRef.getMaxValue();
Log.i(TAG, "Result: " + this.toString());
// and process items
for (int j=0; j < this.m_items.size(); j++)
{
AlarmItem myItem = this.m_items.get(j);
myItem.substractFromRef(myRef.getItems());
}
if (this.getCount() < 0)
{
Log.e(TAG, "substractFromRef generated negative values (" + this.toString() + " - " + myRef.toString() + ")");
}
if (this.getItems().size() < myRef.getItems().size())
{
Log.e(TAG, "substractFromRef error processing alarm items: ref can not have less items");
}
}
}
catch (ClassCastException e)
{
// just log as it is no error not to change the process
// being substracted from to do nothing
Log.e(TAG, "substractFromRef was called with a wrong list type");
}
}
}
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return getName() + " ["
+ getData()
+ "]";
}
/**
* Value holder for alarm items
* @author sven
*
*/
public class AlarmItem implements Serializable
{
@SerializedName("number")
long m_nNumber;
@SerializedName("intent")
String m_strIntent;
public AlarmItem clone()
{
AlarmItem clone = new AlarmItem(m_nNumber, m_strIntent);
return clone;
}
/**
* Default cctor
* @param nCount
* @param strIntent
*/
public AlarmItem(long nCount, String strIntent)
{
m_nNumber = nCount;
m_strIntent = strIntent;
}
/**
* Returns the intent name
* @return
*/
public String getIntent()
{
return m_strIntent;
}
/**
* Returns the count
* @return
*/
public long getCount()
{
return m_nNumber;
}
/**
* Returns the data as a string
* @return
*/
public String getData()
{
return "Alarms: " + m_nNumber + ", Intent: " + m_strIntent;
}
/**
* Substracts the values from a previous object
* found in myList from the current Process
* in order to obtain an object containing only the data since a referenc
* @param myList
*/
public void substractFromRef(List<AlarmItem> myList )
{
if (myList != null)
{
for (int i = 0; i < myList.size(); i++)
{
try
{
AlarmItem myRef = (AlarmItem) myList.get(i);
if (this.getIntent().equals(myRef.getIntent()))
{
// process main values
this.m_nNumber -= myRef.getCount();
Log.i(TAG, "Result: " + this.toString());
}
}
catch (ClassCastException e)
{
// just log as it is no error not to change the process
// being substracted from to do nothing
Log.e(TAG, "AlarmItem.substractFromRef was called with a wrong list type");
}
}
}
}
}
public Drawable getIcon(Context ctx)
{
if (m_icon == null)
{
// retrieve and store the icon for that package
String myPackage = m_strPackageName;
if (!myPackage.equals(""))
{
PackageManager manager = ctx.getPackageManager();
try
{
m_icon = manager.getApplicationIcon(myPackage);
}
catch (Exception e)
{
// nop: no icon found
m_icon = null;
}
}
}
return m_icon;
}
public String getPackageName()
{
return m_strPackageName;
}
/**
* Compare a given Wakelock with this object.
* If the duration of this object is
* greater than the received object,
* then this object is greater than the other.
*/
public int compareTo(Alarm o)
{
// we want to sort in descending order
return ((int)(o.getWakeups() - this.getWakeups()));
}
public static class CountComparator implements Comparator<Alarm>
{
public int compare(Alarm a, Alarm b)
{
return ((int)(b.getCount() - a.getCount()));
}
}
public static class TimeComparator implements Comparator<Alarm>
{
public int compare(Alarm a, Alarm b)
{
return ((int)(b.getDuration() - a.getDuration()));
}
}
}