blob: 7f52b7ea935a6f850d31036abbff9bbb4c23cdbf [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 com.fairphone.fplauncher3.widgets.appswitcher;
import java.util.List;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import com.fairphone.fplauncher3.R;
public class AppSwitcherWidget extends AppWidgetProvider
{
private static final String TAG = AppSwitcherWidget.class.getSimpleName();
private static final boolean APP_SWITCHER_DEBUG_MODE = false; //BuildConfig.DEBUG;
// AppSwitcher settings
public static final String ACTION_APP_SWITCHER_LAUNCH_APP = "com.fairphone.fplauncher3.ACTION_APP_SWITCHER_LAUNCH_APP";
public static final String ACTION_APP_SWITCHER_LAUNCH_ALL_APPS = "com.fairphone.fplauncher3.ACTION_APP_SWITCHER_LAUNCH_ALL_APPS";
public static final String EXTRA_LAUNCH_APP_NAME = "com.fairphone.fplauncher3.EXTRA_LAUNCH_APP_NAME";
public static final String EXTRA_LAUNCH_APP_PACKAGE = "com.fairphone.fplauncher3.EXTRA_LAUNCH_APP_PACKAGE";
public static final String EXTRA_LAUNCH_APP_CLASS_NAME = "com.fairphone.fplauncher3.EXTRA_LAUNCH_APP_CLASS_NAME";
@Override
public void onEnabled(Context context)
{
Log.d(TAG, "Fairphone - WidgetProvicer Context is " + context);
}
@Override
public void onDisabled(Context context)
{
// Called once the last instance of your widget is removed from the
// homescreen
super.onDisabled(context);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds)
{
// Widget instance is removed from the homescreen
Log.d(TAG, "onDeleted - " + appWidgetIds);
}
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)
{
onUpdate(context, appWidgetManager, new int[]{appWidgetId});
// Obtain appropriate widget and update it.
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
}
private static RemoteViews updateUI(Context context)
{
int code = 0;
// get the widgets
RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.fp_app_switcher);
// clear the current data
widget.removeAllViews(R.id.lastUsedApps);
widget.removeAllViews(R.id.mostUsedApps);
// obtain the current data saved
AppSwitcherManager.loadAppSwitcherData(context);
ApplicationRunInfoManager instance = AppSwitcherManager.getInstance();
List<ApplicationRunInformation> mostRecent = instance.getRecentApps();
List<ApplicationRunInformation> mostUsed = instance.getMostUsedApps();
Log.d(TAG, "mostRecent lenght: " + mostRecent.size());
Log.d(TAG, "mostUsed lenght: " + mostUsed.size());
toggleMostAndLastUsedViewsVisibility(widget, mostRecent, mostUsed);
// update the recent apps
code = updateLastUsedAppsList(context, code, widget, mostRecent);
// Process the most used apps
updateMostUsedAppsList(context, code, widget, mostUsed);
return widget;
}
private static void updateMostUsedAppsList(Context context, int code, RemoteViews widget, List<ApplicationRunInformation> mostUsed)
{
int slot_count = ApplicationRunInfoManager.MOST_APP_MAX_COUNT_LIMIT;
for (ApplicationRunInformation mostUsedInfo : mostUsed)
{
RemoteViews view;
try
{
view = getMostUsedView(context, mostUsedInfo, code);
if (view != null)
{
widget.addView(R.id.mostUsedApps, view);
}
} catch (NameNotFoundException e)
{
// if no information is available log it and continue
Log.e(TAG, "Could not find the correct package", e);
continue;
}
// update the code
code++;
}
RemoteViews allAppsView = getAllAppsButton(context, code);
if (allAppsView != null)
{
widget.addView(R.id.mostUsedApps, allAppsView);
}
for (int i = mostUsed.size(); i < slot_count; i++) {
RemoteViews emptyMostRow = new RemoteViews(context.getPackageName(), R.layout.fp_most_used_item);
emptyMostRow.setViewVisibility(R.id.mostUsedRow, View.INVISIBLE);
widget.addView(R.id.mostUsedApps, emptyMostRow);
}
}
private static int updateLastUsedAppsList(Context context, int code, RemoteViews widget, List<ApplicationRunInformation> mostRecent)
{
int slot_count = ApplicationRunInfoManager.RECENT_APP_MAX_COUNT_LIMIT;
for (ApplicationRunInformation appRunInfo : mostRecent)
{
RemoteViews view;
try
{
view = getRecentView(context, appRunInfo, code);
if (view != null)
{
widget.addView(R.id.lastUsedApps, view);
}
} catch (NameNotFoundException e)
{
// if no information is available log it and continue
Log.e(TAG, "Could not find the correct package", e);
continue;
}
// update the code
code++;
}
for (int i = mostRecent.size(); i < slot_count; i++) {
RemoteViews emptyRecentRow = new RemoteViews(context.getPackageName(), R.layout.fp_last_used_item);
emptyRecentRow.setViewVisibility(R.id.recentRow, View.INVISIBLE);
widget.addView(R.id.lastUsedApps, emptyRecentRow);
}
return code;
}
private static void toggleMostAndLastUsedViewsVisibility(RemoteViews widget, List<ApplicationRunInformation> mostRecent, List<ApplicationRunInformation> mostUsed)
{
if (mostRecent.isEmpty() && mostUsed.isEmpty()) {
widget.setViewVisibility(R.id.mostUsedAppsOOBEDescription, View.VISIBLE);
} else {
widget.setViewVisibility(R.id.mostUsedAppsOOBEDescription, View.GONE);
}
}
private static RemoteViews getMostUsedView(Context context, ApplicationRunInformation info, int code) throws NameNotFoundException
{
// generate the mostUsed row
RemoteViews mostUsedRow = new RemoteViews(context.getPackageName(), R.layout.fp_most_used_item);
PackageManager pm = context.getPackageManager();
// get app icon and label
Drawable icon = pm.getActivityIcon(info.getComponentName());
Bitmap iconBitmap = ((BitmapDrawable) icon).getBitmap();
CharSequence appLabel = pm.getActivityInfo(info.getComponentName(), 0).loadLabel(pm);
// debug String with app count
@SuppressWarnings("UnusedAssignment") String fullAppLabel = info.getCount() + "# " + appLabel;
mostUsedRow.setImageViewBitmap(R.id.most_app_logo, iconBitmap);
mostUsedRow.setTextViewText(R.id.mostUsedButton, APP_SWITCHER_DEBUG_MODE ? fullAppLabel : appLabel);
Intent launchIntent = generateLaunchIntent(info, appLabel.toString());
PendingIntent clickRecentApps = PendingIntent.getBroadcast(context, code, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mostUsedRow.setOnClickPendingIntent(R.id.mostUsedRow, clickRecentApps);
return mostUsedRow;
}
private static RemoteViews getAllAppsButton(Context context, int code)
{
// generate the mostUsed row
RemoteViews allAppsButton = new RemoteViews(context.getPackageName(), R.layout.fp_most_used_item);
Drawable draw = context.getResources().getDrawable(R.drawable.icon_allapps_white_widget);
Bitmap icon = ((BitmapDrawable) draw).getBitmap();
allAppsButton.setImageViewBitmap(R.id.most_app_logo, icon);
allAppsButton.setTextViewText(R.id.mostUsedButton, context.getResources().getString(R.string.edge_swipe_all_apps).toUpperCase());
Intent launchIntent = new Intent();
launchIntent.setAction(ACTION_APP_SWITCHER_LAUNCH_ALL_APPS);
PendingIntent launchPendingIntent = PendingIntent.getBroadcast(context, code, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
allAppsButton.setOnClickPendingIntent(R.id.mostUsedRow, launchPendingIntent);
return allAppsButton;
}
private static Intent generateLaunchIntent(ApplicationRunInformation info, String appLabel) throws NameNotFoundException
{
Intent i = new Intent();
i.setAction(ACTION_APP_SWITCHER_LAUNCH_APP);
Bundle extras = new Bundle();
extras.putString(EXTRA_LAUNCH_APP_NAME, appLabel);
extras.putString(EXTRA_LAUNCH_APP_PACKAGE, info.getComponentName().getPackageName());
extras.putString(EXTRA_LAUNCH_APP_CLASS_NAME, info.getComponentName().getClassName());
i.putExtras(extras);
return i;
}
private static RemoteViews getRecentView(Context context, ApplicationRunInformation info, int code) throws NameNotFoundException
{
RemoteViews recentRow = new RemoteViews(context.getPackageName(), R.layout.fp_last_used_item);
PackageManager pm = context.getPackageManager();
// get application icon and label
Drawable icon = pm.getActivityIcon(info.getComponentName());
CharSequence appLabel = pm.getActivityInfo(info.getComponentName(), 0).loadLabel(pm);
// debug String with app count
@SuppressWarnings("UnusedAssignment") String fullAppLabel = info.getCount() + "# " + appLabel;
recentRow.setTextViewText(R.id.recentButton, APP_SWITCHER_DEBUG_MODE ? fullAppLabel : appLabel);
try {
Bitmap iconBitmap = ((BitmapDrawable) icon).getBitmap();
recentRow.setImageViewBitmap(R.id.recent_app_logo, iconBitmap);
} catch (ClassCastException e) {
Log.e(TAG, "Failed to load bitmap drawable for "+fullAppLabel, e);
}
// create the intent for this app
Intent launchIntent = generateLaunchIntent(info, appLabel.toString());
PendingIntent clickRecentApps = PendingIntent.getBroadcast(context, code, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
recentRow.setOnClickPendingIntent(R.id.recentRow, clickRecentApps);
return recentRow;
}
/*
* (non-Javadoc)
*
* @see
* android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,
* android.appwidget.AppWidgetManager, int[])
*
* OnUpdate ==============================================================
* context The Context in which this receiver is running. appWidgetManager A
* AppWidgetManager object you can call updateAppWidget(ComponentName,
* RemoteViews) on. appWidgetIds The appWidgetIds for which an update is
* needed. Note that this may be all of the AppWidget instances for this
* provider, or just a subset of them.
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
Log.i(TAG, "onUpdate");
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Called in response to the ACTION_APPWIDGET_UPDATE broadcast when this
// AppWidget provider
// is being asked to provide RemoteViews for a set of AppWidgets.
// Override this method to implement your own AppWidget functionality.
// update the widget data
appWidgetManager.updateAppWidget(appWidgetIds, null);
appWidgetManager.updateAppWidget(appWidgetIds, updateUI(context));
}
}