/*
* Copyright © 2014 Jeff Corcoran
*
* This file is part of Hangar.
*
* Hangar is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Hangar 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Hangar. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ca.mimic.apphangar;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.RemoteViews;
import java.util.Collections;
import java.util.List;
import ca.mimic.apphangar.Settings.PrefsGet;
public class StatsWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Tools.HangarLog("onUpdate [" + this.getClass().getCanonicalName() + "]");
// (re?)start service. This is specifically so if hangar gets updated the service
// is restarted
Intent intent = new Intent(context, WatchfulService.class);
context.startService(intent);
}
@Override
public void onReceive(Context context, Intent intent) {
Tools.HangarLog("onReceive [" + this.getClass().getCanonicalName() + "]");
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
int[] ids = mgr.getAppWidgetIds(new ComponentName(context, StatsWidget.class));
for(int id : ids) {
Tools.HangarLog("per id: " + id);
try {
Bundle options=mgr.getAppWidgetOptions(id);
updateAppWidget(context, mgr, id, options);
} catch (Exception e) {
e.printStackTrace();
Tools.HangarLog("NPE onReceive");
}
}
super.onReceive(context, intent);
}
public Bitmap drawableToBitmap (Context context, Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(Tools.dpToPx(context, 100), Tools.dpToPx(context, 5), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle options) {
Tools.HangarLog("updateAppWidget (StatsWidget)");
PrefsGet prefs = new PrefsGet(context.getSharedPreferences("StatsWidget", Context.MODE_PRIVATE));
SharedPreferences mPrefs = prefs.prefsGet();
int statsLayout;
int itemHeight;
if (mPrefs.getBoolean(Settings.DIVIDER_PREFERENCE, Settings.DIVIDER_DEFAULT)) {
statsLayout = R.layout.stats_widget;
itemHeight = 36;
} else {
statsLayout = R.layout.stats_widget_no_dividers;
itemHeight = 35; // Not as large w/o dividers
}
boolean appsNoByWidgetSize = mPrefs.getBoolean(Settings.APPS_BY_WIDGET_SIZE_PREFERENCE, Settings.APPS_BY_WIDGET_SIZE_DEFAULT);
boolean roundedCorners = mPrefs.getBoolean(Settings.ROUNDED_CORNERS_PREFERENCE, Settings.ROUNDED_CORNERS_DEFAULT);
int appsNo;
int appsNoLs;
Tools.HangarLog("minHeight: " + options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT));
Tools.HangarLog("maxHeight: " + options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT));
appsNo = (int) Math.floor((options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT) - 14) / itemHeight);
appsNoLs = (int) Math.floor((options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT) - 14) / itemHeight);
if (appsNoByWidgetSize && appsNo > 0) {
Tools.HangarLog("appsNoByWidgetSize=true, appsNo=" + appsNo);
} else {
appsNo = Integer.parseInt(mPrefs.getString(Settings.STATS_WIDGET_APPSNO_PREFERENCE, Integer.toString(Settings.STATS_WIDGET_APPSNO_DEFAULT)));
}
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
if (appsNoByWidgetSize && appsNoLs > 0) {
appsNo = appsNoLs;
Tools.HangarLog("Landscape! appsNoByWidgetSize=true, appsNo=" + appsNo);
} else {
appsNo = Integer.parseInt(mPrefs.getString(Settings.STATS_WIDGET_APPSNO_LS_PREFERENCE, Integer.toString(Settings.STATS_WIDGET_APPSNO_LS_DEFAULT)));
}
Tools.HangarLog("LANDSCAPE");
}
int getColor = mPrefs.getInt(Settings.BACKGROUND_COLOR_PREFERENCE, Settings.BACKGROUND_COLOR_DEFAULT);
RemoteViews views = new RemoteViews(context.getPackageName(), statsLayout);
int mGravity = Integer.parseInt(mPrefs.getString(Settings.ALIGNMENT_PREFERENCE, Integer.toString(Settings.ALIGNMENT_DEFAULT)));
views.setInt(R.id.taskRoot, "setGravity", mGravity);
views.removeAllViews(R.id.taskRoot);
PackageManager pkgm = context.getPackageManager();
String packageName = context.getPackageName();
Intent intent;
TasksDataSource db = TasksDataSource.getInstance(context);
db.open();
int highestSeconds = db.getHighestSeconds();
List<TasksModel> tasks = db.getAllTasks();
db.close();
Collections.sort(tasks, new Tools.TasksModelComparator("seconds"));
IconHelper ih = new IconHelper(context);
int count = 0;
for (TasksModel task : tasks) {
RemoteViews row = new RemoteViews(context.getPackageName(), R.layout.stats_widget_row);
int topPadding = 0;
int bottomPadding = 0;
if (count == 0) {
topPadding = Tools.dpToPx(context, 6);
Tools.setViewBackgroundColor(row, getColor, (roundedCorners) ? R.drawable.rounded_bg_top : R.drawable.empty_bg);
}
if (count == (appsNo-1)) {
bottomPadding = Tools.dpToPx(context, 6);
Tools.setViewBackgroundColor(row, getColor, (roundedCorners) ? R.drawable.rounded_bg_bottom : R.drawable.empty_bg);
}
if (count > 0 && count < (appsNo-1)) {
Tools.setViewBackgroundColor(row, getColor, R.drawable.empty_bg);
}
row.setViewPadding(R.id.clickCont, 0, topPadding, 0, bottomPadding);
int clickID = context.getResources().getIdentifier("clickCont", "id", packageName);
int iconID = context.getResources().getIdentifier("iconCont", "id", packageName);
int labelID = context.getResources().getIdentifier("appName", "id", packageName);
int imgID = context.getResources().getIdentifier("barImg", "id", packageName);
int statsID = context.getResources().getIdentifier("statsCont", "id", packageName);
if (task.getBlacklisted()) { continue; }
if (count >= appsNo) {
Tools.HangarLog("count: " + count + " appsNo: " + appsNo);
break;
}
// Drawable taskIcon;
Bitmap cachedIcon;
ComponentName componentTask = ComponentName.unflattenFromString(task.getPackageName() + "/" + task.getClassName());
cachedIcon = ih.cachedIconHelper(componentTask);
if (cachedIcon == null)
continue;
count++;
// row.setImageViewUri(iconID, uri);
row.setImageViewBitmap(iconID, cachedIcon);
row.setTextViewText(labelID, task.getName());
// int maxWidth = dpToPx(250) - dpToPx(32+14+14); // ImageView + Margin? + Stats text?
float secondsRatio = (float) task.getSeconds() / highestSeconds;
int barColor;
int secondsColor = (Math.round(secondsRatio * 100));
if (secondsColor >= 80 ) {
barColor = 0xFF34B5E2;
} else if (secondsColor >= 60) {
barColor = 0xFFAA66CC;
} else if (secondsColor >= 40) {
barColor = 0xFF74C353;
} else if (secondsColor >= 20) {
barColor = 0xFFFFBB33;
} else {
barColor = 0xFFFF4444;
}
int[] colors = new int[]{barColor, Tools.dpToPx(context, secondsColor-1), 0x00000000, Tools.dpToPx(context, 100-secondsColor)};
Drawable sd = new BarDrawable(colors);
Bitmap bmpIcon2 = drawableToBitmap(context, sd);
row.setImageViewBitmap(imgID, bmpIcon2);
int[] statsTime = new Settings().splitToComponentTimes(task.getSeconds());
String statsString = ((statsTime[0] > 0) ? statsTime[0] + "h " : "") + ((statsTime[1] > 0) ? statsTime[1] + "m " : "") + ((statsTime[2] > 0) ? statsTime[2] + "s " : "");
row.setTextViewText(statsID, statsString);
try {
intent = pkgm.getLaunchIntentForPackage(task.getPackageName());
if (intent == null) {
count --;
throw new PackageManager.NameNotFoundException();
}
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setAction(Intent.ACTION_MAIN);
PendingIntent activity = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
row.setOnClickPendingIntent(clickID, activity);
} catch (PackageManager.NameNotFoundException e) {
}
views.addView(R.id.taskRoot, row);
}
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}