diff --git a/app/build.gradle b/app/build.gradle index 008fc0fe80951850e5ad1c0485c38189addddacc..0a6d4663afebf6754e0e0244a19345bac3ee63b2 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.application' -apply plugin: 'io.fabric' +apply plugin: 'kotlin-android' // Manifest version information! def versionMajor = 1 -def versionMinor = 2 -def versionPatch = 4 +def versionMinor = 3 +def versionPatch = 0 android { compileSdkVersion rootProject.ext.compileSdkVersion @@ -16,7 +16,7 @@ android { versionName "${versionMajor}.${versionMinor}.${versionPatch}" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - renderscriptTargetApi 18 + renderscriptTargetApi 28 renderscriptSupportModeEnabled true } buildTypes { @@ -83,8 +83,6 @@ dependencies { apiNougatImplementation 'org.cyanogenmod:platform.sdk:6.0' apiOreoImplementation files('libs/lineage-sdk.jar') - debugImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.9' - debugImplementation 'com.google.firebase:firebase-core:16.0.6' debugImplementation 'com.amitshekhar.android:debug-db:1.0.4' implementation 'org.greenrobot:eventbus:3.1.1' @@ -111,6 +109,11 @@ dependencies { // Rx Relay implementation "com.jakewharton.rxrelay2:rxrelay:${rootProject.ext.rxRelayVersion}" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + + // Blur Library + implementation project(':hoko-blur') + // Room implementation "android.arch.persistence.room:runtime:1.1.1" annotationProcessor "android.arch.persistence.room:compiler:1.1.1" @@ -140,5 +143,4 @@ dependencies { androidTestImplementation "com.android.support.test:rules:${rootProject.ext.runnerRulesVersion}" } -apply plugin: 'com.google.gms.google-services' apply plugin: 'com.getkeepsafe.dexcount' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1f225ac514833c3c77d68fd5331f04dcf44fed5c..2c8f21854ef0294fd1b1b456f5d0ac9deb47f5bd 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -31,12 +31,15 @@ + + 0) { + statusBarHeight = res.getDimensionPixelSize(resourceId); + } + ComponentName cn = new ComponentName(context.getPackageName(), this.getClass().getName()); @@ -248,8 +253,6 @@ public class DeviceProfile { dateTextBottomPadding = (dateTextviewHeight - (int) (0.86 * Utilities.calculateTextHeight( (float) dateTextSize / 2))) / 2; - Log.i(TAG, "datepadding: " + dateTextTopPadding + "*" + dateTextBottomPadding); - cellHeightWithoutPaddingPx = iconSizePx + Utilities.pxFromDp(4, dm) + Utilities.calculateTextHeight(iconTextSizePx); @@ -304,7 +307,7 @@ public class DeviceProfile { return pageIndicatorSizePx + pageIndicatorBottomPaddingPx + pageIndicatorTopPaddingPx; } - public int getMaxWidgetWidth(){ + public int getMaxWidgetWidth() { return maxWidgetWidth; } @@ -351,6 +354,34 @@ public class DeviceProfile { return resizedPath; } + public boolean hasSoftNavigationBar(Context context) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + DisplayMetrics dm = new DisplayMetrics(); + display.getMetrics(dm); + + Point smallestSize = new Point(); + Point largestSize = new Point(); + display.getCurrentSizeRange(smallestSize, largestSize); + + int availableHeight = largestSize.y; + + Point realSize = new Point(); + display.getRealSize(realSize); + int realHeight = realSize.y; + context = getContext(context, Configuration.ORIENTATION_PORTRAIT); + Resources res = context.getResources(); + + // status bar height + statusBarHeight = 0; + int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + statusBarHeight = res.getDimensionPixelSize(resourceId); + } + + return (realHeight - availableHeight - statusBarHeight) > 0; + } + private int getLauncherIconDensity(int requiredSize) { // Densities typically defined by an app. int[] densityBuckets = new int[]{ diff --git a/app/src/main/java/foundation/e/blisslauncher/core/KotlinUtils.kt b/app/src/main/java/foundation/e/blisslauncher/core/KotlinUtils.kt new file mode 100644 index 0000000000000000000000000000000000000000..e45d2b68824c1cfd0143ccc6e74441211f690a44 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/KotlinUtils.kt @@ -0,0 +1,25 @@ +package foundation.e.blisslauncher.core + +import android.os.Handler +import android.os.Looper + +val mainHandler by lazy { Handler(Looper.getMainLooper()) } + + +fun runOnMainThread(r: () -> Unit) { + runOnThread(mainHandler, r) +} + +fun runOnThread(handler: Handler, r: () -> Unit) { + if (handler.looper.thread.id == Looper.myLooper()?.thread?.id) { + r() + } else { + handler.post(r) + } +} + +inline fun Iterable.safeForEach(action: (T) -> Unit) { + val tmp = ArrayList() + tmp.addAll(this) + for (element in tmp) action(element) +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java b/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java index 48648b6fc5ea4329854267aa9b1110f066980513..52c69eba5760dc045a336acb409b58d2c2b779c0 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/Utilities.java @@ -2,7 +2,10 @@ package foundation.e.blisslauncher.core; import android.content.Context; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; import android.util.DisplayMetrics; @@ -16,6 +19,10 @@ import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Calendar; +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -41,6 +48,19 @@ public class Utilities { public static final boolean ATLEAST_MARSHMALLOW = Build.VERSION.SDK_INT >= 23; + + // These values are same as that in {@link AsyncTask}. + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + private static final int CORE_POOL_SIZE = CPU_COUNT + 1; + private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; + private static final int KEEP_ALIVE = 1; + /** + * An {@link Executor} to be used with async task with no limit on the queue size. + */ + public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor( + CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, + TimeUnit.SECONDS, new LinkedBlockingQueue()); + /** * Compresses the bitmap to a byte array for serialization. */ @@ -159,6 +179,38 @@ public class Utilities { return result; } + public static Bitmap drawableToBitmap(Drawable drawable) { + return Utilities.drawableToBitmap(drawable, true); + } + + public static Bitmap drawableToBitmap(Drawable drawable, boolean forceCreate) { + return drawableToBitmap(drawable, forceCreate, 0); + } + + public static Bitmap drawableToBitmap(Drawable drawable, boolean forceCreate, int fallbackSize) { + if (!forceCreate && drawable instanceof BitmapDrawable) { + return ((BitmapDrawable) drawable).getBitmap(); + } + + int width = drawable.getIntrinsicWidth(); + int height = drawable.getIntrinsicHeight(); + + if (width <= 0 || height <= 0) { + if (fallbackSize > 0) { + width = height = fallbackSize; + } else { + return null; + } + } + + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + return bitmap; + } + public static boolean isBootCompleted() { return "1".equals(getSystemProperty("sys.boot_completed", "1")); } @@ -177,4 +229,6 @@ public class Utilities { return defaultValue; } + + } diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperFilter.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperFilter.kt new file mode 100644 index 0000000000000000000000000000000000000000..0539b85cbbaa4523d7747ca3d773159f724e746f --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperFilter.kt @@ -0,0 +1,33 @@ +package foundation.e.blisslauncher.core.blur + +import android.content.Context +import android.graphics.Bitmap +import com.hoko.blur.HokoBlur +import com.hoko.blur.task.AsyncBlurTask + +class BlurWallpaperFilter(private val context: Context) : WallpaperFilter { + + private var blurRadius = 8 + + override fun apply(wallpaper: Bitmap): WallpaperFilter.ApplyTask { + return WallpaperFilter.ApplyTask.create { emitter -> + HokoBlur.with(context) + .scheme(HokoBlur.SCHEME_OPENGL) + .mode(HokoBlur.MODE_STACK) + .radius(blurRadius) + .sampleFactor(8f) + .forceCopy(false) + .needUpscale(true) + .processor() + .asyncBlur(wallpaper, object : AsyncBlurTask.Callback { + override fun onBlurSuccess(bitmap: Bitmap) { + emitter.onSuccess(bitmap) + } + + override fun onBlurFailed(error: Throwable?) { + emitter.onError(error!!) + } + }) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperProvider.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperProvider.kt new file mode 100644 index 0000000000000000000000000000000000000000..765c27f398efbba063e64d10bf02de05c1e1b766 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/BlurWallpaperProvider.kt @@ -0,0 +1,238 @@ +package foundation.e.blisslauncher.core.blur + +import android.Manifest +import android.app.WallpaperManager +import android.content.Context +import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.ColorMatrix +import android.graphics.ColorMatrixColorFilter +import android.graphics.Paint +import android.support.v4.app.ActivityCompat +import android.util.DisplayMetrics +import android.util.Log +import android.view.WindowManager +import android.widget.Toast +import foundation.e.blisslauncher.core.Utilities +import foundation.e.blisslauncher.core.runOnMainThread +import foundation.e.blisslauncher.core.safeForEach +import foundation.e.blisslauncher.core.utils.SingletonHolder +import foundation.e.blisslauncher.core.utils.ensureOnMainThread +import foundation.e.blisslauncher.core.utils.useApplicationContext +import java.util.* +import kotlin.math.max + +class BlurWallpaperProvider(val context: Context) { + + private val wallpaperManager: WallpaperManager = WallpaperManager.getInstance(context) + private val listeners = ArrayList() + private val displayMetrics = DisplayMetrics() + + var wallpaper: Bitmap? = null + private set(value) { + if (field != value) { + field?.recycle() + field = value + } + } + var placeholder: Bitmap? = null + private set(value) { + if (field != value) { + field?.recycle() + field = value + } + } + + private val vibrancyPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG) + + private val mUpdateRunnable = Runnable { updateWallpaper() } + + private val wallpaperFilter = BlurWallpaperFilter(context) + private var applyTask: WallpaperFilter.ApplyTask? = null + + private var updatePending = false + + init { + isEnabled = getEnabledStatus() + updateAsync() + } + + private fun getEnabledStatus() = wallpaperManager.wallpaperInfo == null + + fun updateAsync() { + Utilities.THREAD_POOL_EXECUTOR.execute(mUpdateRunnable) + } + + private fun updateWallpaper() { + if (applyTask != null) { + updatePending = true + return + } + + // Prepare a placeholder before hand so that it can be used in case wallpaper is null + val wm = + context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + val display = wm.defaultDisplay + display.getRealMetrics(displayMetrics) + val width = displayMetrics.widthPixels + val height = displayMetrics.heightPixels + placeholder = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val canvas = Canvas(placeholder!!) + canvas.drawColor(0x44000000) + + if (ActivityCompat.checkSelfPermission( + context, + Manifest.permission.READ_EXTERNAL_STORAGE + ) != PackageManager.PERMISSION_GRANTED + ) { + Log.d("BWP", "NO permission granted") + return + } + + val enabled = getEnabledStatus() + if (enabled != isEnabled) { + isEnabled = enabled + runOnMainThread { + listeners.safeForEach(Listener::onEnabledChanged) + } + } + + if (!isEnabled) { + wallpaper = null + return + } + + var wallpaper = try { + Utilities.drawableToBitmap(wallpaperManager.drawable, true) as Bitmap + } catch (e: Exception) { + runOnMainThread { + val msg = "Failed: ${e.message}" + Toast.makeText(context, msg, Toast.LENGTH_LONG).show() + notifyWallpaperChanged() + } + return + } + wallpaper = scaleAndCropToScreenSize(wallpaper) + wallpaper = applyVibrancy(wallpaper) + applyTask = wallpaperFilter.apply(wallpaper).setCallback {result, error -> + if(error == null) { + this@BlurWallpaperProvider.wallpaper = result + runOnMainThread(::notifyWallpaperChanged) + wallpaper.recycle() + }else { + if (error is OutOfMemoryError) { + runOnMainThread { + Toast.makeText(context, "Failed", Toast.LENGTH_LONG).show() + notifyWallpaperChanged() + } + } + wallpaper.recycle() + } + } + applyTask = null + if (updatePending) { + updatePending = false + updateWallpaper() + } + } + + + private fun notifyWallpaperChanged() { + listeners.forEach(Listener::onWallpaperChanged) + } + + private fun applyVibrancy(wallpaper: Bitmap?): Bitmap { + val width = wallpaper!!.width + val height = wallpaper.height + val bitmap = Bitmap.createBitmap( + width, + height, + Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas() + canvas.setBitmap(bitmap) + val colorMatrix = ColorMatrix() + colorMatrix.setSaturation(1.25f) + val filter = ColorMatrixColorFilter(colorMatrix) + vibrancyPaint.colorFilter = filter + canvas.drawBitmap(wallpaper, 0f, 0f, vibrancyPaint) + wallpaper.recycle() + return bitmap + } + + private fun scaleAndCropToScreenSize(wallpaper: Bitmap): Bitmap { + val wm = + context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + val display = wm.defaultDisplay + display.getRealMetrics(displayMetrics) + val width = displayMetrics.widthPixels + val height = displayMetrics.heightPixels + val widthFactor = width.toFloat() / wallpaper.width + val heightFactor = height.toFloat() / wallpaper.height + val upscaleFactor = Math.max(widthFactor, heightFactor) + if (upscaleFactor <= 0) { + return wallpaper + } + val scaledWidth = + max(width.toFloat(), wallpaper.width * upscaleFactor).toInt() + val scaledHeight = + max(height.toFloat(), wallpaper.height * upscaleFactor).toInt() + val scaledWallpaper = + Bitmap.createScaledBitmap(wallpaper, scaledWidth, scaledHeight, false) + val navigationBarHeight = 0 + /*if (BlissLauncher.getApplication(context).getDeviceProfile().hasSoftNavigationBar(context)) { + + int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + if (resourceId > 0) { + navigationBarHeight = context.getResources().getDimensionPixelSize(resourceId); + } + }*/ + val y: Int + y = if (scaledWallpaper.height > height) { + (scaledWallpaper.height - height) / 2 + } else 0 + + return Bitmap.createBitmap( + scaledWallpaper, + 0, + y, + width, + height - navigationBarHeight + ) + } + + fun addListener(listener: Listener) { + listeners.add(listener) + } + + fun removeListener(listener: Listener) { + listeners.remove(listener) + } + + fun createDrawable(): ShaderBlurDrawable { + return ShaderBlurDrawable(this) + } + + interface Listener { + fun onWallpaperChanged() {} + fun onEnabledChanged() {} + } + + /*fun clear() { + listener = null + cancelPreTask(true) + sInstance = null + }*/ + + companion object : + SingletonHolder(ensureOnMainThread(useApplicationContext(::BlurWallpaperProvider))) { + + var isEnabled: Boolean = false + private var sEnabledFlag: Int = 0 + + fun isEnabled(flag: Int): Boolean { + return isEnabled && sEnabledFlag and flag != 0 + } + } +} diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt new file mode 100644 index 0000000000000000000000000000000000000000..e74a2792536bc877b2cb66975b6f30543b1af8d8 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/ShaderBlurDrawable.kt @@ -0,0 +1,126 @@ +package foundation.e.blisslauncher.core.blur + +import android.graphics.Bitmap +import android.graphics.BitmapShader +import android.graphics.Canvas +import android.graphics.ColorFilter +import android.graphics.Paint +import android.graphics.Path +import android.graphics.PixelFormat +import android.graphics.RectF +import android.graphics.Shader +import android.graphics.drawable.Drawable +import foundation.e.blisslauncher.core.DeviceProfile + +class ShaderBlurDrawable internal constructor(private val blurWallpaperProvider: BlurWallpaperProvider) : + Drawable(), BlurWallpaperProvider.Listener { + + private var blurAlpha = 255 + private val blurPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG) + private var blurBitmap: Bitmap? = null + set(value) { + if (field != value) { + field = value + blurPaint.shader = + value?.let { BitmapShader(it, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) } + } + } + + private val blurBounds = RectF() + private val blurPath = Path() + private var blurPathValid = false + set(value) { + if (field != value) { + field = value + if (!value) { + invalidateSelf() + } + } + } + + var noRadius = true + + + override fun draw(canvas: Canvas) = draw(canvas, noRadius) + + fun draw(canvas: Canvas, noRadius: Boolean = false) { + if (blurAlpha == 0) return + blurBitmap = blurWallpaperProvider.wallpaper + + if(blurBitmap == null) { + blurBitmap = blurWallpaperProvider.placeholder + } + blurBitmap = + if (blurBitmap!!.height > (blurBounds.bottom.toInt() - blurBounds.top.toInt())) { + + Bitmap.createBitmap( + blurBitmap!!, + blurBounds.left.toInt(), blurBounds.top.toInt(), + blurBounds.right.toInt() - blurBounds.left.toInt(), + blurBounds.bottom.toInt() - blurBounds.top.toInt() + ) + } else { + blurBitmap + } + + //setupBlurPath() + + //canvas.translate(0f, -1500f) + if (noRadius) { + canvas.drawRect( + 0f, 0f, + blurBounds.right - blurBounds.left, blurBounds.bottom - blurBounds.top, + blurPaint + ) + } else { + canvas.drawPath(DeviceProfile.path, blurPaint) + } + //canvas.translate(0f, 1500f) + } + + override fun setAlpha(alpha: Int) { + blurAlpha = alpha + blurPaint.alpha = alpha + } + + override fun getAlpha(): Int { + return blurAlpha + } + + private fun setupBlurPath() { + if (blurPathValid) return + + blurPath.reset() + blurPath.addRect( + 0f, 0f, + blurBounds.right - blurBounds.left, blurBounds.bottom - blurBounds.top, Path.Direction.CW + ) + } + + override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) = + setBlurBounds(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat()) + + fun setBlurBounds(left: Float, top: Float, right: Float, bottom: Float) { + if (blurBounds.left != left || + blurBounds.top != top || + blurBounds.right != right || + blurBounds.bottom != bottom + ) { + blurBounds.set(left, top, right, bottom) + blurPathValid = false + } + } + + override fun getOpacity(): Int = PixelFormat.TRANSLUCENT + + override fun onWallpaperChanged() { + invalidateSelf() + } + + override fun setColorFilter(colorFilter: ColorFilter?) { + } + + fun startListening() = blurWallpaperProvider.addListener(this) + + fun stopListening() = blurWallpaperProvider.removeListener(this) +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/blur/WallpaperFilter.kt b/app/src/main/java/foundation/e/blisslauncher/core/blur/WallpaperFilter.kt new file mode 100644 index 0000000000000000000000000000000000000000..c85321ed76fbc85c543ef392945c6c34e189a6a6 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/blur/WallpaperFilter.kt @@ -0,0 +1,57 @@ +package foundation.e.blisslauncher.core.blur + +import android.graphics.Bitmap + +interface WallpaperFilter { + + fun apply(wallpaper: Bitmap): ApplyTask + + class ApplyTask { + + val emitter = Emitter() + + private var result: Bitmap? = null + private var error: Throwable? = null + + private var callback: ((Bitmap?, Throwable?) -> Unit)? = null + + fun setCallback(callback: (Bitmap?, Throwable?) -> Unit): ApplyTask { + result?.let { + callback(it, null) + return this + } + error?.let { + callback(null, it) + return this + } + this.callback = callback + return this + } + + inner class Emitter { + + fun onSuccess(result: Bitmap) { + callback?.let { + it(result, null) + return + } + this@ApplyTask.result = result + } + + fun onError(error: Throwable) { + callback?.let { + it(null, error) + return + } + this@ApplyTask.error = error + } + } + + companion object { + + inline fun create(source: (Emitter) -> Unit): ApplyTask { + return ApplyTask().also { source(it.emitter) } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/broadcast/WallpaperChangeReceiver.java b/app/src/main/java/foundation/e/blisslauncher/core/broadcast/WallpaperChangeReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..45bebbc83ff6f888b58430c40ac9b81387160260 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/broadcast/WallpaperChangeReceiver.java @@ -0,0 +1,50 @@ +package foundation.e.blisslauncher.core.broadcast; + +import android.app.WallpaperManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.IBinder; +import android.view.View; + +import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider; + +import static android.content.Context.WALLPAPER_SERVICE; + +public class WallpaperChangeReceiver extends BroadcastReceiver { + private final Context mContext; + private IBinder mWindowToken; + private boolean mRegistered; + private View mWorkspace; + + public WallpaperChangeReceiver(View workspace){ + this.mWorkspace = workspace; + this.mContext = mWorkspace.getContext(); + } + + @Override + public void onReceive(Context context, Intent intent) { + BlurWallpaperProvider.Companion.getInstance(context).updateAsync(); + updateOffset(); + } + + public void setWindowToken(IBinder token) { + mWindowToken = token; + if (mWindowToken == null && mRegistered) { + mWorkspace.getContext().unregisterReceiver(this); + mRegistered = false; + } else if (mWindowToken != null && !mRegistered) { + mWorkspace.getContext() + .registerReceiver(this, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); + onReceive(mWorkspace.getContext(), null); + mRegistered = true; + } + } + + private void updateOffset() { + WallpaperManager wm = (WallpaperManager) mContext.getSystemService(WALLPAPER_SERVICE); + wm.setWallpaperOffsets(mWindowToken, 0f, 0.5f); + wm.setWallpaperOffsetSteps(0.0f, 0.0f); + } +} diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java index d52bae8cc1e12b4deddbf2da72063678df535e1d..8f6f8d0d928b87c2c647f1a9c1a09b985c2d8c69 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissFrameLayout.java @@ -34,7 +34,6 @@ import foundation.e.blisslauncher.features.notification.DotRenderer; public class BlissFrameLayout extends FrameLayout { - private static final String TAG = "BlissFrameLayout"; private final Context mContext; private boolean hasBadge = false; @@ -66,16 +65,15 @@ public class BlissFrameLayout extends FrameLayout { } public BlissFrameLayout(Context context, - AttributeSet attrs) { + AttributeSet attrs) { this(context, attrs, 0); } public BlissFrameLayout(Context context, AttributeSet attrs, - int defStyleAttr) { + int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; init(); - } private void init() { @@ -86,8 +84,8 @@ public class BlissFrameLayout extends FrameLayout { } @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); } @Override @@ -148,7 +146,7 @@ public class BlissFrameLayout extends FrameLayout { bindApplicationItem((ApplicationItem) launcherItem); } else if (launcherItem.itemType == Constants.ITEM_TYPE_SHORTCUT) { bindShortcutItem((ShortcutItem) launcherItem); - }else if(launcherItem.itemType == Constants.ITEM_TYPE_FOLDER){ + } else if (launcherItem.itemType == Constants.ITEM_TYPE_FOLDER) { bindFolderItem((FolderItem) launcherItem); } } @@ -253,6 +251,4 @@ public class BlissFrameLayout extends FrameLayout { tags.add(applicationItem); setTag(tags); } - - } diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java index 45b4b3c84b47a695643739ee460619f157066199..fe7368df99ff6b3d7c2f7713e194afe5f4590cde 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlissInput.java @@ -17,7 +17,6 @@ public class BlissInput extends android.support.v7.widget.AppCompatEditText { super(context, attrs, defStyleAttr); } - @Override public boolean onDragEvent(DragEvent event) { // Without this drag/drop apps won't work on API <24. diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlurBackgroundView.kt b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlurBackgroundView.kt new file mode 100644 index 0000000000000000000000000000000000000000..717aa39754749f86286a3c340196c6b92ba9d176 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/BlurBackgroundView.kt @@ -0,0 +1,80 @@ +package foundation.e.blisslauncher.core.customviews + +import android.content.Context +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import android.util.AttributeSet +import android.view.View +import android.view.WindowInsets +import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider +import foundation.e.blisslauncher.core.blur.ShaderBlurDrawable +import foundation.e.blisslauncher.core.runOnMainThread + +class BlurBackgroundView(context: Context, attrs: AttributeSet?) : View(context, attrs), Insettable, + BlurWallpaperProvider.Listener { + + private val blurWallpaperProvider by lazy { BlurWallpaperProvider.getInstance(context) } + + private var fullBlurDrawable: ShaderBlurDrawable? = null + private var blurAlpha = 255 + + private val blurDrawableCallback by lazy { + object : Drawable.Callback { + override fun unscheduleDrawable(who: Drawable?, what: Runnable?) { + } + + override fun invalidateDrawable(who: Drawable?) { + runOnMainThread { invalidate() } + } + + override fun scheduleDrawable(who: Drawable?, what: Runnable?, `when`: Long) { + } + } + } + + init { + createFullBlurDrawable() + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + + BlurWallpaperProvider.getInstance(context).addListener(this) + fullBlurDrawable?.startListening() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + + BlurWallpaperProvider.getInstance(context).removeListener(this) + fullBlurDrawable?.stopListening() + } + + override fun onDraw(canvas: Canvas) { + fullBlurDrawable?.apply { + alpha = blurAlpha + this.draw(canvas) + } + } + + override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { + if (changed) { + fullBlurDrawable?.setBounds(left, top, right, bottom) + } + } + + private fun createFullBlurDrawable() { + fullBlurDrawable?.let { if (isAttachedToWindow) it.stopListening() } + fullBlurDrawable = blurWallpaperProvider.createDrawable().apply { + callback = blurDrawableCallback + setBounds(left, top, right, bottom) + if (isAttachedToWindow) startListening() + } + } + + override fun onEnabledChanged() { + createFullBlurDrawable() + } + + override fun setInsets(insets: WindowInsets) {} +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java index 069312688447756a6d1f70c3ce29a7e9a3c0aa38..126079e484c7e274e09b0592e7127dba2a904375 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/DockGridLayout.java @@ -1,16 +1,47 @@ package foundation.e.blisslauncher.core.customviews; import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; import android.util.AttributeSet; +import android.view.WindowInsets; import android.widget.GridLayout; import foundation.e.blisslauncher.BlissLauncher; import foundation.e.blisslauncher.core.DeviceProfile; +import foundation.e.blisslauncher.core.KotlinUtilsKt; +import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider; +import foundation.e.blisslauncher.core.blur.ShaderBlurDrawable; -public class DockGridLayout extends GridLayout { +public class DockGridLayout extends GridLayout implements Insettable, BlurWallpaperProvider.Listener { private Context mContext; + private final BlurWallpaperProvider blurWallpaperProvider; + private ShaderBlurDrawable fullBlurDrawable = null; + private int blurAlpha = 255; + + private final Drawable.Callback blurDrawableCallback = new Drawable.Callback() { + @Override + public void invalidateDrawable(@NonNull Drawable who) { + KotlinUtilsKt.runOnMainThread(() -> { + invalidate(); + return null; + }); + } + + @Override + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { + + } + + @Override + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { + + } + }; + public DockGridLayout(Context context) { this(context, null); } @@ -22,15 +53,68 @@ public class DockGridLayout extends GridLayout { public DockGridLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; + setWillNotDraw(false); + blurWallpaperProvider = BlurWallpaperProvider.Companion.getInstance(context); + createBlurDrawable(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + BlurWallpaperProvider.Companion.getInstance(mContext).addListener(this); + fullBlurDrawable.startListening(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + BlurWallpaperProvider.Companion.getInstance(mContext).removeListener(this); + fullBlurDrawable.stopListening(); } @Override - protected void onMeasure(int widthSpec, int heightSpec) { - super.onMeasure(widthSpec, heightSpec); + protected void onDraw(Canvas canvas) { + fullBlurDrawable.setAlpha(blurAlpha); + fullBlurDrawable.draw(canvas); + super.onDraw(canvas); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (changed) { + fullBlurDrawable.setBounds(left, top, right, bottom); + } + } + + @Override + public void setInsets(WindowInsets insets) { DeviceProfile deviceProfile = BlissLauncher.getApplication(mContext).getDeviceProfile(); - setMeasuredDimension(deviceProfile.getAvailableWidthPx(), - deviceProfile.hotseatCellHeightPx); - this.setPadding(deviceProfile.iconDrawablePaddingPx / 2, 0, - deviceProfile.iconDrawablePaddingPx / 2, 0); + InsettableRelativeLayout.LayoutParams lp = (InsettableRelativeLayout.LayoutParams) getLayoutParams(); + lp.height = deviceProfile.hotseatCellHeightPx + insets.getSystemWindowInsetBottom(); + setPadding(deviceProfile.iconDrawablePaddingPx / 2, 0, + deviceProfile.iconDrawablePaddingPx / 2, insets.getSystemWindowInsetBottom()); + setLayoutParams(lp); + } + + private void createBlurDrawable() { + if (isAttachedToWindow()) { + fullBlurDrawable.stopListening(); + } + fullBlurDrawable = blurWallpaperProvider.createDrawable(); + fullBlurDrawable.setCallback(blurDrawableCallback); + fullBlurDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom()); + if (isAttachedToWindow()) fullBlurDrawable.startListening(); + } + + @Override + public void onEnabledChanged() { + createBlurDrawable(); + } + + @Override + public void onWallpaperChanged() { } -} +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java index 05b11708a8c478af3e6e85900937952f00b0cd71..c2d52ccfca6f0df6dcbffab0c923e50edf5c62e0 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/HorizontalPager.java @@ -16,6 +16,7 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; +import android.view.WindowInsets; import android.widget.Scroller; import java.util.ArrayList; @@ -27,7 +28,7 @@ import foundation.e.blisslauncher.features.launcher.DetectSwipeGestureListener; import foundation.e.blisslauncher.features.launcher.LauncherActivity; import foundation.e.blisslauncher.features.launcher.OnSwipeDownListener; -public class HorizontalPager extends ViewGroup { +public class HorizontalPager extends ViewGroup implements Insettable{ private static final String TAG = "HorizontalPager"; private static final int INVALID_SCREEN = -1; public static final int SPEC_UNDEFINED = -1; @@ -61,6 +62,7 @@ public class HorizontalPager extends ViewGroup { private Set mListeners = new HashSet<>(); private boolean mIsUiCreated; private GestureDetectorCompat gestureDetectorCompat; + private WindowInsets insets; public HorizontalPager(Context context, AttributeSet attrs) { this(context, attrs, 0); @@ -147,6 +149,7 @@ public class HorizontalPager extends ViewGroup { @Override protected void dispatchDraw(Canvas canvas) { + Log.d(TAG, "dispatchDraw() called with: canvas = [" + canvas + "]"); final long drawingTime = getDrawingTime(); // todo be smarter about which children need drawing final int count = getChildCount(); @@ -156,9 +159,10 @@ public class HorizontalPager extends ViewGroup { for (OnScrollListener mListener : mListeners) { int adjustedScrollX = getScrollX() + pageWidthPadding(); - mListener.onScroll(adjustedScrollX); if (adjustedScrollX % pageWidth == 0) { mListener.onViewScrollFinished(adjustedScrollX / pageWidth); + } else { + mListener.onScroll(adjustedScrollX); } } } @@ -528,6 +532,26 @@ public class HorizontalPager extends ViewGroup { return mAllowLongPress; } + @Override + public void setInsets(WindowInsets insets) { + InsettableRelativeLayout.LayoutParams lp = (InsettableRelativeLayout.LayoutParams) getLayoutParams(); + lp.topMargin = insets.getSystemWindowInsetTop(); + setLayoutParams(lp); + updateInsetsForChildren(); + this.insets = insets; + } + + private void updateInsetsForChildren() { + int childCount = getChildCount(); + for (int index = 0; index < childCount; ++index){ + View child = getChildAt(index); + if(child instanceof Insettable) { + Log.d(TAG, "child is instance of insettable"); + ((Insettable) child).setInsets(insets); + } + } + } + public static class SavedState extends BaseSavedState { int currentScreen = -1; diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/Insettable.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/Insettable.java new file mode 100644 index 0000000000000000000000000000000000000000..91d686b7790e94b225a93e681041a9443139a4e5 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/Insettable.java @@ -0,0 +1,13 @@ +package foundation.e.blisslauncher.core.customviews; + +import android.view.View; +import android.view.WindowInsets; + +/** + * Allows the implementing {@link View} to not draw underneath system bars. + * e.g., notification bar on top and home key area on the bottom. + */ +public interface Insettable { + + void setInsets(WindowInsets insets); +} diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableRelativeLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableRelativeLayout.java new file mode 100644 index 0000000000000000000000000000000000000000..9342c9143f8c16826e978be76a9d40c4a7dac36f --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableRelativeLayout.java @@ -0,0 +1,87 @@ +package foundation.e.blisslauncher.core.customviews; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowInsets; +import android.widget.RelativeLayout; + +import foundation.e.blisslauncher.R; + +public class InsettableRelativeLayout extends RelativeLayout { + + protected WindowInsets mInsets; + + + public InsettableRelativeLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + updateChildInsets(insets); + mInsets = new WindowInsets(insets); + return insets; + } + + private void updateChildInsets(WindowInsets insets) { + if(insets == null) return; + int childCount = getChildCount(); + for (int index = 0; index < childCount; ++index){ + View child = getChildAt(index); + if(child instanceof Insettable) { + ((Insettable) child).setInsets(insets); + } + } + } + + @Override + public LayoutParams generateLayoutParams(AttributeSet attrs) { + return new InsettableRelativeLayout.LayoutParams(getContext(), attrs); + } + + @Override + protected LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + } + + // Override to allow type-checking of LayoutParams. + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof InsettableRelativeLayout.LayoutParams; + } + + @Override + protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + return new LayoutParams(p); + } + + public static class LayoutParams extends RelativeLayout.LayoutParams { + public boolean ignoreInsets = false; + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + TypedArray a = c.obtainStyledAttributes(attrs, + R.styleable.InsettableFrameLayout_Layout); + ignoreInsets = a.getBoolean( + R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false); + a.recycle(); + } + + public LayoutParams(int width, int height) { + super(width, height); + } + + public LayoutParams(ViewGroup.LayoutParams lp) { + super(lp); + } + } + + @Override + public void onViewAdded(View child) { + super.onViewAdded(child); + updateChildInsets(mInsets); + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableScrollLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableScrollLayout.java new file mode 100644 index 0000000000000000000000000000000000000000..438e4b29c9027a5a6fd99321a553e6023896f545 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/InsettableScrollLayout.java @@ -0,0 +1,32 @@ +package foundation.e.blisslauncher.core.customviews; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.WindowInsets; +import android.widget.ScrollView; + +public class InsettableScrollLayout extends ScrollView implements Insettable { + + public InsettableScrollLayout(@NonNull Context context) { + super(context); + } + + public InsettableScrollLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public InsettableScrollLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public void setInsets(WindowInsets insets) { + int top = getPaddingTop(); + int left = getPaddingLeft(); + int right = getPaddingRight(); + int bottom = getPaddingBottom(); + setPadding(left, top, right, bottom + insets.getSystemWindowInsetBottom()); + } +} diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java index 85cca4514a3d3c956147a5e388b51dd8a3f67285..6d6ac74198d6275a8013f0824aaed6ccd200749f 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareFrameLayout.java @@ -11,18 +11,20 @@ import android.widget.FrameLayout; */ public class SquareFrameLayout extends FrameLayout { + public SquareFrameLayout(@NonNull Context context) { - super(context); + this(context, null); } public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); + this(context, attrs, 0); } public SquareFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); + setWillNotDraw(false); } @Override diff --git a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java index ef576dcb26563efca0a4263c8551b427da550cac..a13a834178b5f8fcae38fbad9eb90d72d38adaac 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/customviews/SquareImageView.java @@ -9,28 +9,20 @@ import android.util.AttributeSet; public class SquareImageView extends android.support.v7.widget.AppCompatImageView { - public SquareImageView(Context context) { - super(context); - } - - public SquareImageView(Context context, AttributeSet attrs) { - super(context, attrs); + this(context, null); } - public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); + public SquareImageView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int width = getMeasuredWidth(); int height = getMeasuredHeight(); int size = width < height ? width : height; setMeasuredDimension(size, size); } - - } \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java b/app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..367db09fb02ce557b50b68bc88a760fb47a77a07 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/executors/MainThreadExecutor.java @@ -0,0 +1,52 @@ +package foundation.e.blisslauncher.core.executors; + +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.NonNull; + +import java.util.List; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.TimeUnit; + +public class MainThreadExecutor extends AbstractExecutorService { + + private final Handler mHandler; + + public MainThreadExecutor() { + mHandler = new Handler(Looper.getMainLooper()); + } + @Override + public void shutdown() { + throw new UnsupportedOperationException(); + } + + @NonNull + @Override + public List shutdownNow() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isShutdown() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public boolean awaitTermination(long timeout, @NonNull TimeUnit unit) throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public void execute(@NonNull Runnable runnable) { + if (mHandler.getLooper() == Looper.myLooper()) { + runnable.run(); + } else { + mHandler.post(runnable); + } + } +} diff --git a/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java b/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java index 5beeee8546bb7151d0e56ec11b20a5bdfee429cb..5fc02caba4fdd5d5dc108fdcd244f6a42a6df8f4 100755 --- a/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java +++ b/app/src/main/java/foundation/e/blisslauncher/core/utils/GraphicsUtil.java @@ -130,7 +130,7 @@ public class GraphicsUtil { Bitmap mergedBitmap = Bitmap.createBitmap(width, height, Bitmap .Config.ARGB_8888); Canvas canvas = new Canvas(mergedBitmap); - canvas.drawColor(isFolder ? Color.WHITE : getDominantColor(bitmap)); + canvas.drawColor(isFolder ? 0x88D3D3D3 : getDominantColor(bitmap)); Paint paint = new Paint( Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG); diff --git a/app/src/main/java/foundation/e/blisslauncher/core/utils/SingletonHolder.kt b/app/src/main/java/foundation/e/blisslauncher/core/utils/SingletonHolder.kt new file mode 100644 index 0000000000000000000000000000000000000000..7a9b470ab958b1997e25e6a3023453a048388749 --- /dev/null +++ b/app/src/main/java/foundation/e/blisslauncher/core/utils/SingletonHolder.kt @@ -0,0 +1,55 @@ +package foundation.e.blisslauncher.core.utils + +import android.content.Context +import android.os.Looper +import foundation.e.blisslauncher.core.executors.MainThreadExecutor +import java.util.concurrent.Callable +import java.util.concurrent.ExecutionException + +open class SingletonHolder(creator: (A) -> T) { + private var creator: ((A) -> T)? = creator + @Volatile + private var instance: T? = null + + open fun getInstance(arg: A): T { + val i = instance + if (i != null) { + return i + } + + return synchronized(this) { + val i2 = instance + if (i2 != null) { + i2 + } else { + val created = creator!!(arg) + instance = created + creator = null + created + } + } + } + + protected fun dangerousGetInstance() = instance +} + + +fun ensureOnMainThread(creator: (A) -> T): (A) -> T { + return { it -> + if (Looper.myLooper() == Looper.getMainLooper()) { + creator(it) + } else { + try { + MainThreadExecutor().submit(Callable { creator(it) }).get() + } catch (e: InterruptedException) { + throw RuntimeException(e) + } catch (e: ExecutionException) { + throw RuntimeException(e) + } + + } + } +} +fun useApplicationContext(creator: (Context) -> T): (Context) -> T { + return { it -> creator(it.applicationContext) } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java b/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java index 854839cd4b5a1be2e3e043a1429434a33efe8aa3..fe221fcab4628c7a6dda0201d2e680856a205236 100644 --- a/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java +++ b/app/src/main/java/foundation/e/blisslauncher/features/launcher/AppProvider.java @@ -297,28 +297,15 @@ public class AppProvider { if (databaseItem.itemType == Constants.ITEM_TYPE_APPLICATION) { ApplicationItem applicationItem = mApplicationItems.get(databaseItem.id); if (applicationItem == null) { - UserHandle userHandle = null; - int index = databaseItem.id.lastIndexOf((int) '/'); - if (index > -1) { - String serialText = databaseItem.id.substring(index); - try { - long serial = Long.parseLong(serialText); - userHandle = new UserHandle(serial, Process.myUserHandle()); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - } - if(userHandle == null){ - userHandle = new UserHandle(); - } + UserHandle userHandle = new UserHandle(); if (isAppOnSdcard(databaseItem.packageName, userHandle) || !isSdCardReady) { Log.d(TAG, "Missing package: " + databaseItem.packageName); Log.d(TAG, "Is App on Sdcard " + isAppOnSdcard(databaseItem.packageName, databaseItem.user)); Log.d(TAG, "Is Sdcard ready " + isSdCardReady); - pendingPackages.addToList(userHandle, databaseItem.packageName); applicationItem = new ApplicationItem(); + applicationItem.id = databaseItem.id; applicationItem.title = databaseItem.title; applicationItem.user = userHandle; applicationItem.componentName = databaseItem.getTargetComponent(); diff --git a/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java b/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java index cf00c23cf96855aace279b39145e776d9fdf7d66..05786c476b15451f61163c7297bcb2085ba5188a 100755 --- a/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java +++ b/app/src/main/java/foundation/e/blisslauncher/features/launcher/LauncherActivity.java @@ -4,14 +4,13 @@ import android.Manifest; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; -import android.animation.ArgbEvaluator; import android.animation.LayoutTransition; import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; +import android.app.WallpaperManager; import android.app.usage.UsageStats; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; @@ -19,11 +18,12 @@ import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; -import android.graphics.Color; +import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -38,7 +38,7 @@ import android.os.StrictMode; import android.os.UserManager; import android.provider.Settings; import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; +import android.support.v4.app.ActivityCompat; import android.support.v4.content.LocalBroadcastManager; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; @@ -48,16 +48,15 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextWatcher; +import android.util.Log; import android.view.DragEvent; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; import android.view.animation.AnimationUtils; -import android.view.animation.DecelerateInterpolator; import android.view.animation.LinearInterpolator; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; @@ -66,7 +65,6 @@ import android.widget.GridLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; -import android.widget.ScrollView; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; @@ -90,13 +88,17 @@ import foundation.e.blisslauncher.core.Alarm; import foundation.e.blisslauncher.core.DeviceProfile; import foundation.e.blisslauncher.core.Preferences; import foundation.e.blisslauncher.core.Utilities; +import foundation.e.blisslauncher.core.blur.BlurWallpaperProvider; import foundation.e.blisslauncher.core.broadcast.ManagedProfileBroadcastReceiver; import foundation.e.blisslauncher.core.broadcast.TimeChangeBroadcastReceiver; +import foundation.e.blisslauncher.core.broadcast.WallpaperChangeReceiver; import foundation.e.blisslauncher.core.customviews.BlissDragShadowBuilder; import foundation.e.blisslauncher.core.customviews.BlissFrameLayout; import foundation.e.blisslauncher.core.customviews.BlissInput; import foundation.e.blisslauncher.core.customviews.DockGridLayout; import foundation.e.blisslauncher.core.customviews.HorizontalPager; +import foundation.e.blisslauncher.core.customviews.InsettableRelativeLayout; +import foundation.e.blisslauncher.core.customviews.InsettableScrollLayout; import foundation.e.blisslauncher.core.customviews.PageIndicatorLinearLayout; import foundation.e.blisslauncher.core.customviews.RoundedWidgetView; import foundation.e.blisslauncher.core.customviews.SquareFrameLayout; @@ -149,12 +151,14 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; public class LauncherActivity extends AppCompatActivity implements - AutoCompleteAdapter.OnSuggestionClickListener, OnSwipeDownListener { + AutoCompleteAdapter.OnSuggestionClickListener, + OnSwipeDownListener { public static final int REORDER_TIMEOUT = 350; private final static int EMPTY_LOCATION_DRAG = -999; private static final int REQUEST_PERMISSION_CALL_PHONE = 14; private static final int REQUEST_LOCATION_SOURCE_SETTING = 267; + private static final int STORAGE_PERMISSION_REQUEST_CODE = 586; public static boolean longPressed; private final Alarm mReorderAlarm = new Alarm(); private final Alarm mDockReorderAlarm = new Alarm(); @@ -198,8 +202,8 @@ public class LauncherActivity extends AppCompatActivity implements private List mUsageStats; private FrameLayout swipeSearchContainer; - private RelativeLayout workspace; - private View backgroundLayer; + private InsettableRelativeLayout workspace; + private View blurLayer; // Blur layer for folders and search container. private BroadcastReceiver mWeatherReceiver = new BroadcastReceiver() { @Override @@ -212,14 +216,12 @@ public class LauncherActivity extends AppCompatActivity implements private FolderItem activeFolder; private BlissFrameLayout activeFolderView; private int activeDot; - private int statusBarHeight; private static final String TAG = "LauncherActivity"; private AppWidgetManager mAppWidgetManager; private WidgetHost mAppWidgetHost; private LinearLayout widgetContainer; - ArgbEvaluator argbEvaluator = new ArgbEvaluator(); private FrameLayout widgetsPage; private SearchInputDisposableObserver searchDisposableObserver; private AnimatorSet currentAnimator; @@ -228,22 +230,25 @@ public class LauncherActivity extends AppCompatActivity implements private float startScaleFinal; private boolean showSwipeSearch; private RoundedWidgetView activeRoundedWidgetView; - private boolean widgetResizeContainerVisible; // EventRelay to handle pass events related to app addition, deletion or changed. private EventRelay events; private ManagedProfileBroadcastReceiver managedProfileReceiver; - private boolean forceReload; - private AppProvider appProvider; private int moveTo; + private WallpaperChangeReceiver wallpaperChangeReceiver; + + public static LauncherActivity getLauncher(Context context) { + if (context instanceof LauncherActivity) { + return (LauncherActivity) context; + } + return ((LauncherActivity) ((ContextWrapper) context).getBaseContext()); + } @SuppressLint("InflateParams") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - appProvider = BlissLauncher.getApplication(this).getAppProvider(); - prepareBroadcastReceivers(); mDeviceProfile = BlissLauncher.getApplication(this).getDeviceProfile(); @@ -253,9 +258,13 @@ public class LauncherActivity extends AppCompatActivity implements mLauncherView = LayoutInflater.from(this).inflate( foundation.e.blisslauncher.R.layout.activity_main, null); + setContentView(mLauncherView); setupViews(); + WallpaperManager wm = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); + wm.suggestDesiredDimensions(mDeviceProfile.widthPx, mDeviceProfile.heightPx); + mProgressBar.setVisibility(View.VISIBLE); if (Preferences.shouldAskForNotificationAccess(this)) { @@ -282,6 +291,10 @@ public class LauncherActivity extends AppCompatActivity implements } } + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE); + } + // Start NotificationService to add count badge to Icons Intent notificationServiceIntent = new Intent(this, NotificationService.class); startService(notificationServiceIntent); @@ -291,13 +304,21 @@ public class LauncherActivity extends AppCompatActivity implements private void setupViews() { workspace = mLauncherView.findViewById(R.id.workspace); + wallpaperChangeReceiver = new WallpaperChangeReceiver(workspace); + workspace.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View v) { + wallpaperChangeReceiver.setWindowToken(v.getWindowToken()); + } + + @Override + public void onViewDetachedFromWindow(View v) { + wallpaperChangeReceiver.setWindowToken(null); + } + }); mHorizontalPager = mLauncherView.findViewById(R.id.pages_container); - backgroundLayer = mLauncherView.findViewById(R.id.background_layer); - statusBarHeight = 0; - int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); - if (resourceId > 0) { - statusBarHeight = getResources().getDimensionPixelSize(resourceId); - } + blurLayer = mLauncherView.findViewById(R.id.blur_layer); + blurLayer.setAlpha(0f); mDock = mLauncherView.findViewById(R.id.dock); mIndicator = mLauncherView.findViewById(R.id.page_indicator); @@ -314,7 +335,8 @@ public class LauncherActivity extends AppCompatActivity implements wobbleAnimation = AnimationUtils.loadAnimation(this, R.anim.wobble); wobbleReverseAnimation = AnimationUtils.loadAnimation(this, R.anim.wobble_reverse); getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); workspace.setOnClickListener(v -> { if (swipeSearchContainer.getVisibility() == VISIBLE) { @@ -1039,7 +1061,7 @@ public class LauncherActivity extends AppCompatActivity implements return false; }); mFolderTitleInput.setOnClickListener(view -> mFolderTitleInput.setCursorVisible(true)); - mFolderWindowContainer.setOnClickListener(view -> hideFolderWindowContainer()); + mFolderWindowContainer.setOnClickListener(view -> returnToHomeScreen()); } public void hideKeyboard(View view) { @@ -1070,8 +1092,6 @@ public class LauncherActivity extends AppCompatActivity implements * updated */ private void createPageChangeListener() { - Integer color1 = Color.TRANSPARENT; - Integer color2 = ContextCompat.getColor(this, R.color.dark_grey_44); mHorizontalPager.addOnScrollListener(new HorizontalPager.OnScrollListener() { boolean isViewScrolling = true; @@ -1080,8 +1100,8 @@ public class LauncherActivity extends AppCompatActivity implements if (scrollX >= 0 && scrollX < mDeviceProfile.availableWidthPx) { float fraction = (float) (mDeviceProfile.availableWidthPx - scrollX) / mDeviceProfile.availableWidthPx; - mHorizontalPager.setBackgroundColor( - (Integer) argbEvaluator.evaluate(fraction, color1, color2)); + int radius = (int) (fraction * 18); + blurLayer.setAlpha(fraction); } if (isViewScrolling) { dragDropEnabled = false; @@ -1090,11 +1110,11 @@ public class LauncherActivity extends AppCompatActivity implements @Override public void onViewScrollFinished(int page) { - mHorizontalPager.setBackgroundColor(page == 0 ? color2 : color1); isViewScrolling = false; - if (currentPageNumber != page) { + blurLayer.setAlpha((page == 0 || mFolderWindowContainer.getVisibility() == VISIBLE) ? 1f : 0f); + if (currentPageNumber != page) { currentPageNumber = page; // Remove mIndicator and mDock from widgets page, and make them // reappear when user swipes to the first apps page @@ -1218,7 +1238,7 @@ public class LauncherActivity extends AppCompatActivity implements grid.setRowCount(mDeviceProfile.numRows); grid.setLayoutTransition(getDefaultLayoutTransition()); grid.setPadding(mDeviceProfile.iconDrawablePaddingPx / 2, - (int) (statusBarHeight + Utilities.pxFromDp(8, this)), + (int) (Utilities.pxFromDp(8, this)), mDeviceProfile.iconDrawablePaddingPx / 2, 0); return grid; } @@ -1227,12 +1247,12 @@ public class LauncherActivity extends AppCompatActivity implements widgetsPage = (FrameLayout) getLayoutInflater().inflate(R.layout.widgets_page, mHorizontalPager, false); widgetContainer = widgetsPage.findViewById(R.id.widget_container); - widgetsPage.setPadding(0, - (int) (statusBarHeight + Utilities.pxFromDp(8, this)), - 0, 0); + /*widgetsPage.setPadding(0, + (int) (Utilities.pxFromDp(8, this)), + 0, 0);*/ mHorizontalPager.addView(widgetsPage, 0); widgetsPage.setOnDragListener(null); - ScrollView scrollView = widgetsPage.findViewById(R.id.widgets_scroll_container); + InsettableScrollLayout scrollView = widgetsPage.findViewById(R.id.widgets_scroll_container); scrollView.setOnTouchListener((v, event) -> { if (widgetsPage.findViewById(R.id.widget_resizer_container).getVisibility() == VISIBLE) { @@ -1240,6 +1260,7 @@ public class LauncherActivity extends AppCompatActivity implements } return false; }); + scrollView.post(() -> scrollView.setInsets(workspace.getRootWindowInsets())); currentPageNumber = 1; mHorizontalPager.setCurrentPage(currentPageNumber); @@ -1426,6 +1447,12 @@ public class LauncherActivity extends AppCompatActivity implements .setAction(WeatherUpdateService.ACTION_FORCE_UPDATE)); } } + } else if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) { + if (grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Log.d(TAG, "Storage permission granted"); + BlurWallpaperProvider.Companion.getInstance(getApplicationContext()).updateAsync(); + } } } @@ -2723,46 +2750,57 @@ public class LauncherActivity extends AppCompatActivity implements startBounds.bottom += deltaHeight; } - mFolderWindowContainer.setVisibility(View.VISIBLE); - - // Set the pivot point for SCALE_X and SCALE_Y transformations - // to the top-left corner of the zoomed-in view (the default - // is the center of the view). - mFolderWindowContainer.setPivotX(0f); - mFolderWindowContainer.setPivotY(0f); - // Construct and run the parallel animation of the four translation and // scale properties (X, Y, SCALE_X, and SCALE_Y). AnimatorSet set = new AnimatorSet(); - ValueAnimator valueAnimator = ValueAnimator.ofArgb(Color.parseColor("#00000000"), - Color.parseColor("#44000000")); - valueAnimator.addUpdateListener(animation -> backgroundLayer.setBackgroundColor( - (Integer) animation.getAnimatedValue())); - set - .play(ObjectAnimator.ofFloat(mFolderWindowContainer, View.X, - startBounds.left, finalBounds.left)) + /*ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 18); + valueAnimator.addUpdateListener(animation -> + BlurWallpaperProvider.getInstance(this).blur((Integer) animation.getAnimatedValue()));*/ + set.play(ObjectAnimator.ofFloat(mFolderWindowContainer, View.X, + startBounds.left, finalBounds.left)) .with(ObjectAnimator.ofFloat(mFolderWindowContainer, View.Y, startBounds.top, finalBounds.top)) .with(ObjectAnimator.ofFloat(mFolderWindowContainer, View.SCALE_X, startScale, 1f)) .with(ObjectAnimator.ofFloat(mFolderWindowContainer, View.SCALE_Y, startScale, 1f)) - .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 0f, 1f)) - .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 1f, 0f)) - .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 1f, 0f)) - .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f, 0f)); - + .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 1f)) + .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 0f)) + .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 0f)) + .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 0f)); set.setDuration(300); - set.setInterpolator(new DecelerateInterpolator()); + set.setInterpolator(new LinearInterpolator()); set.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + super.onAnimationStart(animation); + mFolderWindowContainer.setVisibility(View.VISIBLE); + + // Set the pivot point for SCALE_X and SCALE_Y transformations + // to the top-left corner of the zoomed-in view (the default + // is the center of the view). + mFolderWindowContainer.setPivotX(0f); + mFolderWindowContainer.setPivotY(0f); + //BlurWallpaperProvider.getInstance(LauncherActivity.this).clear(); + } + @Override public void onAnimationEnd(Animator animation) { currentAnimator = null; + blurLayer.setAlpha(1f); + mHorizontalPager.setAlpha(0f); + mIndicator.setAlpha(0f); + mDock.setAlpha(0f); } @Override public void onAnimationCancel(Animator animation) { currentAnimator = null; + mFolderWindowContainer.setVisibility(GONE); + blurLayer.setAlpha(0f); + mHorizontalPager.setAlpha(1f); + mIndicator.setAlpha(1f); + mDock.setAlpha(1f); } }); set.start(); @@ -2782,6 +2820,15 @@ public class LauncherActivity extends AppCompatActivity implements } + private Bitmap getLauncherView() { + View view = getWindow().getDecorView().getRootView(); + view.setDrawingCacheEnabled(true); + view.buildDrawingCache(true); + Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache()); + view.setDrawingCacheEnabled(false); + return bitmap; + } + /** * Hides folder window with an animation */ @@ -2796,10 +2843,9 @@ public class LauncherActivity extends AppCompatActivity implements // Animate the four positioning/sizing properties in parallel, // back to their original values. AnimatorSet set = new AnimatorSet(); - ValueAnimator valueAnimator = ValueAnimator.ofArgb(Color.parseColor("#44000000"), - Color.parseColor("#00000000")); - valueAnimator.addUpdateListener(animation -> mFolderWindowContainer.setBackgroundColor( - (Integer) animation.getAnimatedValue())); + /*ValueAnimator valueAnimator = ValueAnimator.ofInt(18, 0); + valueAnimator.addUpdateListener(animation -> + BlurWallpaperProvider.getInstance(this).blurWithLauncherView(mergedView, (Integer) animation.getAnimatedValue()));*/ set.play(ObjectAnimator .ofFloat(mFolderWindowContainer, View.X, startBounds.left)) .with(ObjectAnimator @@ -2811,23 +2857,40 @@ public class LauncherActivity extends AppCompatActivity implements .with(ObjectAnimator .ofFloat(mFolderWindowContainer, View.SCALE_Y, startScaleFinal)) - .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 1f, 0f)) - .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 0f, 1f)) - .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 0f, 1f)) - .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 0f, 1f)); + .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 0f)) + .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 1f)) + .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 1f)) + .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f)); + //.with(valueAnimator); set.setDuration(300); - set.setInterpolator(new AccelerateInterpolator()); + set.setInterpolator(new LinearInterpolator()); set.addListener(new AnimatorListenerAdapter() { + + @Override + public void onAnimationStart(Animator animation) { + mHorizontalPager.setVisibility(VISIBLE); + mDock.setVisibility(VISIBLE); + mIndicator.setVisibility(VISIBLE); + } + @Override public void onAnimationEnd(Animator animation) { mFolderWindowContainer.setVisibility(View.GONE); currentAnimator = null; + blurLayer.setAlpha(0f); + mHorizontalPager.setAlpha(1f); + mIndicator.setAlpha(1f); + mDock.setAlpha(1f); } @Override public void onAnimationCancel(Animator animation) { mFolderWindowContainer.setVisibility(View.GONE); currentAnimator = null; + blurLayer.setAlpha(0f); + mHorizontalPager.setAlpha(1f); + mIndicator.setAlpha(1f); + mDock.setAlpha(1f); } }); set.start(); @@ -2847,10 +2910,18 @@ public class LauncherActivity extends AppCompatActivity implements && mFolderWindowContainer.getVisibility() != View.VISIBLE && (activeRoundedWidgetView == null || !activeRoundedWidgetView.isWidgetActivated()); + if (alreadyOnHome) { + returnToHomeScreen(); + } + if (shouldMoveToDefaultScreen) { + mHorizontalPager.setVisibility(VISIBLE); + mHorizontalPager.setAlpha(1f); + mDock.setVisibility(VISIBLE); + mDock.setAlpha(1f); + mIndicator.setVisibility(VISIBLE); + mIndicator.setAlpha(1f); mHorizontalPager.setCurrentPage(1); - } else if (alreadyOnHome) { - returnToHomeScreen(); } } @@ -2879,12 +2950,15 @@ public class LauncherActivity extends AppCompatActivity implements currentAnimator.cancel(); } AnimatorSet set = new AnimatorSet(); + /*ValueAnimator blurAnimator = ValueAnimator.ofInt(blurRadius, 18); + blurAnimator.addUpdateListener(animation -> + BlurWallpaperProvider.getInstance(this).blurWithLauncherView(mergedView, (Integer) animation.getAnimatedValue()));*/ set.play(ObjectAnimator.ofFloat(swipeSearchContainer, View.TRANSLATION_Y, 0)) - .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 1f)) + .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 1f)) .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 0f)) .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 0f)) .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 0f)); - set.setDuration(200); + set.setDuration(300); set.setInterpolator(new LinearInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override @@ -2892,18 +2966,22 @@ public class LauncherActivity extends AppCompatActivity implements super.onAnimationCancel(animation); currentAnimator = null; swipeSearchContainer.setVisibility(GONE); + blurLayer.setAlpha(0f); mHorizontalPager.setVisibility(VISIBLE); - mIndicator.setVisibility(VISIBLE); mDock.setVisibility(VISIBLE); + mIndicator.setVisibility(VISIBLE); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); currentAnimator = null; + + blurLayer.setAlpha(1f); mHorizontalPager.setVisibility(GONE); - mIndicator.setVisibility(GONE); mDock.setVisibility(GONE); + mIndicator.setVisibility(GONE); + BlissInput searchEditText = swipeSearchContainer.findViewById( R.id.search_input); ImageView clearSuggestions = swipeSearchContainer.findViewById( @@ -2989,28 +3067,31 @@ public class LauncherActivity extends AppCompatActivity implements AnimatorSet set = new AnimatorSet(); set.play(ObjectAnimator.ofFloat(swipeSearchContainer, View.TRANSLATION_Y, -swipeSearchContainer.getHeight())) - .with(ObjectAnimator.ofFloat(backgroundLayer, View.ALPHA, 0f)) .with(ObjectAnimator.ofFloat(mHorizontalPager, View.ALPHA, 1f)) .with(ObjectAnimator.ofFloat(mIndicator, View.ALPHA, 1f)) - .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f)); - set.setDuration(200); + .with(ObjectAnimator.ofFloat(mDock, View.ALPHA, 1f)) + .with(ObjectAnimator.ofFloat(blurLayer, View.ALPHA, 0f)); + set.setDuration(300); set.setInterpolator(new LinearInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); mHorizontalPager.setVisibility(VISIBLE); - mIndicator.setVisibility(VISIBLE); mDock.setVisibility(VISIBLE); + mIndicator.setVisibility(VISIBLE); + //BlurWallpaperProvider.getInstance(LauncherActivity.this).clear(); } @Override public void onAnimationCancel(Animator animation) { super.onAnimationCancel(animation); currentAnimator = null; + swipeSearchContainer.setVisibility(VISIBLE); + blurLayer.setAlpha(1f); mHorizontalPager.setVisibility(GONE); - mIndicator.setVisibility(GONE); mDock.setVisibility(GONE); + mIndicator.setVisibility(GONE); } @Override @@ -3018,6 +3099,7 @@ public class LauncherActivity extends AppCompatActivity implements super.onAnimationEnd(animation); currentAnimator = null; swipeSearchContainer.setVisibility(GONE); + blurLayer.setAlpha(0f); if (searchDisposableObserver != null && !searchDisposableObserver.isDisposed()) { searchDisposableObserver.dispose(); @@ -3050,7 +3132,7 @@ public class LauncherActivity extends AppCompatActivity implements mHorizontalPager.setAlpha(deltaAlpha); mIndicator.setAlpha(deltaAlpha); mDock.setAlpha(deltaAlpha); - backgroundLayer.setAlpha(1 - deltaAlpha); + blurLayer.setAlpha(1 - deltaAlpha); } if (translateBy >= swipeSearchContainer.getHeight() / 2) { @@ -3088,7 +3170,7 @@ public class LauncherActivity extends AppCompatActivity implements AnimatorSet set = new AnimatorSet(); set.play(ObjectAnimator.ofFloat(widgetResizeContainer, View.Y, mDeviceProfile.availableHeightPx, - mDeviceProfile.availableHeightPx - Utilities.pxFromDp(24, this))); + mDeviceProfile.availableHeightPx - Utilities.pxFromDp(48, this))); set.setDuration(200); set.setInterpolator(new LinearInterpolator()); set.addListener(new AnimatorListenerAdapter() { @@ -3128,7 +3210,6 @@ public class LauncherActivity extends AppCompatActivity implements int defaultHeight = activeRoundedWidgetView.getHeight(); int currentProgress = (defaultHeight - minHeight) * 100 / (maxHeight - minHeight); - seekBar.setMin(1); seekBar.setMax(100); seekBar.setProgress(currentProgress); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { diff --git a/app/src/main/res/drawable/folder_window.xml b/app/src/main/res/drawable/folder_window.xml index fdf7c5c0f5191d7fdd519ab73fc1cfc9d454c463..ca9e4d75f53c6134780eec773437ea934b07642c 100755 --- a/app/src/main/res/drawable/folder_window.xml +++ b/app/src/main/res/drawable/folder_window.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index fa3be947194b132a150c7adca202f77c1d4f35ef..fd86f7d15c44e02f176536bd88d0c0d46e925e99 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,18 +1,17 @@ - - + android:layout_height="match_parent" /> @@ -108,4 +106,4 @@ android:layout_centerInParent="true" android:visibility="gone" /> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/widgets_page.xml b/app/src/main/res/layout/widgets_page.xml index 988aae0b48d3ea84025d9b9dae9b12e19f45508d..30cc0f5d8b7b597e08f3a9b38974b36225abd8cb 100755 --- a/app/src/main/res/layout/widgets_page.xml +++ b/app/src/main/res/layout/widgets_page.xml @@ -1,17 +1,18 @@ - + + - + + layout="@layout/layout_weather_info" /> + + android:orientation="vertical" />