Commit f051a3ae authored by Amit Kumar's avatar Amit Kumar
Browse files

Make use of adaptive icon and add bugsnag

parent e6268a04
......@@ -33,6 +33,10 @@ dependencies {
implementation 'me.relex:circleindicator:1.2.2@aar'
implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
implementation 'com.bugsnag:bugsnag-android:4.+'
compile "com.android.support:palette-v7:${rootProject.ext.supportLibraryVersion}"
// Support Libs
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibraryVersion}"
implementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibraryVersion}"
......
......@@ -42,7 +42,7 @@
</intent-filter>
</service>
<meta-data
android:name="io.fabric.ApiKey"
android:value="8fcf342f1b8ac74d6980872082b7216ef4682a29" />
android:name="com.bugsnag.android.API_KEY"
android:value="3c2e123c774b9328c800aa1c230e7a2d"/>
</application>
</manifest>
......@@ -2,6 +2,8 @@ package org.indin.blisslaunchero;
import android.app.Application;
import com.bugsnag.android.Bugsnag;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
public class BlissLauncher extends Application {
......@@ -13,5 +15,6 @@ public class BlissLauncher extends Application {
.setDefaultFontPath("Roboto-Regular.ttf")
.setFontAttrId(R.attr.fontPath)
.build());
Bugsnag.init(this);
}
}
......@@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable;
import java.util.ArrayList;
import java.util.List;
public class AppItem {
private CharSequence mLabel;
......@@ -18,6 +19,7 @@ public class AppItem {
private boolean mIsClock;
private boolean mIsCalendar;
private boolean isPinnedApp;
private boolean isAdaptive;
// Folder specific
private boolean mBelongsToFolder;
......@@ -28,7 +30,7 @@ public class AppItem {
public AppItem(CharSequence label, String packageName, Drawable icon,
Intent intent, String componentName, boolean iconFromIconPack, boolean isSystemApp,
boolean isClock, boolean isCalendar) {
boolean isClock, boolean isCalendar, boolean adaptive) {
this.mLabel = label;
this.mPackageName = packageName;
this.mIcon = icon;
......@@ -38,8 +40,16 @@ public class AppItem {
this.mIsSystemApp = isSystemApp;
this.mIsClock = isClock;
this.mIsCalendar = isCalendar;
this.isAdaptive = adaptive;
}
public boolean isAdaptive(){
return isAdaptive;
}
public void setAdaptive(boolean adaptive){
this.isAdaptive = adaptive;
}
public CharSequence getLabel() {
return mLabel;
}
......@@ -138,4 +148,5 @@ public class AppItem {
public void setBelongsToFolder(boolean belongsToFolder) {
this.mBelongsToFolder = belongsToFolder;
}
}
......@@ -41,9 +41,8 @@ public class DotRenderer {
R.drawable.notification_icon_72);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, mSize,mSize, true);
mPaint.setColor(Color.parseColor("#FF0800"));
canvas.drawBitmap(scaledBitmap, iconBounds.left - scaledBitmap.getWidth() / 3,
iconBounds.top - scaledBitmap.getHeight() / 3, null);
iconBounds.top - scaledBitmap.getHeight() / 3, mPaint);
//canvas.drawCircle(badgeCenterX, badgeCenterY, mSize/2, mPaint);
}
}
......@@ -410,13 +410,13 @@ public class LauncherActivity extends AppCompatActivity {
R.dimen.app_col_margin)) / nCols;
appIconWidth = iconWidth - 2 * appIconMargin;
Log.i(TAG, "prepareResources: "+appIconWidth);
maxDistanceForFolderCreation = getResources()
.getDimensionPixelSize(R.dimen.maxDistanceForFolderCreation) * mPagerWidth / 540;
hotBackground = getResources().getDrawable(R.drawable.rounded_corners_icon_hot, null);
defaultBackground = getResources().getDrawable(R.drawable.rounded_corners_icon, null);
scrollCorner = getResources().getDimensionPixelSize(R.dimen.scrollCorner) * mPagerWidth
/ 480;
scrollCorner = appIconWidth /2;
wobbleAnimation = AnimationUtils.loadAnimation(this, R.anim.wobble);
wobbleReverseAnimation = AnimationUtils.loadAnimation(this, R.anim.wobble_reverse);
transparentBackground = getResources().getDrawable(R.drawable.transparent, null);
......@@ -871,7 +871,8 @@ public class LauncherActivity extends AppCompatActivity {
false,
true,
false,
false);
false,
true);
folderItem.setFolder(true);
folderItem.setFolderID(currentItemData.getString("folderID"));
JSONArray subAppData = currentItemData.getJSONArray("subApps");
......@@ -889,7 +890,7 @@ public class LauncherActivity extends AppCompatActivity {
}
}
folderItem.setIcon(GraphicsUtil.generateFolderIcon(this, folderItem));
folderItem.setIcon(new GraphicsUtil().generateFolderIcon(this, folderItem));
return folderItem;
} else {
return prepareAppItemFromComponent(componentName);
......@@ -924,7 +925,6 @@ public class LauncherActivity extends AppCompatActivity {
final View icon = v.findViewById(R.id.app_icon);
final SquareImageView squareImageView = (SquareImageView) v.findViewById(
R.id.icon_image_view);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) icon.getLayoutParams();
layoutParams.leftMargin = appIconMargin;
layoutParams.rightMargin = appIconMargin;
......@@ -968,7 +968,7 @@ public class LauncherActivity extends AppCompatActivity {
}
final Intent intent = app.getIntent();
if (!app.isClock()) {
if (!app.isClock()||!app.isCalendar()) {
squareImageView.setImageDrawable(app.getIcon());
}
label.setText(app.getLabel());
......@@ -983,12 +983,12 @@ public class LauncherActivity extends AppCompatActivity {
if (app.isIconFromIconPack()) {
squareImageView.setBackgroundResource(0);
} else {
if (!app.isFolder()) {
/*if (!app.isFolder()) {
squareImageView.setBackground(
IconPackUtil.getIconBackground(app.getLabel().charAt(0)));
IconPackUtil.getIconBackground(this, app.getLabel().charAt(0)));
} else {
squareImageView.setBackground(IconPackUtil.folderBackground);
}
}*/
}
}
......@@ -1208,7 +1208,7 @@ public class LauncherActivity extends AppCompatActivity {
final AppItem appItem = getAppDetails(viewGroup);
if (!appItem.isSystemApp()) {
SquareFrameLayout appIcon = (SquareFrameLayout) viewGroup.findViewById(R.id.app_icon);
Log.i(TAG, "addUninstallIcon: "+ (appIcon.getRight() - appIcon.getLeft()));
int size = (appIcon.getRight() - appIcon.getLeft()) / 5;
if (size > appIcon.getTop() || size > appIcon.getLeft()) {
size = Math.min(appIcon.getTop(), appIcon.getLeft());
......@@ -1578,7 +1578,7 @@ public class LauncherActivity extends AppCompatActivity {
((ViewGroup) activeFolderView.getParent()).removeView(activeFolderView);
} else {
updateIcon(activeFolderView, activeFolder,
GraphicsUtil.generateFolderIcon(this, activeFolder), folderFromDock);
new GraphicsUtil().generateFolderIcon(this, activeFolder), folderFromDock);
}
if (movingApp.getParent() != null) {
((ViewGroup) movingApp.getParent()).removeView(movingApp);
......@@ -1647,7 +1647,7 @@ public class LauncherActivity extends AppCompatActivity {
AppItem app1 = (AppItem) ((List<Object>) collidingApp.getTag()).get(2);
AppItem app2 = (AppItem) ((List<Object>) movingApp.getTag()).get(2);
Drawable folderIcon = GraphicsUtil.generateFolderIcon(this,
Drawable folderIcon = new GraphicsUtil().generateFolderIcon(this,
app1.getIcon(), app2.getIcon());
AppItem folder;
......@@ -1661,7 +1661,8 @@ public class LauncherActivity extends AppCompatActivity {
false,
true,
false,
false);
false,
true);
folder.setFolder(true);
folder.setFolderID(UUID.randomUUID().toString());
......@@ -1683,7 +1684,7 @@ public class LauncherActivity extends AppCompatActivity {
} else {
app2.setBelongsToFolder(true);
app1.getSubApps().add(app2);
updateIcon(collidingApp, app1, GraphicsUtil.generateFolderIcon(this, app1),
updateIcon(collidingApp, app1, new GraphicsUtil().generateFolderIcon(this, app1),
folderFromDock);
}
......@@ -1732,7 +1733,7 @@ public class LauncherActivity extends AppCompatActivity {
if (appItem.isIconFromIconPack()) {
return transparentBackground;
} else {
return IconPackUtil.getIconBackground(appItem.getLabel().charAt(0));
return IconPackUtil.getIconBackground(this, appItem.getLabel().charAt(0));
}
}
} else {
......
......@@ -3,6 +3,7 @@ package org.indin.blisslaunchero.utils;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
......@@ -11,78 +12,88 @@ import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.util.Log;
import org.indin.blisslaunchero.data.model.AppItem;
import org.indin.blisslaunchero.R;
import org.indin.blisslaunchero.data.model.AppItem;
import org.indin.blisslaunchero.widgets.AdaptiveIconDrawableCompat;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AppUtil {
private static final String TAG = "AppUtil";
/**
* Uses the PackageManager to find all launchable apps.
*/
public static List<AppItem> loadLaunchableApps(Context context) {
List<AppItem> launchableApps = new ArrayList<>();
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> apps = packageManager.getInstalledApplications(0);
List<AppItem> launchableApps = new ArrayList<>();
for (ApplicationInfo appInfo : apps) {
String packageName = appInfo.packageName;
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if (intent != null) {
String componentName = intent.getComponent().toString();
boolean iconFromIconPack = true;
Drawable appIcon = null;
boolean isClock = false;
boolean isCalendar = false;
// Load icon from icon pack if present
if (IconPackUtil.iconPackPresent) {
isClock = IconPackUtil.isClock(componentName);
isCalendar = IconPackUtil.isCalendar(componentName);
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
// Handle multi-profile support introduced in Android 5 (#542)
for (ApplicationInfo appInfo:apps) {
String packageName = appInfo.packageName;
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
if (intent != null) {
ActivityInfo activityInfo = intent.resolveActivityInfo(packageManager, 0);
String componentName = intent.getComponent().toString();
Log.i(TAG, "loadLaunchableApps: "+componentName);
boolean iconFromIconPack = true;
Drawable appIcon = null;
boolean isClock = false;
boolean isCalendar = false;
boolean isAdaptive = false;
// Load icon from icon pack if present
if (IconPackUtil.iconPackPresent) {
isClock = IconPackUtil.isClock(componentName);
isCalendar = IconPackUtil.isCalendar(componentName);
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
}
if (appIcon == null) {
isAdaptive = true;
appIcon = AdaptiveIconDrawableCompat.load(context, packageName);
if (appIcon == null) {
GraphicsUtil graphicsUtil = new GraphicsUtil();
appIcon = graphicsUtil.convertToRoundedCorner(context,
graphicsUtil.addBackground(appInfo.loadIcon(packageManager),
false));
}
}
boolean isSystemApp = false;
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
isSystemApp = true;
}
AppItem launchableApp = new AppItem(activityInfo.loadLabel(packageManager),
packageName,
appIcon,
intent,
componentName,
iconFromIconPack,
isSystemApp,
isClock,
isCalendar,
isAdaptive);
launchableApps.add(launchableApp);
}
if (appIcon == null) {
appIcon = appInfo.loadIcon(packageManager);
iconFromIconPack = false;
appIcon = GraphicsUtil.scaleImage(context, appIcon, 1f);
appIcon = GraphicsUtil.maskImage(context, appIcon);
}
boolean isSystemApp = false;
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
isSystemApp = true;
}
AppItem launchableApp = new AppItem(
appInfo.loadLabel(packageManager),
packageName,
appIcon,
intent,
componentName,
iconFromIconPack,
isSystemApp,
isClock,
isCalendar);
launchableApps.add(launchableApp);
}
}
Collections.sort(launchableApps, new Comparator<AppItem>() {
@Override
public int compare(AppItem app1, AppItem app2) {
Collator collator = Collator.getInstance();
return collator.compare(app1.getLabel(), app2.getLabel());
}
});
Collections.sort(launchableApps, (app1, app2) -> {
Collator collator = Collator.getInstance();
return collator.compare(app1.getLabel(), app2.getLabel());
});
Log.i(TAG, "loadLaunchableApps: "+launchableApps.size());
return launchableApps;
}
......@@ -131,6 +142,7 @@ public class AppUtil {
public static AppItem createAppItem(Context context, String packageName) {
try {
PackageManager packageManager = context.getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
......@@ -141,6 +153,7 @@ public class AppUtil {
Drawable appIcon = null;
boolean isClock = false;
boolean isCalendar = false;
boolean isAdaptive = false;
// Load icon from icon pack if present
if (IconPackUtil.iconPackPresent) {
isClock = IconPackUtil.isClock(componentName);
......@@ -148,10 +161,14 @@ public class AppUtil {
appIcon = IconPackUtil.getIconFromIconPack(context, componentName);
}
if (appIcon == null) {
appIcon = appInfo.loadIcon(packageManager);
iconFromIconPack = false;
appIcon = GraphicsUtil.scaleImage(context, appIcon, 1f);
appIcon = GraphicsUtil.maskImage(context, appIcon);
isAdaptive = true;
appIcon = AdaptiveIconDrawableCompat.load(context, packageName);
if (appIcon == null) {
GraphicsUtil graphicsUtil = new GraphicsUtil();
appIcon = graphicsUtil.convertToRoundedCorner(context,
graphicsUtil.addBackground(appInfo.loadIcon(packageManager),
false));
}
}
return new AppItem(appInfo.loadLabel(packageManager),
......@@ -162,7 +179,8 @@ public class AppUtil {
iconFromIconPack,
(appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0,
isClock,
isCalendar);
isCalendar,
isAdaptive);
} else {
return null;
}
......
package org.indin.blisslaunchero.utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
public class BitmapUtils {
public static Bitmap getCroppedBitmap(Bitmap src, Path path){
Bitmap output = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setColor(0XFF000000);
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(src, 0, 0, paint);
return output;
}
}
......@@ -3,9 +3,13 @@ package org.indin.blisslaunchero.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.renderscript.Allocation;
......@@ -17,58 +21,40 @@ import android.util.Log;
import org.indin.blisslaunchero.data.model.AppItem;
import org.indin.blisslaunchero.R;
import org.indin.blisslaunchero.ui.LauncherActivity;
import org.indin.blisslaunchero.widgets.AdaptiveIconUtils;
import org.indin.blisslaunchero.widgets.PathParser;
public class GraphicsUtil {
private static final String TAG = "BLISS_GRAPHICS";
public static Bitmap blur(Context context, Bitmap image) {
int width = Math.round(image.getWidth() * 0.2f);
int height = Math.round(image.getHeight() * 0.2f);
Bitmap input = Bitmap.createScaledBitmap(image, width, height, false);
Bitmap output = Bitmap.createBitmap(input);
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation allocInput = Allocation.createFromBitmap(rs, input);
Allocation allocOutput = Allocation.createFromBitmap(rs, output);
theIntrinsic.setRadius(7);
theIntrinsic.setInput(allocInput);
theIntrinsic.forEach(allocOutput);
allocOutput.copyTo(output);
return output;
public GraphicsUtil() {
}
/**
* Takes 1 or more drawables and merges them to form a single Drawable.
* However, if more than 4 drawables are provided, only the first 4 are used.
*/
public static Drawable generateFolderIcon(Context context, Drawable... sources) {
for (Drawable d : sources) {
if (!(d instanceof BitmapDrawable)) {
Log.d(TAG, "Unknown type of icon found");
return context.getResources().getDrawable(R.mipmap.ic_folder, null);
}
}
public Drawable generateFolderIcon(Context context, Drawable... sources) {
int width = sources[0].getIntrinsicWidth();
int height = width; // Square icons
Log.i(TAG, "generateFolderIcon: "+width+"*"+height);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
int xOrigin = bitmap.getWidth() / 20;
int yOrigin = bitmap.getHeight() / 20;
int xOrigin = bitmap.getWidth() / 15;
int yOrigin = bitmap.getHeight() / 15;
int x = xOrigin;
int y = yOrigin;
int xIncrement = bitmap.getWidth() / 10;
int yIncrement = bitmap.getHeight() / 10;
int xIncrement = bitmap.getWidth() / 15;
int yIncrement = bitmap.getHeight() / 15;
int count = 0;
int total = 0;
for (Drawable d : sources) {
BitmapDrawable bd = (BitmapDrawable) d;
bd.setBounds(x, y, (int) (x + width / 2.5f), (int) (y + height / 2.5f));
bd.draw(canvas);
d.setBounds(x, y, (int) (x + width / 2.5f), (int) (y + height / 2.5f));
d.draw(canvas);
x += (int) (width / 2.5f + xIncrement);
count++;
total++;
......@@ -81,20 +67,16 @@ public class GraphicsUtil {
break;
}
}
Drawable output = new BitmapDrawable(context.getResources(), bitmap);
if (IconPackUtil.iconPackPresent) {
output = GraphicsUtil.scaleImage(context, output, 1f);
output = GraphicsUtil.maskImage(context, output);
}
return output;
Drawable convertedBitmap = convertToRoundedCorner(context, addBackground(bitmap, true));
return convertedBitmap;
}
/**
* A utility method that simplifies calls to the generateFolderIcon() method that
* expects an array of Drawables.
*/
public static Drawable generateFolderIcon(Context context, AppItem app) {
public Drawable generateFolderIcon(Context context, AppItem app) {
Drawable[] drawables = new Drawable[app.getSubApps().size()];
for (int i = 0; i < app.getSubApps().size(); i++) {
drawables[i] = app.getSubApps().get(i).getIcon();
......@@ -106,14 +88,18 @@ public class GraphicsUtil {
* Scales icons to match the icon pack
*/
public static Drawable scaleImage(Context context, Drawable image, float scaleFactor) {
Log.i(TAG, "scaleImage: " + image.getIntrinsicWidth() + "*" + image.getIntrinsicHeight());
if ((image == null) || !(image instanceof BitmapDrawable)) {
return image;
}
Bitmap b = ((BitmapDrawable) image).getBitmap();
int sizeX = Math.round(image.getIntrinsicWidth() * scaleFactor);
Log.i(TAG, "sizeX: " + sizeX);
int sizeY = Math.round(image.getIntrinsicHeight() * scaleFactor);
Log.i(TAG, "sizeY: " + sizeY);
Bitmap bitmapResized = Bitmap.createScaledBitmap(b, sizeX, sizeY, false);
image = new BitmapDrawable(context.getResources(), bitmapResized);
Log.i(TAG, "scaleImage2: " + image.getIntrinsicWidth() + "*" + image.getIntrinsicHeight());
return image;
}
......@@ -121,27 +107,92 @@ public class GraphicsUtil {
if ((image == null) || !(image instanceof BitmapDrawable)) {
return image;
}
double scale = 0.85;
double scale = 1;
Drawable maskDrawable;
if(IconPackUtil.getIconMask() != null){
if (IconPackUtil.getIconMask() != null) {
maskDrawable = IconPackUtil.getIconMask();
}else
} else {
maskDrawable = ContextCompat.getDrawable(context, R.drawable.iconmask);
Bitmap mask = ((BitmapDrawable) maskDrawable).getBitmap();
Bitmap original = Bitmap.createScaledBitmap(((BitmapDrawable) image).getBitmap(),
(int) (mask.getWidth() * scale),
(int) (mask.getHeight() * scale), true);
}