Lawnchair: Port Lawnfeed/Bridge to A11
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@
|
||||
attributes and intent filters the same
|
||||
-->
|
||||
<activity
|
||||
android:name="com.android.launcher3.Launcher"
|
||||
android:name="ch.deletescape.lawnchair.LawnchairLauncher"
|
||||
android:launchMode="singleTask"
|
||||
android:clearTaskOnLaunch="true"
|
||||
android:stateNotNeeded="true"
|
||||
|
||||
@@ -189,6 +189,7 @@ android {
|
||||
|
||||
lawn {
|
||||
java.srcDirs = ['src_flags', 'src_shortcuts_overrides', 'lawnchair/src']
|
||||
aidl.srcDirs = ['lawnchair/aidl']
|
||||
res.srcDirs = ['lawnchair/res']
|
||||
manifest.srcFile "lawnchair/AndroidManifest.xml"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import com.google.android.libraries.launcherclient.ILauncherOverlayCallback;
|
||||
|
||||
interface ILauncherOverlay {
|
||||
|
||||
oneway void startScroll();
|
||||
|
||||
oneway void onScroll(in float progress);
|
||||
|
||||
oneway void endScroll();
|
||||
|
||||
oneway void windowAttached(in LayoutParams lp, in ILauncherOverlayCallback cb, in int flags);
|
||||
|
||||
oneway void windowDetached(in boolean isChangingConfigurations);
|
||||
|
||||
oneway void closeOverlay(in int flags);
|
||||
|
||||
oneway void onPause();
|
||||
|
||||
oneway void onResume();
|
||||
|
||||
oneway void openOverlay(in int flags);
|
||||
|
||||
oneway void requestVoiceDetection(in boolean start);
|
||||
|
||||
String getVoiceSearchLanguage();
|
||||
|
||||
boolean isVoiceDetectionRunning();
|
||||
|
||||
boolean hasOverlayContent();
|
||||
|
||||
oneway void windowAttached2(in Bundle bundle, in ILauncherOverlayCallback cb);
|
||||
|
||||
oneway void unusedMethod();
|
||||
|
||||
oneway void setActivityState(in int flags);
|
||||
|
||||
boolean startSearch(in byte[] data, in Bundle bundle);
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
interface ILauncherOverlayCallback {
|
||||
|
||||
oneway void overlayScrollChanged(float progress);
|
||||
|
||||
oneway void overlayStatusChanged(int status);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<integer name="bridge_signature_hash">0xB662CC2F</integer>
|
||||
<string name="bridge_version" translatable="false">v3</string>
|
||||
<integer name="lawnfeed_signature_hash">0x7F7A957A</integer>
|
||||
</resources>
|
||||
@@ -19,37 +19,57 @@ package ch.deletescape.lawnchair
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo.FLAG_SYSTEM
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Process
|
||||
import android.util.Log
|
||||
import ch.deletescape.lawnchair.util.SingletonHolder
|
||||
import ch.deletescape.lawnchair.util.preferences.LawnchairPreferences
|
||||
import com.android.launcher3.BuildConfig
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.config.FeatureFlags
|
||||
import com.android.launcher3.Utilities
|
||||
|
||||
class FeedBridge(private val context: Context) {
|
||||
|
||||
private val bridgePackages = listOf(
|
||||
PixelBridgeInfo("com.google.android.apps.nexuslauncher", R.integer.bridge_signature_hash),
|
||||
BridgeInfo("ch.deletescape.lawnchair.lawnfeed", R.integer.lawnfeed_signature_hash))
|
||||
private val shouldUseFeed = context.applicationInfo.flags and FLAG_SYSTEM == 0
|
||||
private val prefs = LawnchairPreferences.getInstance(context)
|
||||
private val bridgePackages by lazy {
|
||||
listOf(
|
||||
PixelBridgeInfo("com.google.android.apps.nexuslauncher", R.integer.bridge_signature_hash),
|
||||
BridgeInfo("ch.deletescape.lawnchair.lawnfeed", R.integer.lawnfeed_signature_hash))
|
||||
}
|
||||
|
||||
fun resolveBridge(): BridgeInfo? {
|
||||
if (!useBridge) return null
|
||||
val customBridge = customBridgeOrNull()
|
||||
if (customBridge != null) {
|
||||
return customBridge
|
||||
}
|
||||
if (!shouldUseFeed) return null
|
||||
return bridgePackages.firstOrNull { it.isAvailable() }
|
||||
}
|
||||
|
||||
private fun customBridgeOrNull() = if (prefs!!.getString(LawnchairPreferences.FEED_PROVIDER, "")!!.isNotBlank()) {
|
||||
val bridge = prefs.getString(LawnchairPreferences.FEED_PROVIDER, "")?.let { CustomBridgeInfo(it) }
|
||||
if (bridge!!.isAvailable()) {
|
||||
bridge
|
||||
} else null
|
||||
} else null
|
||||
|
||||
private fun customBridgeAvailable() = customBridgeOrNull()?.isAvailable() == true
|
||||
|
||||
fun isInstalled(): Boolean {
|
||||
return !useBridge || bridgePackages.any { it.isAvailable() }
|
||||
return customBridgeAvailable() || !shouldUseFeed || bridgePackages.any { it.isAvailable() }
|
||||
}
|
||||
|
||||
fun resolveSmartspace(): String {
|
||||
return bridgePackages.firstOrNull { it.supportsSmartspace }?.packageName ?: "com.google.android.googlequicksearchbox"
|
||||
return bridgePackages.firstOrNull { it.supportsSmartspace }?.packageName
|
||||
?: "com.google.android.googlequicksearchbox"
|
||||
}
|
||||
|
||||
open inner class BridgeInfo(val packageName: String, signatureHashRes: Int) {
|
||||
|
||||
private val signatureHash = context.resources.getInteger(signatureHashRes)
|
||||
protected open val signatureHash = if (signatureHashRes > 0) context.resources.getInteger(signatureHashRes) else 0
|
||||
|
||||
open val supportsSmartspace = false
|
||||
|
||||
@@ -63,16 +83,16 @@ class FeedBridge(private val context: Context) {
|
||||
.append(Process.myUid())
|
||||
.toString())
|
||||
.buildUpon()
|
||||
.appendQueryParameter("v", Integer.toString(7))
|
||||
.appendQueryParameter("cv", Integer.toString(9))
|
||||
.appendQueryParameter("v", 7.toString())
|
||||
.appendQueryParameter("cv", 9.toString())
|
||||
.build()), 0)
|
||||
return info != null && isSigned()
|
||||
}
|
||||
|
||||
private fun isSigned(): Boolean {
|
||||
if (BuildConfig.FLAVOR_build.equals("dev"))
|
||||
open fun isSigned(): Boolean {
|
||||
if (BuildConfig.DEBUG)
|
||||
return true // Skip signature checks for dev builds
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
if (Utilities.ATLEAST_P) {
|
||||
val info = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES)
|
||||
val signingInfo = info.signingInfo
|
||||
if (signingInfo.hasMultipleSigners()) return false
|
||||
@@ -87,18 +107,48 @@ class FeedBridge(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
private inner class CustomBridgeInfo(packageName: String) : BridgeInfo(packageName, 0) {
|
||||
override val signatureHash = whitelist[packageName]?.toInt() ?: -1
|
||||
private val disableWhitelist = prefs!!.getBoolean(LawnchairPreferences.IGNORE_FEED_WHITELIST, false)
|
||||
override fun isSigned(): Boolean {
|
||||
if (signatureHash == -1 && Utilities.ATLEAST_P) {
|
||||
val info = context.packageManager
|
||||
.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES)
|
||||
val signingInfo = info.signingInfo
|
||||
if (signingInfo.hasMultipleSigners()) return false
|
||||
signingInfo.signingCertificateHistory.forEach {
|
||||
val hash = Integer.toHexString(it.hashCode())
|
||||
Log.d(TAG, "Feed provider $packageName(0x$hash) isn't whitelisted")
|
||||
}
|
||||
}
|
||||
return disableWhitelist || signatureHash != -1 && super.isSigned()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class PixelBridgeInfo(packageName: String, signatureHashRes: Int) : BridgeInfo(packageName, signatureHashRes) {
|
||||
|
||||
override val supportsSmartspace get() = isAvailable()
|
||||
}
|
||||
|
||||
|
||||
companion object : SingletonHolder<FeedBridge, Context>(ensureOnMainThread(
|
||||
useApplicationContext(::FeedBridge))) {
|
||||
|
||||
private const val TAG = "FeedBridge"
|
||||
private const val overlayAction = "com.android.launcher3.WINDOW_OVERLAY"
|
||||
|
||||
private val whitelist = mapOf<String, Long>(
|
||||
"ua.itaysonlab.homefeeder" to 0x887456ed, // HomeFeeder, t.me/homefeeder
|
||||
"launcher.libre.dev" to 0x2e9dbab5 // Librechair, t.me/librechair
|
||||
)
|
||||
|
||||
fun getAvailableProviders(context: Context) = context.packageManager
|
||||
.queryIntentServices(Intent(overlayAction).setData(Uri.parse("app://" + context.packageName)), PackageManager.GET_META_DATA)
|
||||
.map { it.serviceInfo.applicationInfo }
|
||||
.distinct()
|
||||
.filter { getInstance(context).CustomBridgeInfo(it.packageName).isSigned() }
|
||||
|
||||
@JvmStatic
|
||||
val useBridge = FeatureFlags.FORCE_FEED_BRIDGE || !BuildConfig.DEBUG
|
||||
fun useBridge(context: Context) = getInstance(context).let { it.shouldUseFeed || it.customBridgeAvailable() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package ch.deletescape.lawnchair;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
||||
|
||||
import ch.deletescape.nexuslauncher.OverlayCallbackImpl;
|
||||
|
||||
public class LawnchairLauncher extends Launcher {
|
||||
@Override
|
||||
protected LauncherOverlayManager getDefaultOverlay() {
|
||||
return new OverlayCallbackImpl(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package ch.deletescape.lawnchair;
|
||||
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
||||
|
||||
import ch.deletescape.nexuslauncher.OverlayCallbackImpl;
|
||||
|
||||
public class LawnchairLauncherQuickstep extends QuickstepLauncher {
|
||||
@Override
|
||||
protected LauncherOverlayManager getDefaultOverlay() {
|
||||
return new OverlayCallbackImpl(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of Lawnchair Launcher.
|
||||
*
|
||||
* Lawnchair Launcher is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Lawnchair Launcher is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Lawnchair Launcher. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.deletescape.lawnchair
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Looper
|
||||
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ExecutionException
|
||||
|
||||
|
||||
fun <T, A>ensureOnMainThread(creator: (A) -> T): (A) -> T {
|
||||
return { it ->
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
creator(it)
|
||||
} else {
|
||||
try {
|
||||
MAIN_EXECUTOR.submit(Callable { creator(it) }).get()
|
||||
} catch (e: InterruptedException) {
|
||||
throw RuntimeException(e)
|
||||
} catch (e: ExecutionException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T>useApplicationContext(creator: (Context) -> T): (Context) -> T {
|
||||
return { it -> creator(it.applicationContext) }
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of Lawnchair Launcher.
|
||||
*
|
||||
* Lawnchair Launcher is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Lawnchair Launcher is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Lawnchair Launcher. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.deletescape.lawnchair.util
|
||||
|
||||
import android.content.Context
|
||||
import ch.deletescape.lawnchair.ensureOnMainThread
|
||||
import ch.deletescape.lawnchair.useApplicationContext
|
||||
|
||||
// Source: https://medium.com/@BladeCoder/kotlin-singletons-with-argument-194ef06edd9e
|
||||
open class SingletonHolder<out T, in A>(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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun dangerousGetInstance() = instance
|
||||
}
|
||||
|
||||
open class LawnchairSingletonHolder<out T>(creator: (Context) -> T)
|
||||
: SingletonHolder<T, Context>(ensureOnMainThread(useApplicationContext(creator)))
|
||||
@@ -74,6 +74,15 @@ class LawnchairPreferences(val context: Context) {
|
||||
@kotlin.jvm.JvmField
|
||||
var MAKE_COLORED_BACKGROUNDS: String = "pref_makeColoredBackgrounds"
|
||||
|
||||
@kotlin.jvm.JvmField
|
||||
var IGNORE_FEED_WHITELIST: String = "pref_ignoreFeedWhitelist"
|
||||
|
||||
@kotlin.jvm.JvmField
|
||||
var FEED_PROVIDER: String = "pref_feedProvider"
|
||||
|
||||
@kotlin.jvm.JvmField
|
||||
var ENABLE_MINUS_ONE: String = "pref_enableMinusOne"
|
||||
|
||||
fun getInstance(context: Context?): SharedPreferences? = when {
|
||||
context == null -> null
|
||||
INSTANCE == null -> Utilities.getPrefs(context)
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package ch.deletescape.nexuslauncher;
|
||||
|
||||
import static ch.deletescape.lawnchair.util.preferences.LawnchairPreferences.ENABLE_MINUS_ONE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
||||
import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
|
||||
|
||||
import com.google.android.libraries.launcherclient.ISerializableScrollCallback;
|
||||
import com.google.android.libraries.launcherclient.LauncherClient;
|
||||
import com.google.android.libraries.launcherclient.LauncherClientCallbacks;
|
||||
import com.google.android.libraries.launcherclient.StaticInteger;
|
||||
|
||||
import ch.deletescape.lawnchair.FeedBridge;
|
||||
import ch.deletescape.lawnchair.util.preferences.LawnchairPreferences;
|
||||
|
||||
/**
|
||||
* Implements {@link LauncherOverlay} and passes all the corresponding events to {@link
|
||||
* LauncherClient}. {@see setClient}
|
||||
*
|
||||
* <p>Implements {@link LauncherClientCallbacks} and sends all the corresponding callbacks to {@link
|
||||
* Launcher}.
|
||||
*/
|
||||
public class OverlayCallbackImpl
|
||||
implements LauncherOverlay, LauncherClientCallbacks, LauncherOverlayManager,
|
||||
OnSharedPreferenceChangeListener, ISerializableScrollCallback {
|
||||
|
||||
final static String PREF_PERSIST_FLAGS = "pref_persistent_flags";
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final LauncherClient mClient;
|
||||
|
||||
private LauncherOverlayCallbacks mLauncherOverlayCallbacks;
|
||||
private boolean mWasOverlayAttached = false;
|
||||
boolean mFlagsChanged = false;
|
||||
private int mFlags;
|
||||
|
||||
public OverlayCallbackImpl(Launcher launcher) {
|
||||
SharedPreferences prefs = Utilities.getPrefs(launcher);
|
||||
|
||||
mLauncher = launcher;
|
||||
mClient = new LauncherClient(mLauncher, this, new StaticInteger(
|
||||
(prefs.getBoolean(LawnchairPreferences.ENABLE_MINUS_ONE,
|
||||
FeedBridge.useBridge(launcher)) ? 1 : 0) | 2 | 4 | 8));
|
||||
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceProvideChanged() {
|
||||
mClient.redraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
mClient.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
mClient.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openOverlay() {
|
||||
mClient.showOverlay(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideOverlay(boolean animate) {
|
||||
mClient.hideOverlay(animate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideOverlay(int duration) {
|
||||
mClient.hideOverlay(duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startSearch(byte[] config, Bundle extras) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle bundle) {
|
||||
// Not called
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
mClient.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
mClient.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
mClient.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {
|
||||
mClient.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
mClient.mDestroyed = true;
|
||||
mLauncher.getSharedPrefs().unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||
if (ENABLE_MINUS_ONE.equals(key)) {
|
||||
mClient.showOverlay(prefs.getBoolean(ENABLE_MINUS_ONE, FeedBridge.useBridge(mLauncher)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverlayScrollChanged(float progress) {
|
||||
if (mLauncherOverlayCallbacks != null) {
|
||||
mLauncherOverlayCallbacks.onScrollChanged(progress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(boolean overlayAttached, boolean hotwordActive) {
|
||||
this.onServiceStateChanged(overlayAttached);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(boolean overlayAttached) {
|
||||
if (overlayAttached != mWasOverlayAttached) {
|
||||
mWasOverlayAttached = overlayAttached;
|
||||
mLauncher.setLauncherOverlay(overlayAttached ? this : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollInteractionBegin() {
|
||||
mClient.startScroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollInteractionEnd() {
|
||||
mClient.endScroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChange(float progress, boolean rtl) {
|
||||
mClient.setScroll(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks) {
|
||||
mLauncherOverlayCallbacks = callbacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPersistentFlags(int flags) {
|
||||
flags &= (8 | 16);
|
||||
if (flags != mFlags) {
|
||||
mFlagsChanged = true;
|
||||
mFlags = flags;
|
||||
Utilities.getDevicePrefs(mLauncher).edit().putInt(PREF_PERSIST_FLAGS, flags).apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
public interface IScrollCallback {
|
||||
void onOverlayScrollChanged(float progress);
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
public interface ISerializableScrollCallback extends IScrollCallback {
|
||||
void setPersistentFlags(int flags);
|
||||
+5
-10
@@ -1,4 +1,4 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -22,15 +22,13 @@ import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import ch.deletescape.lawnchair.FeedBridge;
|
||||
import ch.deletescape.lawnchair.FeedBridge.BridgeInfo;
|
||||
import com.google.android.libraries.launcherclient.ILauncherOverlay;
|
||||
import com.google.android.libraries.launcherclient.ILauncherOverlayCallback;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class LauncherClient {
|
||||
private static int apiVersion = -1;
|
||||
|
||||
private ILauncherOverlay mOverlay;
|
||||
private final IScrollCallback mScrollCallback;
|
||||
public final IScrollCallback mScrollCallback;
|
||||
|
||||
public final BaseClientService mBaseService;
|
||||
public final LauncherClientService mLauncherService;
|
||||
@@ -188,7 +186,9 @@ public class LauncherClient {
|
||||
}
|
||||
|
||||
public final void onStart() {
|
||||
Log.i("FEED", "1");
|
||||
if (!mDestroyed) {
|
||||
Log.i("FEED", "2");
|
||||
mLauncherService.setStopped(false);
|
||||
reconnect();
|
||||
mActivityState |= 1;
|
||||
@@ -217,12 +217,7 @@ public class LauncherClient {
|
||||
|
||||
private void reconnect() {
|
||||
if (!mDestroyed && (!mLauncherService.connect() || !mBaseService.connect())) {
|
||||
mActivity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setServiceState(0);
|
||||
}
|
||||
});
|
||||
mActivity.runOnUiThread(() -> setServiceState(0));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ServiceConnection;
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
public interface LauncherClientCallbacks {
|
||||
void onOverlayScrollChanged(float f);
|
||||
|
||||
void onServiceStateChanged(boolean z, boolean z2);
|
||||
}
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.google.android.libraries.launcherclient.ILauncherOverlay;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class LauncherClientService extends BaseClientService {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.google.android.libraries.gsa.launcherclient;
|
||||
package com.google.android.libraries.launcherclient;
|
||||
|
||||
public class StaticInteger {
|
||||
public final int mData;
|
||||
@@ -43,7 +43,7 @@
|
||||
attributes and intent filters the same
|
||||
-->
|
||||
<activity
|
||||
android:name="com.android.launcher3.uioverrides.QuickstepLauncher"
|
||||
android:name="ch.deletescape.lawnchair.LawnchairLauncherQuickstep"
|
||||
android:launchMode="singleTask"
|
||||
android:clearTaskOnLaunch="true"
|
||||
android:stateNotNeeded="true"
|
||||
|
||||
Reference in New Issue
Block a user