├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── apksigner.jar │ └── sqlite-android.aar ├── proguard-rules.pro ├── release │ ├── baselineProfiles │ │ ├── 0 │ │ │ └── app-release.dm │ │ └── 1 │ │ │ └── app-release.dm │ └── output-metadata.json └── src │ └── main │ ├── AndroidManifest.xml │ ├── aidl │ └── com │ │ └── kieronquinn │ │ └── app │ │ └── pixellaunchermods │ │ ├── model │ │ └── ipc │ │ │ ├── GridSize.aidl │ │ │ ├── ParceledListSlice.aidl │ │ │ ├── ParceledString.aidl │ │ │ └── ProxyAppWidgetServiceContainer.aidl │ │ └── service │ │ ├── IDatabaseChangedListener.aidl │ │ ├── IIconSizeChangedListener.aidl │ │ ├── IPackageChangedListener.aidl │ │ ├── IPixelLauncherForegroundListener.aidl │ │ ├── IPixelLauncherModsRootService.aidl │ │ ├── IPixelLauncherRestartListener.aidl │ │ └── IResetCompleteCallback.aidl │ ├── assets │ ├── faq.md │ └── overlay │ │ └── build │ │ ├── android-manifest.jar │ │ └── plm.keystore.bk1.keystore │ ├── java │ └── com │ │ └── kieronquinn │ │ └── app │ │ └── pixellaunchermods │ │ ├── PixelLauncherMods.kt │ │ ├── components │ │ ├── navigation │ │ │ └── Navigation.kt │ │ └── notifications │ │ │ └── Notifications.kt │ │ ├── model │ │ ├── backup │ │ │ └── Backup.kt │ │ ├── editor │ │ │ ├── AppEditorInfo.kt │ │ │ ├── IconPack.kt │ │ │ └── ShortcutEditorInfo.kt │ │ ├── github │ │ │ └── GitHubRelease.kt │ │ ├── icon │ │ │ ├── ApplicationIcon.kt │ │ │ ├── IconPickerResult.kt │ │ │ ├── LegacyThemedIcon.kt │ │ │ └── RawBytesIcon.kt │ │ ├── ipc │ │ │ ├── BaseParceledListSlice.java │ │ │ ├── GridSize.kt │ │ │ ├── ParceledListSlice.java │ │ │ ├── ParceledString.kt │ │ │ └── ProxyAppWidgetServiceContainer.kt │ │ ├── remote │ │ │ ├── ModifiedRemoteApp.kt │ │ │ ├── RemoteApp.kt │ │ │ ├── RemoteFavourite.kt │ │ │ └── RemoteWidget.kt │ │ ├── room │ │ │ ├── AppsDao.kt │ │ │ ├── IconMetadata.kt │ │ │ ├── ModifiedApp.kt │ │ │ ├── ModifiedShortcut.kt │ │ │ ├── PixelLauncherModsDatabase.kt │ │ │ └── ShortcutsDao.kt │ │ ├── tweaks │ │ │ └── WidgetReplacement.kt │ │ └── update │ │ │ └── Release.kt │ │ ├── receivers │ │ └── BootReceiver.kt │ │ ├── repositories │ │ ├── AppStateRepository.kt │ │ ├── AppWidgetRepository.kt │ │ ├── AppsRepository.kt │ │ ├── BackupRestoreRepository.kt │ │ ├── DatabaseRepository.kt │ │ ├── HideClockRepository.kt │ │ ├── IconLoaderRepository.kt │ │ ├── IconPackRepository.kt │ │ ├── OverlayRepository.kt │ │ ├── ProxyAppWidgetRepository.kt │ │ ├── RemoteAppsRepository.kt │ │ ├── RootServiceRepository.kt │ │ ├── SettingsRepository.kt │ │ └── UpdateRepository.kt │ │ ├── service │ │ ├── GitHubService.kt │ │ ├── PixelLauncherModsForegroundService.kt │ │ └── PixelLauncherModsRootService.kt │ │ ├── ui │ │ ├── activities │ │ │ ├── MainActivity.kt │ │ │ ├── MainActivityViewModel.kt │ │ │ └── WidgetResizeActivity.kt │ │ ├── base │ │ │ ├── BoundFragment.kt │ │ │ ├── FragmentOptions.kt │ │ │ └── settings │ │ │ │ ├── BaseSettingsAdapter.kt │ │ │ │ ├── BaseSettingsFragment.kt │ │ │ │ └── BaseSettingsViewModel.kt │ │ ├── drawables │ │ │ └── ClockDrawableWrapper.java │ │ ├── screens │ │ │ ├── apps │ │ │ │ ├── AppsAdapter.kt │ │ │ │ ├── AppsFragment.kt │ │ │ │ ├── AppsViewModel.kt │ │ │ │ └── editor │ │ │ │ │ ├── AppEditorFragment.kt │ │ │ │ │ └── AppEditorViewModel.kt │ │ │ ├── autoiconpack │ │ │ │ ├── AutoIconPackAdapter.kt │ │ │ │ ├── AutoIconPackFragment.kt │ │ │ │ ├── AutoIconPackViewModel.kt │ │ │ │ └── apply │ │ │ │ │ ├── AutoIconPackApplyFragment.kt │ │ │ │ │ └── AutoIconPackApplyViewModel.kt │ │ │ ├── backuprestore │ │ │ │ ├── BackupRestoreFragment.kt │ │ │ │ ├── BackupRestoreViewModel.kt │ │ │ │ ├── backup │ │ │ │ │ ├── BackupRestoreBackupFragment.kt │ │ │ │ │ └── BackupRestoreBackupViewModel.kt │ │ │ │ └── restore │ │ │ │ │ ├── BackupRestoreRestoreFragment.kt │ │ │ │ │ ├── BackupRestoreRestoreViewModel.kt │ │ │ │ │ └── issues │ │ │ │ │ ├── BackupRestoreIssuesAdapter.kt │ │ │ │ │ └── BackupRestoreIssuesFragment.kt │ │ │ ├── container │ │ │ │ ├── ContainerFragment.kt │ │ │ │ └── ContainerViewModel.kt │ │ │ ├── iconpicker │ │ │ │ ├── BasePickerFragment.kt │ │ │ │ ├── BasePickerViewModel.kt │ │ │ │ ├── IconPickerAdapter.kt │ │ │ │ ├── IconPickerFragment.kt │ │ │ │ ├── IconPickerViewModel.kt │ │ │ │ ├── apps │ │ │ │ │ ├── IconPickerAppsAdapter.kt │ │ │ │ │ ├── IconPickerAppsFragment.kt │ │ │ │ │ └── IconPickerAppsViewModel.kt │ │ │ │ ├── legacythemed │ │ │ │ │ ├── LegacyThemedIconPickerAdapter.kt │ │ │ │ │ ├── LegacyThemedIconPickerFragment.kt │ │ │ │ │ └── LegacyThemedIconPickerViewModel.kt │ │ │ │ └── pack │ │ │ │ │ ├── IconPickerPackAdapter.kt │ │ │ │ │ ├── IconPickerPackFragment.kt │ │ │ │ │ └── IconPickerPackViewModel.kt │ │ │ ├── magiskinfo │ │ │ │ ├── MagiskInfoFragment.kt │ │ │ │ └── MagiskInfoViewModel.kt │ │ │ ├── options │ │ │ │ ├── OptionsFragment.kt │ │ │ │ ├── OptionsViewModel.kt │ │ │ │ ├── advanced │ │ │ │ │ ├── OptionsAdvancedFragment.kt │ │ │ │ │ └── OptionsAdvancedViewModel.kt │ │ │ │ ├── contributors │ │ │ │ │ ├── ContributorsFragment.kt │ │ │ │ │ └── ContributorsViewModel.kt │ │ │ │ ├── faq │ │ │ │ │ └── OptionsFaqFragment.kt │ │ │ │ └── reapply │ │ │ │ │ ├── OptionsReapplyFragment.kt │ │ │ │ │ └── OptionsReapplyViewModel.kt │ │ │ ├── reset │ │ │ │ ├── ResetInfoFragment.kt │ │ │ │ ├── ResetInfoViewModel.kt │ │ │ │ └── apply │ │ │ │ │ ├── ResetApplyFragment.kt │ │ │ │ │ └── ResetApplyViewModel.kt │ │ │ ├── root │ │ │ │ └── RootFragment.kt │ │ │ ├── shortcuts │ │ │ │ ├── ShortcutsAdapter.kt │ │ │ │ ├── ShortcutsFragment.kt │ │ │ │ ├── ShortcutsViewModel.kt │ │ │ │ └── editor │ │ │ │ │ ├── ShortcutEditorFragment.kt │ │ │ │ │ └── ShortcutEditorViewModel.kt │ │ │ ├── tweaks │ │ │ │ ├── TweaksFragment.kt │ │ │ │ ├── TweaksViewModel.kt │ │ │ │ ├── deferredrestart │ │ │ │ │ ├── DeferredRestartAdapter.kt │ │ │ │ │ ├── DeferredRestartFragment.kt │ │ │ │ │ └── DeferredRestartViewModel.kt │ │ │ │ ├── hideapps │ │ │ │ │ ├── HideAppsAdapter.kt │ │ │ │ │ ├── HideAppsFragment.kt │ │ │ │ │ └── HideAppsViewModel.kt │ │ │ │ ├── overlay │ │ │ │ │ ├── OverlayTweaksFragment.kt │ │ │ │ │ └── OverlayTweaksViewModel.kt │ │ │ │ ├── overlayapply │ │ │ │ │ ├── OverlayApplyFragment.kt │ │ │ │ │ └── OverlayApplyViewModel.kt │ │ │ │ ├── widgetreplacement │ │ │ │ │ ├── WidgetReplacementAdapter.kt │ │ │ │ │ ├── WidgetReplacementFragment.kt │ │ │ │ │ ├── WidgetReplacementViewModel.kt │ │ │ │ │ └── widgetpicker │ │ │ │ │ │ ├── WidgetReplacementPickerAdapter.kt │ │ │ │ │ │ ├── WidgetReplacementPickerFragment.kt │ │ │ │ │ │ └── WidgetReplacementPickerViewModel.kt │ │ │ │ └── widgetresize │ │ │ │ │ ├── WidgetResizeAdapter.kt │ │ │ │ │ ├── WidgetResizeFragment.kt │ │ │ │ │ ├── WidgetResizePageFragment.kt │ │ │ │ │ ├── WidgetResizePagerAdapter.kt │ │ │ │ │ └── WidgetResizeViewModel.kt │ │ │ └── update │ │ │ │ ├── SettingsUpdateFragment.kt │ │ │ │ └── SettingsUpdateViewModel.kt │ │ └── views │ │ │ ├── LifecycleAwareRecyclerView.kt │ │ │ ├── MonetSwitch.kt │ │ │ ├── TouchIgnoringFrameLayout.kt │ │ │ ├── WidgetSizeInput.kt │ │ │ └── viewpager │ │ │ ├── BasePageIndicator.java │ │ │ ├── PageIndicator.java │ │ │ └── UnderlinePageIndicator.java │ │ ├── utils │ │ ├── appbar │ │ │ └── DragDisabledAppBarLayoutBehaviour.kt │ │ ├── drawable │ │ │ └── IconNormalizer.java │ │ ├── extensions │ │ │ ├── Extensions+ActivityOptionsCompat.kt │ │ │ ├── Extensions+AdaptiveIconDrawable.kt │ │ │ ├── Extensions+AppBarLayout.kt │ │ │ ├── Extensions+AppIconLoader.kt │ │ │ ├── Extensions+AppWidgetHost.kt │ │ │ ├── Extensions+AssetManager.kt │ │ │ ├── Extensions+Bitmap.kt │ │ │ ├── Extensions+Color.kt │ │ │ ├── Extensions+ComponentName.kt │ │ │ ├── Extensions+CompoundButton.kt │ │ │ ├── Extensions+ContentResovler.kt │ │ │ ├── Extensions+Context.kt │ │ │ ├── Extensions+Coroutines.kt │ │ │ ├── Extensions+Cursor.kt │ │ │ ├── Extensions+EditText.kt │ │ │ ├── Extensions+File.kt │ │ │ ├── Extensions+Flow.kt │ │ │ ├── Extensions+Fragment.kt │ │ │ ├── Extensions+Inset.kt │ │ │ ├── Extensions+Lifecycle.kt │ │ │ ├── Extensions+Native.kt │ │ │ ├── Extensions+Navigation.kt │ │ │ ├── Extensions+PackageManager.kt │ │ │ ├── Extensions+Reflection.kt │ │ │ ├── Extensions+Resources.kt │ │ │ ├── Extensions+SharedPreferences.kt │ │ │ ├── Extensions+Slider.kt │ │ │ ├── Extensions+Snackbar.kt │ │ │ ├── Extensions+TabLayout.kt │ │ │ ├── Extensions+Toolbar.kt │ │ │ ├── Extensions+UserHandle.kt │ │ │ ├── Extensions+View.kt │ │ │ └── Extensions+XML.kt │ │ ├── glide │ │ │ ├── GlideKt.kt │ │ │ ├── GlideModule.kt │ │ │ └── ScaleTransformation.kt │ │ ├── gson │ │ │ └── RuntimeTypeAdapterFactory.java │ │ ├── recyclerview │ │ │ └── SpannedGridLayoutManager.kt │ │ ├── room │ │ │ └── IconMetadataConverter.kt │ │ └── widget │ │ │ ├── LauncherProxyAppWidgetHost.kt │ │ │ ├── LauncherProxyAppWidgetHostView.kt │ │ │ ├── PreviewAppWidgetHost.kt │ │ │ ├── PreviewAppWidgetHostView.kt │ │ │ ├── ProxyAppWidgetHost.kt │ │ │ └── ProxyAppWidgetService.kt │ │ ├── widget │ │ ├── BlankWidget.kt │ │ └── ProxyWidget.kt │ │ └── work │ │ └── UpdateCheckWorker.kt │ ├── jniLibs │ ├── README.md │ ├── arm64-v8a │ │ ├── libaapt2.so │ │ └── libzipalign.so │ ├── armeabi-v7a │ │ ├── libaapt2.so │ │ └── libzipalign.so │ ├── x86 │ │ ├── libaapt2.so │ │ └── libzipalign.so │ └── x86_64 │ │ ├── libaapt2.so │ │ └── libzipalign.so │ └── res │ ├── anim │ ├── fast_out_extra_slow_in.xml │ ├── slide_in_left.xml │ ├── slide_in_right.xml │ ├── slide_out_left.xml │ └── slide_out_right.xml │ ├── animator │ └── zoom_in_animator.xml │ ├── color │ └── color_surface_quarter.xml │ ├── drawable-v24 │ ├── background_app_editor_header.xml │ ├── background_circle.xml │ ├── ic_add.xml │ ├── ic_app_editor_save.xml │ ├── ic_apps_icon_pack.xml │ ├── ic_arrow_right.xml │ ├── ic_back.xml │ ├── ic_clear.xml │ ├── ic_error.xml │ ├── ic_icon_source_file.xml │ ├── ic_info.xml │ ├── ic_menu_open_external.xml │ ├── ic_reapply_foreground.xml │ ├── ic_reapply_foreground_monochrome.xml │ ├── ic_search.xml │ ├── rounded_ripple_36.xml │ ├── rounded_ripple_48.xml │ ├── search_box_background.xml │ ├── switch_background.xml │ ├── switch_foreground.xml │ ├── switch_thumb.xml │ └── switch_track.xml │ ├── drawable-v26 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── avd_splash.xml │ ├── background_auto_icon_pack_line.xml │ ├── background_configuration_tabs.xml │ ├── background_tweaks_apply_console.xml │ ├── background_tweaks_widget_replacement_preview.xml │ ├── background_tweaks_widget_replacement_preview_container.xml │ ├── background_widget_size_input.xml │ ├── ic_about_translators_ro.xml │ ├── ic_advanced_debug_restart_reason_toast.xml │ ├── ic_backup_restore_backup.xml │ ├── ic_backup_restore_restore.xml │ ├── ic_check_circle.xml │ ├── ic_chevron_right.xml │ ├── ic_community.xml │ ├── ic_contributions_build.xml │ ├── ic_contributions_icons.xml │ ├── ic_donate.xml │ ├── ic_download.xml │ ├── ic_drag_handle.xml │ ├── ic_error_circle.xml │ ├── ic_faq.xml │ ├── ic_github.xml │ ├── ic_icon_remove.xml │ ├── ic_item_widget_replacement_app_expand.xml │ ├── ic_launcher_monochrome.xml │ ├── ic_libraries.xml │ ├── ic_magisk.xml │ ├── ic_magisk_save.xml │ ├── ic_nav_apps.xml │ ├── ic_nav_options.xml │ ├── ic_nav_shortcuts.xml │ ├── ic_nav_tweaks.xml │ ├── ic_notification.xml │ ├── ic_options_advanced.xml │ ├── ic_options_advanced_reset.xml │ ├── ic_options_advanced_restart.xml │ ├── ic_options_advanced_shortcut.xml │ ├── ic_options_backup_restore_backup.xml │ ├── ic_options_reapply.xml │ ├── ic_reset_warning.xml │ ├── ic_tweaks_deferred_restart.xml │ ├── ic_tweaks_hide_apps.xml │ ├── ic_tweaks_hide_clock.xml │ ├── ic_tweaks_recents.xml │ ├── ic_tweaks_recents_transparency.xml │ ├── ic_tweaks_resize_widgets.xml │ ├── ic_tweaks_smartspace.xml │ ├── ic_tweaks_wallpaper_region_colours.xml │ ├── ic_tweaks_wallpaper_scrim.xml │ ├── ic_tweaks_widget_preview_generic.xml │ ├── ic_tweaks_widget_replacement.xml │ ├── ic_tweaks_widget_replacement_reconfigure.xml │ ├── ic_twitter.xml │ ├── ic_update_download_done.xml │ ├── ic_widget_preview_bottom.xml │ ├── ic_widget_preview_top.xml │ ├── ic_widget_resize_horizontal.xml │ ├── ic_widget_resize_vertical.xml │ ├── ic_widget_size_input_minus.xml │ ├── ic_widget_size_input_plus.xml │ ├── ic_xda.xml │ ├── indicator_configuration_tabs.xml │ ├── switch_background_ripple.xml │ └── widget_background_selected.xml │ ├── font │ ├── google_sans_mono.ttf │ ├── google_sans_text.xml │ ├── google_sans_text_bold.ttf │ ├── google_sans_text_bold_italic.ttf │ ├── google_sans_text_italic.ttf │ ├── google_sans_text_medium.ttf │ ├── google_sans_text_medium_italic.ttf │ └── google_sans_text_regular.ttf │ ├── layout │ ├── activity_main.xml │ ├── activity_widget_resize.xml │ ├── fragment_app_editor.xml │ ├── fragment_apps.xml │ ├── fragment_auto_icon_pack.xml │ ├── fragment_auto_icon_pack_apply.xml │ ├── fragment_backup_restore_backup.xml │ ├── fragment_backup_restore_issues.xml │ ├── fragment_backup_restore_restore.xml │ ├── fragment_container.xml │ ├── fragment_deferred_restart.xml │ ├── fragment_hide_apps.xml │ ├── fragment_icon_picker.xml │ ├── fragment_icon_picker_apps.xml │ ├── fragment_icon_picker_legacy_themed.xml │ ├── fragment_icon_picker_pack.xml │ ├── fragment_magisk_info.xml │ ├── fragment_options_faq.xml │ ├── fragment_options_reapply.xml │ ├── fragment_reset_apply.xml │ ├── fragment_reset_info.xml │ ├── fragment_root.xml │ ├── fragment_settings_base.xml │ ├── fragment_settings_tweaks_overlay.xml │ ├── fragment_settings_update.xml │ ├── fragment_shortcut_editor.xml │ ├── fragment_shortcuts.xml │ ├── fragment_tweaks_apply.xml │ ├── fragment_tweaks_widget_replacement.xml │ ├── fragment_widget_replacement_picker.xml │ ├── fragment_widget_resize.xml │ ├── fragment_widget_resize_page.xml │ ├── include_app_editor_icon_container.xml │ ├── include_app_shortcut_editor_icon_container.xml │ ├── include_hide_apps_magisk.xml │ ├── include_search.xml │ ├── include_widget_resize_sheet.xml │ ├── item_app.xml │ ├── item_app_header.xml │ ├── item_auto_icon_pack.xml │ ├── item_auto_icon_pack_header.xml │ ├── item_auto_icon_pack_line.xml │ ├── item_backup_restore_issue.xml │ ├── item_deferred_restart.xml │ ├── item_deferred_restart_header.xml │ ├── item_hide_app.xml │ ├── item_icon.xml │ ├── item_icon_app.xml │ ├── item_icon_app_header.xml │ ├── item_icon_legacy_themed_header.xml │ ├── item_icon_pack_category.xml │ ├── item_icon_pack_icon.xml │ ├── item_icon_picker_header.xml │ ├── item_icon_source.xml │ ├── item_settings_about.xml │ ├── item_settings_header.xml │ ├── item_settings_slider_item.xml │ ├── item_settings_switch_item.xml │ ├── item_settings_text_item.xml │ ├── item_tweaks_widget_replacement_incompatible.xml │ ├── item_tweaks_widget_replacement_info.xml │ ├── item_tweaks_widget_replacement_picker_header.xml │ ├── item_tweaks_widget_replacement_preview.xml │ ├── item_tweaks_widget_replacement_switch.xml │ ├── item_widget_replacement_picker_app.xml │ ├── item_widget_replacement_picker_widget_image.xml │ ├── item_widget_replacement_picker_widget_layout.xml │ ├── item_widget_resize_target_shortcut.xml │ ├── item_widget_resize_target_space.xml │ ├── item_widget_resize_target_widget.xml │ ├── view_monet_switch.xml │ ├── view_widget_size_input.xml │ ├── widget_blank.xml │ ├── widget_empty.xml │ ├── widget_error.xml │ ├── widget_loading.xml │ ├── widget_preview.xml │ └── widget_wrapper.xml │ ├── menu │ ├── menu_app_editor.xml │ ├── menu_bottom_nav.xml │ ├── menu_hide_apps.xml │ ├── menu_icon_picker.xml │ ├── menu_icon_picker_pack.xml │ ├── menu_tweaks.xml │ └── menu_widget_resize.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ ├── ic_launcher_reapply.xml │ └── ic_launcher_round.xml │ ├── navigation │ ├── nav_graph_activity.xml │ ├── nav_graph_app_editor.xml │ ├── nav_graph_apps.xml │ ├── nav_graph_icon_picker.xml │ ├── nav_graph_main.xml │ ├── nav_graph_options.xml │ ├── nav_graph_root.xml │ ├── nav_graph_shortcuts.xml │ └── nav_graph_tweaks.xml │ ├── values-land │ ├── dimens.xml │ └── integers.xml │ ├── values-night │ ├── bools.xml │ └── colors.xml │ ├── values-ro │ └── strings.xml │ ├── values-ru │ └── strings.xml │ ├── values-tr │ └── strings.xml │ ├── values │ ├── attrs.xml │ ├── bools.xml │ ├── colors.xml │ ├── dimens.xml │ ├── integers.xml │ ├── plurals.xml │ ├── strings.xml │ ├── styles.xml │ ├── themes.xml │ ├── values.xml │ └── vpi.xml │ └── xml │ ├── blank_appwidget_info.xml │ ├── provider_paths.xml │ ├── proxy_appwidget_info.xml │ └── shortcuts.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── overlay ├── .gitignore ├── README.md ├── build.gradle ├── module │ ├── META-INF │ │ └── com │ │ │ └── google │ │ │ └── android │ │ │ ├── update-binary │ │ │ └── updater-script │ ├── customize.sh │ └── module.prop ├── overlay.keystore.jks ├── proguard-rules.pro └── src │ └── main │ └── AndroidManifest.xml ├── settings.gradle └── systemstubs ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── aidl ├── android │ ├── app │ │ ├── IApplicationThread.aidl │ │ ├── IProcessObserver.aidl │ │ ├── IServiceConnection.aidl │ │ └── ProfilerInfo.aidl │ └── content │ │ ├── om │ │ ├── IOverlayManager.aidl │ │ ├── OverlayInfo.aidl │ │ └── OverlayManagerTransaction.aidl │ │ └── pm │ │ ├── ILauncherApps.aidl │ │ ├── IOnAppsChangedListener.aidl │ │ └── ParceledListSlice.aidl └── com │ └── android │ └── internal │ └── appwidget │ ├── IAppWidgetHost.aidl │ └── IAppWidgetService.aidl └── java └── android ├── app ├── IActivityManager.java └── ProfilerInfo.java └── content ├── om ├── CriticalOverlayInfo.java ├── FabricatedOverlay.java ├── OverlayIdentifier.java ├── OverlayInfo.java └── OverlayManagerTransaction.java └── pm ├── BaseParceledListSlice.java └── ParceledListSlice.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/libs/apksigner.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/libs/apksigner.jar -------------------------------------------------------------------------------- /app/libs/sqlite-android.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/libs/sqlite-android.aar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/release/baselineProfiles/0/app-release.dm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/release/baselineProfiles/0/app-release.dm -------------------------------------------------------------------------------- /app/release/baselineProfiles/1/app-release.dm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/release/baselineProfiles/1/app-release.dm -------------------------------------------------------------------------------- /app/release/output-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "com.kieronquinn.app.pixellaunchermods", 8 | "variantName": "release", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "attributes": [], 14 | "versionCode": 266, 15 | "versionName": "2.6.6", 16 | "outputFile": "app-release.apk" 17 | } 18 | ], 19 | "elementType": "File", 20 | "baselineProfiles": [ 21 | { 22 | "minApi": 28, 23 | "maxApi": 30, 24 | "baselineProfiles": [ 25 | "baselineProfiles/1/app-release.dm" 26 | ] 27 | }, 28 | { 29 | "minApi": 31, 30 | "maxApi": 2147483647, 31 | "baselineProfiles": [ 32 | "baselineProfiles/0/app-release.dm" 33 | ] 34 | } 35 | ], 36 | "minSdkVersionForDexing": 31 37 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/model/ipc/GridSize.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.ipc; 2 | 3 | parcelable GridSize; -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/model/ipc/ParceledListSlice.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.kieronquinn.app.pixellaunchermods.model.ipc; 17 | 18 | parcelable ParceledListSlice; -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/model/ipc/ParceledString.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.ipc; 2 | 3 | parcelable ParceledString; -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/model/ipc/ProxyAppWidgetServiceContainer.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.ipc; 2 | 3 | parcelable ProxyAppWidgetServiceContainer; -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/service/IDatabaseChangedListener.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service; 2 | 3 | interface IDatabaseChangedListener { 4 | 5 | void onDatabaseChanged(); 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/service/IIconSizeChangedListener.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service; 2 | 3 | interface IIconSizeChangedListener { 4 | 5 | void onIconSizeChanged(int newSize); 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/service/IPackageChangedListener.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service; 2 | 3 | interface IPackageChangedListener { 4 | 5 | void onPackageChanged(String packageName, boolean isShortcut); 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/service/IPixelLauncherForegroundListener.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service; 2 | 3 | interface IPixelLauncherForegroundListener { 4 | 5 | void onStateChanged(boolean isForeground); 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/service/IPixelLauncherRestartListener.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service; 2 | 3 | interface IPixelLauncherRestartListener { 4 | 5 | void onPixeLauncherRestarted(); 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/aidl/com/kieronquinn/app/pixellaunchermods/service/IResetCompleteCallback.aidl: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service; 2 | 3 | interface IResetCompleteCallback { 4 | 5 | void onResetComplete(); 6 | 7 | } -------------------------------------------------------------------------------- /app/src/main/assets/overlay/build/android-manifest.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/assets/overlay/build/android-manifest.jar -------------------------------------------------------------------------------- /app/src/main/assets/overlay/build/plm.keystore.bk1.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/assets/overlay/build/plm.keystore.bk1.keystore -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/editor/IconPack.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.editor 2 | 3 | import android.content.Intent 4 | import android.os.Parcelable 5 | import com.kieronquinn.app.pixellaunchermods.model.icon.ApplicationIcon 6 | import kotlinx.parcelize.Parcelize 7 | 8 | @Parcelize 9 | data class IconPack( 10 | val packageName: String, 11 | val label: CharSequence, 12 | val iconPackIcon: ApplicationIcon, 13 | val externalIntent: Intent? 14 | ) : Parcelable -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/github/GitHubRelease.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.github 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | class GitHubRelease { 6 | 7 | @SerializedName("html_url") 8 | val gitHubUrl: String? = null 9 | 10 | @SerializedName("tag_name") 11 | val tag: String? = null 12 | 13 | @SerializedName("name") 14 | val versionName: String? = null 15 | 16 | @SerializedName("body") 17 | val body: String? = null 18 | 19 | @SerializedName("assets") 20 | val assets: Array? = null 21 | 22 | class Asset { 23 | @SerializedName("browser_download_url") 24 | val downloadUrl: String? = null 25 | 26 | @SerializedName("content_type") 27 | val contentType: String? = null 28 | 29 | @SerializedName("name") 30 | val fileName: String? = null 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/icon/ApplicationIcon.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.icon 2 | 3 | import android.content.pm.ApplicationInfo 4 | import android.os.Parcelable 5 | import kotlinx.parcelize.Parcelize 6 | 7 | @Parcelize 8 | data class ApplicationIcon( 9 | val applicationInfo: ApplicationInfo, 10 | val shrinkNonAdaptiveIcons: Boolean, 11 | val mono: Boolean = false 12 | ): Parcelable 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/icon/RawBytesIcon.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.icon 2 | 3 | data class RawBytesIcon(val bytes: ByteArray, val size: Int) { 4 | override fun equals(other: Any?): Boolean { 5 | if (this === other) return true 6 | if (javaClass != other?.javaClass) return false 7 | 8 | other as RawBytesIcon 9 | 10 | if (!bytes.contentEquals(other.bytes)) return false 11 | if (size != other.size) return false 12 | 13 | return true 14 | } 15 | 16 | override fun hashCode(): Int { 17 | var result = bytes.contentHashCode() 18 | result = 31 * result + size 19 | return result 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/ipc/GridSize.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.ipc 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | data class GridSize(val x: Int, val y: Int): Parcelable { 8 | 9 | companion object { 10 | private const val LAUNCHER_DB_PREFIX = "launcher" 11 | private const val LAUNCHER_DB_FILETYPE = ".db" 12 | } 13 | 14 | fun toLauncherFilename(): String { 15 | return if(x == 5 && y == 5) { 16 | "$LAUNCHER_DB_PREFIX$LAUNCHER_DB_FILETYPE" 17 | }else{ 18 | "${LAUNCHER_DB_PREFIX}_${x}_by_${y}$LAUNCHER_DB_FILETYPE" 19 | } 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/ipc/ParceledString.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.ipc 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | data class ParceledString(val value: String): Parcelable -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/ipc/ProxyAppWidgetServiceContainer.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.ipc 2 | 3 | import android.os.IBinder 4 | import android.os.Parcelable 5 | import com.android.internal.appwidget.IAppWidgetService 6 | import kotlinx.parcelize.Parcelize 7 | 8 | @Parcelize 9 | data class ProxyAppWidgetServiceContainer(val proxy: IBinder): Parcelable 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/remote/RemoteWidget.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.remote 2 | 3 | import android.os.Bundle 4 | import android.os.Parcelable 5 | import androidx.core.os.bundleOf 6 | import kotlinx.parcelize.Parcelize 7 | 8 | @Parcelize 9 | data class RemoteWidget( 10 | val appWidgetId: Int, 11 | var spanX: Int, 12 | var spanY: Int 13 | ) : Parcelable { 14 | 15 | companion object { 16 | private const val KEY_APP_WIDGET_ID = "app_widget_id" 17 | private const val KEY_SPAN_X = "span_x" 18 | private const val KEY_SPAN_Y = "span_y" 19 | } 20 | 21 | 22 | constructor(bundle: Bundle): this( 23 | bundle.getInt(KEY_APP_WIDGET_ID), 24 | bundle.getInt(KEY_SPAN_X), 25 | bundle.getInt(KEY_SPAN_Y) 26 | ) 27 | 28 | fun toBundle(): Bundle { 29 | return bundleOf( 30 | KEY_APP_WIDGET_ID to appWidgetId, 31 | KEY_SPAN_X to spanX, 32 | KEY_SPAN_Y to spanY, 33 | ) 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/room/AppsDao.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.room 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import kotlinx.coroutines.flow.Flow 8 | 9 | @Dao 10 | interface AppsDao { 11 | 12 | @Query("select * from apps") 13 | fun getAll(): Flow> 14 | 15 | @Query("select * from apps where componentName=:componentName") 16 | fun getByComponentName(componentName: String): Flow> 17 | 18 | @Insert(onConflict = OnConflictStrategy.REPLACE) 19 | fun insert(vararg app: ModifiedApp) 20 | 21 | @Query("delete from apps where componentName=:componentName") 22 | fun delete(componentName: String) 23 | 24 | @Query("delete from apps") 25 | fun deleteAll() 26 | 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/room/PixelLauncherModsDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.room 2 | 3 | import android.content.Context 4 | import androidx.room.Database 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.kieronquinn.app.pixellaunchermods.utils.room.IconMetadataConverter 8 | 9 | @Database(entities = [ModifiedApp::class, ModifiedShortcut::class], version = 1) 10 | abstract class PixelLauncherModsDatabase: RoomDatabase() { 11 | 12 | abstract fun appsDao(): AppsDao 13 | abstract fun shortcutsDao(): ShortcutsDao 14 | 15 | } 16 | 17 | private const val DATABASE_NAME = "pixellaunchermods.db" 18 | 19 | fun getRoomDatabase(context: Context) = 20 | Room.databaseBuilder(context, PixelLauncherModsDatabase::class.java, DATABASE_NAME) 21 | .addTypeConverter(IconMetadataConverter()) 22 | .build() -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/room/ShortcutsDao.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.room 2 | 3 | import androidx.room.Dao 4 | import androidx.room.Insert 5 | import androidx.room.OnConflictStrategy 6 | import androidx.room.Query 7 | import kotlinx.coroutines.flow.Flow 8 | 9 | @Dao 10 | interface ShortcutsDao { 11 | 12 | @Query("select * from shortcuts") 13 | fun getAll(): Flow> 14 | 15 | @Query("select * from shortcuts where intent=:intent") 16 | fun getByIntent(intent: String): Flow> 17 | 18 | @Insert(onConflict = OnConflictStrategy.REPLACE) 19 | fun insert(vararg shortcut: ModifiedShortcut) 20 | 21 | @Query("delete from shortcuts where intent=:intent") 22 | fun delete(intent: String) 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/tweaks/WidgetReplacement.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.tweaks 2 | 3 | import android.appwidget.AppWidgetHostView 4 | import android.os.Parcelable 5 | import kotlinx.parcelize.Parcelize 6 | 7 | enum class WidgetReplacement { 8 | NONE, TOP, BOTTOM 9 | } 10 | 11 | @Parcelize 12 | data class ParceledWidgetReplacement(val widgetReplacement: WidgetReplacement): Parcelable 13 | 14 | data class WidgetReplacementOptions( 15 | val widgetView: AppWidgetHostView, 16 | val widgetReplacement: WidgetReplacement 17 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/model/update/Release.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.model.update 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | data class Release(val tag: String, val versionName: String, val downloadUrl: String, val fileName: String, val gitHubUrl: String, val body: String): Parcelable 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/receivers/BootReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.receivers 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import com.kieronquinn.app.pixellaunchermods.repositories.SettingsRepository 7 | import com.kieronquinn.app.pixellaunchermods.service.PixelLauncherModsForegroundService 8 | import org.koin.core.component.KoinComponent 9 | import org.koin.core.component.inject 10 | 11 | class BootReceiver: BroadcastReceiver(), KoinComponent { 12 | 13 | private val settings by inject() 14 | 15 | override fun onReceive(context: Context, intent: Intent) { 16 | if(intent.action != Intent.ACTION_BOOT_COMPLETED) return 17 | if(!settings.shouldLaunchService.getSync()) return 18 | PixelLauncherModsForegroundService.start(context, true) 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/repositories/AppStateRepository.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.repositories 2 | 3 | import kotlinx.coroutines.GlobalScope 4 | import kotlinx.coroutines.flow.MutableStateFlow 5 | import kotlinx.coroutines.flow.StateFlow 6 | import kotlinx.coroutines.launch 7 | 8 | interface AppStateRepository { 9 | 10 | val appInForeground: StateFlow 11 | 12 | fun onResume() 13 | fun onPause() 14 | 15 | } 16 | 17 | class AppStateRepositoryImpl: AppStateRepository { 18 | 19 | override val appInForeground = MutableStateFlow(false) 20 | 21 | override fun onResume() { 22 | GlobalScope.launch { 23 | appInForeground.emit(true) 24 | } 25 | } 26 | 27 | override fun onPause() { 28 | GlobalScope.launch { 29 | appInForeground.emit(false) 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/service/GitHubService.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.service 2 | 3 | import com.kieronquinn.app.pixellaunchermods.model.github.GitHubRelease 4 | import retrofit2.Call 5 | import retrofit2.Retrofit 6 | import retrofit2.converter.gson.GsonConverterFactory 7 | import retrofit2.http.GET 8 | 9 | interface GitHubService { 10 | 11 | @GET("releases") 12 | fun getReleases(): Call> 13 | 14 | } 15 | 16 | fun createGitHubService(): GitHubService = 17 | Retrofit.Builder() 18 | .baseUrl("https://api.github.com/repos/KieronQuinn/PixelLauncherMods/") 19 | .addConverterFactory(GsonConverterFactory.create()) 20 | .build() 21 | .run { 22 | create(GitHubService::class.java) 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/activities/WidgetResizeActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.activities 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.core.view.WindowCompat 6 | import com.google.android.material.color.DynamicColors 7 | import com.kieronquinn.app.pixellaunchermods.R 8 | 9 | class WidgetResizeActivity: AppCompatActivity() { 10 | 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | WindowCompat.setDecorFitsSystemWindows(window, false) 14 | DynamicColors.applyToActivityIfAvailable(this) 15 | setContentView(R.layout.activity_widget_resize) 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/base/FragmentOptions.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.base 2 | 3 | import android.view.Menu 4 | import android.view.MenuInflater 5 | import android.view.MenuItem 6 | 7 | interface BackAvailable 8 | interface LockCollapsed 9 | interface CanShowSnackbar 10 | interface Root 11 | 12 | interface ProvidesBack { 13 | fun onBackPressed(): Boolean 14 | fun interceptBack() = true 15 | } 16 | 17 | interface ProvidesTitle { 18 | fun getTitle(): CharSequence? 19 | } 20 | 21 | interface ProvidesOverflow { 22 | fun inflateMenu(menuInflater: MenuInflater, menu: Menu) 23 | fun onMenuItemSelected(menuItem: MenuItem): Boolean 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/base/settings/BaseSettingsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.base.settings 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import androidx.recyclerview.widget.LinearLayoutManager 6 | import com.kieronquinn.app.pixellaunchermods.databinding.FragmentSettingsBaseBinding 7 | import com.kieronquinn.app.pixellaunchermods.ui.base.BoundFragment 8 | import com.kieronquinn.app.pixellaunchermods.ui.base.settings.BaseSettingsViewModel.SettingsItem 9 | import com.kieronquinn.app.pixellaunchermods.utils.extensions.applyBottomNavigationInset 10 | 11 | abstract class BaseSettingsFragment: BoundFragment(FragmentSettingsBaseBinding::inflate) { 12 | 13 | abstract val viewModel: BaseSettingsViewModel 14 | abstract val items: List 15 | 16 | abstract fun createAdapter(items: List): BaseSettingsAdapter 17 | 18 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 19 | super.onViewCreated(view, savedInstanceState) 20 | setupRecyclerView() 21 | } 22 | 23 | private fun setupRecyclerView() = with(binding.root) { 24 | layoutManager = LinearLayoutManager(context) 25 | adapter = createAdapter(items) 26 | applyBottomNavigationInset() 27 | } 28 | 29 | override fun onDestroyView() { 30 | binding.settingsBaseRecyclerView.adapter = null 31 | super.onDestroyView() 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/backuprestore/restore/issues/BackupRestoreIssuesFragment.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.backuprestore.restore.issues 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import androidx.navigation.fragment.navArgs 6 | import androidx.recyclerview.widget.LinearLayoutManager 7 | import com.kieronquinn.app.pixellaunchermods.R 8 | import com.kieronquinn.app.pixellaunchermods.databinding.FragmentBackupRestoreIssuesBinding 9 | import com.kieronquinn.app.pixellaunchermods.ui.base.BackAvailable 10 | import com.kieronquinn.app.pixellaunchermods.ui.base.BoundFragment 11 | import com.kieronquinn.app.pixellaunchermods.utils.extensions.applyBottomNavigationInset 12 | 13 | class BackupRestoreIssuesFragment: BoundFragment(FragmentBackupRestoreIssuesBinding::inflate), BackAvailable { 14 | 15 | private val args by navArgs() 16 | 17 | private val adapter by lazy { 18 | BackupRestoreIssuesAdapter(requireContext(), args.issues.toList()) 19 | } 20 | 21 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 22 | super.onViewCreated(view, savedInstanceState) 23 | setupRecyclerView() 24 | } 25 | 26 | private fun setupRecyclerView() = with(binding.restoreIssuesRecyclerview) { 27 | adapter = this@BackupRestoreIssuesFragment.adapter 28 | layoutManager = LinearLayoutManager(context) 29 | applyBottomNavigationInset(resources.getDimension(R.dimen.margin_16)) 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/iconpicker/BasePickerViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.iconpicker 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.viewModelScope 5 | import com.kieronquinn.app.pixellaunchermods.R 6 | import com.kieronquinn.app.pixellaunchermods.components.navigation.ContainerNavigation 7 | import com.kieronquinn.app.pixellaunchermods.model.icon.IconPickerResult 8 | import com.kieronquinn.app.pixellaunchermods.repositories.IconLoaderRepository 9 | import kotlinx.coroutines.flow.MutableSharedFlow 10 | import kotlinx.coroutines.flow.MutableStateFlow 11 | import kotlinx.coroutines.launch 12 | 13 | abstract class BasePickerViewModel( 14 | private val iconLoaderRepository: IconLoaderRepository, 15 | private val navigation: ContainerNavigation 16 | ): ViewModel() { 17 | 18 | data class IconPickerResultOptions(val result: IconPickerResult, val mono: Boolean, val loadFullRes: Boolean) 19 | 20 | val iconPickerResultBus = MutableSharedFlow() 21 | val monoConfig = MutableStateFlow(null) 22 | 23 | fun isMono(): Boolean { 24 | return monoConfig.value ?: false 25 | } 26 | 27 | protected fun onIconSelected(result: IconPickerResult?) { 28 | viewModelScope.launch { 29 | iconPickerResultBus.emit(result) 30 | } 31 | } 32 | 33 | fun navigateUpToAppEditor() { 34 | viewModelScope.launch { 35 | navigation.navigateUpTo(R.id.nav_graph_icon_picker, true) 36 | } 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/magiskinfo/MagiskInfoViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.magiskinfo 2 | 3 | import android.net.Uri 4 | import androidx.activity.result.ActivityResultLauncher 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.kieronquinn.app.pixellaunchermods.repositories.OverlayRepository 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.launch 10 | 11 | abstract class MagiskInfoViewModel: ViewModel() { 12 | 13 | abstract fun onSaveModuleClicked(launcher: ActivityResultLauncher) 14 | abstract fun saveModule(uri: Uri) 15 | 16 | } 17 | 18 | class MagiskInfoViewModelImpl( 19 | private val overlayRepository: OverlayRepository 20 | ): MagiskInfoViewModel() { 21 | 22 | override fun onSaveModuleClicked(launcher: ActivityResultLauncher) { 23 | launcher.launch(overlayRepository.getModuleFilename()) 24 | } 25 | 26 | override fun saveModule(uri: Uri) { 27 | viewModelScope.launch(Dispatchers.IO) { 28 | overlayRepository.saveModule(uri) 29 | } 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/options/contributors/ContributorsViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.options.contributors 2 | 3 | import android.content.Intent 4 | import android.net.Uri 5 | import androidx.lifecycle.viewModelScope 6 | import com.kieronquinn.app.pixellaunchermods.components.navigation.ContainerNavigation 7 | import com.kieronquinn.app.pixellaunchermods.ui.base.settings.BaseSettingsViewModel 8 | import kotlinx.coroutines.launch 9 | 10 | abstract class ContributorsViewModel: BaseSettingsViewModel() { 11 | 12 | abstract fun onLinkClicked(url: String) 13 | 14 | } 15 | 16 | class ContributorsViewModelImpl( 17 | private val navigation: ContainerNavigation 18 | ): ContributorsViewModel() { 19 | 20 | override fun onLinkClicked(url: String) { 21 | viewModelScope.launch { 22 | navigation.navigate(Intent(Intent.ACTION_VIEW).apply { 23 | data = Uri.parse(url) 24 | }) 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/options/reapply/OptionsReapplyFragment.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.options.reapply 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import android.widget.Toast 6 | import androidx.lifecycle.lifecycleScope 7 | import com.kieronquinn.app.pixellaunchermods.R 8 | import com.kieronquinn.app.pixellaunchermods.databinding.FragmentOptionsReapplyBinding 9 | import com.kieronquinn.app.pixellaunchermods.ui.base.BackAvailable 10 | import com.kieronquinn.app.pixellaunchermods.ui.base.BoundFragment 11 | import org.koin.androidx.viewmodel.ext.android.viewModel 12 | 13 | class OptionsReapplyFragment: BoundFragment(FragmentOptionsReapplyBinding::inflate), BackAvailable { 14 | 15 | private val viewModel by viewModel() 16 | 17 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 18 | super.onViewCreated(view, savedInstanceState) 19 | setupFinished() 20 | } 21 | 22 | private fun setupFinished() = viewLifecycleOwner.lifecycleScope.launchWhenResumed { 23 | viewModel.finishedBus.collect { 24 | Toast.makeText(requireContext(), R.string.options_reapply_finished, Toast.LENGTH_LONG).show() 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/options/reapply/OptionsReapplyViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.options.reapply 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.viewModelScope 5 | import com.kieronquinn.app.pixellaunchermods.components.navigation.ContainerNavigation 6 | import com.kieronquinn.app.pixellaunchermods.repositories.RemoteAppsRepository 7 | import kotlinx.coroutines.Dispatchers 8 | import kotlinx.coroutines.flow.Flow 9 | import kotlinx.coroutines.flow.MutableSharedFlow 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.withContext 12 | 13 | abstract class OptionsReapplyViewModel: ViewModel() { 14 | 15 | abstract val finishedBus: Flow 16 | 17 | } 18 | 19 | class OptionsReapplyViewModelImpl( 20 | private val remoteAppsRepository: RemoteAppsRepository, 21 | private val navigation: ContainerNavigation 22 | ): OptionsReapplyViewModel() { 23 | 24 | override val finishedBus = MutableSharedFlow() 25 | 26 | private fun applyIcons() = viewModelScope.launch { 27 | withContext(Dispatchers.IO) { 28 | remoteAppsRepository.getRemoteApps(true) 29 | } 30 | finishedBus.emit(Unit) 31 | navigation.navigateBack() 32 | } 33 | 34 | init { 35 | applyIcons() 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/reset/apply/ResetApplyFragment.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.reset.apply 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import android.widget.Toast 6 | import androidx.lifecycle.lifecycleScope 7 | import com.kieronquinn.app.pixellaunchermods.R 8 | import com.kieronquinn.app.pixellaunchermods.databinding.FragmentResetApplyBinding 9 | import com.kieronquinn.app.pixellaunchermods.ui.base.BackAvailable 10 | import com.kieronquinn.app.pixellaunchermods.ui.base.BoundFragment 11 | import org.koin.androidx.viewmodel.ext.android.viewModel 12 | 13 | class ResetApplyFragment: BoundFragment(FragmentResetApplyBinding::inflate), BackAvailable { 14 | 15 | private val viewModel by viewModel() 16 | 17 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 18 | super.onViewCreated(view, savedInstanceState) 19 | setupComplete() 20 | } 21 | 22 | private fun setupComplete() = viewLifecycleOwner.lifecycleScope.launchWhenResumed { 23 | viewModel.completeBus.collect { 24 | if(it) viewModel 25 | val message = if(it) { 26 | R.string.reset_apply_toast_success 27 | } else { 28 | R.string.reset_apply_toast_failed 29 | } 30 | Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show() 31 | viewModel.close() 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/reset/apply/ResetApplyViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.reset.apply 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.viewModelScope 5 | import com.kieronquinn.app.pixellaunchermods.components.navigation.ContainerNavigation 6 | import com.kieronquinn.app.pixellaunchermods.repositories.RemoteAppsRepository 7 | import kotlinx.coroutines.flow.Flow 8 | import kotlinx.coroutines.launch 9 | 10 | abstract class ResetApplyViewModel: ViewModel() { 11 | 12 | abstract val completeBus: Flow 13 | 14 | abstract fun reload() 15 | abstract fun close() 16 | 17 | } 18 | 19 | class ResetApplyViewModelImpl( 20 | private val remoteAppsRepository: RemoteAppsRepository, 21 | private val navigation: ContainerNavigation 22 | ): ResetApplyViewModel() { 23 | 24 | override val completeBus = remoteAppsRepository.resetAllApps() 25 | 26 | override fun reload() { 27 | viewModelScope.launch { 28 | remoteAppsRepository.forceReload() 29 | } 30 | } 31 | 32 | override fun close() { 33 | viewModelScope.launch { 34 | navigation.navigateBack() 35 | } 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/root/RootFragment.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.root 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import androidx.lifecycle.lifecycleScope 6 | import androidx.navigation.fragment.NavHostFragment 7 | import com.kieronquinn.app.pixellaunchermods.R 8 | import com.kieronquinn.app.pixellaunchermods.components.navigation.RootNavigation 9 | import com.kieronquinn.app.pixellaunchermods.components.navigation.setupWithNavigation 10 | import com.kieronquinn.app.pixellaunchermods.databinding.FragmentRootBinding 11 | import com.kieronquinn.app.pixellaunchermods.ui.base.BoundFragment 12 | import kotlinx.coroutines.launch 13 | import org.koin.android.ext.android.inject 14 | 15 | class RootFragment: BoundFragment(FragmentRootBinding::inflate) { 16 | 17 | private val navHostFragment by lazy { 18 | childFragmentManager.findFragmentById(R.id.nav_host_fragment_root) as NavHostFragment 19 | } 20 | 21 | private val navigation by inject() 22 | 23 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 24 | super.onViewCreated(view, savedInstanceState) 25 | setupNavigation() 26 | } 27 | 28 | private fun setupNavigation() = viewLifecycleOwner.lifecycleScope.launchWhenResumed { 29 | launch { 30 | navHostFragment.setupWithNavigation(navigation) 31 | } 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/screens/tweaks/widgetresize/WidgetResizePagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.screens.tweaks.widgetresize 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.viewpager2.adapter.FragmentStateAdapter 5 | 6 | class WidgetResizePagerAdapter(fragment: Fragment, var pageCount: Int, var spanX: Int, var spanY: Int): FragmentStateAdapter(fragment) { 7 | 8 | override fun getItemCount() = pageCount 9 | 10 | override fun createFragment(position: Int): Fragment { 11 | return WidgetResizePageFragment.newInstance(position, spanX, spanY) 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/views/TouchIgnoringFrameLayout.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.views 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.MotionEvent 6 | import android.view.View 7 | import android.widget.FrameLayout 8 | 9 | /** 10 | * A [FrameLayout] that will block touch events to its children, and instead send them on to its 11 | * parent, if one is attached. Used to block widget preview layout touches. 12 | */ 13 | class TouchIgnoringFrameLayout: FrameLayout { 14 | 15 | constructor(context: Context, attributeSet: AttributeSet? = null, defStyleRes: Int): 16 | super(context, attributeSet, defStyleRes) 17 | constructor(context: Context, attributeSet: AttributeSet?): 18 | this(context, attributeSet, 0) 19 | constructor(context: Context): 20 | this(context, null, 0) 21 | 22 | override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { 23 | (parent as? View)?.let { 24 | it.dispatchTouchEvent(ev) 25 | return true 26 | } 27 | return false 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/views/viewpager/BasePageIndicator.java: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.ui.views.viewpager; 2 | 3 | import androidx.viewpager2.widget.ViewPager2; 4 | 5 | /** 6 | * Split off from PageIndicator to allow both the actual implementation and the View to implement 7 | * the same interface. 8 | */ 9 | public interface BasePageIndicator { 10 | 11 | /** 12 | * Bind the indicator to a ViewPager. 13 | * 14 | * @param view 15 | */ 16 | void setViewPager(ViewPager2 view); 17 | 18 | /** 19 | * Bind the indicator to a ViewPager. 20 | * 21 | * @param view 22 | * @param initialPosition 23 | */ 24 | void setViewPager(ViewPager2 view, int initialPosition); 25 | 26 | /** 27 | *

Set the current page of both the ViewPager and indicator.

28 | * 29 | *

This must be used if you need to set the page before 30 | * the views are drawn on screen (e.g., default start page).

31 | * 32 | * @param item 33 | */ 34 | void setCurrentItem(int item); 35 | 36 | /** 37 | * Set a page change listener which will receive forwarded events. 38 | * 39 | * @param listener 40 | */ 41 | void setOnPageChangeListener(ViewPager2.OnPageChangeCallback listener); 42 | 43 | /** 44 | * Notify the indicator that the fragment list has changed. 45 | */ 46 | void notifyDataSetChanged(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/ui/views/viewpager/PageIndicator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Patrik Akerfeldt 3 | * Copyright (C) 2011 Jake Wharton 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.kieronquinn.app.pixellaunchermods.ui.views.viewpager; 19 | 20 | import androidx.viewpager2.widget.ViewPager2; 21 | 22 | /** 23 | * A PageIndicator is responsible to show an visual indicator on the total views 24 | * number and the current visible view. 25 | */ 26 | public abstract class PageIndicator extends ViewPager2.OnPageChangeCallback implements BasePageIndicator {} -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/appbar/DragDisabledAppBarLayoutBehaviour.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.appbar 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import com.google.android.material.appbar.AppBarLayout 6 | 7 | class DragDisabledAppBarLayoutBehaviour: AppBarLayout.Behavior { 8 | 9 | constructor(): super() 10 | constructor(context: Context?, attrs: AttributeSet?): super(context, attrs) 11 | 12 | init { 13 | setDragCallback(object: DragCallback() { 14 | override fun canDrag(appBarLayout: AppBarLayout): Boolean { 15 | return false 16 | } 17 | }) 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+ActivityOptionsCompat.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.app.ActivityOptions 4 | import android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED 5 | import android.os.Build 6 | import androidx.core.app.ActivityOptionsCompat 7 | 8 | fun ActivityOptionsCompat.allowBackground() = apply { 9 | if (Build.VERSION.SDK_INT >= 34) { 10 | val impl = Class 11 | .forName("androidx.core.app.ActivityOptionsCompat\$ActivityOptionsCompatImpl") 12 | val inner = impl.getDeclaredField("mActivityOptions").apply { 13 | isAccessible = true 14 | }.get(this) as ActivityOptions 15 | inner.apply { 16 | pendingIntentBackgroundActivityStartMode = MODE_BACKGROUND_ACTIVITY_START_ALLOWED 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+AdaptiveIconDrawable.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.graphics.drawable.AdaptiveIconDrawable 4 | import android.graphics.drawable.Drawable 5 | 6 | fun AdaptiveIconDrawable.getMonochromeOrForeground(): Drawable { 7 | return getMonochromeInternal() ?: foreground 8 | } 9 | 10 | //TODO move to using standard API when targeting T 11 | private fun AdaptiveIconDrawable.getMonochromeInternal(): Drawable? { 12 | return try { 13 | AdaptiveIconDrawable::class.java.getMethod("getMonochrome").invoke(this) as? Drawable 14 | }catch (e: NoSuchMethodException){ 15 | null 16 | } 17 | } 18 | 19 | fun AdaptiveIconDrawable_getInsetFraction(): Float { 20 | return AdaptiveIconDrawable.getExtraInsetFraction() / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction()) 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+AppBarLayout.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.Fragment 5 | import com.google.android.material.appbar.AppBarLayout 6 | import kotlinx.coroutines.channels.awaitClose 7 | import kotlinx.coroutines.flow.callbackFlow 8 | import kotlin.math.abs 9 | 10 | fun AppBarLayout.collapsedState() = callbackFlow { 11 | var cachedState = false 12 | val listener = AppBarLayout.OnOffsetChangedListener { _, verticalOffset -> 13 | if(verticalOffset == 0){ 14 | if(cachedState) { 15 | cachedState = false 16 | trySend(false) 17 | } 18 | }else if(abs(verticalOffset) >= totalScrollRange){ 19 | if(!cachedState) { 20 | cachedState = true 21 | trySend(true) 22 | } 23 | } 24 | } 25 | addOnOffsetChangedListener(listener) 26 | awaitClose { 27 | removeOnOffsetChangedListener(listener) 28 | } 29 | } 30 | 31 | private const val FRAGMENT_ARGUMENTS_APP_BAR_COLLAPSED = "app_bar_collapsed" 32 | 33 | fun Fragment.rememberAppBarCollapsed(collapsed: Boolean) { 34 | val arguments = this.arguments ?: Bundle() 35 | arguments.putBoolean(FRAGMENT_ARGUMENTS_APP_BAR_COLLAPSED, collapsed) 36 | this.arguments = arguments 37 | } 38 | 39 | fun Fragment.getRememberedAppBarCollapsed(): Boolean { 40 | return arguments?.getBoolean(FRAGMENT_ARGUMENTS_APP_BAR_COLLAPSED, false) ?: false 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+AppIconLoader.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import me.zhanghai.android.appiconloader.AppIconLoader 4 | 5 | fun AppIconLoader.setShrinkNonAdaptiveIcons(shrinkNonAdaptiveIcons: Boolean){ 6 | AppIconLoader::class.java.getDeclaredField("mShrinkNonAdaptiveIcons").apply { 7 | isAccessible = true 8 | }.set(this, shrinkNonAdaptiveIcons) 9 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+AssetManager.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.content.res.AssetManager 4 | import java.io.File 5 | import java.io.FileOutputStream 6 | 7 | //https://stackoverflow.com/a/54193251/1088334 8 | fun AssetManager.copyRecursively(assetPath: String, targetFile: File) { 9 | val list = list(assetPath) ?: return 10 | if (list.isEmpty()) { // assetPath is file 11 | open(assetPath).use { input -> 12 | FileOutputStream(targetFile.absolutePath).use { output -> 13 | input.copyTo(output) 14 | output.flush() 15 | } 16 | } 17 | } else { // assetPath is folder 18 | targetFile.delete() 19 | targetFile.mkdir() 20 | list.forEach { 21 | copyRecursively("$assetPath/$it", File(targetFile, it)) 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Color.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.content.Context 4 | import androidx.core.content.ContextCompat 5 | 6 | fun Context.getPlateColours(): IntArray { 7 | val colors = IntArray(2) 8 | if (isDarkMode) { 9 | colors[0] = ContextCompat.getColor(this, android.R.color.system_neutral1_800) 10 | colors[1] = ContextCompat.getColor(this, android.R.color.system_accent1_100) 11 | } else { 12 | colors[0] = ContextCompat.getColor(this, android.R.color.system_accent1_100) 13 | colors[1] = ContextCompat.getColor(this, android.R.color.system_neutral2_700) 14 | } 15 | return colors 16 | } 17 | 18 | fun Int.toHexString(): String { 19 | return "#" + Integer.toHexString(this) 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+ComponentName.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.content.ComponentName 4 | import java.lang.Exception 5 | 6 | fun String.parseToComponentName(): ComponentName? { 7 | return try { 8 | ComponentName.unflattenFromString(this) 9 | }catch (e: Exception){ 10 | null 11 | } 12 | } 13 | 14 | fun ComponentName.unshortenToString(): String { 15 | val clazz = if(className.startsWith(".")){ 16 | "$packageName$className" 17 | }else className 18 | return ComponentName(packageName, clazz).flattenToString() 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+CompoundButton.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.widget.CompoundButton 4 | import kotlinx.coroutines.channels.awaitClose 5 | import kotlinx.coroutines.flow.callbackFlow 6 | import kotlinx.coroutines.flow.debounce 7 | 8 | fun CompoundButton.onChanged() = callbackFlow { 9 | val listener = CompoundButton.OnCheckedChangeListener { _, checked -> 10 | trySend(checked) 11 | } 12 | setOnCheckedChangeListener(listener) 13 | awaitClose { 14 | setOnCheckedChangeListener(null) 15 | } 16 | }.debounce(TAP_DEBOUNCE) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+ContentResovler.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.content.ContentResolver 4 | import android.database.ContentObserver 5 | import android.net.Uri 6 | import android.os.Handler 7 | import android.os.Looper 8 | import kotlinx.coroutines.channels.awaitClose 9 | import kotlinx.coroutines.flow.callbackFlow 10 | 11 | fun ContentResolver.observerAsFlow(uri: Uri, notifyForDecedents: Boolean, handler: Handler = Handler(Looper.getMainLooper()), ignoreSelfChanges: Boolean = false) = callbackFlow{ 12 | val observer = object: ContentObserver(handler) { 13 | override fun onChange(selfChange: Boolean, uri: Uri?) { 14 | super.onChange(selfChange, uri) 15 | if(ignoreSelfChanges && selfChange) return 16 | trySend(uri) 17 | } 18 | } 19 | registerContentObserver(uri, notifyForDecedents, observer) 20 | awaitClose { 21 | unregisterContentObserver(observer) 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Coroutines.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import kotlinx.coroutines.suspendCancellableCoroutine 4 | import kotlinx.coroutines.withTimeoutOrNull 5 | import kotlin.coroutines.Continuation 6 | 7 | suspend inline fun suspendCoroutineWithTimeout(timeout: Long, crossinline block: (Continuation) -> Unit ) : T? { 8 | var finalValue : T? = null 9 | withTimeoutOrNull(timeout) { 10 | finalValue = suspendCancellableCoroutine(block = block) 11 | } 12 | return finalValue 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Cursor.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.database.Cursor 4 | 5 | fun Cursor.map(row: (Cursor) -> T): List { 6 | moveToFirst() 7 | if(isAfterLast) return emptyList() 8 | val list = ArrayList() 9 | do { 10 | try { 11 | list.add(row(this)) 12 | }catch (e: IllegalStateException){ 13 | //Cursor has hit a snag, suppress for now 14 | //TODO try to find a better solution to this - probably concurrent change with the launcher 15 | } 16 | }while (moveToNext()) 17 | return list 18 | } 19 | 20 | fun Cursor.firstNotNull(row: (Cursor) -> T?): T? { 21 | moveToFirst() 22 | if(isAfterLast){ 23 | return null 24 | } 25 | do { 26 | val processed = row(this) 27 | if(processed != null){ 28 | return processed 29 | } 30 | }while (moveToNext()) 31 | return null 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+EditText.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.widget.EditText 4 | import android.widget.TextView 5 | import androidx.core.widget.addTextChangedListener 6 | import kotlinx.coroutines.channels.awaitClose 7 | import kotlinx.coroutines.flow.callbackFlow 8 | import kotlinx.coroutines.flow.debounce 9 | 10 | fun EditText.onChanged() = callbackFlow { 11 | val watcher = addTextChangedListener { 12 | trySend(it?.toString() ?: "") 13 | } 14 | addTextChangedListener(watcher) 15 | awaitClose { 16 | removeTextChangedListener(watcher) 17 | } 18 | }.debounce(TAP_DEBOUNCE) 19 | 20 | fun EditText.onEditorActionSent(filter: Int? = null) = callbackFlow { 21 | val listener = TextView.OnEditorActionListener { _, actionId, _ -> 22 | trySend(actionId) 23 | filter?.let { actionId == filter } ?: true 24 | } 25 | setOnEditorActionListener(listener) 26 | awaitClose { 27 | setOnEditorActionListener(null) 28 | } 29 | }.debounce(TAP_DEBOUNCE) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+File.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.os.FileObserver 4 | import kotlinx.coroutines.channels.awaitClose 5 | import kotlinx.coroutines.flow.callbackFlow 6 | import java.io.File 7 | 8 | fun File.observe() = callbackFlow { 9 | val observer = object: FileObserver(this@observe, ALL_EVENTS) { 10 | override fun onEvent(event: Int, path: String?) { 11 | trySend(event) 12 | } 13 | } 14 | observer.startWatching() 15 | awaitClose { 16 | observer.stopWatching() 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Flow.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import kotlinx.coroutines.delay 4 | import kotlinx.coroutines.flow.* 5 | import kotlinx.coroutines.launch 6 | 7 | fun Flow.debounceIf(requirement: Boolean, time: Long): Flow { 8 | return this.debounce { _: T -> 9 | if(requirement) time else 0L 10 | } 11 | } 12 | 13 | fun tickerFlow(timePeriod: Long, initialDelay: Long) = flow { 14 | delay(initialDelay) 15 | while(true){ 16 | emit(Unit) 17 | delay(timePeriod) 18 | } 19 | } 20 | 21 | suspend fun Flow.collectUntilNull(flowCollector: FlowCollector) = 22 | takeWhile { it != null }.mapNotNull { it }.collect(flowCollector) 23 | 24 | inline fun instantCombine(vararg flows: Flow) = channelFlow { 25 | val array = Array(flows.size) { 26 | false to (null as T?) 27 | } 28 | 29 | flows.forEachIndexed { index, flow -> 30 | launch { 31 | flow.collect { emittedElement -> 32 | array[index] = true to emittedElement 33 | send(array.filter { it.first }.map { it.second }) 34 | } 35 | } 36 | } 37 | } 38 | 39 | suspend fun Flow.collectUntilTimeout(timeoutMillis: Long, collector: FlowCollector) = mapLatest { 40 | delay(timeoutMillis) 41 | null 42 | }.collectUntilNull(collector) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Fragment.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import kotlinx.coroutines.CoroutineScope 6 | import kotlinx.coroutines.channels.awaitClose 7 | import kotlinx.coroutines.flow.callbackFlow 8 | 9 | fun Fragment.childBackStackTopFragment() = callbackFlow { 10 | val listener = FragmentManager.OnBackStackChangedListener { 11 | trySend(getTopFragment()) 12 | } 13 | childFragmentManager.addOnBackStackChangedListener(listener) 14 | trySend(getTopFragment()) 15 | awaitClose { 16 | childFragmentManager.removeOnBackStackChangedListener(listener) 17 | } 18 | } 19 | 20 | fun Fragment.getTopFragment(): Fragment? { 21 | if(!isAdded) return null 22 | return childFragmentManager.fragments.firstOrNull() 23 | } 24 | 25 | /** 26 | * Helper for [LifecycleOwner].[whenResumed] 27 | */ 28 | fun Fragment.whenResumed(block: suspend CoroutineScope.() -> Unit) { 29 | viewLifecycleOwner.whenResumed(block) 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Inset.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.view.View 4 | import android.view.ViewGroup 5 | import androidx.core.view.WindowInsetsCompat 6 | import androidx.core.view.updateLayoutParams 7 | import androidx.core.view.updateMargins 8 | import androidx.core.view.updatePadding 9 | import com.kieronquinn.app.pixellaunchermods.R 10 | 11 | fun View.applyBottomNavigationInset(extraPadding: Float = 0f) { 12 | val bottomNavHeight = resources.getDimension(R.dimen.bottom_nav_height).toInt() 13 | updatePadding(bottom = bottomNavHeight + extraPadding.toInt()) 14 | onApplyInsets { _, insets -> 15 | val bottomInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom 16 | updatePadding(bottom = bottomInsets + bottomNavHeight + extraPadding.toInt()) 17 | } 18 | } 19 | 20 | fun View.applyBottomNavigationMargin(extraPadding: Float = 0f) { 21 | val bottomNavHeight = resources.getDimension(R.dimen.bottom_nav_height_margins).toInt() 22 | onApplyInsets { _, insets -> 23 | val bottomInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom 24 | updateLayoutParams { 25 | updateMargins(bottom = bottomInsets + bottomNavHeight + extraPadding.toInt()) 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Lifecycle.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import androidx.lifecycle.LifecycleObserver 5 | import androidx.lifecycle.LifecycleOwner 6 | import androidx.lifecycle.OnLifecycleEvent 7 | import androidx.lifecycle.lifecycleScope 8 | import androidx.lifecycle.repeatOnLifecycle 9 | import kotlinx.coroutines.CoroutineScope 10 | import kotlinx.coroutines.Job 11 | import kotlinx.coroutines.launch 12 | 13 | fun Lifecycle.runOnDestroy(block: () -> Unit) { 14 | addObserver(object: LifecycleObserver { 15 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 16 | fun onDestroy() { 17 | block() 18 | } 19 | }) 20 | } 21 | 22 | fun LifecycleOwner.whenResumed(block: suspend CoroutineScope.() -> Unit): Job { 23 | return lifecycleScope.launch { 24 | lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) { 25 | block() 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Native.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.annotation.SuppressLint 4 | 5 | /** 6 | * Bypasses writable library issues on Android 16+, prefers directly calling nativeLoad where 7 | * possible, falling back to regular load call where not. 8 | */ 9 | @SuppressLint("UnsafeDynamicallyLoadedCode", "DiscouragedPrivateApi") 10 | fun loadLibrary(path: String, classLoader: ClassLoader) { 11 | try { 12 | Runtime::class.java.getDeclaredMethod( 13 | "nativeLoad", 14 | String::class.java, 15 | ClassLoader::class.java 16 | ).apply { 17 | isAccessible = true 18 | }.invoke(Runtime.getRuntime(), path, classLoader) 19 | }catch (e: Throwable) { 20 | System.load(path) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+PackageManager.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.content.pm.ApplicationInfo 4 | import android.content.pm.PackageManager 5 | 6 | fun PackageManager.getApplicationInfoOrNull(packageName: String): ApplicationInfo? { 7 | return try { 8 | getApplicationInfo(packageName, 0) 9 | }catch (e: PackageManager.NameNotFoundException){ 10 | null 11 | } 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Reflection.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import kotlin.reflect.KProperty 4 | 5 | inline fun C.reflect(vararg fieldNames: String): Reflect { 6 | fieldNames.forEach { fieldName -> 7 | try { 8 | return Reflect(C::class.java, this, fieldName) 9 | }catch (e: NoSuchFieldException){ 10 | return@forEach 11 | } 12 | } 13 | throw NoSuchFieldException() 14 | } 15 | 16 | class Reflect constructor(clazz: Class, private val instance: C, fieldName: String) { 17 | 18 | private val field = clazz.getDeclaredField(fieldName).apply { 19 | isAccessible = true 20 | } 21 | 22 | operator fun getValue(ref: Any?, prop: KProperty<*>): R { 23 | return field.get(instance) as R 24 | } 25 | 26 | operator fun setValue(ref: Any?, prop: KProperty<*>, v: R) { 27 | field.set(instance, v) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Resources.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.content.res.Resources 4 | import androidx.annotation.ArrayRes 5 | 6 | /** 7 | * Hacky method for checking if a given resource is *probably* an adaptive icon, by checking 8 | * its contents for `adaptive-icon`. May be slow on large resources. 9 | */ 10 | fun Resources.isAdaptiveIcon(identifier: Int): Boolean { 11 | return rawResourceContains(identifier, "adaptive-icon") 12 | } 13 | 14 | fun Resources.rawResourceContains(identifier: Int, searchString: String): Boolean { 15 | return try { 16 | openRawResource(identifier).use { 17 | it.bufferedReader().use { reader -> 18 | reader.readText().contains(searchString) 19 | } 20 | } 21 | }catch (e: Resources.NotFoundException){ 22 | false 23 | } 24 | } 25 | 26 | fun Resources.getResourceIdArray(@ArrayRes resourceId: Int): Array { 27 | val array = obtainTypedArray(resourceId) 28 | val items = mutableListOf() 29 | for(i in 0 until array.length()){ 30 | items.add(array.getResourceId(i, 0)) 31 | } 32 | array.recycle() 33 | return items.toTypedArray() 34 | } 35 | 36 | fun Resources.px(value: Int): Int = (value / displayMetrics.density).toInt() 37 | 38 | val Int.px 39 | get() = Resources.getSystem().px(this) 40 | 41 | fun Resources.dip(value: Int): Int = (value * displayMetrics.density).toInt() 42 | 43 | val Int.dp 44 | get() = Resources.getSystem().dip(this) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+SharedPreferences.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.content.SharedPreferences 6 | import java.io.File 7 | 8 | @SuppressLint("PrivateApi") 9 | fun SharedPreferences_openFile(file: File): SharedPreferences { 10 | val sharedPreferencesImpl = Class.forName("android.app.SharedPreferencesImpl") 11 | return sharedPreferencesImpl.getDeclaredConstructor(File::class.java, Integer.TYPE).apply { 12 | isAccessible = true 13 | }.newInstance(file, Context.MODE_PRIVATE) as SharedPreferences 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Slider.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import com.google.android.material.slider.Slider 4 | import kotlinx.coroutines.channels.awaitClose 5 | import kotlinx.coroutines.flow.callbackFlow 6 | 7 | fun Slider.onChanged() = callbackFlow { 8 | val listener = Slider.OnChangeListener { _, value, fromUser -> 9 | if(fromUser) { 10 | trySend(value) 11 | } 12 | } 13 | addOnChangeListener(listener) 14 | awaitClose { 15 | removeOnChangeListener(listener) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Snackbar.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.graphics.Typeface 4 | import android.widget.TextView 5 | import com.google.android.material.snackbar.Snackbar 6 | 7 | fun Snackbar.setTypeface(typeface: Typeface?) { 8 | val tv = view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView 9 | val actionTv = view.findViewById(com.google.android.material.R.id.snackbar_action) as TextView 10 | tv.typeface = typeface 11 | actionTv.typeface = typeface 12 | } 13 | 14 | fun Snackbar.onSwipeDismissed(block: () -> Unit) { 15 | addCallback(object: Snackbar.Callback() { 16 | override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { 17 | super.onDismissed(transientBottomBar, event) 18 | if(event == DISMISS_EVENT_SWIPE){ 19 | block() 20 | } 21 | } 22 | }) 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+TabLayout.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import com.google.android.material.tabs.TabLayout 4 | import kotlinx.coroutines.channels.awaitClose 5 | import kotlinx.coroutines.flow.callbackFlow 6 | import kotlinx.coroutines.flow.debounce 7 | 8 | fun TabLayout.selectTab(index: Int) { 9 | getTabAt(index)?.let { 10 | selectTab(it) 11 | } 12 | } 13 | 14 | fun TabLayout.onSelected(includeReselection: Boolean = false) = callbackFlow { 15 | val listener = object: TabLayout.OnTabSelectedListener { 16 | override fun onTabSelected(tab: TabLayout.Tab) { 17 | trySend(tab.position) 18 | } 19 | 20 | override fun onTabUnselected(tab: TabLayout.Tab) { 21 | //No-op 22 | } 23 | 24 | override fun onTabReselected(tab: TabLayout.Tab) { 25 | if(includeReselection){ 26 | trySend(tab.position) 27 | } 28 | } 29 | } 30 | addOnTabSelectedListener(listener) 31 | awaitClose { 32 | removeOnTabSelectedListener(listener) 33 | } 34 | }.debounce(TAP_DEBOUNCE) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+Toolbar.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.view.View 4 | import androidx.appcompat.widget.Toolbar 5 | import kotlinx.coroutines.channels.awaitClose 6 | import kotlinx.coroutines.flow.callbackFlow 7 | import kotlinx.coroutines.flow.debounce 8 | 9 | fun Toolbar.onNavigationIconClicked() = callbackFlow { 10 | setNavigationOnClickListener { 11 | trySend(it) 12 | } 13 | awaitClose { 14 | setOnClickListener(null) 15 | } 16 | }.debounce(TAP_DEBOUNCE) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+UserHandle.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import android.os.UserHandle 4 | 5 | fun UserHandle.getIdentifier(): Int { 6 | return UserHandle::class.java.getMethod("getIdentifier").invoke(this) as Int 7 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/extensions/Extensions+XML.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.extensions 2 | 3 | import org.xmlpull.v1.XmlSerializer 4 | import java.io.StringWriter 5 | 6 | // https://medium.com/android-news/how-to-generate-xml-with-kotlin-extension-functions-and-lambdas-in-android-app-976229f1e4d8 7 | 8 | fun XmlSerializer.document( 9 | docName: String = "UTF-8", 10 | xmlStringWriter: StringWriter = StringWriter(), 11 | init: XmlSerializer.() -> Unit 12 | ): String { 13 | startDocument(docName, true) 14 | xmlStringWriter.buffer.setLength(0) 15 | setOutput(xmlStringWriter) 16 | init() 17 | endDocument() 18 | return xmlStringWriter.toString() 19 | } 20 | 21 | fun XmlSerializer.element(name: String, init: XmlSerializer.() -> Unit) { 22 | startTag("", name) 23 | init() 24 | endTag("", name) 25 | } 26 | 27 | fun XmlSerializer.element( 28 | name: String, 29 | content: String, 30 | init: XmlSerializer.() -> Unit 31 | ) { 32 | startTag("", name) 33 | init() 34 | text(content) 35 | endTag("", name) 36 | } 37 | 38 | fun XmlSerializer.element(name: String, content: String) = element(name) { 39 | text(content) 40 | } 41 | 42 | fun XmlSerializer.attribute(name: String, value: String) = attribute("", name, value) -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/glide/ScaleTransformation.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.glide 2 | 3 | import android.graphics.Bitmap 4 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool 5 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation 6 | import java.security.MessageDigest 7 | 8 | class ScaleTransformation(private val scale: Float): BitmapTransformation() { 9 | 10 | override fun transform( 11 | pool: BitmapPool, 12 | toTransform: Bitmap, 13 | outWidth: Int, 14 | outHeight: Int 15 | ): Bitmap { 16 | val cropEdgeFraction = (scale - 1f) / 2f 17 | val cropWidth = (cropEdgeFraction * outWidth).toInt() 18 | val cropHeight = (cropEdgeFraction * outHeight).toInt() 19 | val croppedBitmap = Bitmap.createBitmap( 20 | toTransform, 21 | cropWidth, 22 | cropHeight, 23 | toTransform.width - (cropWidth * 2), 24 | toTransform.height - (cropHeight * 2) 25 | ) 26 | return Bitmap.createScaledBitmap(croppedBitmap, outWidth, outHeight, true).also { 27 | croppedBitmap.recycle() 28 | } 29 | } 30 | 31 | override fun updateDiskCacheKey(messageDigest: MessageDigest) { 32 | //No-op 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/room/IconMetadataConverter.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.room 2 | 3 | import androidx.room.ProvidedTypeConverter 4 | import androidx.room.TypeConverter 5 | import com.google.gson.Gson 6 | import com.kieronquinn.app.pixellaunchermods.model.room.IconMetadata 7 | import org.koin.core.component.KoinComponent 8 | import org.koin.core.component.inject 9 | 10 | @ProvidedTypeConverter 11 | class IconMetadataConverter: KoinComponent { 12 | 13 | private val gson by inject() 14 | 15 | @TypeConverter 16 | fun StringToModifiedAppMetadata(string: String?): IconMetadata? { 17 | return gson.fromJson(string ?: return null, IconMetadata::class.java) 18 | } 19 | 20 | @TypeConverter 21 | fun IconMetadataToString(iconMetadata: IconMetadata?): String? { 22 | return gson.toJson(iconMetadata ?: return null) 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/widget/LauncherProxyAppWidgetHostView.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.widget 2 | 3 | import android.appwidget.AppWidgetHostView 4 | import android.appwidget.AppWidgetManager 5 | import android.content.ComponentName 6 | import android.content.Context 7 | import android.util.Log 8 | import android.widget.RemoteViews 9 | import com.kieronquinn.app.pixellaunchermods.widget.ProxyWidget 10 | 11 | /** 12 | * [AppWidgetHostView] that stores and exposes its [RemoteViews] for use in the [ProxyWidget] 13 | */ 14 | class LauncherProxyAppWidgetHostView(context: Context): AppWidgetHostView(context) { 15 | 16 | private val appWidgetManager = 17 | context.getSystemService(Context.APPWIDGET_SERVICE) as AppWidgetManager 18 | 19 | private var remoteViews: RemoteViews? = null 20 | 21 | override fun updateAppWidget(remoteViews: RemoteViews?) { 22 | super.updateAppWidget(remoteViews) 23 | this.remoteViews = remoteViews 24 | appWidgetManager.getAppWidgetIds(ComponentName(context, ProxyWidget::class.java)).forEach { 25 | appWidgetManager.updateAppWidget(it, remoteViews) 26 | } 27 | } 28 | 29 | fun getRemoteViews(): RemoteViews? { 30 | return remoteViews 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/widget/PreviewAppWidgetHost.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.widget 2 | 3 | import android.appwidget.AppWidgetHost 4 | import android.appwidget.AppWidgetHostView 5 | import android.appwidget.AppWidgetProviderInfo 6 | import android.content.Context 7 | 8 | /** 9 | * [AppWidgetHost] that creates a [PreviewAppWidgetHostView] instance. 10 | */ 11 | class PreviewAppWidgetHost(context: Context, hostId: Int): AppWidgetHost(context, hostId) { 12 | 13 | override fun onCreateView( 14 | context: Context, 15 | appWidgetId: Int, 16 | appWidget: AppWidgetProviderInfo? 17 | ): AppWidgetHostView { 18 | return PreviewAppWidgetHostView(context) 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kieronquinn/app/pixellaunchermods/utils/widget/ProxyAppWidgetHost.kt: -------------------------------------------------------------------------------- 1 | package com.kieronquinn.app.pixellaunchermods.utils.widget 2 | 3 | import android.appwidget.AppWidgetHost 4 | import android.content.Context 5 | import com.android.internal.appwidget.IAppWidgetService 6 | import com.kieronquinn.app.pixellaunchermods.utils.extensions.reflect 7 | 8 | /** 9 | * [AppWidgetHost] with the ability to replace its normally private [IAppWidgetService] 10 | * connection with a custom one, retrieved over the root service. 11 | */ 12 | class ProxyAppWidgetHost( 13 | context: Context, 14 | hostId: Int 15 | ): AppWidgetHost(context, hostId) { 16 | 17 | private var sService by reflect("sService") 18 | 19 | fun setService(service: IAppWidgetService) { 20 | sService = service 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /app/src/main/jniLibs/README.md: -------------------------------------------------------------------------------- 1 | # Prebuilt Libraries 2 | 3 | These shared libraries are actually just binaries, prebuilt `aapt2` and `zipalign`. 4 | They're used to generate a dynamic overlay to hide apps. 5 | 6 | https://github.com/rendiix/termux-zipalign 7 | https://github.com/rendiix/termux-aapt -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libaapt2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/arm64-v8a/libaapt2.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/arm64-v8a/libzipalign.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/arm64-v8a/libzipalign.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libaapt2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/armeabi-v7a/libaapt2.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libzipalign.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/armeabi-v7a/libzipalign.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libaapt2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/x86/libaapt2.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libzipalign.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/x86/libzipalign.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libaapt2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/x86_64/libaapt2.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86_64/libzipalign.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/jniLibs/x86_64/libzipalign.so -------------------------------------------------------------------------------- /app/src/main/res/anim/fast_out_extra_slow_in.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 24 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_right.xml: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 25 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 24 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 24 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/animator/zoom_in_animator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/color/color_surface_quarter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/background_app_editor_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/background_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_add.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_app_editor_save.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_apps_icon_pack.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_arrow_right.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_back.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_clear.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_error.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_icon_source_file.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_info.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_menu_open_external.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_reapply_foreground.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_reapply_foreground_monochrome.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_search.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/rounded_ripple_36.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/rounded_ripple_48.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/search_box_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/switch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/switch_foreground.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/switch_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/switch_track.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_auto_icon_pack_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_configuration_tabs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_tweaks_apply_console.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_tweaks_widget_replacement_preview.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_tweaks_widget_replacement_preview_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_widget_size_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_about_translators_ro.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 12 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_advanced_debug_restart_reason_toast.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_backup_restore_backup.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_backup_restore_restore.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chevron_right.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_community.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_contributions_build.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_contributions_icons.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_download.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_drag_handle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_faq.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_icon_remove.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_item_widget_replacement_app_expand.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_libraries.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_magisk_save.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_nav_apps.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_nav_options.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_nav_shortcuts.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_nav_tweaks.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_options_advanced.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_options_advanced_reset.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_options_advanced_restart.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_options_advanced_shortcut.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_options_backup_restore_backup.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_options_reapply.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reset_warning.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_deferred_restart.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_hide_apps.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_hide_clock.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_recents.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_resize_widgets.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_smartspace.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_wallpaper_region_colours.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_wallpaper_scrim.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_widget_preview_generic.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_widget_replacement.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tweaks_widget_replacement_reconfigure.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twitter.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_update_download_done.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widget_preview_bottom.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 14 | 18 | 22 | 26 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widget_preview_top.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 14 | 18 | 22 | 26 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widget_resize_horizontal.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widget_resize_vertical.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widget_size_input_minus.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_widget_size_input_plus.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/indicator_configuration_tabs.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/switch_background_ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/widget_background_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_mono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_mono.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 13 | 17 | 22 | 26 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_text_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text_bold_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_text_bold_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_text_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_text_medium.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text_medium_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_text_medium_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/google_sans_text_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/app/src/main/res/font/google_sans_text_regular.ttf -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_widget_resize.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_backup_restore_issues.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_magisk_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_options_faq.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_options_reapply.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_root.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings_base.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_widget_resize_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_app_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_auto_icon_pack_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_icon_app.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_icon_app_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_icon_pack_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_icon_pack_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_settings_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_tweaks_widget_replacement_switch.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_widget_resize_target_space.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_widget_resize_target_widget.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_monet_switch.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 23 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_widget_size_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 26 | 27 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_blank.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_empty.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_preview.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_wrapper.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_app_editor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_bottom_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 12 | 13 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_hide_apps.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_icon_picker.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_icon_picker_pack.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_tweaks.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_widget_resize.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_reapply.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph_app_editor.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 15 | 18 | 21 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 16 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph_root.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/values-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 56dp 4 | 0dp 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-land/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -2 4 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/bools.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @android:color/system_neutral2_700 4 | @android:color/system_neutral2_800 5 | @android:color/system_neutral1_900 6 | @android:color/system_neutral1_900 7 | @android:color/system_neutral1_700 8 | @android:color/system_neutral1_100 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/bools.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @android:color/system_neutral1_50 4 | @android:color/system_neutral1_200 5 | #bfffffff 6 | #4486F4 7 | @android:color/system_neutral1_10 8 | @android:color/system_neutral1_50 9 | @android:color/system_neutral1_100 10 | @android:color/system_accent1_600 11 | @android:color/system_accent1_700 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -1 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/plurals.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @string/widget_replacement_picker_item_app_count_one 5 | @string/widget_replacement_picker_item_app_count_other 6 | 7 | 8 | @string/backup_restore_restore_issues_content_one 9 | @string/backup_restore_restore_issues_content_other 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Igor Sorocean 5 | 6 | 7 | 8 | @string/contributors_translators_romanian 9 | 10 | 11 | 12 | @string/contributors_translators_romanian_content 13 | 14 | 15 | 16 | @drawable/ic_about_translators_ro 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/values/vpi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 300 5 | 400 6 | #FF33B5E5 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/xml/blank_appwidget_info.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/xml/provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/xml/proxy_appwidget_info.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/xml/shortcuts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | android.enableJetifier=true 19 | # Kotlin code style for this project: "official" or "obsolete": 20 | kotlin.code.style=official 21 | # Enables namespacing of each library's R class so that its R class includes only the 22 | # resources declared in the library itself and none from the library's dependencies, 23 | # thereby reducing the size of the R class for that library 24 | android.nonTransitiveRClass=true 25 | android.defaults.buildfeatures.buildconfig=true 26 | android.nonFinalResIds=false -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue May 20 23:58:55 BST 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /overlay/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /overlay/README.md: -------------------------------------------------------------------------------- 1 | # Overlay 2 | 3 | This module contains a 'stub' for the overlay. By default, it overlays no resources and is built 4 | into the Magisk module. This allows it to then be installed on top of by PLM, and overlay resources 5 | in the Pixel Launcher. 6 | 7 | Any changes to this module will be built into the module, but will not persist in builds made in 8 | the app. 9 | 10 | See the root-level gradle file for the script responsible for building it. -------------------------------------------------------------------------------- /overlay/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | } 4 | 5 | android { 6 | compileSdk 33 7 | 8 | defaultConfig { 9 | applicationId "com.google.android.apps.nexuslauncher.plmoverlay" 10 | 11 | //Also change in the Manifest - required for dynamic building 12 | minSdk 31 13 | targetSdk 33 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_21 28 | targetCompatibility JavaVersion.VERSION_21 29 | } 30 | 31 | buildFeatures { 32 | buildConfig = false 33 | } 34 | 35 | signingConfigs { 36 | release { 37 | storeFile file("overlay.keystore.jks") 38 | storePassword "android" 39 | keyAlias "plm" 40 | keyPassword "android" 41 | 42 | v1SigningEnabled true 43 | } 44 | } 45 | namespace 'com.google.android.apps.nexuslauncher.plmoverlay' 46 | 47 | buildTypes { 48 | release { 49 | signingConfig signingConfigs.release 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /overlay/module/META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | ################# 4 | # Initialization 5 | ################# 6 | 7 | umask 022 8 | 9 | # echo before loading util_functions 10 | ui_print() { echo "$1"; } 11 | 12 | require_new_magisk() { 13 | ui_print "*******************************" 14 | ui_print " Please install Magisk v20.4+! " 15 | ui_print "*******************************" 16 | exit 1 17 | } 18 | 19 | ######################### 20 | # Load util_functions.sh 21 | ######################### 22 | 23 | OUTFD=$2 24 | ZIPFILE=$3 25 | 26 | mount /data 2>/dev/null 27 | 28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk 29 | . /data/adb/magisk/util_functions.sh 30 | [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk 31 | 32 | install_module 33 | exit 0 34 | -------------------------------------------------------------------------------- /overlay/module/META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #MAGISK 2 | -------------------------------------------------------------------------------- /overlay/module/customize.sh: -------------------------------------------------------------------------------- 1 | ui_print "" 2 | ui_print "---------------------------" 3 | ui_print "" 4 | ui_print "Pixel Launcher Mods Overlay" 5 | ui_print "" 6 | ui_print "---------------------------" 7 | ui_print "" 8 | ui_print " Installing overlay... " 9 | ui_print "" 10 | ui_print " ✓ Done " 11 | ui_print "" 12 | ui_print "---------------------------" 13 | ui_print "" 14 | ui_print "Reboot your device to activate the hide apps" 15 | ui_print "option in Pixel Launcher Mods." 16 | ui_print "" 17 | ui_print "You must keep this module installed for hide" 18 | ui_print "apps and overlay tweaks to work." 19 | ui_print "" -------------------------------------------------------------------------------- /overlay/module/module.prop: -------------------------------------------------------------------------------- 1 | id=PixelLauncherModsOverlay 2 | name=Pixel Launcher Mods Overlay 3 | version=1.1 4 | versionCode=11 5 | author=Kieron Quinn / Quinny899 6 | description=Installs overlay required to hide apps and replace widgets from the Pixel Launcher. Configure settings in the Pixel Launcher Mods app. -------------------------------------------------------------------------------- /overlay/overlay.keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/overlay/overlay.keystore.jks -------------------------------------------------------------------------------- /overlay/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /overlay/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 19 | 20 | 25 | 26 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | maven { url 'https://jitpack.io' } 14 | } 15 | } 16 | rootProject.name = "Pixel Launcher Mods" 17 | include ':app' 18 | include ':systemstubs' 19 | include ':overlay' 20 | -------------------------------------------------------------------------------- /systemstubs/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /systemstubs/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdk 33 8 | 9 | defaultConfig { 10 | minSdk 31 11 | targetSdk 33 12 | 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | consumerProguardFiles "consumer-rules.pro" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | compileOptions { 24 | sourceCompatibility JavaVersion.VERSION_21 25 | targetCompatibility JavaVersion.VERSION_21 26 | } 27 | kotlinOptions { 28 | jvmTarget = '21' 29 | } 30 | buildFeatures { 31 | aidl true 32 | } 33 | namespace 'com.kieronquinn.app.systemstubs' 34 | } 35 | 36 | dependencies { 37 | implementation 'androidx.annotation:annotation:1.9.1' 38 | } -------------------------------------------------------------------------------- /systemstubs/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KieronQuinn/PixelLauncherMods/d02db4e0f4babdd45c55f7e1e349cdb1967e828e/systemstubs/consumer-rules.pro -------------------------------------------------------------------------------- /systemstubs/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /systemstubs/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/app/IApplicationThread.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.app; 17 | 18 | interface IApplicationThread { 19 | 20 | //Stub! 21 | 22 | } -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/app/IProcessObserver.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.app; 17 | 18 | interface IProcessObserver { 19 | 20 | void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities); 21 | void onForegroundServicesChanged(int pid, int uid, int serviceTypes); 22 | void onProcessDied(int pid, int uid); 23 | void onProcessStarted(int pid, int processUid, int packageUid, String packageName, String processName); 24 | 25 | } -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/app/IServiceConnection.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.app; 17 | 18 | interface IServiceConnection { 19 | 20 | //Stub! 21 | 22 | } -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/app/ProfilerInfo.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.app; 17 | 18 | parcelable ProfilerInfo; -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/content/om/OverlayInfo.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.content.om; 17 | 18 | parcelable OverlayInfo; -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/content/om/OverlayManagerTransaction.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.content.om; 17 | 18 | parcelable OverlayManagerTransaction; -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/content/pm/ILauncherApps.aidl: -------------------------------------------------------------------------------- 1 | package android.content.pm; 2 | 3 | import android.content.pm.IOnAppsChangedListener; 4 | 5 | interface ILauncherApps { 6 | 7 | void addOnAppsChangedListener(String callingPackage, in IOnAppsChangedListener listener); 8 | void removeOnAppsChangedListener(in IOnAppsChangedListener listener); 9 | 10 | } -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/android/content/pm/ParceledListSlice.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.content.pm; 17 | 18 | parcelable ParceledListSlice; 19 | -------------------------------------------------------------------------------- /systemstubs/src/main/aidl/com/android/internal/appwidget/IAppWidgetHost.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.internal.appwidget; 17 | import android.content.pm.ApplicationInfo; 18 | import android.content.ComponentName; 19 | import android.appwidget.AppWidgetProviderInfo; 20 | import android.widget.RemoteViews; 21 | 22 | interface IAppWidgetHost { 23 | void updateAppWidget(int appWidgetId, in RemoteViews views); 24 | void providerChanged(int appWidgetId, in AppWidgetProviderInfo info); 25 | void providersChanged(); 26 | void viewDataChanged(int appWidgetId, int viewId); 27 | void appWidgetRemoved(int appWidgetId); 28 | } -------------------------------------------------------------------------------- /systemstubs/src/main/java/android/app/IActivityManager.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.os.IBinder; 6 | 7 | import java.util.List; 8 | 9 | public interface IActivityManager extends android.os.IInterface { 10 | 11 | abstract class Stub extends android.os.Binder implements android.app.IServiceConnection { 12 | public static IActivityManager asInterface(android.os.IBinder obj) { 13 | throw new RuntimeException("Stub!"); 14 | } 15 | } 16 | 17 | void registerProcessObserver(IProcessObserver observer); 18 | void unregisterProcessObserver(IProcessObserver observer); 19 | List getRunningAppProcesses(); 20 | 21 | int startActivityWithFeature( 22 | IApplicationThread caller, 23 | String callingPackage, 24 | String callingFeatureId, 25 | Intent intent, 26 | String resolvedType, 27 | IBinder resultTo, 28 | String resultWho, 29 | int requestCode, 30 | int flags, 31 | ProfilerInfo profilerInfo, 32 | Bundle options); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /systemstubs/src/main/java/android/app/ProfilerInfo.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class ProfilerInfo implements Parcelable { 7 | 8 | protected ProfilerInfo(Parcel in) { 9 | } 10 | 11 | public static final Creator CREATOR = new Creator() { 12 | @Override 13 | public ProfilerInfo createFromParcel(Parcel in) { 14 | return new ProfilerInfo(in); 15 | } 16 | 17 | @Override 18 | public ProfilerInfo[] newArray(int size) { 19 | return new ProfilerInfo[size]; 20 | } 21 | }; 22 | 23 | @Override 24 | public int describeContents() { 25 | throw new RuntimeException("Stub!"); 26 | } 27 | 28 | @Override 29 | public void writeToParcel(Parcel parcel, int i) { 30 | throw new RuntimeException("Stub!"); 31 | } 32 | } --------------------------------------------------------------------------------