blob: 25001f686758a0eddc4e2766055af9962253f881 [file] [log] [blame]
/*
* Copyright (C) 2013 Fairphone Project
*
* 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 org.fairphone.widgets.appswitcher;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import android.content.ComponentName;
import android.util.Log;
/**
* This class processes the count for the most used apps and the most recent.
*
* @author Tiago Costa
*
*/
public class ApplicationRunInfoManager {
public static final int RECENT_APP_MAX_COUNT_LIMIT = 5;
public static final int MOST_APP_MAX_COUNT_LIMIT = 6;
public static final int MINIMAL_COUNT = 2;
private static final String TAG = null;
private LimitedQueue<ApplicationRunInformation> _mostUsed;
private LimitedQueue<ApplicationRunInformation> _recentApps;
private Map<String, ApplicationRunInformation> _appRunInfos;
private int _mostUsedAppsLimit;
private int _recentAppsLimit;
public ApplicationRunInfoManager() {
setUpLimits(MOST_APP_MAX_COUNT_LIMIT, RECENT_APP_MAX_COUNT_LIMIT);
_appRunInfos = new HashMap<String, ApplicationRunInformation>();
}
public void setUpLimits(int maxMostUsed, int maxRecentApps){
_mostUsedAppsLimit = maxMostUsed;
_recentAppsLimit = maxRecentApps;
// refactor the limits
setUpNewLimits();
}
private void setUpNewLimits() {
_mostUsed = new LimitedQueue<ApplicationRunInformation>(_mostUsedAppsLimit);
_recentApps = new LimitedQueue<ApplicationRunInformation>(_recentAppsLimit);
// update the information
if(_appRunInfos != null){
updateAppInformation();
}
}
public void loadNewRunInformation(List<ApplicationRunInformation> allApps){
// clear the current state
resetState();
// add application to the bag
for(ApplicationRunInformation appInfo : allApps){
_appRunInfos.put(ApplicationRunInformation.serializeComponentName(appInfo.getComponentName()), appInfo);
}
// update the information
updateAppInformation();
}
public void resetState() {
_mostUsed.clear();
_recentApps.clear();
_appRunInfos.clear();
}
public void applicationStarted(ApplicationRunInformation appInfo){
// obtain the cached app information
ApplicationRunInformation cachedApp = _appRunInfos.get(ApplicationRunInformation.serializeComponentName(appInfo.getComponentName()));
// if does not exist, create one
if(cachedApp == null){
_appRunInfos.put(ApplicationRunInformation.serializeComponentName(appInfo.getComponentName()), appInfo);
cachedApp = appInfo;
cachedApp.resetCount();
}
// increment count
cachedApp.incrementCount();
Log.d( TAG, "Logging application : " + cachedApp.getComponentName() + " : " + cachedApp.getCount() );
// set the current time for the last execution
cachedApp.setLastExecution(appInfo.getLastExecution());
// update the information
updateAppInformation();
}
public void applicationRemoved(ComponentName component){
// remove data
ApplicationRunInformation appInfo = _appRunInfos.remove(ApplicationRunInformation.serializeComponentName(component));
// if does not exist return
if(appInfo == null){
return;
}
// if its being used in the lists refactor the lists
if(_mostUsed.contains(appInfo) || _recentApps.contains(appInfo)){
updateAppInformation();
}
}
private void updateAppInformation() {
_mostUsed.clear();
_recentApps.clear();
// most used
// calculate the most used
for(ApplicationRunInformation current : _appRunInfos.values()){
if(current.getCount() >= MINIMAL_COUNT){
addByCount(current, _mostUsed, _mostUsedAppsLimit);
}
}
printMostUsedApps();
// calculate the most recent
for(ApplicationRunInformation current : _appRunInfos.values()){
if(!_mostUsed.contains(current)){
addByDate(current, _recentApps, _recentAppsLimit);
}
}
printRecentApps();
}
private void printRecentApps() {
for(ApplicationRunInformation current : _recentApps){
Log.d(TAG, "Fairphone RecentApps - " + current);
}
}
private void printMostUsedApps() {
for(ApplicationRunInformation current : _mostUsed){
Log.d(TAG, "Fairphone MostUsed - " + current);
}
}
private static void addByDate(ApplicationRunInformation info, LimitedQueue<ApplicationRunInformation> queue, int limit) {
for (int insertIdx = 0; insertIdx < queue.size(); insertIdx++)
{
if (queue.get(insertIdx).getLastExecution().before(info.getLastExecution()))
{
queue.add(insertIdx, info);
return;
}
}
if(queue.size() < limit){
queue.addLast(info);
}
}
private static void addByCount(ApplicationRunInformation info, LimitedQueue<ApplicationRunInformation> queue, int limit)
{
for (int insertIdx = 0; insertIdx < queue.size(); insertIdx++)
{
Log.d(TAG, "Fairphone - Contacting ... " + queue.get(insertIdx));
if(info.getCount() > queue.get(insertIdx).getCount() ){
Log.d(TAG, "FairPhone - Qs : " + queue.size() + " : Most Used : Adding " + info.getComponentName() + " to position " + insertIdx);
queue.add(insertIdx, info);
return;
}
}
Log.d(TAG, "Fairphone - Qs : " + queue.size() + " : Most Used : Adding " + info.getComponentName() + " to first position ");
if(queue.size() < limit){
queue.addLast(info);
}
}
private static class LimitedQueue<E> extends LinkedList<E> {
/**
*
*/
private static final long serialVersionUID = 8174761694444365605L;
private final int limit;
public LimitedQueue(int limit) {
this.limit = limit;
}
@Override
public void add(int idx, E o) {
super.add(idx, o);
while (size() > limit) {
super.removeLast();
}
}
@Override
public boolean add(E o) {
super.addLast(o);
while (size() > limit) {
super.removeLast();
}
return true;
}
}
public List<ApplicationRunInformation> getRecentApps() {
Log.d(TAG, "Fairphone - Getting recent apps... " + _recentApps.size() );
return _recentApps;
}
public List<ApplicationRunInformation> getMostUsedApps() {
Log.d(TAG, "Fairphone - Getting most Used apps... " + _mostUsed.size() );
return _mostUsed;
}
public int getMostUsedAppsLimit() {
return _mostUsedAppsLimit;
}
public int getRecentAppsLimit() {
return _recentAppsLimit;
}
public List<ApplicationRunInformation> getAllAppRunInfo() {
return new ArrayList<ApplicationRunInformation>(_appRunInfos.values());
}
public void setAllRunInfo(List<ApplicationRunInformation> allApps){
resetState();
for(ApplicationRunInformation app : allApps){
_appRunInfos.put(ApplicationRunInformation.serializeComponentName(app.getComponentName()), app);
}
updateAppInformation();
}
}