Commit 4159a700 authored by Amit Kumar's avatar Amit Kumar
Browse files

Merge branch 'reactive' into develop

parents f051a3ae 828e907c
......@@ -33,9 +33,7 @@ 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}"
/*implementation 'com.bugsnag:bugsnag-android:4.+'*/
// Support Libs
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibraryVersion}"
......
......@@ -6,10 +6,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk
android:minSdkVersion="22"
<uses-sdk android:minSdkVersion="22"
android:targetSdkVersion="26"/>
<application
android:name=".BlissLauncher"
android:allowBackup="true"
......@@ -19,7 +17,7 @@
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".ui.LauncherActivity"
android:name=".features.launcher.LauncherActivity"
android:clearTaskOnLaunch="true"
android:launchMode="singleTask"
android:screenOrientation="nosensor"
......@@ -35,7 +33,7 @@
</activity>
<service
android:name=".notification.NotificationService"
android:name=".features.notification.NotificationService"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
......
......@@ -2,8 +2,6 @@ package org.indin.blisslaunchero;
import android.app.Application;
import com.bugsnag.android.Bugsnag;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
public class BlissLauncher extends Application {
......@@ -15,6 +13,6 @@ public class BlissLauncher extends Application {
.setDefaultFontPath("Roboto-Regular.ttf")
.setFontAttrId(R.attr.fontPath)
.build());
Bugsnag.init(this);
//Bugsnag.init(this);
}
}
package org.indin.blisslaunchero.features.launcher;
import org.indin.blisslaunchero.data.model.AppItem;
import java.util.ArrayList;
import java.util.List;
public class AllAppsList {
public List<AppItem> launchableApps;
public List<AppItem> pinnedApps;
public AllAppsList(List<AppItem> launchableApps, List<AppItem> pinnedApps){
this.launchableApps = launchableApps;
this.pinnedApps = pinnedApps;
}
}
package org.indin.blisslaunchero.features.launcher;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridLayout;
import org.indin.blisslaunchero.framework.DeviceProfile;
public class DockGridLayout extends GridLayout {
private Context mContext;
public DockGridLayout(Context context) {
this(context, null);
}
public DockGridLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DockGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
DeviceProfile deviceProfile = LauncherActivity.getLauncher(mContext).getDeviceProfile();
setMeasuredDimension(deviceProfile.getAvailableWidthPx(), deviceProfile.hotseatCellHeightPx);
}
}
package org.indin.blisslaunchero.features.launcher;
import android.content.Context;
import org.indin.blisslaunchero.data.model.AppItem;
import org.indin.blisslaunchero.framework.mvp.MvpContract;
import java.util.List;
public interface LauncherContract {
interface View extends MvpContract.View {
void showApps(List<AppItem> appItemList, List<AppItem> pinnedApps);
}
interface Presenter extends MvpContract.Presenter<View> {
void loadApps(Context context);
}
}
package org.indin.blisslaunchero.features.launcher;
import android.content.Context;
import android.util.Log;
import org.indin.blisslaunchero.framework.mvp.MvpPresenter;
import org.indin.blisslaunchero.framework.util.AppUtil;
import org.indin.blisslaunchero.framework.util.IconPackUtil;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
public class LauncherPresenter extends MvpPresenter<LauncherContract.View> implements
LauncherContract.Presenter {
private CompositeDisposable mCompositeDisposable;
private static final String TAG = "LauncherPresenter";
public LauncherPresenter() {
}
@Override
public void attachView(LauncherContract.View view) {
super.attachView(view);
mCompositeDisposable = new CompositeDisposable();
}
@Override
public void detachView() {
super.detachView();
mCompositeDisposable.dispose();
mCompositeDisposable = null;
}
@Override
public void loadApps(Context context) {
checkViewAttached();
mCompositeDisposable.add(loadAppsAndIconCache(context).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<AllAppsList>() {
@Override
public void onNext(AllAppsList allAppsList) {
getView().showApps(allAppsList.launchableApps,
allAppsList.pinnedApps);
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: ", e);
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete() called");
}
}));
}
private Observable<AllAppsList> loadAppsAndIconCache(Context context) {
IconPackUtil.cacheIconsFromIconPack(context);
return Observable.defer(
() -> Observable.just(AppUtil.loadAllApps(context)));
}
}
package org.indin.blisslaunchero.features.launcher;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewPager;
import org.indin.blisslaunchero.framework.DeviceProfile;
public class LauncherViewPager extends ViewPager {
private Context mContext;
public LauncherViewPager(@NonNull Context context) {
super(context);
this.mContext = context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
DeviceProfile deviceProfile = LauncherActivity.getLauncher(mContext).getDeviceProfile();
setMeasuredDimension(deviceProfile.getAvailableWidthPx(), deviceProfile.getWorkspaceHeight());
}
}
package org.indin.blisslaunchero.features.launcher;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import org.indin.blisslaunchero.framework.DeviceProfile;
public class PageIndicatorLinearLayout extends LinearLayout {
private Context mContext;
public PageIndicatorLinearLayout(Context context) {
this(context, null);
}
public PageIndicatorLinearLayout(Context context,
@Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public PageIndicatorLinearLayout(Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
DeviceProfile deviceProfile = LauncherActivity.getLauncher(mContext).getDeviceProfile();
setMeasuredDimension(deviceProfile.getAvailableWidthPx(), deviceProfile.getPageIndicatorHeight());
}
}
package org.indin.blisslaunchero.notification;
package org.indin.blisslaunchero.features.notification;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
......@@ -18,7 +17,7 @@ import org.indin.blisslaunchero.R;
public class DotRenderer {
private static final String TAG = "DotRenderer";
private static final float SIZE_PERCENTAGE = 0.35f;
private static final float SIZE_PERCENTAGE = 0.3375f;
private final Context mContext;
private final int mSize;
......@@ -33,16 +32,14 @@ public class DotRenderer {
public void drawDot(Canvas canvas, Rect iconBounds) {
Log.d(TAG, "drawDot() called with: canvas = [" + canvas + "], iconBounds = [" + iconBounds
+ "]");
int badgeCenterX = (int) (iconBounds.left + mSize * 0.25);
int badgeCenterY = (int) (iconBounds.top + mSize * 0.25);
Bitmap myBitmap = BitmapFactory.decodeResource(
mContext.getResources(),
R.drawable.notification_icon_72);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, mSize,mSize, true);
canvas.drawBitmap(scaledBitmap, iconBounds.left - scaledBitmap.getWidth() / 3,
iconBounds.top - scaledBitmap.getHeight() / 3, mPaint);
canvas.drawBitmap(scaledBitmap, iconBounds.left - scaledBitmap.getWidth() / 2,
iconBounds.top - scaledBitmap.getHeight() / 2, mPaint);
//canvas.drawCircle(badgeCenterX, badgeCenterY, mSize/2, mPaint);
}
}
package org.indin.blisslaunchero.notification;
package org.indin.blisslaunchero.features.notification;
import android.service.notification.StatusBarNotification;
import android.util.Log;
......
package org.indin.blisslaunchero.notification;
package org.indin.blisslaunchero.features.notification;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import org.indin.blisslaunchero.utils.ListUtil;
import org.indin.blisslaunchero.framework.util.ListUtil;
/**
* Created by falcon on 14/3/18.
......
package org.indin.blisslaunchero.framework;
import android.os.Handler;
import android.os.SystemClock;
public class Alarm implements Runnable {
// if we reach this time and the alarm hasn't been cancelled, call the listener
private long mAlarmTriggerTime;
// if we've scheduled a call to run() (ie called mHandler.postDelayed), this variable is true.
// We use this to avoid having multiple pending callbacks
private boolean mWaitingForCallback;
private Handler mHandler;
private OnAlarmListener mAlarmListener;
private boolean mAlarmPending = false;
public Alarm() {
mHandler = new Handler();
}
public void setOnAlarmListener(OnAlarmListener alarmListener) {
mAlarmListener = alarmListener;
}
// Sets the alarm to go off in a certain number of milliseconds. If the alarm is already set,
// it's overwritten and only the new alarm setting is used
public void setAlarm(long millisecondsInFuture) {
long currentTime = SystemClock.uptimeMillis();
mAlarmPending = true;
long oldTriggerTime = mAlarmTriggerTime;
mAlarmTriggerTime = currentTime + millisecondsInFuture;
// If the previous alarm was set for a longer duration, cancel it.
if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) {
mHandler.removeCallbacks(this);
mWaitingForCallback = false;
}
if (!mWaitingForCallback) {
mHandler.postDelayed(this, mAlarmTriggerTime - currentTime);
mWaitingForCallback = true;
}
}
public void cancelAlarm() {
mAlarmPending = false;
}
// this is called when our timer runs out
@Override
public void run() {
mWaitingForCallback = false;
if (mAlarmPending) {
long currentTime = SystemClock.uptimeMillis();
if (mAlarmTriggerTime > currentTime) {
// We still need to wait some time to trigger spring loaded mode--
// post a new callback
mHandler.postDelayed(this, Math.max(0, mAlarmTriggerTime - currentTime));
mWaitingForCallback = true;
} else {
mAlarmPending = false;
if (mAlarmListener != null) {
mAlarmListener.onAlarm(this);
}
}
}
}
public boolean alarmPending() {
return mAlarmPending;
}
public interface OnAlarmListener {
void onAlarm(Alarm alarm);
}
}
package org.indin.blisslaunchero.framework;
/**
* Base class which represents an area on the grid.
*/
public class CellAndSpan {
/**
* Indicates the X position of the associated cell.
*/
public int cellX = -1;
/**
* Indicates the Y position of the associated cell.
*/
public int cellY = -1;
/**
* Indicates the X cell span.
*/
public int spanX = 1;
/**
* Indicates the Y cell span.
*/
public int spanY = 1;
public CellAndSpan() {
}
public void copyFrom(CellAndSpan copy) {
cellX = copy.cellX;
cellY = copy.cellY;
spanX = copy.spanX;
spanY = copy.spanY;
}
public CellAndSpan(int cellX, int cellY, int spanX, int spanY) {
this.cellX = cellX;
this.cellY = cellY;
this.spanX = spanX;
this.spanY = spanY;
}
public String toString() {
return "(" + cellX + ", " + cellY + ": " + spanX + ", " + spanY + ")";
}
}
package org.indin.blisslaunchero.framework;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import org.indin.blisslaunchero.framework.customviews.AdaptiveIconUtils;
import org.indin.blisslaunchero.framework.customviews.PathParser;
import java.util.ArrayList;
public class DeviceProfile {
private static final float TALL_DEVICE_ASPECT_RATIO_THRESHOLD = 2.0f;
private static final int TYPE_WORKSPACE = 0;
private static final int TYPE_FOLDER = 1;
private static final int TYPE_HOTSEAT = 2;
public static Path path;
public int cellHeightWithoutPaddingPx;
public int hotseatCellHeightWithoutPaddingPx;
public interface LauncherLayoutChangeListener {
void onLauncherLayoutChanged();
}
/**
* Number of icons per row and column in the workspace.
*/
public int numRows;
public int numColumns;
public int maxAppsPerPage;
/**
* Number of icons per row and column in the folder.
*/
public int numFolderRows;
public int numFolderColumns;
/**
* Number of icons inside the hotseat area.
*/
public int numHotseatIcons;
// Device properties in current orientation
public final int widthPx;
public final int heightPx;
public final int availableWidthPx;
public final int availableHeightPx;
// Page indicator
public int pageIndicatorSizePx;
public int pageIndicatorTopPaddingPx;
public int pageIndicatorBottomPaddingPx;
// Workspace icons
public int iconSizePx;
public int iconTextSizePx;
public int iconDrawablePaddingPx;
public int iconDrawablePaddingOriginalPx;
//Uninstall icon
public int uninstallIconSizePx;
public int uninstallIconPadding;
public int cellWidthPx;
public int cellHeightPx;
public int workspaceCellPaddingXPx;
// Folder
public int folderBackgroundOffset;
public int folderIconSizePx;
public int folderIconPreviewPadding;
// Folder cell
public int folderCellWidthPx;
public int folderCellHeightPx;
// Folder child
public int folderChildIconSizePx;
public int folderChildTextSizePx;
public int folderChildDrawablePaddingPx;
// Hotseat
public int hotseatCellHeightPx;
// In portrait: size = height, in landscape: size = width
public int hotseatBarSizePx;
public int hotseatBarTopPaddingPx;
public int hotseatBarBottomPaddingPx;
public int hotseatBarLeftNavBarLeftPaddingPx;
public int hotseatBarLeftNavBarRightPaddingPx;
public int hotseatBarRightNavBarLeftPaddingPx;
public int hotseatBarRightNavBarRightPaddingPx;
// All apps
public int allAppsCellHeightPx;
public int allAppsNumCols;
public int allAppsNumPredictiveCols;
public int allAppsButtonVisualSize;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
public float allAppsIconTextSizePx;
// Drop Target
public int dropTargetBarSizePx;
// Insets
private Rect mInsets = new Rect();
// Listeners
private ArrayList<LauncherLayoutChangeListener> mListeners = new ArrayList<>();
private Context mContext;
private static final String TAG = "DeviceProfile";
public DeviceProfile(Context context) {
mContext = context;