Loading app/src/main/java/foundation/e/blisslauncher/core/utils/ItemInfoMatcher.java 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package foundation.e.blisslauncher.core.utils; import android.content.ComponentName; import android.os.UserHandle; import java.util.HashSet; import foundation.e.blisslauncher.core.database.model.ApplicationItem; import foundation.e.blisslauncher.core.database.model.FolderItem; import foundation.e.blisslauncher.core.database.model.LauncherItem; import foundation.e.blisslauncher.core.database.model.ShortcutItem; import foundation.e.blisslauncher.features.shortcuts.ShortcutKey; /** * A utility class to check for {@link foundation.e.blisslauncher.core.database.model.LauncherItem} */ public interface ItemInfoMatcher { boolean matches(LauncherItem info, ComponentName cn); /** * Filters {@param infos} to those satisfying the {@link #matches(LauncherItem, ComponentName)}. */ default HashSet<LauncherItem> filterItemInfos(Iterable<LauncherItem> infos) { HashSet<LauncherItem> filtered = new HashSet<>(); for (LauncherItem i : infos) { if (i instanceof ApplicationItem) { ApplicationItem info = (ApplicationItem) i; ComponentName cn = info.getTargetComponent(); if (cn != null && matches(info, cn)) { filtered.add(info); } } else if (i instanceof ShortcutItem) { ShortcutItem info = (ShortcutItem) i; ComponentName cn = info.getTargetComponent(); if (cn != null && matches(info, cn)) { filtered.add(info); } } else if (i instanceof FolderItem) { FolderItem info = (FolderItem) i; for (LauncherItem s : info.items) { ComponentName cn = s.getTargetComponent(); if (cn != null && matches(s, cn)) { filtered.add(s); } } } } return filtered; } /** * Returns a new matcher with returns true if either this or {@param matcher} returns true. */ default ItemInfoMatcher or(ItemInfoMatcher matcher) { return (info, cn) -> matches(info, cn) || matcher.matches(info, cn); } /** * Returns a new matcher with returns true if both this and {@param matcher} returns true. */ default ItemInfoMatcher and(ItemInfoMatcher matcher) { return (info, cn) -> matches(info, cn) && matcher.matches(info, cn); } /** * Returns a new matcher which returns the opposite boolean value of the provided * {@param matcher}. */ static ItemInfoMatcher not(ItemInfoMatcher matcher) { return (info, cn) -> !matcher.matches(info, cn); } static ItemInfoMatcher ofUser(UserHandle user) { return (info, cn) -> info.user.equals(user); } static ItemInfoMatcher ofComponents(HashSet<ComponentName> components, UserHandle user) { return (info, cn) -> components.contains(cn) && info.user.equals(user); } static ItemInfoMatcher ofPackages(HashSet<String> packageNames, UserHandle user) { return (info, cn) -> packageNames.contains(cn.getPackageName()) && info.user.equals(user); } static ItemInfoMatcher ofShortcutKeys(HashSet<ShortcutKey> keys) { return (info, cn) -> info.itemType == Constants.ITEM_TYPE_SHORTCUT && keys.contains(ShortcutKey.fromItem((ShortcutItem) info)); } static ItemInfoMatcher ofItemIds(IntSparseArrayMap<Boolean> ids, Boolean matchDefault) { return (info, cn) -> ids.get(Integer.parseInt(info.id), matchDefault); } } app/src/main/java/foundation/e/blisslauncher/features/test/LauncherAppState.java +78 −0 Original line number Diff line number Diff line Loading @@ -22,14 +22,23 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.os.Looper; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; import foundation.e.blisslauncher.core.ConfigMonitor; import foundation.e.blisslauncher.core.UserManagerCompat; import foundation.e.blisslauncher.core.executors.MainThreadExecutor; import foundation.e.blisslauncher.core.utils.Preconditions; import foundation.e.blisslauncher.core.utils.SecureSettingsObserver; import foundation.e.blisslauncher.features.notification.NotificationListener; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; Loading @@ -45,6 +54,8 @@ public class LauncherAppState { // We do not need any synchronization for this variable as its only written on UI thread. private static LauncherAppState INSTANCE; private LauncherApps launcherApps; private final Context mContext; private final InvariantDeviceProfile mInvariantDeviceProfile; Loading @@ -52,6 +63,9 @@ public class LauncherAppState { private TestActivity launcher; private LauncherModel mModel; private final ArrayMap<OnAppsChangedCallback, WrappedCallback> mCallbacks = new ArrayMap<>(); public static LauncherAppState getInstance(final Context context) { if (INSTANCE == null) { if (Looper.myLooper() == Looper.getMainLooper()) { Loading Loading @@ -82,6 +96,7 @@ public class LauncherAppState { private LauncherAppState(Context context) { launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE); Log.v(TestActivity.TAG, "LauncherAppState initiated"); Preconditions.assertUIThread(); mContext = context; Loading @@ -89,6 +104,12 @@ public class LauncherAppState { mInvariantDeviceProfile = new InvariantDeviceProfile(mContext); mModel = new LauncherModel(this); WrappedCallback wrappedCallback = new WrappedCallback(mModel); synchronized (mCallbacks) { mCallbacks.put(mModel, wrappedCallback); } launcherApps.registerCallback(wrappedCallback); mModel.registerCallbacks(launcherApps); // Register intent receivers IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_LOCALE_CHANGED); Loading Loading @@ -129,6 +150,13 @@ public class LauncherAppState { if (mNotificationDotsObserver != null) { mNotificationDotsObserver.unregister(); } final WrappedCallback wrappedCallback; synchronized (mCallbacks) { wrappedCallback = mCallbacks.remove(mModel); } if (wrappedCallback != null) { launcherApps.unregisterCallback(wrappedCallback); } } LauncherModel setLauncher(TestActivity launcher) { Loading @@ -153,4 +181,54 @@ public class LauncherAppState { } private static class WrappedCallback extends LauncherApps.Callback { private final OnAppsChangedCallback mCallback; public WrappedCallback(OnAppsChangedCallback callback) { mCallback = callback; } @Override public void onPackageRemoved(String packageName, UserHandle user) { mCallback.onPackageRemoved(packageName, user); } @Override public void onPackageAdded(String packageName, UserHandle user) { mCallback.onPackageAdded(packageName, user); } @Override public void onPackageChanged(String packageName, UserHandle user) { mCallback.onPackageChanged(packageName, user); } @Override public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) { mCallback.onPackagesAvailable(packageNames, user, replacing); } @Override public void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing) { mCallback.onPackagesUnavailable(packageNames, user, replacing); } @Override public void onPackagesSuspended(String[] packageNames, UserHandle user) { mCallback.onPackagesSuspended(packageNames, user); } @Override public void onPackagesUnsuspended(String[] packageNames, UserHandle user) { mCallback.onPackagesUnsuspended(packageNames, user); } @Override public void onShortcutsChanged(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { mCallback.onShortcutsChanged(packageName, shortcuts, user); } } } app/src/main/java/foundation/e/blisslauncher/features/test/LauncherModel.java +72 −1 Original line number Diff line number Diff line /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package foundation.e.blisslauncher.features.test; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.telecom.Call; import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; Loading @@ -23,7 +45,8 @@ import foundation.e.blisslauncher.core.utils.Constants; import foundation.e.blisslauncher.core.utils.Preconditions; import foundation.e.blisslauncher.features.shortcuts.DeepShortcutManager; public class LauncherModel extends BroadcastReceiver { public class LauncherModel extends BroadcastReceiver implements OnAppsChangedCallback { private static final boolean DEBUG_RECEIVER = false; Loading @@ -43,6 +66,54 @@ public class LauncherModel extends BroadcastReceiver { } static final Handler sWorker = new Handler(mWorkerLooper); @Override public void onPackageRemoved(String packageName, UserHandle user) { // TODO: Handle package removed here. onPackagesRemoved(user, packageName); } public void onPackagesRemoved(UserHandle user, String... packages) { final HashSet<String> removedPackages = new HashSet<>(); Collections.addAll(removedPackages, packages); } @Override public void onPackageAdded(String packageName, UserHandle user) { } @Override public void onPackageChanged(String packageName, UserHandle user) { } @Override public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) { } @Override public void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing) { } @Override public void onPackagesSuspended(String[] packageNames, UserHandle user) { } @Override public void onPackagesUnsuspended(String[] packageNames, UserHandle user) { } @Override public void onShortcutsChanged( String packageName, List<ShortcutInfo> shortcuts, UserHandle user ) { } // Runnable to check if the shortcuts permission has changed. /*private final Runnable mShortcutPermissionCheckRunnable = new Runnable() { @Override Loading app/src/main/java/foundation/e/blisslauncher/features/test/OnAppsChangedCallback.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package foundation.e.blisslauncher.features.test; import android.content.pm.ShortcutInfo; import android.os.UserHandle; import java.util.List; public interface OnAppsChangedCallback { void onPackageRemoved(String packageName, UserHandle user); void onPackageAdded(String packageName, UserHandle user); void onPackageChanged(String packageName, UserHandle user); void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing); void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing); void onPackagesSuspended(String[] packageNames, UserHandle user); void onPackagesUnsuspended(String[] packageNames, UserHandle user); void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts, UserHandle user); } Loading
app/src/main/java/foundation/e/blisslauncher/core/utils/ItemInfoMatcher.java 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package foundation.e.blisslauncher.core.utils; import android.content.ComponentName; import android.os.UserHandle; import java.util.HashSet; import foundation.e.blisslauncher.core.database.model.ApplicationItem; import foundation.e.blisslauncher.core.database.model.FolderItem; import foundation.e.blisslauncher.core.database.model.LauncherItem; import foundation.e.blisslauncher.core.database.model.ShortcutItem; import foundation.e.blisslauncher.features.shortcuts.ShortcutKey; /** * A utility class to check for {@link foundation.e.blisslauncher.core.database.model.LauncherItem} */ public interface ItemInfoMatcher { boolean matches(LauncherItem info, ComponentName cn); /** * Filters {@param infos} to those satisfying the {@link #matches(LauncherItem, ComponentName)}. */ default HashSet<LauncherItem> filterItemInfos(Iterable<LauncherItem> infos) { HashSet<LauncherItem> filtered = new HashSet<>(); for (LauncherItem i : infos) { if (i instanceof ApplicationItem) { ApplicationItem info = (ApplicationItem) i; ComponentName cn = info.getTargetComponent(); if (cn != null && matches(info, cn)) { filtered.add(info); } } else if (i instanceof ShortcutItem) { ShortcutItem info = (ShortcutItem) i; ComponentName cn = info.getTargetComponent(); if (cn != null && matches(info, cn)) { filtered.add(info); } } else if (i instanceof FolderItem) { FolderItem info = (FolderItem) i; for (LauncherItem s : info.items) { ComponentName cn = s.getTargetComponent(); if (cn != null && matches(s, cn)) { filtered.add(s); } } } } return filtered; } /** * Returns a new matcher with returns true if either this or {@param matcher} returns true. */ default ItemInfoMatcher or(ItemInfoMatcher matcher) { return (info, cn) -> matches(info, cn) || matcher.matches(info, cn); } /** * Returns a new matcher with returns true if both this and {@param matcher} returns true. */ default ItemInfoMatcher and(ItemInfoMatcher matcher) { return (info, cn) -> matches(info, cn) && matcher.matches(info, cn); } /** * Returns a new matcher which returns the opposite boolean value of the provided * {@param matcher}. */ static ItemInfoMatcher not(ItemInfoMatcher matcher) { return (info, cn) -> !matcher.matches(info, cn); } static ItemInfoMatcher ofUser(UserHandle user) { return (info, cn) -> info.user.equals(user); } static ItemInfoMatcher ofComponents(HashSet<ComponentName> components, UserHandle user) { return (info, cn) -> components.contains(cn) && info.user.equals(user); } static ItemInfoMatcher ofPackages(HashSet<String> packageNames, UserHandle user) { return (info, cn) -> packageNames.contains(cn.getPackageName()) && info.user.equals(user); } static ItemInfoMatcher ofShortcutKeys(HashSet<ShortcutKey> keys) { return (info, cn) -> info.itemType == Constants.ITEM_TYPE_SHORTCUT && keys.contains(ShortcutKey.fromItem((ShortcutItem) info)); } static ItemInfoMatcher ofItemIds(IntSparseArrayMap<Boolean> ids, Boolean matchDefault) { return (info, cn) -> ids.get(Integer.parseInt(info.id), matchDefault); } }
app/src/main/java/foundation/e/blisslauncher/features/test/LauncherAppState.java +78 −0 Original line number Diff line number Diff line Loading @@ -22,14 +22,23 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.os.Looper; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; import foundation.e.blisslauncher.core.ConfigMonitor; import foundation.e.blisslauncher.core.UserManagerCompat; import foundation.e.blisslauncher.core.executors.MainThreadExecutor; import foundation.e.blisslauncher.core.utils.Preconditions; import foundation.e.blisslauncher.core.utils.SecureSettingsObserver; import foundation.e.blisslauncher.features.notification.NotificationListener; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; Loading @@ -45,6 +54,8 @@ public class LauncherAppState { // We do not need any synchronization for this variable as its only written on UI thread. private static LauncherAppState INSTANCE; private LauncherApps launcherApps; private final Context mContext; private final InvariantDeviceProfile mInvariantDeviceProfile; Loading @@ -52,6 +63,9 @@ public class LauncherAppState { private TestActivity launcher; private LauncherModel mModel; private final ArrayMap<OnAppsChangedCallback, WrappedCallback> mCallbacks = new ArrayMap<>(); public static LauncherAppState getInstance(final Context context) { if (INSTANCE == null) { if (Looper.myLooper() == Looper.getMainLooper()) { Loading Loading @@ -82,6 +96,7 @@ public class LauncherAppState { private LauncherAppState(Context context) { launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE); Log.v(TestActivity.TAG, "LauncherAppState initiated"); Preconditions.assertUIThread(); mContext = context; Loading @@ -89,6 +104,12 @@ public class LauncherAppState { mInvariantDeviceProfile = new InvariantDeviceProfile(mContext); mModel = new LauncherModel(this); WrappedCallback wrappedCallback = new WrappedCallback(mModel); synchronized (mCallbacks) { mCallbacks.put(mModel, wrappedCallback); } launcherApps.registerCallback(wrappedCallback); mModel.registerCallbacks(launcherApps); // Register intent receivers IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_LOCALE_CHANGED); Loading Loading @@ -129,6 +150,13 @@ public class LauncherAppState { if (mNotificationDotsObserver != null) { mNotificationDotsObserver.unregister(); } final WrappedCallback wrappedCallback; synchronized (mCallbacks) { wrappedCallback = mCallbacks.remove(mModel); } if (wrappedCallback != null) { launcherApps.unregisterCallback(wrappedCallback); } } LauncherModel setLauncher(TestActivity launcher) { Loading @@ -153,4 +181,54 @@ public class LauncherAppState { } private static class WrappedCallback extends LauncherApps.Callback { private final OnAppsChangedCallback mCallback; public WrappedCallback(OnAppsChangedCallback callback) { mCallback = callback; } @Override public void onPackageRemoved(String packageName, UserHandle user) { mCallback.onPackageRemoved(packageName, user); } @Override public void onPackageAdded(String packageName, UserHandle user) { mCallback.onPackageAdded(packageName, user); } @Override public void onPackageChanged(String packageName, UserHandle user) { mCallback.onPackageChanged(packageName, user); } @Override public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) { mCallback.onPackagesAvailable(packageNames, user, replacing); } @Override public void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing) { mCallback.onPackagesUnavailable(packageNames, user, replacing); } @Override public void onPackagesSuspended(String[] packageNames, UserHandle user) { mCallback.onPackagesSuspended(packageNames, user); } @Override public void onPackagesUnsuspended(String[] packageNames, UserHandle user) { mCallback.onPackagesUnsuspended(packageNames, user); } @Override public void onShortcutsChanged(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { mCallback.onShortcutsChanged(packageName, shortcuts, user); } } }
app/src/main/java/foundation/e/blisslauncher/features/test/LauncherModel.java +72 −1 Original line number Diff line number Diff line /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package foundation.e.blisslauncher.features.test; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.telecom.Call; import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; Loading @@ -23,7 +45,8 @@ import foundation.e.blisslauncher.core.utils.Constants; import foundation.e.blisslauncher.core.utils.Preconditions; import foundation.e.blisslauncher.features.shortcuts.DeepShortcutManager; public class LauncherModel extends BroadcastReceiver { public class LauncherModel extends BroadcastReceiver implements OnAppsChangedCallback { private static final boolean DEBUG_RECEIVER = false; Loading @@ -43,6 +66,54 @@ public class LauncherModel extends BroadcastReceiver { } static final Handler sWorker = new Handler(mWorkerLooper); @Override public void onPackageRemoved(String packageName, UserHandle user) { // TODO: Handle package removed here. onPackagesRemoved(user, packageName); } public void onPackagesRemoved(UserHandle user, String... packages) { final HashSet<String> removedPackages = new HashSet<>(); Collections.addAll(removedPackages, packages); } @Override public void onPackageAdded(String packageName, UserHandle user) { } @Override public void onPackageChanged(String packageName, UserHandle user) { } @Override public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) { } @Override public void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing) { } @Override public void onPackagesSuspended(String[] packageNames, UserHandle user) { } @Override public void onPackagesUnsuspended(String[] packageNames, UserHandle user) { } @Override public void onShortcutsChanged( String packageName, List<ShortcutInfo> shortcuts, UserHandle user ) { } // Runnable to check if the shortcuts permission has changed. /*private final Runnable mShortcutPermissionCheckRunnable = new Runnable() { @Override Loading
app/src/main/java/foundation/e/blisslauncher/features/test/OnAppsChangedCallback.java 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package foundation.e.blisslauncher.features.test; import android.content.pm.ShortcutInfo; import android.os.UserHandle; import java.util.List; public interface OnAppsChangedCallback { void onPackageRemoved(String packageName, UserHandle user); void onPackageAdded(String packageName, UserHandle user); void onPackageChanged(String packageName, UserHandle user); void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing); void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing); void onPackagesSuspended(String[] packageNames, UserHandle user); void onPackagesUnsuspended(String[] packageNames, UserHandle user); void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts, UserHandle user); }