From 208e67537b13fba8f23953814b28c519832602cd Mon Sep 17 00:00:00 2001 From: xiongjie Date: Sat, 28 May 2022 16:30:18 +0800 Subject: [PATCH 001/627] add support for miui 13 --- .gitignore | 1 + BUGS_EN | 4 - BUGS_RU | 4 - CHANGELOG_EN | 715 ----------- CHANGELOG_RU | 715 ----------- app/build.gradle | 26 +- app/libs/WeatherView-2.0.3.aar | Bin 32549 -> 0 bytes app/src/main/AndroidManifest.xml | 419 ++++--- .../mikanoshi/customiuizer/AboutFragment.java | 14 - .../mikanoshi/customiuizer/MainActivity.java | 58 +- .../customiuizer/MainApplication.java | 78 +- .../mikanoshi/customiuizer/MainFragment.java | 395 +------ .../customiuizer/PreferenceFragmentBase.java | 204 ++-- .../customiuizer/SnoozedActivity.java | 1 - .../customiuizer/SnoozedFragment.java | 26 +- .../mikanoshi/customiuizer/SubFragment.java | 775 ++++++------ .../customiuizer/SubFragmentWithSearch.java | 118 +- .../customiuizer/crashreport/Dialog.java | 587 --------- .../crashreport/DialogInteraction.java | 46 - .../customiuizer/holidays/CoinGenerator.java | 29 - .../customiuizer/holidays/CoinParticle.java | 110 -- .../customiuizer/holidays/FilthGenerator.java | 29 - .../customiuizer/holidays/FilthyParticle.java | 106 -- .../holidays/FlowerGenerator.java | 29 - .../customiuizer/holidays/FlowerParticle.java | 70 -- .../customiuizer/holidays/HolidayHelper.java | 141 --- .../customiuizer/holidays/SnowGenerator.java | 29 - .../customiuizer/holidays/SnowParticle.java | 84 -- .../customiuizer/mods/GlobalActions.java | 8 +- .../mikanoshi/customiuizer/mods/Various.java | 33 +- .../prefs/CheckBoxPreferenceEx.java | 4 +- .../prefs/PreferenceCategoryEx.java | 2 +- .../customiuizer/prefs/SeekBarPreference.java | 2 - .../customiuizer/prefs/SpinnerEx.java | 4 +- .../mikanoshi/customiuizer/subs/BTList.java | 2 + .../customiuizer/subs/ColorSelector.java | 8 +- .../customiuizer/subs/MultiAction.java | 6 + .../customiuizer/subs/SortableList.java | 16 - .../mikanoshi/customiuizer/subs/System.java | 2 +- .../subs/System_VibrationAmp.java | 4 +- .../subs/Various_CallUIBright.java | 4 +- .../customiuizer/utils/GravitySensor.java | 104 -- .../customiuizer/utils/GuidePopup.java | 65 - .../mikanoshi/customiuizer/utils/Helpers.java | 149 +-- .../utils/NestedHeaderLayout.java | 12 +- .../res/layout-land/fragment_selectcolor.xml | 4 +- app/src/main/res/layout/activity_main.xml | 48 +- app/src/main/res/layout/fragment_about.xml | 2 +- .../main/res/layout/fragment_selectcolor.xml | 7 +- app/src/main/res/layout/fragment_snoozed.xml | 8 +- .../main/res/layout/preference_seekbar12.xml | 6 +- .../main/res/layout/prefs_app_selector.xml | 5 +- app/src/main/res/layout/prefs_bt_networks.xml | 2 +- app/src/main/res/layout/prefs_main12.xml | 2 - .../res/layout/prefs_system_audiosilencer.xml | 2 +- .../main/res/layout/prefs_wifi_networks.xml | 2 +- app/src/main/res/layout/search_stub.xml | 4 +- app/src/main/res/menu/menu_mods.xml | 27 +- app/src/main/res/values-de/strings.xml | 917 -------------- app/src/main/res/values-es/strings.xml | 1048 ---------------- app/src/main/res/values-fr/strings.xml | 917 -------------- app/src/main/res/values-id/strings.xml | 1041 ---------------- app/src/main/res/values-it/strings.xml | 1040 ---------------- app/src/main/res/values-night/styles.xml | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 1004 ---------------- app/src/main/res/values-sk/strings.xml | 1050 ----------------- app/src/main/res/values-tr/strings.xml | 915 -------------- app/src/main/res/values-uk-rUK/strings.xml | 928 --------------- app/src/main/res/values-zh-rCN/strings.xml | 13 +- app/src/main/res/values/arrays.xml | 17 - app/src/main/res/values/dimens.xml | 2 +- app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 15 +- app/src/main/res/xml/prefs_launcher_cat.xml | 3 - app/src/main/res/xml/prefs_main.xml | 44 +- 75 files changed, 841 insertions(+), 13473 deletions(-) delete mode 100644 BUGS_EN delete mode 100644 BUGS_RU delete mode 100644 CHANGELOG_EN delete mode 100644 CHANGELOG_RU delete mode 100644 app/libs/WeatherView-2.0.3.aar delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/crashreport/DialogInteraction.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinGenerator.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinParticle.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthGenerator.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthyParticle.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/utils/GuidePopup.java delete mode 100644 app/src/main/res/values-de/strings.xml delete mode 100644 app/src/main/res/values-es/strings.xml delete mode 100644 app/src/main/res/values-fr/strings.xml delete mode 100644 app/src/main/res/values-id/strings.xml delete mode 100644 app/src/main/res/values-it/strings.xml delete mode 100644 app/src/main/res/values-pt-rBR/strings.xml delete mode 100644 app/src/main/res/values-sk/strings.xml delete mode 100644 app/src/main/res/values-tr/strings.xml delete mode 100644 app/src/main/res/values-uk-rUK/strings.xml diff --git a/.gitignore b/.gitignore index 455d3751..e7a80134 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.iml .gradle +app/release/* /local.properties /.idea/caches /.idea/libraries diff --git a/BUGS_EN b/BUGS_EN deleted file mode 100644 index 12151373..00000000 --- a/BUGS_EN +++ /dev/null @@ -1,4 +0,0 @@ -Known bugs: - -- Latest versions of some Xiaomi apps (e.g. POCO Launcher past 2.6.8) are obfuscated and are not compatible with mods in this module (never will be) -- Not all mods are compatible with latest beta ROMs right away \ No newline at end of file diff --git a/BUGS_RU b/BUGS_RU deleted file mode 100644 index dd16a734..00000000 --- a/BUGS_RU +++ /dev/null @@ -1,4 +0,0 @@ -Известные баги: - -- Код в последних версиях некоторых Xiaomi приложений (например POCO Launcher после версии 2.6.8) обфусцирован, поэтому они не совместимы с модами в данном модуле (и никогда не будут) -- Не все моды совместимы с последними бета прошивками сразу после их выхода \ No newline at end of file diff --git a/CHANGELOG_EN b/CHANGELOG_EN deleted file mode 100644 index a00d69be..00000000 --- a/CHANGELOG_EN +++ /dev/null @@ -1,715 +0,0 @@ -3.2.1 -[New] Horizontal widget margin -[New] Remove app launch zoom animation in MIUI Launcher -[New] Launch different hidden system features from module's UI -[Improved][Disable overscroll] Support more apps -[Improved][Collapse MIUI titles] Support more apps -[Improved][Show additional app details] Support latest Security versions -[Improved][Installed apps initial sort order] Support latest Security versions -[Improved][Prevent app force close] Allow killing most apps by default if mod is active (Security, Contacts, Backup, etc) -[Improved][Folder background blur] Wallpaper blur support for latest MIUI Launcher versions -Added all MIUI apps as recommended scope in LSPosed - -3.2.0 -[Improved][Auto close folders/app drawer] Also works when app is launched using shortcut menu -[Fixed][Clean Open with menu] All suitable apps are listed -Better LSPosed compatibility -Removed unnecessary split action bar in module's UI on MIUI 12.5 -MIUI 12.5 mods compatibility: - Installed apps initial sort order - Disable overscroll - Apply lock screen wallpaper using any app (Themes app is no longer required on MIUI 11+) - -3.1.7 -[New] Allow configuring battery saver and access to Wi-Fi for system apps -[Fixed][Remove unlock animation] Compatibility with latest MIUI Launcher versions -Detect that LSPosed framework is installed - -3.1.6 -[New] Configure allowed communications in airplane mode -[New] Allow 3rd-party apps to set lock screen wallpaper -[New] Display popup notifications in the middle of the screen -[New] Minimize brightness slider visual changes when starting to adjust brightness -[New][Launcher gestures] Pinch and spread gestures -[Improved][Horizontal gestures] Black list -[Improved][Disable secure content protection] Works in more places now -[Improved][Secure Quick settings] Compatibility with older MIUI versions -[Improved][Show additional app details] Compatibility with newer Security app versions installed on older ROMs - -3.1.5 -[New] Unlock frame rate up to 90 in Screen Recorder app (whether it will actually work depends on device and video driver) -[New] Display a switch between App Vault and Google Discover in Home screen settings on global ROMs -[New] Automatically close app drawer in MIUI Launcher after app launch -[New] Enable or disable network activity indicators in status bar -[Improved][Unlock grid sizes] Launcher grids up to 10x10 -[Improved][Top margin for app titles in launcher] Negative values -[Improved][Display next alarm] Option to display both relative and regular time -[Improved][Seconds in status bar clock] Option to try to synchronize updates with beginning or end of a second -[Fixed][Seconds in status bar clock] Premature update from 59 to 00 -[Fixed][Clock app in notification drawer] Clock app instead of Calendar app replacement in landscape mode -[Fixed] Unnecessary preferences migration after restoring them from backup - -3.1.4 -[Fixed] EdXposed Manager freeze on launch (it might still happen on EdXposed SandHook when Own repository option is active) -[Fixed] Searching for newly added mods - -3.1.3 -[New] Action: Force close current app -[New] Action: Toggle Hotspot -[New] Hide status bar on lock screen -[New] Hide unlock hint on lock screen -[New] Mute notification sound when screen is on -[New][Full screen navigation gestures][MIUI 12] Custom action on swipe up from corner -[Fixed][App info in installer] Fit info into new Google Package Installer dialog -[Fixed] Navbar height -Additional repository with CustoMIUIzer module in it for EdXposed Manager to get updates more reliably -Chinese New Year design updated -New design added ₿ - -3.1.2 -[New] Require device unlock before toggling selected Quick settings tiles -[Fixed][Separate volume controls] Volume settings crash -[Fixed][Display charging data] Compatibility with older Android versions -[Fixed] Some Launcher mods not keeping changes after reboot - -3.1.1 -[Fixed][Remove unlock animation] Compatibility with latest MIUI Launcher versions -[Fixed] Module's settings crash on older Android versions - -3.1.0 -[New] Bypass app lock for selected activities (activity names of locked apps are written to Xposed log upon launch) -[Improved][Display charging data] Show battery info (current, voltage, wattage, temperature) -[Improved][Custom lock screen actions] Option to center actions list horizontally -[Improved][Disable screen lock] Face unlock skipping is optional -[Improved][Extended power menu] Faster animations and dynamic background blur -Minor performance improvements -EdXposed 0.5.x.x support (build 4653+ is required): - Module's settings will be migrated to work with new EdXposed Framework version on first module UI launch. - It is recommended to make a backup using built-in function before updating. - Old settings could still be loaded by disabling EdXposed Framework or downgrading it to 0.4.x.x. - Launching any app on device can have an additional delay depending on the number of active mods. - It's a result of how new EdXposed loads modules, this cannot be avoided without breaking some system mods. - -3.0.6 -[New][MIUI 12] Allow using split screen and floating windows together -[New][MIUI 12] Disable Control center while screen lock is active -[New][MIUI 12] Change maximum line count in messaging style notifications (can fix truncated action buttons bug) -[New][MIUI 12] Bring back minimalistic collapsed view for unimportant notifications -[New][MIUI 12] Open notification channel settings instead of app's common notification settings from notification menu -[Improved][Disable screen lock] Don't start face unlock and don't hide contents of all notifications if lock is disabled -[Improved][Allow floating window] Supports black list now to disallow opening floating windows from popup notifications -[Improved][Compact notifications][MIUI 12] Smaller bottom padding in MIUI style -[Fixed][Custom lock screen actions] Zero top margin for actions list on some devices -[Fixed][Sticky floating windows] Remember window state when launched from top widget in recent apps list -[Fixed][Recent apps background blur] Compatibility with latest MIUI launcher versions -[Fixed] Module's settings crash on MIUI 11 and lower - -3.0.5 -Revert changes introduced in 3.0.2 that break some system mods - -3.0.4 -[Fixed][Detailed network speed indicator] Show correct values when VPN is active -[Fixed] Module's settings crash -[MIUI 12] Control center compatibility: - Show illuminance level - Show brightness percentage - Deactivate brightness slider - Status bar gesture controls - Notification drawer background blur - -3.0.3 -[New] Audio silencer: mute any sound that can be uniquely identified -[New][MIUI 12] Sticky floating windows: remember window state, position and dimensions -[New][MIUI 12] Allow any app to be opened in floating window -[Improved][Recent apps background blur] Compatibility with recents from MIUI Launcher -[Fixed][Expand QS action][MIUI 12] Expands Control center too -[Fixed][Detailed network speed indicator] Android 7.1 compatibility -[Fixed][Custom lock screen actions] Android 7.1 compatibility -[Fixed][MIUI 12] Module's settings crash on beta ROMs - -3.0.2 -[New] Disable media stream muting in Do not disturb mode -[New] Toggle DND instead of Silent mode from collapsed volume dialog -[New] Volume dialog autohide delay -[New] Google Keyboard's bottom padding -[New][MIUI 12] Allow floating window to be opened from any notification that has an appropriate click action defined -[Improved][Compact notifications][MIUI 12] Increased height of action buttons -[Fixed][Display next alarm on lock screen] Compatibility with super wallpaper clock style -[Fixed][Custom lock screen actions] Compatibility with some ancient Android versions -[Fixed][Popup notification swipe down] Ignore notifications with floating windows -[Fixed] Show seconds in status bar clock -[Fixed] Hide No SIM card icon - -3.0.0 -[New] Increase limit of active notifications from a single app -[New] Increase/remove notification icons limit in status bar -[New] Disable forced dark mode -[New][MIUI 12] Collapse MIUI titles -[Improved][Navbar height, Additional navbar buttons margin] Increased value ranges -[Improved][Show additional app details] APK version code -[Fixed][Show seconds in status bar clock] Adding seconds twice -[Fixed][Back gesture area height and width] Support for gestures implementation from MIUI Launcher -[Fixed][Launcher gestures] Swipe up and down gestures; compatibility with latest MIUI Launcher versions -[Fixed][Fingerprint actions during calls] Longpress action -[Fixed][Separate volume controls] Muted state indication for notification slider in volume dialog when DND is active -Coronavirus anti-holiday is back! Now even more viral! -MIUI 12 compatibility: - Fast access icon - Rotation animation - Custom lock screen shortcuts (launching without unlock) - Separate volume controls - Compact notifications - Extended notification menu - Shortcut/Clock/Calendar app in notification drawer - Display next alarm on lock screen - Hide top block on lock screen - More notification snooze options - Show additional app details - Horizontal gestures - -2.2.1 -[New] Disable emergency call button on lock screen -[Improved][Screenshot configuration] Option to select a custom save folder -[Improved][Additional toast elements] Disable stock adding of an app name on China ROMs -[Improved][Extended notification menu] Display all icons in one row in notification of minimal importance so they fit in when notification is collapsed -[Fixed][Colorize notification title] Don't apply to styled media notifications -[Fixed][Screen off timeout on lock screen] Was also affecting timeout outside lock screen -Module's UI fixes - -2.2.0 -[New] Use native recent apps list implementation instead of the one from MIUI Launcher -[Improved][Album art as wallpaper] Option to convert album art to grayscale -[Improved][Display charging current] Option to append/prepend/insert as new line -[Fixed][Custom lock screen actions] Swipe left action and right icon replacement compatibility with latest beta ROMs -[Fixed][Custom suggestions box actions] Compatibility with recent apps list from MIUI Launcher -[Fixed][Remove cleaner button] Compatibility with recent apps list from MIUI Launcher -[Fixed][Remove unlock animation] Compatibility with latest beta ROMs; also disables fade/zoom out unlock animation of lock screen -[Fixed][Use old launch animation] Compatibility with latest launcher alpha versions -[Fixed][Fix launcher animation] Compatibility with latest launcher alpha versions -[Fixed][App info in installer] Compatibility with latest MIUI package installer version -[Fixed][Floating screenshot display time] Compatibility with latest beta ROMs -Show main menu on all pages in module settings -New anti-holiday design ☣️ - -2.1.5 -[New] Scramble App Lock PIN -[New] Show a value of charging current at the bottom of lock screen -[Improved][Battery bar indicator] Option to only show in notification drawer and on lock screen -[Improved][Snoozed notifications manager] Option to snooze notification indefinitely (until the next device reboot) -[Fixed][Snoozed notifications manager] Show correct time until snoozed notification is reposted - -2.1.4 -[New] Change delay before a floating window with newly created screenshot disappears -[New] Unlimited number of icons in launcher's dock -[Improved][Battery bar indicator] Align to the bottom of status bar (indicator will also appear at the bottom of the screen in notification drawer and on lock screen) -[Fixed][Use entire folder's width] Truncated icons during folder close animation - -2.1.3 -[New] Hide overlays while making a screenshot -[New] Reverse portrait orientation support in launcher -[Improved][Dynamic page indicator] Option to show only in edit mode -[Improved][Auto brightness range] Option to switch to non-linear scale on older Android versions (use if mod sets incorrect percentages) -[Improved][Clean Open with menu] Hide apps from menu based on type of content that is being opened -[Improved][Music visualizer] Option to display visualizer only if media controller exists (usually used by audio players for notification controls) -[Fixed][Music visualizer] Visualizer wasn't showing right away in notification drawer - -2.1.2 -[New][Hide icons] Hide VoWiFi icon -[New][MIUI Launcher] Remove unlock animation -[New][MIUI Launcher] Use old launch animation -[Improved][Show illuminance level] Lower update rate to prevent chaotic value changes -[Fixed][Hide low battery warning] Compatibility with some ROMs -[Fixed][Clear all recent tasks] Compatibility with Android 10 -Module UI crash fixes - -2.1.1 -[New] Disable warning dialog about unsafe volume level -[New] Disable warning dialog about low battery level -[New] Disable screenshot on Power+Volume down key combination -[New] Do not wake device using fingerprint scanner if no fingerprints are enrolled -[New] Tap bottom area of lock screen to start device unlock -[New][Hide icons] Hide Wi-Fi icon -[Improved][Auto brightness range] Minimum and maximum values in percents -[Improved][Music visualizer] Faster rendering in some cases; option to select rendering method -[Fixed][Colorize notification title] Compatibility with Android 10 - -2.1.0 -[Improved][Extended notification menu] Always open MIUI-styled app info -[Improved][Android 9+] Better app list (black/white list) mode support (but not perfect, so warning will remain) -[Fixed] No vibration on fingerprint authentication failure -[Fixed] Crash in snoozed notifications list -[Fixed][Missed call reminder] Stop playing ringtone when missed call notification is dismissed -[Fixed][Compact notifications] Wrong height of action buttons in some notifications -[Fixed][Status bar gesture controls] Mod was broken on older Androids after some recent changes -New holiday design 🐀🏮 -Android 10 compatibility: - No screen light up on charge/headset connection - No password after boot - Disable screen lock - Orientation lock - Media position slider - Disable overscroll - Hide from recents - Toasts display duration - [Fingerprint authentication] Vibrate on success, no vibration on failure, turn screen on after failure - -2.0.10 -[New] More snooze time options and snoozed notifications manager -[New] Clear all tasks using cleaner button in recent apps list -[New] Remove brightness slider or make it display only -[Improved][Volume steps multiplier] Multiplier up to 5x -[Improved][Quick flashlight] Temporarily disable raise to wake when flashlight is active -[Improved][Status bar gesture controls] Show percentage when adjusting brightness if "Show brightness percentage" mod is enabled -[Fixed][Toasts display duration] Compatibility with some ROMs -[Fixed][Android 7] Crash in some app lists - -2.0.9 -[New] Toasts display duration -[New] Do not show vertical line between time and network speed on devices with waterdrop notches -[New] Make all MIUI launcher screens support both widgets and apps on tablets -[New][Additional navbar buttons] Option to increase distance from screen edges -[New][Disable screen lock] Tasker plugin to force enable/disable device lock -[Improved][Disable screen lock] Option to require authentication once after boot -[Improved][Disable screen lock] Apply device lock changes right away when state of Bluetooth connections change -[Fixed][Invert colors action] Restore color scheme/reading mode after inversion is disabled -[Fixed][Music visualizer] Music playing state detection on some ROMs; also visualizer will now be active when any music is playing, not just the one with media notification - -2.0.8.1 -[Fixed][Fingerprint call control] Error during mod activation that was also causing other mods to break - -2.0.8 -[New] Customize screenshot format, quality and save folder -[New] Accept or reject incoming calls and disconnect active calls using fingerprint scanner -[New] Launcher dock bottom margin -[New][Launcher bug fixes] Always open MIUI-styled app info from long press menu -[Improved][Quick Settings grid] Up to 7 columns -[Improved][Custom lock screen shortcuts] Allow to open whole app without unlock, not just a single activity -[Improved][Custom lock screen shortcuts] Launch Mi Home and Mi Remote without unlock if corresponding option for shortcuts is enabled -[Fixed][Separate volume controls] Crash in sound settings -[Fixed][Hide icons] Hide charging icon inside battery icon -New Year is nigh! :) - -2.0.7 -[New][Launcher bug fixes] Apply value animators' duration scaling to some launcher animations -[Improved][All rotations] Option to enable or disable -[Improved][Auto close folders] Option to enable or disable -[Improved][Separate volume controls] New icons for notification and system sounds volume sliders in Settings -[Improved][Status bar gesture controls] Better slide detection method with configurable sensitivity -[Fixed][Auto rotation toggle action] Incorrect orientation in some cases -[Fixed][Custom lock screen shortcuts] Compatibility with latest ROMs - -2.0.6 -[New] Make all widgets freely resizable (exceptions are some MIUI ones) -[New] Show next alarm time on lock screen -[New][Status bar gesture controls] Adjust brightness or volume by sliding with 1 or 2 fingers; double tap to perform action -[Improved][Control input cursor] Black list -[Fixed][Status bar height] Update launcher's top padding to match modified status bar height -[Fixed][Minimum auto brightness] Compatibility with some Android 8 ROMs - -2.0.5 -[New] Reduce vibration intensity (strength or duration) during selected hours -[New][Full screen navigation gestures] Back gesture area width -[Improved][Custom lock screen shortcuts] Unlimited number of shortcuts with app icons and top/bottom alignment -[Improved][Modify app titles] Dual apps support -Interface language selection -Module's UI improvements: preserve current state on configuration changes; correct checkbox size in dark mode - -2.0.4 -[New] Folder background blur options (MIUI Launcher with folder blur support is required) -[Improved][Show brightness percentage] Configurable top margin -[Improved][Folder background color overlay] Configurable level of darkening/lightening; smoothly change overlay opacity when folder is opened -[Improved][Clean Open with menu] Hide apps that can accept links with http, https and vnd.youtube protocols -[Improved][Modify app titles] Change titles in app drawer too -[Improved][Additional navbar buttons] Original buttons are a little more spaced, full screen mode button moved to the right to prevent it from being truncated -[Fixed][Volume keys long press actions] Wake up on volume keys press option support -[Fixed][Custom lock screen shortcuts] Compatibility with latest ROMs - -2.0.3 -[New][Number of columns in folders] Use entire folder's width -[Improved][Volume dialog background blur] Background dimming is disabled when blur is active -[Fixed][Shortcut actions in recents] Missing titles of some actions -[Fixed][Launcher compatibility mode] It actually works now -[Fixed][Show brightness percentage] Compatibility with some ROMs -Better themes support, UI fixes - -2.0.2 -[New] Force all notifications from MIUI apps to be able to appear on lock screen and as floating ones -[New] Remove Quick Settings and brightness slider in expanded notifications mode on lock screen -[New] Remove notification drawer background on lock screen -[New] Double press power key launch action -[Improved][Number of columns in folders] Option to reduce side padding for more than 3 columns -[Improved][Show titles in dock] Additional bottom padding for dock when full screen gestures are active (MIUI Launcher only) -[Improved][Disable signature verification] Skip signature check in MIUI installer -[Improved][Show seconds] Equal update intervals -[Improved][Folder background] Use white color when light wallpaper is applied -[Fixed][Media position slider] Compatibility with some ROMs -Long press search box to display a list of new mods -Scroll found mod into view and highlight it beautifully :) -MIUI-styled checkboxes in lists on MIUI 11 -Adaptive module icon - -2.0.1 -[New] Show app titles in launcher dock -[New] Allow screenshots and video recording of any app -[New] Blur background behind collapsed and expanded volume dialogs -[New] Compatibility mode for all launcher mods -[Improved][Unlock grid sizes] Launcher grids up to 8x8 -[Improved][Album art as wallpaper] Scaling option -Module's UI fixes - -2.0.0 -[New] Alternative back navbar button icon in input mode -[New] Replace App Vault with Google Discover in MIUI Launcher -[New] Make MIUI package installer the default one and allow it to update system apps -[Improved][Media position slider] Option to switch to system slider style -[Improved][App info in installer] MIUI package installer support -[Improved][App state control] Ability to disable more apps (System launcher, Find device, etc) -[Fixed][Dim duration] Compatibility with some ROMs, now configured in % of screen off timeout -[Fixed][Custom lock screen actions] Launching shortcut actions -[Fixed][Navbar actions] Media actions on main buttons long press -MIUI 11 compatibility: - Fast access icon - Additional toasts elements - Unblock launchers - Media position slider - Open menu action - -1.8.1 -[New] Dark mode Quick Settings tile -[New] Hide app titles in launcher -[New] Horizontal launcher grid margins -[New] Top launcher grid margin -[New] Page indicator height in launcher -[New] Display brightness level in percentages while dragging brightness slider -[Improved][Number of rows in Quick Settings] Option for 2 rows with reduced QS height -[Fixed][Font size of titles in launcher] Do not apply to opened folder's title -[Fixed][Custom lock screen actions] Right icon and text replacement; Revert to stock camera launch when no custom action is selected -[Fixed][Extended power menu] System UI restart -Minor module's UI fixes - -1.8.0 -[New] Action: Toggle one-handed mode -[New] Display version info about app that is being installed -[New] Disable overscroll in list views -[New] Font size of titles in launcher -[New] Top margin of titles in launcher -[New] Dual apps support in mods: -- App lock -- Hidden apps -- Clean share menu -- Clean Open with menu -- Additional app details -- Extended notification menu -- Shortcut/Clock/Calendar app in notification drawer -- Launch app and Launch activity actions -[Improved][Number of columns in launcher folders] Increased width of folder grid -[Improved][Default USB configuration] Do not show dialog automatically upon connection on latest ROMs -[Improved][Music visualizer] Customizable interval for dynamic color change -[Fixed][Minimum auto brightness] Compatibility with some ROMs -[Fixed][Hide mobile network type] Compatibility with some ROMs -[Fixed][Custom lock screen actions] Compatibility with latest ROMs -[Fixed][Disable hidden apps folder] Compatibility with latest ROMs -[Fixed][Number of columns in collapsed Quick Settings panel] Compatibility with latest ROMs -Detailed report compression to save that precious traffic - -1.7.5 -[New] Disable APK signature verification when app is being updated -[New] Dim duration before automatic screen off -[Improved][Music visualizer] Dynamic color option (changes color to a random one every 10 seconds) -[Fixed][Custom app titles] Compatibility with latest launcher alpha versions -[Fixed][Default USB configuration] Incorrect default value -[Fixed][Minimum auto brightness] Compatibility with some ROMs -[Fixed][Extended notification menu] Compatibility with some ROMs -Detect TaiChi app and don't complain about Xposed not being installed - -1.7.4 -[New] Adjust media stream volume on first key press -[New] Disable test vibration when switching ringer mode to silent or turning on vibration in this mode -[Improved][Battery bar indicator] Zero bar height -[Improved][Music visualizer] Animation duration option to configure visualizer update rate -[Fixed][Launcher icons scale] App icon badge scale -[Fixed][Clean Open With and Share menus] Compatibility with some ROMs -[Fixed] Color picker not drawing on some devices -[Fixed] Module UI crashes - -1.7.3 -[New] Action: Switch keyboard -[New] Hide covered earphone area warning -[New] Hide top block (clock, date, etc) on lock screen -[New] Custom sound, vibration and interval for missed call reminder -[New] Switch between dark/light/auto UI modes (does the same thing as Dark mode is Settings, option is mainly for turning off dark mode on ROMs that don't support it) -[New][Hide icons] Hide VoLTE status bar icon -[Fixed][Show illuminance level] Right slider icon visual bug while changing brightness -[Fixed][Launcher icons scale] Scale MIUI quick functions widgets -[Fixed][Custom app titles] Changing titles without reboot on latest launcher versions -[Fixed][Minimum auto brightness] Compatibility with some devices -[Fixed][Custom lock screen shortcuts] Compatibility with some ROMs -[Fixed][Detailed network speed indicator] Spacing between tx and rx speeds without indicator icons -[Fixed] Dark mode - -1.7.2 -[New] Show ambient illuminance value in lux inside brightness slider -[New] Position slider in media notifications -[New] Turn screen on after failed fingerprint authentication -[New] LTE icon instead of 4G -[New] Show incoming call UI instead of just a notification -[New] Configurable screen brightness during call -[New] System animations scale from x0 to x20 with 0.1x step -[New] Icon and folder scale in Launcher -[New][Hide icons] Hide No SIM and Managed profile status bar icons -[Improved][Volume steps multiplier] 0.25x multiplier step -[Removed][Pocket mode] Mod was draining battery during sleep by getting proximity values once a second; ultrasonic sensors are not reliable in such situations as they require 1 second to start showing correct values -[Fixed][Extended notification menu] Vertical position when Compact notification mod is not active -[Fixed][Custom lock screen actions] Restore default right image when no action is selected; Better compatibility with different ROMs -[Fixed][Hide clear button] Compatibility with latest ROMs -[Fixed][Android 7] Image resource hooks not working (was affecting a number of mods) -[Fixed] Single app selection lists in module settings -[Improved] Mods' settings categorization - -1.7.1 -[Fixed][Status bar height, Navbar height] Incomplete height changes, slow boot, bootloops -[Fixed][Custom lock screen actions] Hide left icon when swipe right gesture is disabled; Better compatibility with different ROMs -[Fixed][Quick flashlight, Volume keys long press actions] Always On Display compatibility - -1.7.0 -[New] Disable any notification including system ones -[New] Customizable actions for shortcuts and swipes on lock screen -[New][Hide icons] Hide VPN and Hotspot status bar icons -[Improved][Separate volume controls] Notification slider in expanded volume dialog is optional -[Fixed][Extended notification menu] Vertical position -[Fixed][Hide clear button, Default USB configuration, Navbar long press actions] Compatibility with some ROMs -[Fixed][App state control, Show additional app details] Compatibility with latest Security app -Resource hooks support in Xposed framework is no longer required for module to work - -1.6.7 -[New] Customizable battery bar indicator -[New] Hide statusbar icons -[New] Show alarm icon only during the defined number of hours before next alarm -[New] Hide Bluetooth icon when no devices are connected -[New] Prevent stock MIUI action from closing selected apps -[New] Action: Launch any activity of any package -[New][Android 9+] Display text magnifier during selection (for TextView-based elements only) -[Improved] Color pickers in module settings (darker colors selection and landscape layout support) -[Fixed][Alarm clock compatibility] Incorrect alarm time -[Fixed] Some UI bugs - -1.6.6 -[New] Allow all screen rotations -[New] Vibrate on successful fingerprint authentication -[New] Do not vibrate on fingerprint authentication failure -[New] Clean "Open with" menu -[New] Default USB configuration when connected to another device -[New][Music visualizer] Glow option -[New][Detailed network speed indicator] Optionally reduce indicator visibility when both speeds are zero -[New] Option to mark newly added mods for a number of days after update or forever -[Improved][Quick settings haptic feedback] Option to not disable vibration when "Vibrate on tap" is off -[Improved][Separate volume controls] Add notification volume slider to expanded volume dialog -[Improved][Show additional app details] Open app in Play Store, copy APK filename and data path to clipboard -[Fixed][Music visualizer] Horizontal rainbow colors on Android versions below 9 -[Fixed] Custom actions for shortcuts in recent apps list - -1.6.5 -[New] Make selected apps display correct next alarm time set by stock MIUI Clock app -[New] Make selected apps ignore incoming calls and keep playing audio -[New] Enhanced App lock option to lock any app -[New] Infinite page scroll in MIUI/POCO Launcher - jump from the last page to the first one and vice versa -[New] Autohide page indicator in MIUI Launcher -[New][Fingerprint actions] Option to disable actions during calls -[Improved] Open volume dialog action opens dialog that changes appropriate volume during calls -[Fixed][Music visualizer] Drawing of dashed bars and circles on Android versions below 9 -[Fixed] Some bugs and crashes - -1.6.4 -[New][Music visualizer] Option to draw on top of custom lock screen -[Improved][Music visualizer] Draw on top of themed background in notification drawer -[Fixed][Album art as wallpaper] Disable on custom lock screens -[Fixed][Separate volume controls] Keep system volume between reboots -[Fixed] Remove labels of Quick Settings tiles -[Fixed again] Detailed network speed indicator - -1.6.3 -[New] Hide navigation bar -[New] Music visualizer on lock screen and notification drawer -[New][Detailed network speed indicator] Font size options -[Fixed] Detailed network speed indicator -[Fixed] Go to sleep action was preventing screen from turning on again on some devices -[Fixed][Clean share menu] Removing messaging apps was breaking their functionality -[Improved][Keep notifications] Compatibility with new ROMs -[Improved] Open EdXposed Manager from module settings menu - -1.6.2 -[New] Navigation bar height -[New] Minimum auto brightness value -[New] Do not lock apps when device is locked (when option with locking after exit is selected) -[New] Change app lock timeout after exit -[Fixed][Clean share menu] Not all apps were available for removal -[Fixed][Fast access icon] Better compatibility, new position options - -1.6.1 -[New] More intervals for Silent/Do Not Disturb timers -[New] Remove apps from share menu -[New] Restrict toasts for selected apps -[New] Darker app title shadow in launcher -[New] Unblock 3rd-party launchers on China ROMs -[New] Define actions for 4 shortcuts in suggestion box in recents list -[New] Define action for double tap on empty space in launcher -[New] Actions: Open menu, Open volume dialog, Raise volume, Lower volume -[New] Shortcut to unlock credentials (long press CustoMIUIzer icon in launcher that supports shortcuts) -[New] Mod searching function in module settings -[Fixed] Disable launcher gestures during icons reorder -[Improved][Detailed network speed indicator] Compatibility with new ROMs - -1.6.0 -[New] POCO Launcher support for a number of mods -[New] MIUI Launcher support up to 4.9.5-dev -[New] Fix status bar contents color for light/dark wallpapers on dev launcher version -[New] Make status bar background color the same as app's action bar background color where possible -[New] Define apps that will be launched when clock, date and shortcut icon in notification drawer's header are tapped -[New] Action: Go back -[New] Dark mode support for module settings (some popup dialogs still have wrong text color) -[Improved][Additional navbar buttons] Left and right buttons appear independently if actions are assigned to them - -1.5.7 -[Fixed][Extended power menu] Power off button animation bug -[Fixed][Extended power menu] Localization -[Fixed] Unlock credentials -[Improved] Error handling and logging - -1.5.6 -[New] Extended power menu (Fastboot/Recovery/Soft Reboot/Restart System UI/Restart Launcher) -[New] Bring back Pocket mode option on devices with ultrasonic proximity sensor -[New] Change status bar height -[New] Customizable Quick Settings grids (both collapsed and expanded) -[New] Hide labels in Quick Settings -[New] Remove cleaner button from recent apps list -[New] Remove button that clears all notifications -[New] Disable (almost) any app from its info page -[New] Combine horizontal full screen gestures and navigation bar -[New] Actions: Clear memory, Invert colors -[New] Long press actions for Back, Home and Menu navbar buttons - -1.5.5 -[New] Quick Settings tile to lock orientation in portrait or landscape positions -[New] Disable music ducking (lowering volume during notifications) -[New] Disable fingerprint actions in Camera app -[New] Auto close MIUI launcher folders after app launch -[New][Better popup notifications] Auto hide delay -[Improved] All multiselection lists in module settings display selected apps on top -[Improved] Check if Xposed resource hooks are disabled -[Fixed][Extended notification menu] Latest stable MIUI support -[Fixed][Block vibration] Android 7 support -[Fixed][Album art as wallpaper] Better support for different Android versions -[Fixed][Hide from recents] Switched from dynamic to static to prevent bootloops -[Fixed][Custom app titles] Bug fixes - -1.5.4 -[New] Restrict vibration usage for selected apps -[New] Modify app titles in MIUI Launcher -[New][Disable screen lock] Use trusted Bluetooth devices -[New] Create launcher icon or use shortcut to unlock device credentials (they remain locked if you skip PIN/password/pattern after boot, but are required for authentication in some apps) - -1.5.3 -[New] Show notifications on lock screen even after it's dismissed and then opened again -[New] Open app info and force close app from its notification menu -[New] Do not show icon with 3 dots in system area when notification icons are hidden -[New][Quick Settings haptic feedback] Light/strong vibration options -[New][Full screen navigation gestures] Back gesture area height -[New][Android 8+] Change number of notifications from one app that triggers auto grouping -[Fixed][Theme background opacity] Separated from notification drawer background blur -[Fixed][Detailed network speed indicator] Excessive left padding -[Fixed][Compact notifications] Opacity bug after opening notification drawer -[Fixed] Better handling of mods' errors -Less cluttered module settings, new indication of dynamic mods - -1.5.2 -[New] Compact notifications -[New] Enhanced Hidden apps -[New] Hide apps from recent tasks list -[New] Quick settings haptic feedback -[New] Toggle module's launcher icon -[Fixed] Fade screen rotation animation -[Fixed] Vibration in mods respects "Vibrate on tap" system setting -[Fixed] Module UI bugs - -1.5.1 -[New][Expand notifications] Black & white list -[New][Control input cursor] Option to swap cursor moving directions -[New][Hide mobile network type] Hide completely or only when not connected -[New] Do not hide status bar clock on home screens with clock widgets -[New] Allow installing older app version on top of a newer one -[New] Action to open system power menu -[New] Brand new fast access icon :) -[Fixed][Android 7] Enhanced toasts -[Fixed] EdXposed Manager detection - -1.5.0 -[New] Darken MIUI launcher folder background -[New] Unlock MIUI launcher grids from 3x4 to 6x7 -[New] Number of columns in MIUI launcher folders -[New] Screen rotation animation (none or fade) -[New] Open notification drawer automatically on notifications from selected apps -[New] Display album art of currently playing track as lock screen wallpaper -[New][Better popup notifications] Do not dismiss popups automatically -[New][Better popup notifications] Swipe down from popup to open notification drawer -[Fixed][Disable screen lock] Selecting multiple trusted Wi-Fi networks - -1.4.3 -[New] Dynamic screen lock (disable completely, require only once after boot, disable on trusted Wi-Fi networks; bypass lock screen too) -[New] Detailed network speed indicator (incoming/outgoing traffic speeds and icons, low speed threshold for different indication) -[New] Network speed update interval - -1.4.2 -[Fixed] Override swipe up action in launcher (search usually) with mod's action -[Fixed] Additional check whether scanner is currently used or not in fingerprint actions mod -[New] Customizable double tap and long press delays for fingerprint actions mod - -1.4.1 -[Fixed] Quick flashlight -[New] Action to switch to previous app for navbar buttons and fingerprint scanner -[New] Optional vibration on volume keys long press action - -1.4.0 -[New] Customizable actions for single/double/long press on fingerprint scanner while screen is on -[New] Option to disable screen light up on charge in all cases or only when there is no charging animation -[New] Define how long screen should be kept on after charging animation starts -[New] Actions to open notification drawer/quick settings/recent apps do toggle instead of just opening when possible -[New] Volume steps multiplier - -1.3.1 -[Fixed][Compatibility] MIUI 10.3 -[Fixed] Screen off animation duration -[Fixed] No screen light up on charge (including wireless) -[New] No screen light up on headset connection - -1.3.0 -[Fixed][Compatibility] Loading module settings on devices with encrypted storage. Backup settings before updating to this version, they will be reset to defaults! -[Fixed][Compatibility] Additional app details -[Fixed][Compatibility] Quick flashlight -[Fixed][Compatibility] Volume keys media actions -[Fixed][Compatibility] All mods with customizable actions/toggles -[New] Two additional buttons on navigation bar with customizable actions -[New] Themed notification drawer background opacity -[New] Remove mobile network type icon from status bar -[New] Increase right margin for traffic speed indicator - -1.2.0 -[New] Display seconds in the status bar clock -[New] Always show notifications fully expanded -[New] Media actions for Volume Up/Down long press when screen is off -[New] Background blur intensity in recent apps and notification drawer -[Moved] "Control input cursor" mod was moved to Controls section, requires reactivation - -1.1.1 -[New] Configure separate volume for rings/notifications/system sounds in Settings -[New] Move text input cursor using volume keys - -1.1.0 -[New] Double tap on lockscreen to sleep -[Fixed][Android 7.0+] Module initialization, actions for toggles. Mods are not guaranteed to work. - -1.0.1 -[Fixed] Fast access icon on some devices -[Fixed] Update check - -1.0.0 -Initial release \ No newline at end of file diff --git a/CHANGELOG_RU b/CHANGELOG_RU deleted file mode 100644 index eae643f4..00000000 --- a/CHANGELOG_RU +++ /dev/null @@ -1,715 +0,0 @@ -3.2.1 -[Новое] Горизонтальные отступы виджетов -[Новое] Убрать анимацию иконок Рабочего стола MIUI при запуске приложений -[Новое] Запуск различных скрытых системных функций из интерфейса модуля -[Улучшено][Отключить избыточную прокрутку] Поддержка большего числа приложений -[Улучшено][Сворачивать заголовки MIUI] Поддержка большего числа приложений -[Улучшено][Доп. сведения о приложении] Поддержка последних версий Безопасности -[Улучшено][Порядок сортировки Всех приложений] Поддержка последних версий Безопасности -[Улучшено][Предотвратить закрытие приложений] Разрешить убийство большинста приложений по умолчанию, если мод активен (Безопасность, Контакты, Рез. копирование и пр.) -[Улучшено][Размытие фона папок] Поддержка размытия обоев на последних версиях Рабочего стола MIUI -Все MIUI приложения добавлены в рекомендованные в LSPosed - -3.2.0 -[Улучшено][Автозакрытие папки/меню приложений после запуска приложения] Также работает при запуске из меню ярлыков -[Исправлено][Очистка меню "Открыть с помощью"] Все подходящие приложения видны в списке -Улучшена совместимость с LSPosed -Удалено ненужное разделённое меню действий в интерфейсе модуля на MIUI 12.5 -Совместимость модов с MIUI 12.5: - Порядок сортировки Всех приложений - Отключить избыточную прокрутку - Установка обоев на локскрине любым приложением (Приложение Темы больше не требуется на MIUI 11+) - -3.1.7 -[Новое] Разрешить настраивать контроль активности и доступ к Wi-Fi для системных приложений -[Исправлено][Убрать анимацию разблокировки] Совместимость с последними версиями Рабочего стола MIUI -Определять установленный LSPosed фреймворк - -3.1.6 -[Новое] Настройка разрешённых коммуникаций в режиме полёта -[Новое] Установка обоев для экрана блокировки сторонними приложениями -[Новое] Отображение всплывающих уведомлений по центру экрана -[Новое] Минимизировать визуальные изменения слайдера при старте регулировки яркости -[Новое][Жесты ланчера] Жесты сведения и разведения пальцев -[Улучшено][Горизонтальные жесты] Чёрный список -[Улучшено][Отключить защиту контента] Теперь работает в большем количестве мест -[Улучшено][Безопасные Быстрые настройки] Совместимость со старыми версиями MIUI -[Улучшено][Доп. сведения о приложении] Совместимость с новыми версиями приложения Безопасность, установленными на старые прошивки - -3.1.5 -[Новое] Разблокировать частоту кадров вплоть до 90 в приложении Запись экрана (будет ли это действительно работать, зависит от устройства и видео драйвера) -[Новое] Переключатель между лентой виджетов и Google Discover в настройках Рабочего стола на глобальных прошивках -[Новое] Автозакрытие меню приложений Рабоего стола MIUI после запуска приложения -[Новое] Включение или отключение индикаторов сетевой активности в строке состояния -[Улучшено][Разблокировать размеры сетки] Размеры до 10x10 -[Улучшено][Отступ сверху для названий приложений в ланчере] Отрицательные значения -[Улучшено][Показ будильника] Опция для показа обычного и относительного времени вместе -[Улучшено][Секунды на часах в строке состояния] Опция для попытки синхронизировать обновления с началом или концом секунды -[Исправлено][Секунды на часах в строке состояния] Преждевременное обновление с 59 до 00 -[Исправлено][Приложение часов в панели уведомлений] Замена приложения часов вместо календаря в ландшафтном режиме -[Исправлено] Ненужная миграция настроек при восстановлении их из бэкапа - -3.1.4 -[Исправлено] Зависание EdXposed Manager при запуске (всё равно может происходить на EdXposed SandHook, если включена опция Свой репозиторий) -[Исправлено] Поиск недавно добавленных модов - -3.1.3 -[Новое] Действие: Принудительное закрытие текущего приложения -[Новое] Действие: Переключение мобильной точки доступа -[Новое] Скрыть строку состояния на экране блокировки -[Новое] Скрыть подсказку разблокировки на экране блокировки -[Новое] Не проигрывать звук уведомления при включенном экране -[Новое][Полноэкранные жесты навигации][MIUI 12] Действие на свайп вверх в углу -[Исправлено][Данные о приложении при инсталляции] Вместить в новое окно диалога установщика пакетов Google -[Исправлено] Высота панели навигации -Доп. репозиторий для EdXposed Менеджера с модулем CustoMIUIzer в нём для более надёжной загрузки данных о модуле -Обновлён дизайн Китайский Новый Год -Добавлен новый дизайн ₿ - -3.1.2 -[Новое] Требовать разблокировки девайса для переключения выбранных Быстрых настроек -[Исправлено][Раздельные настройки громкости] Вылет настроек громкости -[Исправлено][Показывать данные зарядки] Совместимость со старыми версиями Android -[Исправлено] Некоторые моды Рабочего стола не сохраняли изменения после перезагрузки - -3.1.1 -[Исправлено][Убрать анимацию разблокировки] Совместимость с последними версиями Рабочего стола MIUI -[Исправлено] Вылет настроек модуля на старых версиях Android - -3.1.0 -[Новое] Пропуск защиты приложения для выбранных компонентов (имена компонентов защищённых приложений пишутся в Xposed лог при их запуске) -[Улучшено][Показывать данные зарядки] Отображать данные батареи (ток, напряжение, потребление энергии, температура) -[Улучшено][Пользовательские действия на локскрине] Опция для выравнивания списка действий по горизонтали -[Улучшено][Отключить блокировку] Пропуск разблокировки по лицу опционален -[Улучшено][Расширенное меню питания] Быстрые анимации и динамическое размытие фона -Мелкие улучшения производительности -Поддержка EdXposed 0.5.x.x (требуется сборка 4653+): - Настройки модуля будут мигрированы для работы с новой версией EdXposed Framework при первом запуске интерфейса модуля. - Перед обновлением рекомендуется сделать бэкап настроек встроенным менеджером. - Для загрузки старых настроек нужно отключить EdXposed Framework или понизить его версию до 0.4.x.x. - Запуск любого приложения на устройстве может иметь доп. задержку в зависимости от количества активированных модов. - Виноват новый принцип работы EdXposed, и исправить это невозможно не сломав некоторые системные моды. - -3.0.6 -[Новое][MIUI 12] Разрешить совместное использование разделения экрана и плавающих окон -[Новое][MIUI 12] Отключать Центр управления когда устройство заблокировано -[Новое][MIUI 12] Изменить максимальное число строк в уведомлениях в стиле сообщений (может исправить баг с обрезанием кнопок действий) -[Новое][MIUI 12] Вернуть минималистичный свёрнутый вид уведомлений низкой важности -[Новое][MIUI 12] Открытие настроек канала вместо общих настроек уведомлений приложения из меню уведомления -[Улучшено][Отключить блокировку] Не начинать разблокировку по лицу и не прятать содержимое всех уведомлений, если блокировка была пропущена -[Улучшено][Разрешить плавающее окно] Поддержка чёрного списка для запрета открытия плаващих окон из всплывающих уведомлений -[Улучшено][Компактные уведомления][MIUI 12] Уменьшен отступ снизу в MIUI стиле -[Исправлено][Пользовательские действия на локскрине] Нулевой отступ сверху для списка действий на некоторых устройствах -[Исправлено][Запоминать состояние плавающих окон] Запоминать состояние при запуске из верхнего виджета в списке последних приложений -[Исправлено][Размытие фона списка последних приложений] Совместимость с последними версиями Рабочего стола MIUI -[Исправлено] Вылет настроек модуля на MIUI 11 и ниже - -3.0.5 -Откат изменений в версии 3.0.2, которые делают некоторые системные моды нерабочими - -3.0.4 -[Исправлено][Подробный индикатор скорости соединения] Отображение корректных значений при активном VPN -[Исправлено] Вылет настроек модуля -[MIUI 12] Совместимость с Центром управления: - Показать уровень освещённости - Показывать процент яркости - Отключить ползунок яркости - Управление жестами в статусбаре - Размытие фона панели уведомлений - -3.0.3 -[Новое] Аудио глушитель: позволяет заглушить любой уникально опознаваемый звук -[Новое][MIUI 12] Перманентные плавающие окна: запоминание состояния, позиции и размеров -[Новое][MIUI 12] Разрешить открывать любое приложение в плавающем окне -[Улучшено][Размытие фона списка последних приложений] Совместимость со списком из Рабочего стола MIUI -[Исправлено][Действие открытия Быстрых Настроек][MIUI 12] Также открывать Центр управления -[Исправлено][Подробный индикатор скорости соединения] Совместимость с Android 7.1 -[Исправлено][Пользовательские действия на локскрине] Совместимость с Android 7.1 -[Исправлено][MIUI 12] Вылет настроек модуля на бета прошивках - -3.0.2 -[Новое] Отключить заглушение музыки в режиме Не беспокоить -[Новое] Переключение режима Не беспокоить вместо Бесшумного режима из свёрнутого диалога громкости -[Новое] Время перед автоскрытием диалога громкости -[Новое] Нижний отступ в Google Клавиатуре -[Новое][MIUI 12] Разрешить плавающее окно по свайпу вниз, если у уведомления задано подходящее действие на нажатие -[Улучшено][Компактные уведомления][MIUI 12] Увеличена высота кнопок действий -[Исправлено][Показ будильника на локскрине] Совместимость со стилем часов от супер обоев -[Исправлено][Пользовательские действия на локскрине] Совместимость с некоторыми древними версиями Андроида -[Исправлено][Свайп вниз по всплывающим уведомлениям] Игнорировать уведомления с плавающими окнами -[Исправлено] Показ секунд на часах в строке состояния -[Исправлено] Скрытие иконки отстутствия SIM карты - -3.0.0 -[Новое] Увеличение лимита активных уведомлений от одного приложения -[Новое] Увеличение/отключение лимита на количество иконок уведомлений в строке состояния -[Новое] Отключение принудительного тёмного режима -[Новое][MIUI 12] Сворачивать заголовки MIUI -[Улучшено][Высота навбара, Отступ доп. кнопок навбара] Увеличен диапазон значений -[Улучшено][Доп. сведения о приложении] Версия кода APK -[Исправлено][Показывать секунды в строке состояния] Добавление секунд дважды -[Исправлено][Высота и ширина области срабатывания жеста Назад] Поддержка жестов из MIUI Launcher -[Исправлено][Жесты ланчера] Свайп вверх и вниз; совместимость с последними версиями MIUI Launcher -[Исправлено][Действия на отпечаток пальца при звонке] Действие на долгое нажатие -[Исправлено][Раздельные настройки громкости] Правильное отображение слайдера уведомлений в заглушённом состоянии в диалоге громкости при включенном режиме Не беспокоить -Коронавирусный анти-праздник снова с нами! Теперь ещё более вирусный! -Совместимость с MIUI 12: - Иконка быстрого доступа - Анимация при повороте - Пользовательские ярлыки на экране блокировки (запуск без разблокировки) - Раздельные настройки громкости - Компактные уведомления - Расширенное меню уведомления - Приложение быстрого доступа/Часов/Календаря в панели уведомлений - Показ будильника на экране блокировки - Скрыть верхний блок на экране блокировки - Увеличение числа отложенных интервалов уведомлений - Доп. сведения о приложении - Горизонтальные жесты - -2.2.1 -[Новое] Отключение кнопки экстренного вызова на экране блокировки -[Улучшено][Конфигурация снимков экрана] Опция для выбора произвольной папки сохранения -[Улучшено][Дополнительные элементы всплывающего сообщения] Отключение родного добавления названия приложения на китайских прошивках -[Улучшено][Расширенное меню уведомления] Отображение всех иконок в один ряд в уведомлениях минимальной важности, чтобы они влезали по высоте, когда уведомление свёрнуто -[Исправлено][Раскрасить заголовок уведомления] Не применять к стилизированным медиа уведомлениям -[Исправлено][Задержка перед выключением на экране блокировки] Мод также влиял на задержку вне экрана блокировки -Исправления интерфейса настроек модуля - -2.2.0 -[Новое] Использовать родной список последних приложений вместо списка из Рабочего стола MIUI -[Улучшено][Обложка альбома на обоях] Опция для конвертации обложки в чёрно-белое изображение -[Улучшено][Показывать ток зарядки] Опция для добавления значения после/перед/новой строкой -[Исправлено][Пользовательские действия на локскрине] Действие на свайп влево и замена правой иконки: совместимость с последними бета прошивками -[Исправлено][Пользовательские действия виджета безопасности] Совместимость со списком последних приложений из Рабочего стола MIUI -[Исправлено][Убрать кнопку очистки] Совместимость со списком последних приложений из Рабочего стола MIUI -[Исправлено][Убрать анимацию разблокировки] Совместимость с последними бета прошивками; также отключает анимацию затухания/уменьшения экрана блокировки -[Исправлено][Использовать старую анимацию запуска] Совместимость с последними альфа версиями Рабочего стола MIUI -[Исправлено][Исправить анимацию рабочего стола] Совместимость с последними альфа версиями Рабочего стола MIUI -[Исправлено][Данные о приложении при инсталляции] Совместимость с последней версией установщика пакетов MIUI -[Исправлено][Время показа всплывающего скриншота] Совместимость с последними бета прошивками -Отображение главного меню на всех страницах настроек модуля -Новый анти-праздничный дизайн ☣️ - -2.1.5 -[Новое] Усложнить PIN в Защите приложений -[Новое] Отображение значения текущего тока зарядки в нижней области экрана блокировки -[Улучшено][Индикатор батареи полоской] Опция для отображения только в панели уведомлений и на экране блокировки -[Улучшено][Менеджер отложенных уведомлений] Опция для безвременного отключения уведомления (до следующей перезагрузки) -[Исправлено][Менеджер отложенных уведомлений] Правильное время до возобновления показа отложенного уведомления - -2.1.4 -[Новое] Изменение задержки перед скрытием плавающего окна с только что сделанным снимком экрана -[Новое] Неограниченное число иконок в доке рабочего стола -[Улучшено][Индикатор батареи полоской] Выравнивание по низу (индикатор также будет внизу экрана в панели уведомлений и на экране блокировки) -[Исправлено][Использовать всю ширину папки] Обрезанные иконки при анимации закрытия папки - -2.1.3 -[Новое] Скрыть оверлеи при создании снимка экрана -[Новое] Поддержка обратной портретной ориентации рабочим столом -[Улучшено][Динамический индикатор экранов] Опция для показа только в режиме редактирования -[Улучшено][Пределы автояркости] Опция для переключения на нелинейную шкалу для старых версий Android (использовать, если мод задаёт неверные проценты) -[Улучшено][Очистка меню "Открыть с помощью"] Скрытие приложений из меню на основе типа открываемого контента -[Улучшено][Визуализация музыки] Опция для отображения визуализации только при наличии медиа контроллера (обычно создаётся аудио плеерами для уведомлений с кнопками управления) -[Исправлено][Визуализация музыки] Визуализация не показывалась сразу после открытия шторки - -2.1.2 -[Новое][Скрытие иконок] Скрывать иконку VoWiFi -[Новое][Рабочий стол MIUI] Убрать анимацию разблокировки -[Новое][Рабочий стол MIUI] Использовать старую анимацию запуска -[Улучшено][Показать уровень освещённости] Пониженная частота обновлений для предотвращения хаотичного изменния значений -[Исправлено][Скрыть предупреждение о низком заряде батареи] Совместимость с некоторыми прошивками -[Исправлено][Очистить все последние приложения] Совместимость с Android 10 -Исправление вылетов интерфейса модуля - -2.1.1 -[Новое] Не показывать диалог при достижении небезопасного уровня громкости -[Новое] Не показывать диалог о низком заряде батареи -[Новое] Отключить скриншот на одновременное нажатие кнопки питания и понижения громкости -[Новое] Не включать экран при нажатии на сканер, если не заданы отпечатки -[Новое] Начать разблокировку устройства при нажатии на нижнюю область экрана блокировки -[Новое][Скрытие иконок] Скрывать иконку Wi-Fi -[Улучшено][Пределы автояркости] Минимальное и максимальное значение автояркости в процентах -[Улучшено][Визуализация музыки] Более высокая скорость отрисовки в некоторых случаях; опция для выбора метода отрисовки -[Исправлено][Раскрасить заголовок уведомления] Совместимость с Android 10 - -2.1.0 -[Улучшено][Расширенное меню уведомления] Всегда открывать страницу с данными о приложении в MIUI стиле -[Улучшено][Android 9+] Поддержка режима списка приложений (чёрный/белый список) (некоторые моды всё равно могут не работать, поэтому предупреждение останется) -[Исправлено] Не вибрировать при неудачной аутентификации отпечатком -[Исправлено] Вылет в списке отложенных уведомлений -[Исправлено][Напоминание о пропущенном звонке] Останавливать играющий рингтон при удалении уведомления о пропущенном звонке -[Исправлено][Компактные уведомления] Некорректная высота кнопок действий в некоторых уведомлениях -[Исправлено][Управление жестами в строке состояния] Мод был сломан на старых версиях Android после недавних изменений -Новый праздничный дизайн 🐀🏮 -Совместимость с Android 10: - Не включать экран при зарядке/подключении наушников - Не требовать пароль после загрузки - Отключить блокировку - Закрепление ориентации - Слайдер медиа позиции - Отключить избыточную прокрутку - Скрыть в недавних - Время отображения всплывающих сообщений - [Авторизация отпечатком] Вибрация при успехе, отключение вибрации при неудаче, включение экрана при неудаче - -2.0.10 -[Новое] Больше опций времени и менеджер отложенных уведомлений -[Новое] Закрывать все запущенные приложения при нажатиии на кнопку очистки в списке последних приложений -[Новое] Убрать ползунок яркости или сделать его только для отображения -[Улучшено][Множитель шагов громкости] Множитель до 5x -[Улучшено][Быстрый фонарик] Временно отключать пробуждение при взятии в руки, если фонарик активен -[Улучшено][Управление жестами в строке состояния] Показывать процент при изменении яркости, если включен мод "Показывать процент яркости" -[Исправлено][Время показа всплывающих сообщений] Совместимость с некоторыми прошивками -[Исправлено][Android 7] Вылет в некоторых списках приложений - -2.0.9 -[Новое] Время показа всплывающих сообщений -[Новое] Не показывать вертикальный разделитель между временем и индикатором скорости на устройствах с вырезом-каплей -[Новое] Разрешить добавлять виджеты и приложения на любой экран рабочего стола MIUI на планшетах -[Новое][Дополнительные кнопки навбара] Опция для увеличения расстояния от кнопок до краёв экрана -[Новое][Отключить блокировку] Tasker плагин для принудительного включения/выключения блокировки -[Улучшено][Отключить блокировку] Опция для обязательной аутентификации после перезагрузки -[Улучшено][Отключить блокировку] Изменение блокировки сразу при изменении статуса Bluetooth подключений -[Исправлено][Действие инвертирования цветов] Восстанавливать цветовую схему/режим чтения после отключения инвертирования -[Исправлено][Визуализация музыки] Определение статуса проигрывания музыки на некоторых прошивках; также визуализация теперь будет активна при проигрывании любой музыки, а не только той, что имеет медиа уведомление - -2.0.8.1 -[Исправлено][Управление звонками отпечатком] Ошибка при активации мода, которая также влияла на работоспособность других модов - -2.0.8 -[Новое] Настройка формата, качества и папки сохранения скриншотов -[Новое] Принятие или отклонение входящих вызовов и завершение текущего вызова с помощью сканера отпечатков -[Новое] Отступ дока ланчера снизу -[Новое][Исправление багов рабочего стола] Всегда открывать данные о приложении в стиле MIUI из меню по долгому нажатию -[Улучшено][Сетка Быстрых Настроек] До 7 колонок -[Улучшено][Пользовательские ярлыки на локскрине] Разрешить показ всего приложения полностью на экране блокировки, а не только одной activity -[Улучшено][Пользовательские ярлыки на локскрине] Запуск приложений Mi Home и Mi Пульт без разблокировки, если включена соответствующая опция для ярлыков -[Исправлено][Раздельные настройки громкости] Вылет в настройках звука -[Исправлено][Скрытие иконок] Скрывать иконку зарядки внутри иконки батареи -Праздник к нам приходит! :) - -2.0.7 -[Новое][Исправление багов рабочего стола] Применение масштабирования продолжительности аниматоров значений к некоторым анимациям ланчера -[Улучшено][Все ориентации] Опция для включения и отключения -[Улучшено][Закрывать папки автоматом] Опция для включения и отключения -[Улучшено][Раздельные настройки громкости] Новые иконки в Настройках для слайдеров громкости уведомлений и системных звуков -[Улучшено][Управление жестами в строке состояния] Лучший метод обработки скольжения с настраиваемой чувствительностью -[Исправлено][Действие переключения автоповорота] Неправильная ориентация в некоторых случаях -[Исправлено][Пользовательские ярлыки на локскрине] Совместимость с последними прошивками - -2.0.6 -[Новое] Свободное изменение размера любых виджетов (за исключением некоторых виджетов MIUI) -[Новое] Отображение времени следующего будильника на экране блокировки -[Новое][Управление жестами в строке состояния] Регулировка яркости или громкости скольжением 1 или 2 пальцами; действие на двойное нажатие -[Улучшено][Управлять курсором ввода] Чёрный список -[Исправлено][Высота строки состояния] Обновление отступа сверху в ланчере для соответствия изменённой высоте строки состояния -[Исправлено][Минимальная автояркость] Совместимость с некоторыми прошивками на Android 8 - -2.0.5 -[Новое] Уменьшение интенсивности вибрации (силы или продолжительности) в указанные часы -[Новое][Полноэкранные жесты навигации] Ширина области срабатывания жеста Назад -[Улучшено][Пользовательские ярлыки на локскрине] Неограниченное количество ярлыков с иконками приложений и выравниванием по верху/низу -[Улучшено][Модификация названий приложений] Поддержка клонированных приложений -Выбор языка интерфейса -Улучшение интерфейса модуля: сохранение текущего состояния при смене конфигурации; правильный размер чекбоксов в тёмном режиме - -2.0.4 -[Новое] Опции размытия фона папок (требуется Рабочий стол MIUI с поддержкой размытия фона в папках) -[Улучшено][Показывать процент яркости] Настраиваемый отступ сверху -[Улучшено][Наложение цвета на фон папок] Настраиваемый уровень затемнения/осветления; плавное изменение прозрачности наложения при открытии папки -[Улучшено][Очистка меню "Открыть с помощью"] Скрытие приложений, способных открывать ссылки с протоколами http, https и vnd.youtube -[Улучшено][Модификация названий приложений] Изменение названий в полном списке приложений -[Улучшено][Дополнительные кнопки навбара] Чуть больше расстояние между оригинальными кнопками, кнопка полноэкранного режима сдвинута вправо для предотвращения обрезания -[Исправлено][Действия на долгое нажатие клавиш громкости] Поддержка опции включения экрана при одиночном нажатии -[Исправлено][Пользовательские ярлыки на локскрине] Совместимость с последними прошивками - -2.0.3 -[Новое][Число колонок в папках] Использовать всю ширину папки -[Улучшено][Размытия фона диалога громкости] Отключено затемнение фона при активном размытии -[Исправлено][Действия на ярлыках в списке последних приложений] Отсутствовали названия некоторых действий -[Исправлено][Режим совместимости ланчера] Теперь действительно работает -[Исправлено][Показывать процент яркости] Совместимость с некоторыми прошивками -Улучшение поддержки тем оформления, исправления интерфейса - -2.0.2 -[Новое] Разрешить любому уведомлению из MIUI приложений отображаться на экране блокировки и в виде всплывающего -[Новое] Скрыть панель Быстрых Настроек и слайдер яркости в режиме развёрнутых уведомлений на экране блокировки -[Новое] Убрать фон панели уведомлений на экране блокировки -[Новое] Действия запуска на двойное нажатие кнопки питания -[Улучшено][Число колонок в папках] Опция уменьшения боковых отступов для 4 и более колонок -[Улучшено][Показать названия в доке] Дополнительный отступ дока снизу при включенных полноэкранных жестах (только для MIUI ланчера) -[Улучшено][Отключить проверку подписи] Пропуск проверки в MIUI установщике -[Улучшено][Показывать секунды] Равные промежутки обновления -[Улучшено][Фон папок] Использовать белый цвет для светлых обоев -[Исправлено][Слайдер медиа позиции] Совместимость с некоторыми прошивками -Долгое нажатие на строку поиска показывает список новых модов -Прокручивать до найденного мода и красиво его подсвечивать :) -Чекбоксы в MIUI стиле в списках на MIUI 11 -Адаптивная иконка модуля - -2.0.1 -[Новое] Показывать названия приложений в доке ланчера -[Новое] Разрешить запись видео и скриншоты во всех приложениях -[Новое] Размытие фона в свёрнутом и развёрнутом диалогах громкости -[Новое] Режим совместимости для всех модов ланчера -[Улучшено][Разблокировать размеры сетки] Сетка ланчера до 8x8 -[Улучшено][Обложка альбома на обоях] Масштабирование обложки -Исправления интерфейса настроек модуля - -2.0.0 -[Новое] Альтернативная иконка кнопки Назад в режиме ввода -[Новое] Заменить ленту виджетов на Google Discover в MIUI ланчере -[Новое] Использовать установщик пакетов MIUI по умолчанию и разрешить ему обновление системных приложений -[Улучшено][Слайдер медиа позиции] Опция для переключения на системный стиль слайдера -[Улучшено][Данные о приложении при инсталляции] Поддержка установщика пакетов MIUI -[Улучшено][Контроль состояния приложений] Возможность отключать больше приложений (Системный рабочий стол, Поиск устройства и пр.) -[Исправлено][Продолжительность затемнения] Совместимость с некоторыми прошивками, теперь настраивается в процентах от задержки выключения экрана -[Исправлено][Пользовательские действия на локскрине] Запуск действий, назначенных на ярлыки -[Исправлено][Действия навбара] Медиа действия при долгом нажатии основных кнопок -Совместимость с MIUI 11: - Иконка быстрого доступа - Дополнительные элементы всплывающих уведомлений - Разблокировать ланчеры - Слайдер медиа позиции - Действие открытия меню - -1.8.1 -[Новое] Переключатель тёмного режима в Быстрых Настройках -[Новое] Скрыть названия приложений в ланчере -[Новое] Горизонтальные отступы сетки ланчера -[Новое] Отступ сетки ланчера сверху -[Новое] Высота индикатора страниц ланчера -[Новое] Отображение уровня яркости в процентах при изменении яркости слайдером -[Улучшено][Число рядов в панели Быстрых Настроек] Опция для 2 рядов с уменьшенной высотой БН -[Исправлено][Размер шрифта для названий в ланчере] Не применять размер к заголовку открытой папки -[Исправлено][Пользовательские действия на локскрине] Замена иконки и текста справа; Запуск стоковой камеры, если не задано пользователькое действие -[Исправлено][Расширенное меню питания] Перезапуск интерфейса (System UI) -Мелкие исправления интерфейса модуля - -1.8.0 -[Новое] Действие: Переключение режима управления одной рукой -[Новое] Отображение данных об устанавливаемом приложении в окне инсталлера -[Новое] Отключение избыточной прокрутки в списках -[Новое] Размер шрифта для названий в ланчере -[Новое] Отступ сверху для названий в ланчере -[Новое] Поддержка клонированных приложений в модах: -- Защита приложений -- Скрытые приложения -- Очистка меню "Поделиться" -- Очистка меню "Открыть с помощью" -- Доп. сведения о приложении -- Расширенное меню уведомления -- Приложение быстрого доступа/часов/календаря в панели уведомлений -- Действия Запустить приложение и Запустить компонент -[Улучшено][Число колонок в папках ланчера] Увеличенная ширина сетки в папках -[Улучшено][Конфигурация USB по умолчанию] Не показывать диалог при подключении автоматически на последних прошивках -[Улучшено][Визуализация музыки] Настраиваемый интервал смены динамического цвета -[Исправлено][Минимальная автояркость] Совместимость с некоторыми прошивками -[Исправлено][Скрывать тип мобильной сети] Совместимость с некоторыми прошивками -[Исправлено][Пользовательские действия на локскрине] Совместимость с последними прошивками -[Исправлено][Убрать скрытую папку] Совместимость с последними прошивками -[Исправлено][Число колонок в свёрнутой панели Быстрых Настроек] Совместимость с последними прошивками -Сжатие подробных отчётов для сохранения драгоценного траффика - -1.7.5 -[Новое] Отключение проверки подписи APK при обновлении приложений -[Новое] Продолжительность затемнения перед автоматическим выключением экрана -[Улучшено][Визуализация музыки] Опция динамического цвета (меняет цвет на случайный каждые 10 секунд) -[Исправлено][Модификация названий приложений] Совместимость с последними альфа версиями ланчера -[Исправлено][Конфигурация USB по умолчанию] Неправильное значение по умолчанию -[Исправлено][Минимальная автояркость] Совместимость с некоторыми прошивками -[Исправлено][Расширенное меню уведомления] Совместимость с некоторыми прошивками -Определять, что установлено приложение TaiChi, и не жаловаться на отсутствие Xposed - -1.7.4 -[Новое] Менять громкость медиа при первом нажатии кнопки -[Новое] Не вибрировать при переключении в режим "Без звука" и при включении вибрации в этом режиме -[Улучшено][Индикатор батареи полоской] Нулевая высота полоски -[Улучшено][Визуализация музыки] Настройка продолжительности анимации для изменения частоты обновления визуализации -[Исправлено][Масштаб иконок ланчера] Масштаб метки на иконке приложения -[Исправлено][Очистка меню "Открыть с помощью" и "Поделиться"] Совместимость с некоторыми прошивками -[Исправлено] Круг для выбора цвета не отрисовывался на некоторых устройствах -[Исправлено] Вылеты интерфейса модуля - -1.7.3 -[Новое] Действие: Выбор клавиатуры -[Новое] Не показывать предупреждение о закрытой области динамика -[Новое] Скрыть верхний блок на экране блокировки с часами, датой и прочими данными -[Новое] Настраиваемые звук, вибрация и интервал напоминаний о пропущенном звонке -[Новое] Переключение между тёмным/светлым/авто режимами интерфейса (делает то же, что и Тёмный режим в Настройках, опция главным образом для отключения тёмного режима на прошивках, котрые его не поддерживают) -[Новое][Скрытие иконок] Скрытие иконки VoLTE в строке состояния -[Исправлено][Показать уровень освещённости] Визуальный баг правой иконки на слайдере при изменении яркости -[Исправлено][Масштаб иконок ланчера] Масштабировать виджеты быстрого доступа MIUI -[Исправлено][Модификация названий приложений] Изменение названий без перезагрузки на последних версиях ланчера -[Исправлено][Минимальная автояркость] Совместимость с некоторыми устройствами -[Исправлено][Пользовательские ярлыки на локскрине] Совместимость с некоторыми прошивками -[Исправлено][Подробный индикатор скорости соединения] Расстояние между скоростями при отсутствии иконок индикатора -[Исправлено] Тёмный режим - -1.7.2 -[Новое] Показывать значение окружающей освещённости в люксах внутри ползунка яркости -[Новое] Слайдер позиции в медиа уведомлениях -[Новое] Включение экрана после неудачной авторизации отпечатком -[Новое] LTE иконка вместо 4G -[Новое] Показ интерфейса входящего звонка вместо уведомления -[Новое] Настраиваемая яркость экрана во время звонка -[Новое] Масштаб системной анимации от x0 до x10 с шагом в 0.1x -[Новое] Масштаб иконок и папок в ланчере -[Новое][Скрытие иконок] Скрытие иконок рабочего профиля и отсутствия SIM в строке состояния -[Улучшено][Множитель шагов громкости] Шаг в 0.25x -[Удалено][Режим "В кармане"] Мод потреблял батарею во время сна, получая значения от датчика приближения раз в секунду; ультразвуковые сенсоры ненадёжны в подобных ситуациях, т.к. начинают возвращать верные значения только спустя 1 секунду -[Исправлено][Расширенное меню уведомления] Вертикальная позиция при выключенном моде Компактные уведомления -[Исправлено][Пользовательские действия на локскрине] Восстанавливать оригинальное изображение камеры справа, если в моде не выбрано действие; Лучшая совместимость с некоторыми прошивками -[Исправлено][Скрыть кнопку удаления] Совместимость с новыми прошивками -[Исправлено][Android 7] Не работала замена изображений в ресурсах (влияло на несколько модов) -[Исправлено] Списки выбора одиночного приложения в настройках модуля -[Улучшено] Категоризация настроек модов - -1.7.1 -[Исправлено][Высота строки состояния, Высота панели навигации] Неполное изменение высоты, медленная загрузка, бутлупы -[Исправлено][Пользовательские действия на экране блокировки] Скрытие иконки слева при отключении свайпа вправо; Лучшая совместимость с некоторыми прошивками -[Исправлено][Быстрый фонарик, Действия на долгое нажатие кнопок громкости] Совместимость с режимом AOD ("Экран всегда активен") - -1.7.0 -[Новое] Отключение любых уведомлений, включая системные -[Новое] Настраиваемые действия на ярлыки и жесты на экране блокировки -[Новое][Скрытие иконок] Скрытие иконок VPN и мобильной точки доступа в строке состояния -[Улучшено][Раздельные настройки громкости] Ползунок уведомлений в развёрнутой панели громкости теперь опциональный -[Исправлено][Расширенное меню уведомления] Вертикальная позиция -[Исправлено][Скрыть кнопку удаления, Конфигурация USB по умолчанию, Действия на долгое нажатие кнопок навбара] Совместимость с некоторыми прошивками -[Исправлено][Контроль состояния приложений, Доп. сведения о приложении] Совместимость с последними версиями приложения Безопасность -Поддержка замены ресурсов в Xposed framework больше не требуется для работы модуля - -1.6.7 -[Новое] Настраиваемая полоска-индикатор батареи -[Новое] Скрытие иконок в строке состояния -[Новое] Показывать иконку будильника только за указанное количество часов до его срабатывания -[Новое] Скрывать иконку Bluetooth когда нет подключенных устройств -[Новое] Запретить стандартному MIUI действию насильно закрывать указанные приложения -[Новое] Действия: Запуск любого компонента из любого установленного приложения -[Новое][Android 9+] Показывать лупу при выделении текста (только для элементов основанных на TextView) -[Улучшено] Выбор цвета в настройках модуля (поддержка тёмных цветов и ландшафтного режима) -[Исправлено][Совместимость будильника] Отображалось неверное время срабатывания -[Исправлено] Баги интерфейса - -1.6.6 -[Новое] Разрешить все ориентации экрана -[Новое] Виброотклик при успешной аутентификации -[Новое] Убрать виброотклик при неудачной аутентификации -[Новое] Очистка меню "Открыть с помощью" -[Новое] Конфигурация USB по умолчанию при подключении к другим устройствам -[Новое][Визуализация музыки] Опция, добавляющая свечение -[Новое][Подробный индикатор скорости соединения] Опционально делать индикатор полупрозрачным, если обе скорости равны нулю -[Новое] Опция для пометки новых модов определённое количество дней посе обновления или всегда -[Улучшено][Виброотклик при переключении настроек] Опция для игнорирования отключения виброотклика в системных настойках -[Улучшено][Раздельные настройки громкости] Добавление ползунка уведомлений в раскрытый диалог громкости -[Улучшено][Доп. сведения о приложении] Открытие приложения в Play Маркете, копирование имени APK и пути к данным в буфер обмена -[Исправлено][Визуализация музыки] Цвета радуги горизонтально на версиях Android ниже 9 -[Исправлено] Действия на ярлыки виджета безопасности в списке последних приложений - -1.6.5 -[Новое] В выбранных приложениях правильно показывать время следующего будильника, установленного стандартным приложением часов MIUI -[Новое] Заставить выбранные приложения игнорировать входящие звонки и продолжать играть аудио -[Новое] Улучшенная версия функции Защита приложений, позволяющая заблокировать любое установленное приложение -[Новое] Бесконечная прокрутка в MIUI/POCO ланчерах - позволяет переходить с последнего экрана на первый и обратно -[Новое] Автоскрытие индикатора экранов в MIUI ланчере -[Новое][Действия на отпечаток пальца] Опция для отключения действий при активном звонке -[Улучшено] Действие открытия диалога громкости открывает диалог, который регулирует правильную громкость при активном звонке -[Исправлено][Визуализация музыки] Отрисовка пунктирных полосок и кругов на версиях Android ниже 9 -[Исправлено] Прочие мелкие баги и вылеты - -1.6.4 -[Новое][Визуализация музыки] Опция для рисования визуализации поверх стороннего экрана блокировки -[Улучшено][Визуализация музыки] Рисование визуализации поверх фона из темы в панели уведомлений -[Исправлено][Обложка альбома на обоях] Отключение на сторонних экранах блокировки -[Исправлено][Раздельные настройки громкости] Сохранять системную громкость между перезагрузками -[Исправлено] Скрытие подписей к переключателям в Быстрых Настройках -[Исправлено снова] Подробный индикатор скорости соединения - -1.6.3 -[Новое] Скрыть панель навигации -[Новое] Визуализация музыки на экране блокировки и в панели уведомлений -[Новое][Подробный индикатор скорости соединения] Выбор размера шрифта -[Исправлено] Подробный индикатор скорости соединения -[Исправлено] На некоторых устройствах действие выключения экрана приводило к невозможности включить его обратно -[Исправлено][Очистка меню "Поделиться"] Удаление смс приложений приводило к их неработоспособности -[Улучшено][Не скрывать уведомления] Совместимость с новыми прошивками -[Улучшено] Открытие EdXposed Manager из меню в настройках модуля - -1.6.2 -[Новое] Высота панели навигации -[Новое] Минимальное значение автояркости -[Новое] Не блокировать приложения при блокировке устройства (когда выбрана опция с блокировкой после закрытия) -[Новое] Изменение интервала между закрытием приложения и его блокировкой -[Исправлено][Очистка меню "Поделиться"] Не все приложения были доступны для удаления -[Исправлено][Иконка быстрого доступа] Улучшена совместимость, добавлен выбор позиции в списке - -1.6.1 -[Новое] Больше интервалов для таймеров бесшумного режима и режима не беспокоить -[Новое] Удаление приложений из меню Поделиться -[Новое] Запрет выбранным приложениям показывать всплывающие сообщения -[Новое] Более тёмная тень у названий приложений в ланчере -[Новое] Убрать ограничение на сторонние ланчеры на китайских прошивках -[Новое] Действия для 4 ярлыков в виджете безопасности в списке последних приложений -[Новое] Действие на двойное нажатие на пустое место в ланчере -[Новое] Действия: Открыть меню, Открыть панель громкости, Увеличить громкость, Уменьшить громкость -[Новое] Ярлык для разблокировки учётных данных (долгое нажатие на иконку CustoMIUIzer в ланчерах, поддерживающих подобные ярлыки) -[Новое] Функция поиска модов в настройках модуля -[Исправлено] Отключение жестов в ланчере в режиме редактирования -[Улучшено][Подробный индикатор скорости соединения] Совместимость с новыми прошивками - -1.6.0 -[Новое] Поддержка POCO Launcher для некоторых модов -[Новое] Поддержка MIUI Launcher до версии 4.9.5-dev -[Новое] Исправление цвета содержимого строки состояния в зависимости от светлых/тёмных обоев на версии ланчера для разработчиков -[Новое] Одинаковые цвета фона строки состояния и панели действий приложения, где это возможно -[Новое] Выбор приложений, которые будут запущены при тапе по часам, дате и иконке над батареей в заголовке открытой панели уведомлений -[Новое] Действие: Назад -[Новое] Поддержка тёмного режима для настроек модуля (цвет текста в некоторых диалогах неправильный, исправлению пока не поддаётся :)) -[Улучшено][Доп. кнопки на панели навигации] Левая и правая кнопки появляются независимо друг от друга - -1.5.7 -[Исправлено][Расширенное меню питания] Баг анимации кнопки выключения -[Исправлено][Расширенное меню питания] Локализация -[Исправлено] Разблокировать учётные данные -[Улучшено] Обработка и логирование ошибок - -1.5.6 -[Новое] Расширенное меню питания (Fastboot/Recovery/Быстрая перезагрузка/Перезапуск интерфейса (System UI)/Перезапуск ланчера) -[Новое] Возвращение режима "В кармане" в расширенные настройки экрана блокировки на устройствах с ультразвуковым датчиком приближения -[Новое] Изменение высоты строки состояния -[Новое] Настраиваемая сетка Быстрых Настроек (в свёрнутом и развёрнутом состоянии) -[Новое] Скрыть все подписи в Быстрых Настройках -[Новое] Скрыть кнопку для очистки списка последних приложений и памяти -[Новое] Скрыть в шторке кнопку для удаления всех уведомлений -[Новое] Возможность отключения (почти) любого приложения с его страницы "О приложении" -[Новое] Активировать вместе горизонтальные жесты и панель навигации -[Новое] Действия: Очистить память, Инвертировать цвета -[Новое] Действия на долгое нажатие кнопок навбара Назад, Домой и Меню - -1.5.5 -[Новое] Переключатель в Быстрых Настройках для закрепления портретной или ландшафтной ориентации -[Новое] Отключение заглушения музыки при проигрывании звуков уведомлений -[Новое] Отключение действий на сканер отпечатка пальца в Камере -[Новое] Автоматически закрывать папки в MIUI ланчере после запуска приложений -[Новое][Улучшенные всплывающие уведомления] Задержка перед скрытием -[Улучшено] Отображение выбранных приложений в начале списков в настройках модуля -[Улучшено] Проверка на отключение замены ресурсов в Xposed Framework -[Исправлено][Расширенное меню уведомления] Поддержка последней стабильной версии MIUI -[Исправлено][Блокировка вибрации] Поддержка Android 7 -[Исправлено][Обложка альбома на обоях] Улучшена поддержка различных версий Android -[Исправлено][Скрыть в недавних] Мод переключен с динамического на обычный для предотвращения бутлупов -[Исправлено][Модификация названий приложений] Исправление багов - -1.5.4 -[Новое] Запретить выбранным приложениям использовать вибрацию -[Новое] Модификация названий приложений на Рабочем столе MIUI -[Новое][Отключить блокировку] Использовать доверенные Bluetooth устройства -[Новое] Добавить иконку в ланчере или использовать ярлык для разблокировки учётных данных (авторизация в некоторых приложениях требует доступа к учётным данным, но при пропуске ПИН-кода/пароля/графического ключа после загрузки они остаются заблокированными) - -1.5.3 -[Новое] Показывать уведомления на экране блокировки даже после того как он был закрыт и потом открыт вновь -[Новое] Новые действия в меню уведомления (открывается по свайпу влево) - открыть информацию о приложении и принудительно закрыть приложение -[Новое] Не показывать иконку с 3 точками, когда активна опция скрытия иконок уведомлений -[Новое][Виброотклик при переключении настроек] Опция сильной/слабой вибрации -[Новое][Полноэкранные жесты навигации] Высота области срабатывания жеста Назад -[Новое][Android 8+] Настройка числа уведомлений от одного приложения при котором срабатывает их автоматическая группировка -[Исправлено][Прозрачность фона из темы] Отвязана от значения размытия фона панели уведомлений -[Исправлено][Подробный индикатор скорости соединения] Чрезмерный отступ слева -[Исправлено][Компактные уведомления] Баг с прозрачностью после открытия панели уведомлений -[Исправлено] Улучшена обработка ошибок в модах -Настройки модуля лучше организованы, добавлена новая индикация динамических модов - -1.5.2 -[Новое] Компактные уведомления -[Новое] Улучшенные Скрытые приложения -[Новое] Скрытие приложений из списка недавних -[Новое] Виброотдача при переключении Быстрых настроек -[Новое] Возможность скрыть иконку модуля в ланчере -[Исправлено] Анимация затухания при повороте экрана -[Исправлено] Системная настройка "Виброотклик" теперь влияет на вибрацию в модах -[Исправлено] Баги интерфейса настроек модуля - -1.5.1 -[Новое][Разворачивать уведомления] Чёрно-белый список -[Новое][Управлять курсором ввода] Опция для перемены местами направлений движения курсора -[Новое][Скрывать тип мобильной сети] Скрывать полностью или только когда нет подключения -[Новое] Не скрывать часы в статус баре на домашних экранах с виджетами часов -[Новое] Разрешить установку старых версий приложений поверх новых -[Новое] Действие открытия системного меню питания (на сканер отпечатка и доп. кнопки на навбаре) -[Новое] Новенькая иконка быстрого доступа :) -[Исправлено][Android 7] Расширенные уведомления -[Исправлено] Определение установлен ли EdXposed Manager - -1.5.0 -[Новое][Рабочий стол MIUI] Затемнение фона папок -[Новое][Рабочий стол MIUI] Разблокировка размеров сетки от 3x4 до 6x7 -[Новое][Рабочий стол MIUI] Количество столбцов в папках -[Новое] Анимация при повороте экрана (плавный переход или без анимации) -[Новое] Открытие панели уведомлений автоматически при получении уведомлений от выбранных приложений -[Новое] Отображение обложки текущего трека в качестве обоев на экране блокировки -[Новое][Улучшенные всплывающие уведомления] Не скрывать автоматически -[Новое][Улучшенные всплывающие уведомления] Свайп вниз открывает панель уведомлений -[Исправлено][Отключение блокировки устройства] Выбор нескольких доверенных Wi-Fi сетей - -1.4.3 -[Новое] Динамическая блокировка устройства (полное отключение, блокировка только раз после загрузки, отключение блокировки в доверенных Wi-Fi сетях; также можно пропустить и экран блокировки) -[Новое] Подробный индикатор скорости соединения (скорость и различные иконки для входящего/исходящего трафика, задание уровня низкой скорости для изменения индикации) -[Новое] Частота обновления индикатора скорости - -1.4.2 -[Исправлено] Мод, задающий действие на свайп вверх в ланчере, заменяет стандартное действие (поиск) -[Исправлено] Доп. проверка на использование сканера в моде действий на сканер отпечатка пальца -[Новое] Настраиваемые задержки для двойного и долгого нажатия в моде действий на сканер отпечатка пальца - -1.4.1 -[Исправлено] Быстрый фонарик -[Новое] Действие переключения на предыдущее приложение для кнопок навбара и сканера отпечатков -[Новое] Опциональная вибрация при выполеннии действия на долгое нажатие кнопок громкости - -1.4.0 -[Новое] Настраиваемые действия на одиночное/двойное/долгое нажатие на сканер отпечатка пальца при включенном экране -[Новое] Опция для запрета включения экрана при любом событии зарядки, либо только для тех, где нет анимации -[Новое] Настраиваемое время удержания экрана включенным при старте анимации зарядки -[Новое] Действия открытия панели уведомлений/быстрых настроек/последних приложений также закрывают их, если они уже открыты -[Новое] Увеличение количества шагов громкости для всех типов потоков множителем - -1.3.1 -[Исправлено][Совместимость] MIUI 10.3 -[Исправлено] Длительность анимации при выключении экрана -[Исправлено] Не включать экран при подключении зарядки (включая беспроводную) -[Новое] Не включать экран при подключении наушников - -1.3.0 -[Исправлено][Совместимость] Загрузка настроек модуля на устройствах с зашифрованным хранилищем. Перед установкой данной версии стоит сделать бэкап настроек, т.к. они будут сброшены до дефолтных! -[Исправлено][Совместимость] Доп. сведения о приложении -[Исправлено][Совместимость] Быстрый фонарик -[Исправлено][Совместимость] Медиа действия на кнопки громкости -[Исправлено][Совместимость] Все моды с настраиваемыми действиями/переключателями -[Новое] Две новых кнопки на панели навигации с настраиваемыми действиями -[Новое] Уровень прозрачности фона панели уведомлений из текущей темы -[Новое] Скрыть иконку типа мобильной сети в строке состояния -[Новое] Увеличить отступ справа для индикатора скорости трафика - -1.2.0 -[Новое] Отображать секунды на часах в статусбаре -[Новое] Всегда показывать уведомления в полностью развёрнутом виде -[Новое] Медиа действия на долгое нажатие клавиш повышения/понижения громкости при выключенном экране -[Новое] Уровень размытия фона в окне последних приложений и в панели уведомлений -[Перемещено] Мод "Управлять курсором ввода" был перемещён в категорию Управление, требуется повторная активация - -1.1.1 -[Новое] Отдельная громкость в Настройках для звонков/уведомлений/системных звуков -[Новое] Перемещать курсор ввода текста кнопками громкости - -1.1.0 -[Новое] Двойное нажатие на экране блокировки для выключения экрана -[Исправлено][Android 7.0+] Инициализация модуля, действия для переключателей. Моды всё равно могут не работать. - -1.0.1 -[Исправлено] Иконка быстрого доступа на некоторых устройствах -[Исправлено] Проверка обновлений - -1.0.0 -Первый релиз \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 3123388c..1033b318 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.android.application' -def acraVersion = '5.7.0' +//def acraVersion = '5.7.0' def keystorePropertiesFile = rootProject.file("../keystore.properties") def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) @@ -28,15 +28,16 @@ android { v2SigningEnabled true } } - compileSdkVersion 29 + compileSdkVersion 31 defaultConfig { - applicationId "name.mikanoshi.customiuizer" - minSdkVersion 24 + applicationId "name.monwf.customiuizer" + minSdkVersion 30 //noinspection OldTargetApi,ExpiredTargetSdkVersion - targetSdkVersion 27 + targetSdkVersion 30 versionCode 71 - versionName "3.2.1" - resConfigs 'ru-rRU', 'uk-rUK', 'zh-rCN', 'pt-rBR', 'de', 'es', 'it', 'tr' + versionName "1.3.2.1" + resConfigs 'ru-rRU', 'zh-rCN' + ndk { abiFilters "arm64-v8a" } } buildTypes { release { @@ -55,8 +56,8 @@ android { flavorDimensions 'api' productFlavors { standalone { - targetSdkVersion 27 - signingConfig signingConfigs.v1 + targetSdkVersion 30 + signingConfig signingConfigs.v2 } playstore { targetSdkVersion 30 @@ -79,11 +80,12 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation "ch.acra:acra-core:$acraVersion" - //noinspection DifferentStdlibGradleVersion +// implementation "ch.acra:acra-core:$acraVersion" +// noinspection DifferentStdlibGradleVersion + implementation "androidx.appcompat:appcompat:1.4.1" +// implementation "androidx.preference:preference:1.2.0" implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10' implementation 'com.github.jinatonic.confetti:confetti:1.1.2' - implementation files('libs/WeatherView-2.0.3.aar') compileOnly 'de.robv.android.xposed:api:82' compileOnly files('lib/miui.jar') compileOnly files('lib/miuisystem.jar') diff --git a/app/libs/WeatherView-2.0.3.aar b/app/libs/WeatherView-2.0.3.aar deleted file mode 100644 index 6da15dd97fc78238003a6bc3d5260b543d83fa2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32549 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 z%0A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 A2mk;8 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 98666fde..af781465 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,216 +1,205 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java index e66756cc..69b4d486 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java @@ -5,7 +5,6 @@ import android.os.Bundle; import android.preference.Preference; import android.view.View; -import android.widget.LinearLayout; import android.widget.TextView; import name.mikanoshi.customiuizer.utils.Helpers; @@ -14,7 +13,6 @@ public class AboutFragment extends SubFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { - supressMenu = true; super.onActivityCreated(savedInstanceState); final Activity act = getActivity(); @@ -47,18 +45,6 @@ public boolean onPreferenceClick(Preference pref) { if (view != null) try { TextView version = view.findViewById(R.id.about_version); version.setText(String.format(getResources().getString(R.string.about_version), act.getPackageManager().getPackageInfo(act.getPackageName(), 0).versionName)); - if (Helpers.currentHoliday == Helpers.Holidays.NEWYEAR) view.findViewById(R.id.santa_hat).setVisibility(View.VISIBLE); - else if (Helpers.currentHoliday == Helpers.Holidays.LUNARNEWYEAR) { - view.findViewById(R.id.lunar_animal).setVisibility(View.VISIBLE); - LinearLayout logoSection = view.findViewById(R.id.logo_section); - logoSection.setPadding(logoSection.getPaddingLeft(), Math.round(view.getResources().getDisplayMetrics().density * 80), logoSection.getPaddingRight(), logoSection.getPaddingBottom()); - } else if (Helpers.currentHoliday == Helpers.Holidays.PANDEMIC) { - view.findViewById(R.id.medical_mask).setVisibility(View.VISIBLE); - view.findViewById(R.id.hand_sanitizer).setVisibility(View.VISIBLE); - } else if (Helpers.currentHoliday == Helpers.Holidays.CRYPTO) { - view.findViewById(R.id.doge).setVisibility(View.VISIBLE); - view.findViewById(R.id.uptrend).setVisibility(View.VISIBLE); - } } catch (Throwable e) { //Shouldn't happen... e.printStackTrace(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java index 52600c64..dc4bdb6d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java @@ -16,12 +16,14 @@ import android.view.MenuItem; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + import java.util.Set; -import name.mikanoshi.customiuizer.holidays.HolidayHelper; import name.mikanoshi.customiuizer.utils.Helpers; -public class MainActivity extends Activity { +public class MainActivity extends AppCompatActivity { MainFragment mainFrag = null; SharedPreferences.OnSharedPreferenceChangeListener prefsChanged; @@ -39,19 +41,9 @@ protected void attachBaseContext(Context base) { @Override protected void onCreate(Bundle savedInstanceState) { - boolean mSDKFound = ((MainApplication)getApplication()).mStarted; - if (mSDKFound) Helpers.setMiuiTheme(this, R.style.MIUIPrefs); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - if (!mSDKFound) { - Toast.makeText(this, R.string.sdk_failed, Toast.LENGTH_LONG).show(); - finish(); - return; - } - - HolidayHelper.setup(this); - prefsChanged = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) { @@ -87,7 +79,11 @@ public void onEvent(int event, String path) { Log.e("prefs", "Failed to start FileObserver!"); } - Helpers.updateNewModsMarking(this); +// Helpers.updateNewModsMarking(this); + + + Toolbar myToolbar = findViewById(R.id.mainActionBar); + setSupportActionBar(myToolbar); if (savedInstanceState != null) mainFrag = (MainFragment)getFragmentManager().getFragment(savedInstanceState, "mainFrag"); @@ -108,7 +104,6 @@ protected void onDestroy() { try { if (prefsChanged != null) Helpers.prefs.unregisterOnSharedPreferenceChangeListener(prefsChanged); if (fileObserver != null) fileObserver.stopWatching(); - HolidayHelper.onDestroy(); if (migrateOnExit) { boolean migrated = Helpers.migratePrefs(); Helpers.prefs = Helpers.getSharedPrefs(this, true, true); @@ -128,9 +123,7 @@ public void onBackPressed() { return; } if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); - if (fragment instanceof MainFragment && ((MainFragment)fragment).actionMode != null) - ((MainFragment)fragment).actionMode.finish(); - else if (fragment instanceof SubFragment) + if (fragment instanceof SubFragment) ((SubFragment)fragment).finish(); else super.onBackPressed(); @@ -139,7 +132,14 @@ else if (fragment instanceof SubFragment) @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { - finish(); + Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container); + if (fragment == null) { + finish(); + return true; + } + if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); + if (fragment instanceof SubFragment) + ((SubFragment)fragment).finish(); return true; } return super.onOptionsItemSelected(item); @@ -148,11 +148,7 @@ public boolean onOptionsItemSelected(MenuItem item) { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { - PreferenceFragmentBase fragment = (PreferenceFragmentBase)getFragmentManager().findFragmentById(R.id.fragment_container); - if (fragment != null && fragment.getView() != null && !fragment.supressMenu) try { - fragment.getView().post(fragment::showImmersionMenu); - return true; - } catch (Throwable t) {} + return true; } return super.onKeyDown(keyCode, event); } @@ -196,26 +192,10 @@ else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); break; case Helpers.REQUEST_PERMISSIONS_REPORT: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) - mainFrag.createReport(); - else Toast.makeText(this, ":(", Toast.LENGTH_SHORT).show(); break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } - - @Override - public void onPause() { - HolidayHelper.onPause(); - super.onPause(); - } - - @Override - public void onResume() { - super.onResume(); - HolidayHelper.onResume(); - } - } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java b/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java index 4f4e59e4..6f9d3441 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java @@ -4,50 +4,15 @@ import android.content.Context; import android.util.Log; -import org.acra.ACRA; -import org.acra.collector.ApplicationStartupCollector; -import org.acra.collector.ConfigurationCollector; -import org.acra.collector.CustomDataCollector; -import org.acra.collector.DeviceFeaturesCollector; -import org.acra.collector.DisplayManagerCollector; -import org.acra.collector.LogCatCollector; -import org.acra.collector.MemoryInfoCollector; -import org.acra.collector.PackageManagerCollector; -import org.acra.collector.ReflectionCollector; -import org.acra.collector.SettingsCollector; -import org.acra.collector.SharedPreferencesCollector; -import org.acra.collector.SimpleValuesCollector; -import org.acra.collector.StacktraceCollector; -import org.acra.collector.ThreadCollector; -import org.acra.collector.TimeCollector; -import org.acra.config.CoreConfigurationBuilder; -import org.acra.data.StringFormat; -import org.acra.plugins.SimplePluginLoader; - -import java.util.HashMap; import java.util.Locale; -import miui.core.SdkManager; - -import name.mikanoshi.customiuizer.crashreport.DialogInteraction; import name.mikanoshi.customiuizer.utils.Helpers; -import static org.acra.ReportField.*; public class MainApplication extends Application { - private boolean mInitialized; public boolean mStarted = false; - public MainApplication() { - try { - mInitialized = SdkManager.initialize(this, new HashMap()) == 0; - } catch (Throwable t) { - mInitialized = false; - t.printStackTrace(); - } - } - @Override protected void attachBaseContext(Context base) { Context pContext; @@ -61,48 +26,7 @@ protected void attachBaseContext(Context base) { Log.e("miuizer", "Failed to use protected storage!"); } super.attachBaseContext(pContext); - - if (mInitialized) try { - int res = SdkManager.start(new HashMap()); - if (res == 1) { - Log.e("miuizer", "MIUI SDK version is too low"); - mStarted = false; - } else if (res == 0) { - mStarted = true; - } else { - Log.e("miuizer", "Failed to start MIUI SDK Manager"); - mStarted = false; - } - } catch (Throwable t) { - t.printStackTrace(); - } else Log.e("miuizer", "Failed to init MIUI SDK Manager"); - - ACRA.DEV_LOGGING = false; - CoreConfigurationBuilder builder = new CoreConfigurationBuilder(this).setPluginLoader(new SimplePluginLoader( - ConfigurationCollector.class, - ApplicationStartupCollector.class, - ConfigurationCollector.class, - CustomDataCollector.class, - DeviceFeaturesCollector.class, - DisplayManagerCollector.class, - LogCatCollector.class, - MemoryInfoCollector.class, - PackageManagerCollector.class, - ReflectionCollector.class, - SettingsCollector.class, - SharedPreferencesCollector.class, - SimpleValuesCollector.class, - StacktraceCollector.class, - ThreadCollector.class, - TimeCollector.class, - DialogInteraction.class - )); - builder.setBuildConfigClass(BuildConfig.class).setReportFormat(StringFormat.JSON).setLogcatArguments("-t", "500", "-v", "time").setSharedPreferencesName(Helpers.prefsName); - builder.setReportContent(REPORT_ID, APP_VERSION_CODE, APP_VERSION_NAME, PACKAGE_NAME, FILE_PATH, PHONE_MODEL, BRAND, PRODUCT, ANDROID_VERSION, - BUILD, TOTAL_MEM_SIZE, AVAILABLE_MEM_SIZE, CUSTOM_DATA, STACK_TRACE, INITIAL_CONFIGURATION, CRASH_CONFIGURATION, DISPLAY, USER_COMMENT, USER_EMAIL, - USER_APP_START_DATE, USER_CRASH_DATE, DUMPSYS_MEMINFO, LOGCAT, INSTALLATION_ID, DEVICE_FEATURES, ENVIRONMENT, SHARED_PREFERENCES, - SETTINGS_SYSTEM, SETTINGS_SECURE, SETTINGS_GLOBAL); - ACRA.init(this, builder); + mStarted = true; } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java index 5ee8dd47..b6295448 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java @@ -2,46 +2,32 @@ import android.annotation.SuppressLint; import android.app.Activity; +import android.app.AlertDialog; import android.content.ComponentName; import android.content.DialogInterface; import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.graphics.Color; import android.graphics.Paint; -import android.graphics.drawable.ColorDrawable; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.CheckBoxPreference; import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; -import android.text.Editable; import android.text.Layout; import android.text.Spannable; import android.text.SpannableString; -import android.text.TextWatcher; import android.text.style.AlignmentSpan; import android.text.style.LineHeightSpan; import android.view.ActionMode; -import android.view.KeyEvent; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; -import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; -import android.widget.PopupWindow; -import android.widget.TextView; - -import org.acra.ACRA; import java.io.BufferedReader; import java.io.File; @@ -50,16 +36,12 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; -import miui.app.AlertDialog; -import miui.view.SearchActionMode; - import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; import name.mikanoshi.customiuizer.prefs.PreferenceEx; import name.mikanoshi.customiuizer.subs.CategorySelector; @@ -67,7 +49,6 @@ import name.mikanoshi.customiuizer.subs.Launcher; import name.mikanoshi.customiuizer.subs.System; import name.mikanoshi.customiuizer.subs.Various; -import name.mikanoshi.customiuizer.utils.GuidePopup; import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.ModData; import name.mikanoshi.customiuizer.utils.ModSearchAdapter; @@ -86,100 +67,7 @@ public class MainFragment extends PreferenceFragmentBase { private View modsCat = null; private View markCat = null; boolean isSearchFocused = false; - boolean areGuidesCleared = false; - boolean actionModeNew = false; ActionMode actionMode = null; - SearchActionMode.Callback actionModeCallback = new SearchActionMode.Callback() { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - if (searchView == null || listView == null) { - if (mode != null) mode.finish(); - return false; - } - - SearchActionMode samode = (SearchActionMode)mode; - samode.setAnchorView(searchView); - samode.setAnimateView(listView); - samode.getSearchInput().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - isSearchFocused = hasFocus; - } - }); - samode.getSearchInput().setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - isSearchFocused = v.hasFocus(); - } - }); - samode.getSearchInput().setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { - Helpers.hideKeyboard(getActivity(), v); - resultView.requestFocus(); - return true; - } - return false; - } - }); - samode.getSearchInput().addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - - @Override - public void afterTextChanged(Editable s) { - findMod(s.toString().trim()); - } - }); - - if (actionModeNew) { - actionModeNew = false; - resultView.postDelayed(new Runnable() { - @Override - public void run() { - samode.getSearchInput().setText(Helpers.NEW_MODS_SEARCH_QUERY); - samode.getSearchInput().setSelection(1, 1); - Helpers.hideKeyboard(getActivity(), getView()); - resultView.requestFocus(); - } - }, getResources().getInteger(android.R.integer.config_longAnimTime)); - } - - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - if (searchView == null || listView == null) { - if (mode != null) mode.finish(); - return false; - } - - SearchActionMode samode = (SearchActionMode)mode; - samode.setAnchorView(searchView); - samode.setAnimateView(listView); - - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - TextView input = search == null ? null : search.findViewById(android.R.id.input); - if (input != null) input.setText(""); - findMod(""); - getActionBar().show(); - actionMode = null; - } - }; private final Runnable showUpdateNotification = new Runnable() { @Override @@ -204,6 +92,12 @@ public void run() { private boolean isFragmentReady(Activity act) { return act != null && !act.isFinishing() && MainFragment.this.isAdded(); } + @Override + public View onCreateView(LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + return LayoutInflater.from(getActivity()).inflate(R.layout.prefs_main12, container, false); + } @Override @SuppressLint("MissingSuperCall") @@ -212,7 +106,6 @@ public void onCreate(Bundle savedInstanceState) { addPreferencesFromResource(R.xml.prefs_main); final Activity act = getActivity(); - final Handler handler = new Handler(act.getMainLooper()); if (Helpers.miuizerModuleActive && !Helpers.prefs.getBoolean("miuizer_prefs_migrated", false) && Helpers.usingNewSharedPrefs()) { ((MainActivity)act).migrateOnExit = true; @@ -223,30 +116,12 @@ public void onCreate(Bundle savedInstanceState) { // Preventing launch delay new Thread(new Runnable() { public void run() { - if (!Helpers.isXposedInstallerInstalled(act)) - act.runOnUiThread(new Runnable() { - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(act); - builder.setTitle(R.string.xposed_not_found); - builder.setMessage(R.string.xposed_not_found_explain); - builder.setNeutralButton(R.string.okay, null); - builder.setNegativeButton(R.string.i_use_lsp, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Helpers.prefs.edit().putBoolean("pref_key_miuizer_assumelsposed", true).apply(); - getActivity().recreate(); - } - }); - AlertDialog dlg = builder.create(); - if (isFragmentReady(act)) dlg.show(); - } - }); else if (isFragmentReady(act) && !Helpers.miuizerModuleActive) + if (isFragmentReady(act) && !Helpers.miuizerModuleActive) act.runOnUiThread(new Runnable() { public void run() { showXposedDialog(act); } - }); else areGuidesCleared = true; + }); if (Helpers.prefs.getBoolean("miuizer_prefs_migrated", false)) { int result = Helpers.prefs.getInt("miuizer_prefs_migration_result", 0); @@ -260,47 +135,6 @@ public void run() { } } - String dataPath = act.getFilesDir().getAbsolutePath(); - try { - URL url = new URL("https://code.highspec.ru/Mikanoshi/CustoMIUIzer/raw/branch/master/last_build"); - //URL url = new URL("https://code.highspec.ru/last_build"); - HttpURLConnection connection = (HttpURLConnection)url.openConnection(); - connection.setDefaultUseCaches(false); - connection.setUseCaches(false); - connection.setRequestProperty("Pragma", "no-cache"); - connection.setRequestProperty("Cache-Control", "no-cache"); - connection.setRequestProperty("Expires", "-1"); - connection.connect(); - - if (connection.getResponseCode() == HttpURLConnection.HTTP_OK || connection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) { - String last_build = ""; - - try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - last_build = reader.readLine().trim(); - } catch (Throwable t) { t.printStackTrace(); } - - File tmp = new File(dataPath); - if (!tmp.exists()) tmp.mkdirs(); - try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(dataPath + "/last_build", false))) { - writer.write(last_build); - } catch (Throwable t) { t.printStackTrace(); } - } - - connection.disconnect(); - } catch (Throwable t) { t.printStackTrace(); } - - try (InputStream inputFile = new FileInputStream(dataPath + "/last_build")) { - int last_build = 0; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputFile))) { - last_build = Integer.parseInt(reader.readLine().trim()); - } catch (Throwable ignore) {} - - if (last_build > BuildConfig.VERSION_CODE) - handler.post(showUpdateNotification); - else - handler.post(hideUpdateNotification); - } catch (Throwable t) { t.printStackTrace(); } - Helpers.getAllMods(act, savedInstanceState != null); } }).start(); @@ -311,16 +145,6 @@ public void run() { } } - public View onInflateView(LayoutInflater inflater, ViewGroup group, Bundle bundle) { - return inflater.inflate(Helpers.is12() ? R.layout.prefs_main12 : R.layout.prefs_main, group, false); - } - - private void openActionMode(boolean isNew) { - actionModeNew = isNew; - actionMode = startActionMode(actionModeCallback); - hideSplitView(); - } - private static class SetLineOverlap implements LineHeightSpan { private int originalBottom = 15; private int originalDescent = 13; @@ -351,6 +175,7 @@ public void chooseHeight(CharSequence text, int start, int end, int spanstartv, @Override public void onActivityCreated(Bundle savedInstanceState) { + supressMenu = true; super.onActivityCreated(savedInstanceState); if (getView() == null) return; @@ -382,84 +207,12 @@ public void run() { } }); setViewBackground(resultView); - - searchView = getView().findViewById(R.id.searchView); - setActionModeStyle(searchView); - - search = searchView.findViewById(android.R.id.inputArea); - search.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - openActionMode(false); - } - }); - search.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - openActionMode(true); - return true; - } - }); - - TextView searchInput = search.findViewById(android.R.id.input); - searchInput.setHint(R.string.search_input_description); - - modsCat = null; markCat = null; - listView = getView().findViewById(android.R.id.list); - listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { - @Override - public void onChildViewAdded(View parent, View child) { - if (child == null) return; - CharSequence title = ((TextView)child.findViewById(android.R.id.title)).getText(); - if (title.equals(getResources().getString(R.string.system_mods))) modsCat = child; - if (title.equals(getResources().getString(R.string.miuizer_show_newmods_title))) markCat = child; - if (modsCat != null && markCat != null) { - if (areGuidesCleared) try { - showGuides(); - } catch (Throwable t) { - t.printStackTrace(); - } - listView.setOnHierarchyChangeListener(null); - } - } - - @Override - public void onChildViewRemoved(View parent, View child) {} - }); - - if (actionMode != null) actionMode.invalidate(); final Activity act = getActivity(); PreferenceEx warning = (PreferenceEx)findPreference("pref_key_warning"); - if (warning != null) - if (Helpers.isRPlus()) { - warning.setTitle(R.string.warning); - warning.setSummary(getString(R.string.warning_unsupported_os, Build.VERSION.RELEASE)); - warning.setNotice(true); - } else if (Helpers.usingNewSharedPrefs() && Helpers.isXposedScopeEnabled(act)) { - warning.setTitle(R.string.warning); - warning.setSummary(R.string.warning_scope); - warning.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Helpers.openXposedApp(getValidContext()); - return true; - } - }); - } else if (!Helpers.usingNewSharedPrefs() && Helpers.areXposedBlacklistsEnabled()) { - warning.setTitle(R.string.warning); - if (act.getApplicationContext().getApplicationInfo().targetSdkVersion > 27) - warning.setSummary(getString(R.string.warning_blacklist) + "\n" + getString(R.string.warning_blacklist_sdk)); - else - warning.setSummary(R.string.warning_blacklist); - warning.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Helpers.openXposedApp(getValidContext()); - return true; - } - }); - } else getPreferenceScreen().removePreference(warning); + if (warning != null) { + getPreferenceScreen().removePreference(warning); + } findPreference("pref_key_miuizer_launchericon").setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { @Override @@ -473,16 +226,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } }); - String[] locales; - try { - AssetManager am = getContext().getAssets(); - @SuppressWarnings("JavaReflectionMemberAccess") @SuppressLint("SoonBlockedPrivateApi") - Method getNonSystemLocales = AssetManager.class.getDeclaredMethod("getNonSystemLocales"); - locales = (String[])getNonSystemLocales.invoke(am); - if (locales == null) locales = new String[] {}; - } catch (Throwable t) { - locales = new String[] { "de", "es", "it", "pt-BR", "ru-RU", "tr", "uk-UK", "zh-CN" }; - } + String[] locales = new String[] { "ru-RU", "zh-CN" }; ArrayList localesArr = new ArrayList(Arrays.asList(locales)); ArrayList localeNames = new ArrayList(); @@ -519,48 +263,6 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } }); - findPreference("pref_key_miuizer_holiday").setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - getActivity().recreate(); - return true; - } - }); - - findPreference("pref_key_miuizer_sendreport").setOnPreferenceClickListener(new CheckBoxPreference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - if (Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_REPORT)) createReport(); - return true; - } - }); - - findPreference("pref_key_miuizer_feedback").setOnPreferenceClickListener(new CheckBoxPreference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openSubFragment(new SubFragment(), null, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, R.string.miuizer_acramail_title, R.layout.prefs_freedback); - return true; - } - }); - - findPreference("pref_key_issuetracker").setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference pref) { - Helpers.openURL(act, "https://code.highspec.ru/Mikanoshi/CustoMIUIzer/issues"); - return true; - } - }); - -// findPreference("pref_key_payinapp").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { -// @Override -// public boolean onPreferenceClick(Preference pref) { -// Bundle args = new Bundle(); -// args.putInt("baseResId", R.layout.fragment_inapp); -// openSubFragment(new InAppFragment(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.support_donate_title, R.xml.prefs_inapp); -// return true; -// } -// }); - findPreference("pref_key_paycrypto").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference pref) { @@ -581,71 +283,14 @@ public boolean onPreferenceClick(Preference pref) { } }); - findPreference("pref_key_miuizer_marknewmods").setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { + findPreference("pref_key_github").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - Helpers.updateNewModsMarking(getActivity(), Integer.parseInt((String)newValue)); + @SuppressWarnings("deprecation") + public boolean onPreferenceClick(Preference pref) { + Helpers.openURL(act, "https://github.com/monwf/customiuizer"); return true; } }); - -// if (Helpers.isUnsupportedManager(act)) { -// CheckBoxPreferenceEx ownrepo = (CheckBoxPreferenceEx)findPreference("pref_key_miuizer_ownrepo"); -// ownrepo.setSummary(R.string.miuizer_ownrepo_unsupported); -// ownrepo.setEnabled(false); -// ownrepo.setChecked(false); -// } - -// Helpers.removePref(this, "pref_key_miuizer_force_material", "pref_key_miuizer"); - } - - void showGuides() { - if (getView() == null || getActivity() == null) return; - Button more = getView().findViewById(getResources().getIdentifier("more", "id", "miui")); - View search = getView().findViewById(android.R.id.inputArea); - View overlay = getActivity().findViewById(R.id.guide_overlay); - if (more == null || search == null || overlay == null || Helpers.prefs.getBoolean("miuizer_guides_shown", false)) return; - - overlay.setBackgroundColor(Helpers.isNightMode(getActivity()) ? Color.argb(150, 0, 0, 0) : Color.argb(150, 255, 255, 255)); - overlay.setVisibility(View.VISIBLE); - overlay.bringToFront(); - - showGuide(search, GuidePopup.ARROW_TOP_MODE, R.string.guide_search).setOnDismissListener(new PopupWindow.OnDismissListener() { - @Override - public void onDismiss() { - showGuide(markCat, GuidePopup.ARROW_BOTTOM_MODE, R.string.guide_marknew).setOnDismissListener(new PopupWindow.OnDismissListener() { - @Override - public void onDismiss() { - showImmersionMenu(); - showGuide(more, GuidePopup.ARROW_TOP_MODE, R.string.guide_softreboot).setOnDismissListener(new PopupWindow.OnDismissListener() { - @Override - public void onDismiss() { - dismissImmersionMenu(true); - overlay.setVisibility(View.GONE); - } - }); - } - }); - } - }); - - Helpers.prefs.edit().putBoolean("miuizer_guides_shown", true).apply(); - } - - @SuppressWarnings({"UnusedReturnValue", "SameParameterValue"}) - GuidePopup showGuide(View anchor, int arrowMode, int textResId) { - return showGuide(anchor, arrowMode, textResId, 0, 0); - } - - @SuppressWarnings({"UnusedReturnValue", "SameParameterValue"}) - GuidePopup showGuide(View anchor, int arrowMode, int textResId, int x, int y) { - GuidePopup guidePopup = new GuidePopup(getActivity()); - guidePopup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); - guidePopup.setArrowMode(arrowMode); - guidePopup.setGuideText(textResId); - guidePopup.setOutsideTouchable(true); - guidePopup.show(anchor, x, y); - return guidePopup; } void findMod(String filter) { @@ -656,10 +301,6 @@ void findMod(String filter) { ((ModSearchAdapter)resultView.getAdapter()).getFilter().filter(filter); } - public void createReport() { - ACRA.getErrorReporter().handleException(null); - } - // PreferenceScreens management private boolean openModCat(String cat) { return openModCat(cat, null, null); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java index e09b3d34..aff5b8c7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java @@ -4,6 +4,7 @@ import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.Activity; +import android.app.AlertDialog; import android.app.Fragment; import android.content.Context; import android.content.DialogInterface; @@ -12,44 +13,37 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; +import android.preference.PreferenceFragment; import android.preference.PreferenceManager; -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; import android.util.TypedValue; -import android.view.Gravity; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; -import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.miui.internal.widget.ActionBarView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.ActionBar; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.lang.reflect.Field; +import java.text.SimpleDateFormat; import java.util.Map; import java.util.Set; -import miui.app.ActionBar; -import miui.app.AlertDialog; -import miui.preference.PreferenceFragment; - import name.mikanoshi.customiuizer.mods.GlobalActions; import name.mikanoshi.customiuizer.utils.Helpers; @@ -58,51 +52,57 @@ public class PreferenceFragmentBase extends PreferenceFragment { private Context actContext = null; public boolean isAnimating = false; public boolean supressMenu = false; - public int animDur = 650; - - public boolean onCreateOptionsMenu(Menu menu) { - if (supressMenu) return false; - getMenuInflater().inflate(R.menu.menu_mods, menu); - if (Helpers.isNightMode(getActivity())) - for (int i = 0; i < menu.size(); i++) try { - MenuItem item = menu.getItem(i); - SpannableString spanString = new SpannableString(item.getTitle().toString()); - spanString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.preference_primary_text_color, getActivity().getTheme())), 0, spanString.length(), 0); - item.setTitle(spanString); - } catch (Throwable t) {} - return true; + public int animDur = 350; + + public static final int PICK_BACKFILE = 11; + public boolean isCustomActionBar = false; + + protected ActionBar getActionBar() { + AppCompatActivity act = (AppCompatActivity) getActivity(); + return act.getSupportActionBar(); + } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + if (supressMenu) { + inflater.inflate(R.menu.menu_mods, menu); + } + if (isCustomActionBar) { + MenuItem item = null; + for (int i = 0; i < menu.size(); i++) { + item = menu.getItem(i); + item.setVisible(item.getItemId() == R.id.edit_confirm); + } + } } + @Override public void onPrepareOptionsMenu(Menu menu) { - if (supressMenu) return; - if (menu.size() == 0) return; - menu.getItem(0).setVisible(false); - if (getView() == null) return; - ImageView alert = getView().findViewById(R.id.update_alert); - if (alert != null && alert.isShown()) menu.getItem(0).setVisible(true); + if (isCustomActionBar) { + MenuItem confirmMenu = menu.findItem(R.id.edit_confirm); + confirmMenu.setTitle(null); + int applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_confirm_dark" : "action_mode_title_button_confirm_light", "drawable", "miui"); + if (applyResId == 0) + applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_done_dark" : "action_mode_immersion_done_light", "drawable", "miui"); + confirmMenu.setIcon(applyResId); + } + super.onPrepareOptionsMenu(menu); } + public void confirmEdit() {} + + @Override public boolean onOptionsItemSelected(MenuItem item) { Activity act = getActivity(); switch (item.getItemId()) { + case R.id.edit_confirm: + confirmEdit(); + return true; case android.R.id.home: if (this instanceof MainFragment) act.finish(); else ((SubFragment)this).finish(); return true; - case R.id.get_update: - try { - Intent detailsIntent = new Intent("de.robv.android.xposed.installer.DOWNLOAD_DETAILS"); - detailsIntent.addCategory(Intent.CATEGORY_DEFAULT); - detailsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - detailsIntent.setData(Uri.fromParts("package", Helpers.modulePkg, null)); - startActivity(detailsIntent); - } catch (Throwable e) { - Helpers.openURL(getActivity(), "https://code.highspec.ru/Mikanoshi/CustoMIUIzer/releases"); - } - case R.id.xposedinstaller: - return Helpers.openXposedApp(getValidContext()); case R.id.backuprestore: showBackupRestoreDialog(); return true; @@ -140,7 +140,7 @@ public void showXposedDialog(Activity act) { builder.setTitle(R.string.warning); builder.setMessage(R.string.module_not_active); builder.setCancelable(true); - builder.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton){} }); AlertDialog dlg = builder.create(); @@ -169,70 +169,8 @@ public void onClick(DialogInterface dialog, int whichButton) { alert.show(); } - private void setupImmersiveMenu() { - ActionBar actionBar = getActionBar(); - if (actionBar != null && Helpers.is12()) try { actionBar.setExpandState(ActionBar.STATE_COLLAPSE, false); } catch (Throwable ignore) {} - if (supressMenu) return; - setImmersionMenuEnabled(true); - hideSplitActionBar(); - - View view = getView(); - if (view != null) - if (view.findViewById(R.id.update_alert) == null) { - Button more = view.findViewById(getResources().getIdentifier("more", "id", "miui")); - if (more == null) return; - float density = getResources().getDisplayMetrics().density; - FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); - lp.gravity = Gravity.END | Gravity.TOP; - ImageView alert = new ImageView(getValidContext()); - alert.setImageResource(R.drawable.alert); - alert.setAdjustViewBounds(true); - alert.setMaxWidth(Math.round(16 * density)); - alert.setMaxHeight(Math.round(16 * density)); - alert.setLayoutParams(lp); - alert.setId(R.id.update_alert); - alert.setVisibility(View.GONE); - ((ViewGroup)more.getParent()).addView(alert); - } - } - - void hideSplitActionBar() { - try { - getActionBar().showSplitActionBar(false, false); - } catch (Throwable t) { - hideSplitView(); - return; - } - if (Helpers.is125()) hideSplitView125(); - } - - void hideSplitView() { - // Hide stupid auto split actionbar - try { - ActionBar actionBar = getActionBar(); - Field mSplitViewField = actionBar.getClass().getDeclaredField("mSplitView"); - mSplitViewField.setAccessible(true); - View mSplitView = (View)mSplitViewField.get(actionBar); - if (mSplitView != null) mSplitView.setVisibility(View.GONE); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - void hideSplitView125() { - try { - ActionBar actionBar = getActionBar(); - Field mActionViewField = actionBar.getClass().getDeclaredField("mActionView"); - mActionViewField.setAccessible(true); - ActionBarView mActionView = (ActionBarView)mActionViewField.get(actionBar); - if (mActionView != null) mActionView.setSplitActionBar(true); - } catch (Throwable t) { - t.printStackTrace(); - } - } - private void initFragment() { - setHasOptionsMenu(true); + setHasOptionsMenu(supressMenu); boolean showBack = false; if (this instanceof MainFragment) { @@ -249,7 +187,6 @@ private void initFragment() { ActionBar actionBar = getActionBar(); actionBar.setTitle(R.string.app_name); actionBar.setDisplayHomeAsUpEnabled(showBack); - actionBar.setBackgroundDrawable(new ColorDrawable(Helpers.getSystemBackgroundColor(getValidContext()))); } @SuppressLint("WorldReadableFiles") @@ -269,7 +206,6 @@ public void onCreate(Bundle savedInstanceState, int pref_defaults) { public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initFragment(); - setupImmersiveMenu(); } @Override @@ -279,14 +215,7 @@ public void onViewCreated(View view, Bundle savedInstanceState) { } public void setViewBackground(View view) { - boolean isNight = Helpers.isNightMode(getValidContext()); - int bgResId = getResources().getIdentifier(isNight ? "settings_window_bg_dark" : "settings_window_bg_light", "drawable", "miui"); - if (bgResId != 0) - view.setBackgroundResource(bgResId); - else if (Helpers.is11()) - view.setBackgroundColor(Helpers.getSystemBackgroundColor(getValidContext())); - else - view.setBackgroundColor(isNight ? Color.BLACK : Color.rgb(247, 247, 247)); + view.setBackgroundColor(Helpers.getSystemBackgroundColor(getValidContext())); } public void setActionModeStyle(View searchView) { @@ -357,7 +286,7 @@ public Animator onCreateAnimator(int transit, boolean enter, final int nextAnim) final View top = getView(); if (top == null) return null; - final View content = top.findViewById(android.R.id.content); + final View content = top.findViewById(android.R.id.list); //ValueAnimator.setFrameDelay(17); ValueAnimator valAnimator = new ValueAnimator(); @@ -386,7 +315,6 @@ public void onAnimationCancel(Animator animation) {} public void onAnimationRepeat(Animator animation) {} }); else isAnimating = false; - boolean is11 = Helpers.is11(); valAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { @@ -394,7 +322,7 @@ public void onAnimationUpdate(ValueAnimator animation) { float val = (float)animation.getAnimatedValue(); if (nextAnim == R.animator.fragment_open_enter) { top.setX(scrWidth * (1.0f - val)); - content.setAlpha(is11 ? val * 1.0f : 0.6f + val * 0.4f); + content.setAlpha(0.6f + val * 0.4f); } else if (nextAnim == R.animator.fragment_open_exit) { top.setX(-scrWidth / 4.0f * val); top.setAlpha(1.0f - val * 0.4f); @@ -423,11 +351,11 @@ public void onDetach() { this.actContext = null; } - @Override - public void onResume() { - super.onResume(); - setupImmersiveMenu(); - } +// @Override +// public void onResume() { +// super.onResume(); +// setupImmersiveMenu(); +// } public Context getValidContext() { if (actContext != null) return actContext; @@ -439,7 +367,7 @@ public void backupSettings(Activity act) { if (!Helpers.preparePathForBackup(act, backupPath)) return; ObjectOutputStream output = null; try { - output = new ObjectOutputStream(new FileOutputStream(backupPath + Helpers.backupFile)); + output = new ObjectOutputStream(new FileOutputStream(backupPath + Helpers.backupFile + new SimpleDateFormat("-MMddHHmmss").format(new java.util.Date()))); output.writeObject(Helpers.prefs.getAll()); AlertDialog.Builder alert = new AlertDialog.Builder(act); @@ -470,13 +398,33 @@ public void onClick(DialogInterface dialog, int whichButton) {} } } - @SuppressWarnings("unchecked") + @Override + public void onActivityResult(int requestCode, int resultCode, + Intent resultData) { + if (requestCode == MainFragment.PICK_BACKFILE + && resultCode == Activity.RESULT_OK) { + Uri uri = null; + if (resultData != null) { + uri = resultData.getData(); + doRestoreSettings(uri); + } + } + } + public void restoreSettings(final Activity act) { if (!Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_RESTORE)) return; if (!Helpers.checkStorageReadable(act)) return; + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("application/octet-stream"); + startActivityForResult(intent, PICK_BACKFILE); + } + + public void doRestoreSettings(Uri uri) { ObjectInputStream input = null; + final Activity act = getActivity(); try { - input = new ObjectInputStream(new FileInputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder + Helpers.backupFile)); + input = new ObjectInputStream(act.getContentResolver().openInputStream(uri)); Map entries = (Map)input.readObject(); if (entries == null || entries.isEmpty()) throw new RuntimeException("Cannot read entries"); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java index 2e04d6ee..1f9706fa 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java @@ -21,7 +21,6 @@ protected void attachBaseContext(Context base) { @Override protected void onCreate(Bundle savedInstanceState) { boolean mSDKFound = ((MainApplication)getApplication()).mStarted; - if (mSDKFound) Helpers.setMiuiTheme(this, R.style.MIUIPrefs); super.onCreate(savedInstanceState); setContentView(R.layout.activity_snoozed); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java index 3bcc053e..c1fe6a26 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java @@ -20,8 +20,7 @@ import java.util.ArrayList; import java.util.HashMap; -import miui.app.ActionBar; -import miui.app.AlertDialog; +import android.app.AlertDialog; import miui.util.AttributeResolver; import miui.widget.ProgressBar; @@ -96,12 +95,6 @@ public void onCreate(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) { supressMenu = true; super.onActivityCreated(savedInstanceState); - ActionBar actionBar = getActionBar(); - if (actionBar != null) try { - actionBar.setTitle(R.string.title_snoozed); - actionBar.showSplitActionBar(true, true); - } catch (Throwable ignore) {} - setImmersionMenuEnabled(false); if (getView() == null) return; @@ -162,21 +155,6 @@ public View onInflateView(LayoutInflater inflater, ViewGroup group, Bundle bundl return inflater.inflate(R.layout.fragment_snoozed, group, false); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuItem update = menu.add(R.string.menu_update); - update.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - update.setIcon(AttributeResolver.resolveDrawable(getContext(), getResources().getIdentifier("actionBarRefreshIcon", "attr", "miui"))); - update.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - fetchSnoozed(); - return true; - } - }); - return true; - } - @Override public void onPrepareOptionsMenu(Menu menu) { if (menu != null && menu.size() > 0) @@ -234,7 +212,6 @@ private void updateListView() { private void startLoading() { if (loading) return; loading = true; - invalidateOptionsMenu(); snoozedList.clear(); updateListView(); if (loader != null) loader.setVisibility(View.VISIBLE); @@ -243,7 +220,6 @@ private void startLoading() { private void finishLoading() { loading = false; - invalidateOptionsMenu(); updateListView(); if (loader != null) loader.setVisibility(View.GONE); if (empty != null) empty.setVisibility(snoozedList.size() == 0 ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java index f9bc0651..040d74c7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java @@ -16,12 +16,12 @@ import android.widget.ListView; import android.widget.TextView; +import androidx.appcompat.app.ActionBar; + import java.util.ArrayList; -import miui.app.ActionBar; import miui.widget.ClearableEditText; import name.mikanoshi.customiuizer.prefs.PreferenceCategoryEx; -import name.mikanoshi.customiuizer.prefs.PreferenceState; import name.mikanoshi.customiuizer.prefs.SpinnerEx; import name.mikanoshi.customiuizer.prefs.SpinnerExFake; import name.mikanoshi.customiuizer.subs.AppSelector; @@ -30,424 +30,361 @@ import name.mikanoshi.customiuizer.subs.SortableList; import name.mikanoshi.customiuizer.utils.ColorCircle; import name.mikanoshi.customiuizer.utils.Helpers; -import name.mikanoshi.customiuizer.utils.ModData; public class SubFragment extends PreferenceFragmentBase { - private int baseResId = 0; - private int resId = 0; - public int titleId = 0; - private float order = 100.0f; - private String highlight = null; - public boolean padded = true; - Helpers.SettingsType settingsType = Helpers.SettingsType.Preference; - Helpers.ActionBarType abType = Helpers.ActionBarType.Edit; - - @Override - public void onCreate(Bundle savedInstanceState) { - settingsType = Helpers.SettingsType.values()[getArguments().getInt("settingsType")]; - abType = Helpers.ActionBarType.values()[getArguments().getInt("abType")]; - baseResId = getArguments().getInt("baseResId"); - resId = getArguments().getInt("contentResId"); - titleId = getArguments().getInt("titleResId"); - order = getArguments().getFloat("order") + 10.0f; - highlight = getArguments().getString("mod"); - - if (resId == 0) { - getActivity().finish(); - return; - } - - if (settingsType == Helpers.SettingsType.Preference) { - super.onCreate(savedInstanceState, resId); - addPreferencesFromResource(resId); - } else { - super.onCreate(savedInstanceState); - } - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - supressMenu = supressMenu || abType == Helpers.ActionBarType.Edit; - super.onActivityCreated(savedInstanceState); - loadSharedPrefs(); - - ActionBar actionBar = getActionBar(); - if (actionBar != null) - if (abType == Helpers.ActionBarType.Edit) { - actionBar.setCustomView(getResources().getIdentifier("edit_mode_title", "layout", "miui")); - actionBar.setDisplayShowCustomEnabled(true); - - View customView = actionBar.getCustomView(); - ((TextView)customView.findViewById(android.R.id.title)).setText(titleId); - - TextView cancelBtn = customView.findViewById(android.R.id.button1); - int cancelResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_cancel_dark" : "action_mode_title_button_cancel_light", "drawable", "miui"); - if (cancelResId == 0) cancelResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_close_dark" : "action_mode_immersion_close_light", "drawable", "miui"); - cancelBtn.setBackgroundResource(cancelResId); - cancelBtn.setText(null); - cancelBtn.setContentDescription(getText(android.R.string.cancel)); - cancelBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - finish(); - } - }); - TextView applyBtn = customView.findViewById(android.R.id.button2); - int applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_confirm_dark" : "action_mode_title_button_confirm_light", "drawable", "miui"); - if (applyResId == 0) applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_done_dark" : "action_mode_immersion_done_light", "drawable", "miui"); - applyBtn.setBackgroundResource(applyResId); - applyBtn.setText(null); - applyBtn.setContentDescription(getText(android.R.string.ok)); - applyBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - saveSharedPrefs(); - finish(); - } - }); - } else { - actionBar.setTitle(titleId); - } - - if (Helpers.showNewMods) - for (String mod: Helpers.newMods) { - Preference pref = findPreference(mod); - if (pref != null) ((PreferenceState)pref).markAsNew(); - } - - if (highlight != null && getView() != null && savedInstanceState == null) try { - ListView listView = getView().findViewById(android.R.id.list); - int order = 0; - for (ModData mod: Helpers.allModsList) - if (mod.key.equals(highlight)) { - order = mod.order; - break; - } - highlight = null; - listView.clearFocus(); - int fOrder = order; - listView.postDelayed(new Runnable() { - @Override - public void run() { - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) {} - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - int first = view.getFirstVisiblePosition(); - int last = view.getLastVisiblePosition(); - if (fOrder >= first && fOrder <= last) { - view.setOnScrollListener(null); - View item = view.getChildAt(fOrder - first); - if (item == null) return; - TextView title = item.findViewById(android.R.id.title); - if (title != null) Helpers.applyShimmer(title); - } - } - }); - listView.smoothScrollToPositionFromTop(fOrder, getResources().getDisplayMetrics().heightPixels / 3); - } - }, Math.round(animDur * Settings.Global.getFloat(getValidContext().getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f))); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - public View onInflateView(LayoutInflater inflater, ViewGroup group, Bundle bundle) { - if (settingsType == Helpers.SettingsType.Preference) - return baseResId != 0 ? inflater.inflate(baseResId, group, false) : super.onInflateView(inflater, group, bundle); - - View view = inflater.inflate(padded ? R.layout.prefs_common_padded : R.layout.prefs_common, group, false); - inflater.inflate(resId, (FrameLayout)view); - return view; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - view.setTranslationZ(order); - } - - public void saveSharedPrefs() { - if (getView() == null) Log.e("miuizer", "View not yet ready!"); - ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); - for (View nView : nViews) - if (nView != null) try { - if (nView.getTag() != null) - if (nView instanceof TextView) - Helpers.prefs.edit().putString((String)nView.getTag(), ((TextView)nView).getText().toString()).apply(); - else if (nView instanceof SpinnerExFake) { - Helpers.prefs.edit().putString((String)nView.getTag(), ((SpinnerExFake)nView).getValue()).apply(); - ((SpinnerExFake)nView).applyOthers(); - } else if (nView instanceof SpinnerEx) - Helpers.prefs.edit().putInt((String)nView.getTag(), ((SpinnerEx)nView).getSelectedArrayValue()).apply(); - else if (nView instanceof ColorCircle) - Helpers.prefs.edit().putInt((String)nView.getTag(), ((ColorCircle)nView).getColor()).apply(); - } catch (Throwable e) { - Log.e("miuizer", "Cannot save sub preference!"); - } - } - - public void loadSharedPrefs() { - if (getView() == null) Log.e("miuizer", "View not yet ready!"); - ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); - for (View nView: nViews) - if (nView != null) try { - if (nView.getTag() != null) - if (nView instanceof TextView) { - ((TextView)nView).setText(Helpers.prefs.getString((String)nView.getTag(), "")); - if (nView instanceof ClearableEditText) nView.setBackgroundResource(getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "edit_text_bg_dark" : "edit_text_bg_light", "drawable", "miui")); - } - } catch (Throwable e) { - Log.e("miuizer", "Cannot load sub preference!"); - } - } - - public Preference.OnPreferenceClickListener openAppsEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openApps(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openAppsBWEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openAppsBW(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openShareEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openShare(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openOpenWithEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openOpenWith(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openLauncherActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.LAUNCHER); - return true; - } - }; - - public Preference.OnPreferenceClickListener openControlsActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.CONTROLS); - return true; - } - }; - - public Preference.OnPreferenceClickListener openNavbarActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.NAVBAR); - return true; - } - }; - - public Preference.OnPreferenceClickListener openRecentsActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.RECENTS); - return true; - } - }; - - public Preference.OnPreferenceClickListener openStatusbarActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.STATUSBAR); - return true; - } - }; - - public Preference.OnPreferenceClickListener openLockScreenActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.LOCKSCREEN); - return true; - } - }; - - public Preference.OnPreferenceClickListener openLaunchActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.LAUNCH); - return true; - } - }; - - public Preference.OnPreferenceClickListener openSortableList = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openSortableItemList(preference); - return true; - } - }; - - public Preference.OnPreferenceClickListener openActivitiesList = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openActivitiesItemList(preference); - return true; - } - }; - - public Preference.OnPreferenceClickListener openColorSelector = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openColorSelector(preference); - return true; - } - }; - - void openApps(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openAppsBW(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - args.putBoolean("bw", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openShare(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - args.putBoolean("share", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openOpenWith(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - args.putBoolean("openwith", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openMultiAction(Preference pref, MultiAction.Actions actions) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putInt("actions", actions.ordinal()); - openSubFragment(new MultiAction(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitleRes(), R.layout.prefs_multiaction); - } - - public void openStandaloneApp(Preference pref, Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putBoolean("standalone", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_app, R.layout.prefs_app_selector); - } - - public void openPrivacyAppEdit(Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putBoolean("privacy", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - public void openLockedAppEdit(Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putBoolean("applock", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - public void openLaunchableList(Preference pref, Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putBoolean("custom_titles", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.launcher_renameapps_list_title, R.layout.prefs_app_selector); - } - - public void openColorSelector(Preference pref) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - openSubFragment(new ColorSelector(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitleRes(), R.layout.fragment_selectcolor); - } - - public void openSortableItemList(Preference pref) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putInt("titleResId", pref.getTitleRes()); - openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitleRes(), R.layout.prefs_sortable_list); - } - - public void openActivitiesItemList(Preference pref) { - Bundle args = new Bundle(); - args.putBoolean("activities", true); - args.putString("key", pref.getKey()); - args.putInt("titleResId", pref.getTitleRes()); - openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitleRes(), R.layout.prefs_sortable_list); - } - - public void selectSub(String cat, String sub) { - PreferenceScreen screen = (PreferenceScreen)findPreference(cat); - int cnt = screen.getPreferenceCount(); - for (int i = cnt - 1; i >= 0; i--) { - Preference pref = screen.getPreference(i); - if (!pref.getKey().equals(sub)) - screen.removePreference(pref); - else { - PreferenceCategoryEx category = (PreferenceCategoryEx)pref; - if (category.isDynamic()) - getActionBar().setTitle(pref.getTitle() + " ⟲"); - else - getActionBar().setTitle(pref.getTitleRes()); - category.hide(); - } - } - } - - public void finish() { - //View view = getView(); - //if (isAnimating && view != null) ((ViewGroup)view.getParent()).removeView(view); - if (isAnimating) return; - if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); - Helpers.hideKeyboard(getActivity(), getView()); - FragmentManager fragmentManager = getFragmentManager(); - if (fragmentManager == null || !isResumed()) { - Activity act = getActivity(); - if (act != null) act.getFragmentManager().popBackStack(); - } else { - fragmentManager.popBackStackImmediate(); - } - } + private int baseResId = 0; + private int resId = 0; + public int titleId = 0; + private float order = 100.0f; + public boolean padded = true; + Helpers.SettingsType settingsType = Helpers.SettingsType.Preference; + Helpers.ActionBarType abType = Helpers.ActionBarType.Edit; + + @Override + public void onCreate(Bundle savedInstanceState) { + settingsType = Helpers.SettingsType.values()[getArguments().getInt("settingsType")]; + abType = Helpers.ActionBarType.values()[getArguments().getInt("abType")]; + baseResId = getArguments().getInt("baseResId"); + resId = getArguments().getInt("contentResId"); + titleId = getArguments().getInt("titleResId"); + order = getArguments().getFloat("order") + 10.0f; + + if (resId == 0) { + getActivity().finish(); + return; + } + + if (settingsType == Helpers.SettingsType.Preference) { + super.onCreate(savedInstanceState, resId); + addPreferencesFromResource(resId); + } else { + super.onCreate(savedInstanceState); + } + if (abType == Helpers.ActionBarType.Edit) { + isCustomActionBar = true; + } + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + supressMenu = supressMenu || abType == Helpers.ActionBarType.Edit; + super.onActivityCreated(savedInstanceState); + loadSharedPrefs(); + ActionBar actionBar = getActionBar(); + if (actionBar != null) { + actionBar.setTitle(titleId); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + LayoutInflater crtInflator = LayoutInflater.from(getActivity()); + if (settingsType == Helpers.SettingsType.Preference) { + if (baseResId != 0) { + return LayoutInflater.from(getActivity()).inflate(baseResId, container, false); + } + else { + return super.onCreateView(crtInflator, container, savedInstanceState); + } + } + View view = crtInflator.inflate(padded ? R.layout.prefs_common_padded : R.layout.prefs_common, container, false); + crtInflator.inflate(resId, (FrameLayout)view); + return view; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + view.setTranslationZ(order); + } + + public void saveSharedPrefs() { + if (getView() == null) Log.e("miuizer", "View not yet ready!"); + ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); + for (View nView : nViews) + if (nView != null) try { + if (nView.getTag() != null) + if (nView instanceof TextView) + Helpers.prefs.edit().putString((String)nView.getTag(), ((TextView)nView).getText().toString()).apply(); + else if (nView instanceof SpinnerExFake) { + Helpers.prefs.edit().putString((String)nView.getTag(), ((SpinnerExFake)nView).getValue()).apply(); + ((SpinnerExFake)nView).applyOthers(); + } else if (nView instanceof SpinnerEx) + Helpers.prefs.edit().putInt((String)nView.getTag(), ((SpinnerEx)nView).getSelectedArrayValue()).apply(); + else if (nView instanceof ColorCircle) + Helpers.prefs.edit().putInt((String)nView.getTag(), ((ColorCircle)nView).getColor()).apply(); + } catch (Throwable e) { + Log.e("miuizer", "Cannot save sub preference!"); + } + } + + public void loadSharedPrefs() { + if (getView() == null) Log.e("miuizer", "View not yet ready!"); + ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); + for (View nView: nViews) + if (nView != null) try { + if (nView.getTag() != null) + if (nView instanceof TextView) { + ((TextView)nView).setText(Helpers.prefs.getString((String)nView.getTag(), "")); + if (nView instanceof ClearableEditText) nView.setBackgroundResource(getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "edit_text_bg_dark" : "edit_text_bg_light", "drawable", "miui")); + } + } catch (Throwable e) { + Log.e("miuizer", "Cannot load sub preference!"); + } + } + + public Preference.OnPreferenceClickListener openAppsEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openApps(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openAppsBWEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openAppsBW(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openShareEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openShare(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openOpenWithEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openOpenWith(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openLauncherActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.LAUNCHER); + return true; + } + }; + + public Preference.OnPreferenceClickListener openControlsActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.CONTROLS); + return true; + } + }; + + public Preference.OnPreferenceClickListener openNavbarActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.NAVBAR); + return true; + } + }; + + public Preference.OnPreferenceClickListener openRecentsActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.RECENTS); + return true; + } + }; + + public Preference.OnPreferenceClickListener openStatusbarActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.STATUSBAR); + return true; + } + }; + + public Preference.OnPreferenceClickListener openLockScreenActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.LOCKSCREEN); + return true; + } + }; + + public Preference.OnPreferenceClickListener openLaunchActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.LAUNCH); + return true; + } + }; + + public Preference.OnPreferenceClickListener openSortableList = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openSortableItemList(preference); + return true; + } + }; + + public Preference.OnPreferenceClickListener openActivitiesList = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openActivitiesItemList(preference); + return true; + } + }; + + public Preference.OnPreferenceClickListener openColorSelector = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openColorSelector(preference); + return true; + } + }; + + void openApps(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openAppsBW(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + args.putBoolean("bw", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openShare(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + args.putBoolean("share", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openOpenWith(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + args.putBoolean("openwith", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openMultiAction(Preference pref, MultiAction.Actions actions) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putInt("actions", actions.ordinal()); + openSubFragment(new MultiAction(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitleRes(), R.layout.prefs_multiaction); + } + + public void openStandaloneApp(Preference pref, Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putBoolean("standalone", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_app, R.layout.prefs_app_selector); + } + + public void openPrivacyAppEdit(Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putBoolean("privacy", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + public void openLockedAppEdit(Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putBoolean("applock", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + public void openLaunchableList(Preference pref, Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putBoolean("custom_titles", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.launcher_renameapps_list_title, R.layout.prefs_app_selector); + } + + public void openColorSelector(Preference pref) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + openSubFragment(new ColorSelector(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitleRes(), R.layout.fragment_selectcolor); + } + + public void openSortableItemList(Preference pref) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putInt("titleResId", pref.getTitleRes()); + openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitleRes(), R.layout.prefs_sortable_list); + } + + public void openActivitiesItemList(Preference pref) { + Bundle args = new Bundle(); + args.putBoolean("activities", true); + args.putString("key", pref.getKey()); + args.putInt("titleResId", pref.getTitleRes()); + openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitleRes(), R.layout.prefs_sortable_list); + } + + public void selectSub(String cat, String sub) { + PreferenceScreen screen = (PreferenceScreen)findPreference(cat); + int cnt = screen.getPreferenceCount(); + for (int i = cnt - 1; i >= 0; i--) { + Preference pref = screen.getPreference(i); + if (!pref.getKey().equals(sub)) + screen.removePreference(pref); + else { + PreferenceCategoryEx category = (PreferenceCategoryEx)pref; + if (category.isDynamic()) + getActionBar().setTitle(pref.getTitle() + " ⟲"); + else + getActionBar().setTitle(pref.getTitleRes()); + category.hide(); + } + } + } + + public void finish() { + //View view = getView(); + //if (isAnimating && view != null) ((ViewGroup)view.getParent()).removeView(view); + if (isAnimating) return; + if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); + Helpers.hideKeyboard(getActivity(), getView()); + FragmentManager fragmentManager = getFragmentManager(); + if (fragmentManager == null || !isResumed()) { + Activity act = getActivity(); + if (act != null) act.getFragmentManager().popBackStack(); + } else { + fragmentManager.popBackStackImmediate(); + } + } + + @Override + public void confirmEdit() { + saveSharedPrefs(); + finish(); + } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java index d1deb302..b632f3b6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java @@ -1,14 +1,11 @@ package name.mikanoshi.customiuizer; import android.annotation.SuppressLint; -import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.ActionMode; import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; @@ -16,8 +13,6 @@ import android.widget.ListView; import android.widget.TextView; -import miui.view.SearchActionMode; - import name.mikanoshi.customiuizer.utils.AppDataAdapter; import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.LockedAppAdapter; @@ -29,104 +24,53 @@ public class SubFragmentWithSearch extends SubFragment { public ListView listView = null; View searchView = null; LinearLayout search = null; - ActionMode actionMode = null; boolean isSearchFocused = false; + TextView textInput = null; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - getActionBar().setBackgroundDrawable(new ColorDrawable(Helpers.getSystemBackgroundColor(getValidContext()))); if (getView() == null) return; - SearchActionMode.Callback actionModeCallback = new SearchActionMode.Callback() { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - if (searchView == null || listView == null) { - if (mode != null) mode.finish(); - return false; - } - - SearchActionMode samode = (SearchActionMode)mode; - samode.setAnchorView(searchView); - samode.setAnimateView(listView); - samode.getSearchInput().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - isSearchFocused = hasFocus; - } - }); - samode.getSearchInput().setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - isSearchFocused = v.hasFocus(); - } - }); - samode.getSearchInput().setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { - Helpers.hideKeyboard(getActivity(), v); - listView.requestFocus(); - return true; - } - return false; - } - }); - samode.getSearchInput().addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - - @Override - public void afterTextChanged(Editable s) { - applyFilter(s.toString().trim()); - } - }); - - return true; - } + searchView = getView().findViewById(R.id.searchView); + setActionModeStyle(searchView); + search = searchView.findViewById(android.R.id.inputArea); + textInput = searchView.findViewById(android.R.id.input); + textInput.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - if (searchView == null || listView == null) { - if (mode != null) mode.finish(); - return false; - } - - SearchActionMode samode = (SearchActionMode)mode; - samode.setAnchorView(searchView); - samode.setAnimateView(listView); - - return true; + public void onFocusChange(View v, boolean hasFocus) { + isSearchFocused = hasFocus; } - + }); + textInput.setOnClickListener(new View.OnClickListener() { @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return true; + public void onClick(View v) { + isSearchFocused = v.hasFocus(); } - + }); + textInput.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override - public void onDestroyActionMode(ActionMode mode) { - TextView input = search == null ? null : search.findViewById(android.R.id.input); - if (input != null) input.setText(""); - applyFilter(""); - getActionBar().show(); - actionMode = null; + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { + Helpers.hideKeyboard(getActivity(), v); + listView.requestFocus(); + return true; + } + return false; } - }; + }); + textInput.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - searchView = getView().findViewById(R.id.searchView); - setActionModeStyle(searchView); + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} - search = searchView.findViewById(android.R.id.inputArea); - search.setOnClickListener(new View.OnClickListener() { @Override - public void onClick(View v) { - actionMode = startActionMode(actionModeCallback); - hideSplitView(); + public void afterTextChanged(Editable s) { + applyFilter(s.toString().trim()); } }); @@ -135,15 +79,13 @@ public void onClick(View v) { @Override @SuppressLint("ClickableViewAccessibility") public boolean onTouch(View v, MotionEvent event) { - if (actionMode != null && isSearchFocused) { + if (isSearchFocused) { isSearchFocused = false; Helpers.hideKeyboard(getActivity(), v); } return false; } }); - - if (actionMode != null) actionMode.invalidate(); } void applyFilter(String filter) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java b/app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java deleted file mode 100644 index 4aa190f4..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java +++ /dev/null @@ -1,587 +0,0 @@ -package name.mikanoshi.customiuizer.crashreport; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Serializable; -import java.io.StringWriter; -import java.lang.reflect.Field; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; -import java.util.zip.GZIPOutputStream; - -import org.acra.ACRA; -import org.acra.ReportField; -import org.acra.config.CoreConfiguration; -import org.acra.data.CrashReportData; -import org.acra.file.BulkReportDeleter; -import org.acra.file.CrashReportPersister; -import org.acra.sender.ReportSenderException; -import org.json.JSONObject; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Bundle; -import android.os.Environment; -import android.util.Log; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnTouchListener; -import android.view.WindowManager; -import android.view.inputmethod.EditorInfo; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; -import android.widget.EditText; -import android.widget.FrameLayout.LayoutParams; - -import miui.app.ProgressDialog; - -import name.mikanoshi.customiuizer.R; -import name.mikanoshi.customiuizer.mods.GlobalActions; -import name.mikanoshi.customiuizer.utils.Helpers; - -import static org.acra.ReportField.USER_COMMENT; -import static org.acra.ReportField.USER_EMAIL; - -public class Dialog extends Activity { - - private ProgressDialog loader; - private CrashReportData crashData; - private CoreConfiguration config; - private File reportFile; - private final StringBuilder debugLog = new StringBuilder(); - private EditText desc; - String errorText = null; - - private boolean isNetworkAvailable() { - ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetworkInfo = connectivityManager == null ? null : connectivityManager.getActiveNetworkInfo(); - return activeNetworkInfo != null && activeNetworkInfo.isConnected(); - } - - void showFinishDialog(boolean isOk, String details) { - AlertDialog.Builder dlg = new AlertDialog.Builder(this); - dlg.setTitle(R.string.crash_result); - dlg.setCancelable(true); - if (isOk) - dlg.setMessage(R.string.crash_ok); - else { - String errorTxt = getResources().getString(R.string.crash_error); - if (details != null) errorTxt += ": " + details; - dlg.setMessage(errorTxt); - } - dlg.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - finish(); - } - }); - dlg.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - finish(); - } - }); - dlg.show(); - } - - private String getProp(String prop) { - String res = ""; - Process ifc = null; - try { - ifc = Runtime.getRuntime().exec("getprop " + prop); - BufferedReader bis = new BufferedReader(new InputStreamReader(ifc.getInputStream()), 2048); - res = bis.readLine(); - } catch (Throwable t) {} finally { - if (ifc != null) ifc.destroy(); - } - return res; - } - - private void sendCrash() { - crashData.put(USER_COMMENT, desc.getText().toString()); - - loader.setMessage(getResources().getString(R.string.crash_sending_report)); - loader.show(); - - new Thread(() -> { - final boolean res = sendReport(); - runOnUiThread(new Runnable() { - @Override - public void run() { - loader.hide(); - if (res) { - Helpers.emptyFile(Helpers.getProtectedContext(Dialog.this).getFilesDir().getAbsolutePath() + "/uncaught_exceptions", true); - cancelReports(); - showFinishDialog(true, null); - } else { - showFinishDialog(false, errorText == null ? "REQUEST_ERROR" : errorText); - } - } - }); - }).start(); - } - - protected boolean sendReport() { - try { - byte[] jsonData = crashData.toJSON().getBytes(StandardCharsets.UTF_8); - if (jsonData.length == 0) { - errorText = "ZERO_LENGTH"; - return false; - } - - //final String basicAuth = "Basic " + Base64.encodeToString("login:pass".getBytes(), Base64.NO_WRAP); - URL url = new URL("https://code.highspec.ru/crashreports/reporter.php"); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - conn.setReadTimeout(10000); - conn.setConnectTimeout(10000); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Accept", "application/json"); - conn.setRequestProperty("Content-Type", "application/json"); - conn.setRequestProperty("Content-Encoding", "gzip"); - conn.setDoInput(true); - conn.setDoOutput(true); - conn.setUseCaches(false); - conn.setDefaultUseCaches(false); - conn.connect(); - - try (OutputStream os = conn.getOutputStream()) { - try (GZIPOutputStream dataStream = new GZIPOutputStream(os)) { - dataStream.write(jsonData); - dataStream.flush(); - } catch (Throwable t) {} - } catch (Throwable t) {} - -// StringBuilder builder = new StringBuilder(); -// try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { -// String tmp; -// while ((tmp = in.readLine()) != null) builder.append(tmp); -// } -// Log.e("miuizer", "Response: " + builder.toString()); - - if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) throw new ReportSenderException(String.valueOf(conn.getResponseMessage())); - //Log.e("HTTP", "Report server response code: " + String.valueOf(conn.getResponseCode())); - //Log.e("HTTP", "Report server response: " + conn.getResponseMessage()); - conn.disconnect(); - return true; - } catch (Throwable t) { - errorText = t.getMessage(); - t.printStackTrace(); - return false; - } - } - - protected final void cancelReports() { - (new Thread(() -> (new BulkReportDeleter(this)).deleteReports(false, 0))).start(); - } - - protected void cancelReportsAndFinish() { - cancelReports(); - finish(); - } - - int densify(int size) { - return Math.round(getResources().getDisplayMetrics().density * size); - } - - @Override - protected final void onCreate(Bundle savedInstanceState) { - overridePendingTransition(0, 0); - Helpers.setMiuiTheme(this, R.style.ApplyInvisible, true); - super.onCreate(savedInstanceState); - - if (getIntent().getBooleanExtra("FORCE_CANCEL", false)) { - cancelReportsAndFinish(); - return; - } - - Serializable sConfig = getIntent().getSerializableExtra(DialogInteraction.EXTRA_REPORT_CONFIG); - Serializable sReportFile = getIntent().getSerializableExtra(DialogInteraction.EXTRA_REPORT_FILE); - if (sConfig instanceof CoreConfiguration && sReportFile instanceof File) { - config = (CoreConfiguration) sConfig; - reportFile = (File)sReportFile; - } else { - ACRA.log.w(ACRA.LOG_TAG, "Illegal or incomplete call of CrashReportDialog."); - finish(); - } - - loader = new ProgressDialog(this); - loader.setMessage(getResources().getString(R.string.crash_collecting_report)); - loader.setCancelable(false); - loader.setCanceledOnTouchOutside(false); - loader.show(); - - File sdcardLog = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder + Helpers.logFile); - if (sdcardLog.exists()) { - debugLog.append("Log on external storage found, removing\n"); - sdcardLog.delete(); - } - if (!Helpers.usingNewSharedPrefs()) { - debugLog.append("Asking System UI to collect Xposed log\n"); - sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "CollectXposedLog")); - } - - final Activity act = this; - new Thread(new Runnable() { - public void run() { - try { Thread.sleep(1500); } catch (Throwable t) {} - act.runOnUiThread(Dialog.this::showReportDialog); - } - }).start(); - } - - @SuppressLint({"SetTextI18n", "ClickableViewAccessibility"}) - void showReportDialog() { - int title = R.string.warning; - int neutralText = R.string.crash_ignore; - int text = R.string.crash_dialog; - LinearLayout dialogView = new LinearLayout(this); - dialogView.setOrientation(LinearLayout.VERTICAL); - - PackageManager pkgMgr = getPackageManager(); - String xposedLog = null; - try { - File errorLogFile = null; - File sdcardLog = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder + Helpers.logFile); - try { - if (Helpers.usingNewSharedPrefs()) { - String errorLogFilename = pkgMgr.getInstallerPackageName("EdXposedLog"); - if (errorLogFilename != null) { - errorLogFile = new File(errorLogFilename); - debugLog.append("Log found in misc: ").append(errorLogFilename).append("\n"); - } - } else { - String errorLog = Helpers.getXposedInstallerErrorLog(this); - debugLog.append("Installer log path: ").append(errorLog).append("\n"); - if (sdcardLog.exists() && sdcardLog.canRead()) { - debugLog.append("Log found on external storage: ").append(sdcardLog.getAbsolutePath()).append("\n"); - errorLogFile = sdcardLog; - } else if (errorLog != null) { - errorLogFile = new File(errorLog); - if (errorLogFile.exists() && errorLogFile.canRead()) - debugLog.append("Log found in installer: ").append(errorLog).append("\n"); - } - } - } catch (Throwable ignore) {} - - if (errorLogFile != null) - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(errorLogFile)))) { - String line; - StringBuilder sb = new StringBuilder(); - while ((line = reader.readLine()) != null) sb.append(line).append("\n"); - xposedLog = sb.toString(); - } catch (Throwable t) { - t.printStackTrace(); - debugLog.append("Error reading log: ").append(t.getMessage()).append("\n"); - } else debugLog.append("No accessible Xposed log found!\n"); - - if (sdcardLog.exists()) sdcardLog.delete(); - } catch (Throwable t) {} - - SharedPreferences prefs; - try { - prefs = Helpers.getSharedPrefs(this, true); - } catch (Throwable t) { - Log.e("miuizer", "Failed to use protected storage!"); - prefs = Helpers.getSharedPrefs(this, false); - } - - CrashReportPersister persister = new CrashReportPersister(); - try { - crashData = persister.load(reportFile); - crashData.put(USER_EMAIL, prefs.getString("acra.user.email", "")); - } catch (Throwable t) { - t.printStackTrace(); - cancelReports(); - showFinishDialog(false, "REPORT_READ_ERROR"); - return; - } - - try { - //Log.e("AndroidRuntime", crashData.getString(ReportField.STACK_TRACE)); - - String ROM = getProp("ro.modversion"); - String MIUI = getProp("ro.miui.ui.version.name"); - - String kernel = System.getProperty("os.version"); - if (kernel == null) kernel = ""; - - JSONObject buildData = (JSONObject)crashData.get("BUILD"); - buildData.put("ROM_VERSION", ROM); - buildData.put("MIUI_VERSION", MIUI); - buildData.put("KERNEL_VERSION", kernel); - crashData.put("BUILD", buildData); - crashData.put("DEBUG_LOG", debugLog.toString()); - crashData.put("TARGET_API", getApplicationContext().getApplicationInfo().targetSdkVersion); - - StringBuilder sb = new StringBuilder(); - try (FileInputStream in = new FileInputStream(Helpers.getProtectedContext(this).getFilesDir().getAbsolutePath() + "/uncaught_exceptions")) { - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in))) { - String line; - while ((line = bufferedReader.readLine()) != null) sb.append(line).append("\n"); - } catch (Throwable t) {} - } catch (Throwable t) {} - - String edxpVersion = null; - if (Helpers.usingNewSharedPrefs()) try { - String lsposed = Helpers.isLSPosedManagerInstalled(this); - edxpVersion = lsposed != null ? lsposed : pkgMgr.getInstallerPackageName("EdXposedVersion"); - if (edxpVersion == null || edxpVersion.startsWith("unknown")) { - File versionFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder + Helpers.versionFile); - if (versionFile.exists()) - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(versionFile)))) { edxpVersion = reader.readLine(); } - } - } catch (Throwable ignore) {} - - if (edxpVersion == null) { - final ArrayList xposedPropFiles = new ArrayList(Arrays.asList( - "/system/framework/edconfig.jar", // EdXposed - "/system/xposed.prop", // Classic - "/magisk/xposed/system/xposed.prop", - "/magisk/PurifyXposed/system/xposed.prop", - "/su/xposed/system/xposed.prop", - "/vendor/xposed.prop", - "/xposed/xposed.prop", - "/xposed.prop", - "/su/xposed/xposed.prop" - )); - - File[] files = new File("/system/framework").listFiles(); - if (files != null && files.length > 0) - for (File file: files) try { - long fsize = file.length(); - if (fsize < 128) { - xposedPropFiles.add(0, file.getAbsolutePath()); - break; - } - } catch (Throwable ignore) {} - - for (String prop: xposedPropFiles) { - File propFile = new File(prop); - if (propFile.exists() && propFile.canRead()) { - edxpVersion = Helpers.getXposedPropVersion(propFile, false); - break; - } - } - } - if (edxpVersion != null) crashData.put("XPOSED_VERSION", edxpVersion); - - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_HOME); - ResolveInfo launcherInfo = pkgMgr.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); - if (launcherInfo != null) { - PackageInfo packageInfo = pkgMgr.getPackageInfo(launcherInfo.activityInfo.packageName, 0); - if (packageInfo != null) crashData.put("LAUNCHER_VERSION", launcherInfo.activityInfo.loadLabel(pkgMgr) + " " + packageInfo.versionName); - } - - if (edxpVersion == null || edxpVersion.startsWith("unknown")) try { - PackageInfo taichiInfo = pkgMgr.getPackageInfo("me.weishu.exp", 0); - if (taichiInfo != null) - crashData.put("XPOSED_VERSION", taichiInfo.applicationInfo.loadLabel(pkgMgr) + " " + taichiInfo.versionName); - } catch (Throwable t) {} - - crashData.put("SHARED_PREFERENCES", new JSONObject(prefs.getAll())); - if (!sb.toString().isEmpty()) - crashData.put("UNCAUGHT_EXCEPTIONS", sb.toString()); - - if (xposedLog == null || xposedLog.trim().equals("")) - crashData.put(ReportField.CUSTOM_DATA, "Xposed log is empty..."); - else - crashData.put(ReportField.CUSTOM_DATA, xposedLog); - } catch (Throwable t) { - StringWriter sw = new StringWriter(); - t.printStackTrace(new PrintWriter(sw)); - crashData.put(ReportField.CUSTOM_DATA, "Retrieval failed. Stack trace:\n" + sw); - } - - int payloadSize; - try { - try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { - try (GZIPOutputStream dataStream = new GZIPOutputStream(os)) { - dataStream.write(crashData.toJSON().getBytes(StandardCharsets.UTF_8)); - dataStream.flush(); - } - payloadSize = os.size(); - } - } catch (Throwable t) { - t.printStackTrace(); - cancelReports(); - showFinishDialog(false, "JSON_PAYLOAD_ERROR"); - return; - } - - if (payloadSize == 0) { - cancelReports(); - showFinishDialog(false, "EMPTY_PAYLOAD_ERROR"); - return; - } - - try { - TextView mainText = new TextView(this); - mainText.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - mainText.setGravity(Gravity.START); - mainText.setPadding(0, 0, 0, densify(10)); - mainText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); - mainText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - - TextView descText = new TextView(this); - descText.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - descText.setGravity(Gravity.START); - descText.setPadding(0, 0, 0, densify(5)); - descText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); - descText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - - desc = new EditText(this); - desc.setGravity(Gravity.TOP | Gravity.START); - desc.setInputType(EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE); - desc.setSingleLine(false); - desc.setPadding(densify(5), densify(5), densify(5), densify(5)); - - boolean isManualReport = crashData.getString(ReportField.STACK_TRACE).contains("Report requested by developer"); - if (isManualReport) { - title = R.string.crash_confirm; - text = R.string.crash_dialog_manual; - neutralText = R.string.cancel; - descText.setText(R.string.crash_dialog_manual_desc); - - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, densify(80)); - lp.setMargins(0, densify(5), 0, densify(10)); - desc.setLayoutParams(lp); - } else { - descText.setText(R.string.crash_dialog_manual_desc2); - - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, densify(60)); - lp.setMargins(0, densify(5), 0, densify(10)); - desc.setLayoutParams(lp); - desc.setFocusable(false); - desc.setFocusableInTouchMode(false); - desc.setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - v.setFocusable(true); - v.setFocusableInTouchMode(true); - v.performClick(); - return false; - } - }); - } - - mainText.setText(text); - - TextView feedbackNote = new TextView(this); - feedbackNote.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - feedbackNote.setGravity(Gravity.START); - feedbackNote.setPadding(0, 0, 0, 0); - feedbackNote.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12); - feedbackNote.setText(R.string.crash_dialog_note); - - dialogView.addView(mainText); - dialogView.addView(descText); - dialogView.addView(desc); - - String email = Helpers.prefs.getString("acra.user.email", ""); - if (Objects.equals(email, "")) dialogView.addView(feedbackNote); - - mainText.setText(mainText.getText() + "\n" + getResources().getString(R.string.crash_dialog_manual_size) + ": " + Math.round(payloadSize / 1024.0f) + " KB"); - } catch (Throwable t) {} - - AlertDialog.Builder alert = new AlertDialog.Builder(this); - alert.setTitle(title); - alert.setView(dialogView); - alert.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - cancelReportsAndFinish(); - } - }); - alert.setNeutralButton(neutralText, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - cancelReportsAndFinish(); - } - }); - alert.setPositiveButton(R.string.crash_send, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) {} - }); - loader.hide(); - final AlertDialog alertDlg = alert.show(); - alertDlg.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (desc != null && desc.getText().toString().trim().equals("")) { - Toast.makeText(Dialog.this, R.string.crash_needs_desc, Toast.LENGTH_LONG).show(); - } else if (!isNetworkAvailable()) { - Toast.makeText(Dialog.this, R.string.crash_needs_inet, Toast.LENGTH_LONG).show(); - } else { - Helpers.hideKeyboard(null, v); - alertDlg.dismiss(); - sendCrash(); - } - } - }); - } - - protected final CoreConfiguration getConfig() { - return config; - } - - @SuppressWarnings({"deprecation", "JavaReflectionMemberAccess"}) - private void updateBlurRatio() { - try { - View rootView = getWindow().getDecorView(); - if (rootView.getLayoutParams() instanceof WindowManager.LayoutParams) { - WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams)rootView.getLayoutParams(); - layoutParams.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND; - Field blurRatio = WindowManager.LayoutParams.class.getDeclaredField("blurRatio"); - blurRatio.setAccessible(true); - blurRatio.set(layoutParams, Helpers.isNightMode(this) ? 0.5f : 0.75f); - getWindowManager().updateViewLayout(rootView, layoutParams); - } - } catch (Throwable t) {} - } - - @Override - protected void onResume() { - super.onResume(); - updateBlurRatio(); - } - - @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - updateBlurRatio(); - } - - @Override - public void onDetachedFromWindow() { - if (loader != null && loader.isShowing()) loader.dismiss(); - super.onDetachedFromWindow(); - } - - @Override - public void finish() { - super.finish(); - overridePendingTransition(0, 0); - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/crashreport/DialogInteraction.java b/app/src/main/java/name/mikanoshi/customiuizer/crashreport/DialogInteraction.java deleted file mode 100644 index 175d28a6..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/crashreport/DialogInteraction.java +++ /dev/null @@ -1,46 +0,0 @@ -package name.mikanoshi.customiuizer.crashreport; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; - -import org.acra.ACRA; -import org.acra.config.CoreConfiguration; -import org.acra.interaction.ReportInteraction; -import org.acra.prefs.SharedPreferencesFactory; - -import java.io.File; - -import name.mikanoshi.customiuizer.utils.Helpers; - -import static org.acra.ACRA.LOG_TAG; - -public class DialogInteraction implements ReportInteraction { - static final String EXTRA_REPORT_FILE = "REPORT_FILE"; - static final String EXTRA_REPORT_CONFIG = "REPORT_CONFIG"; - - public DialogInteraction() { - super(); - } - - @Override - public boolean performInteraction(Context context, CoreConfiguration config, File reportFile) { - try { - final SharedPreferences prefs = new SharedPreferencesFactory(Helpers.getProtectedContext(context), config).create(); - if (prefs.getBoolean(ACRA.PREF_ALWAYS_ACCEPT, false)) return true; - if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Creating CrashReportDialog for " + reportFile); - final Intent dialogIntent = createCrashReportDialogIntent(context, config, reportFile); - dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION); - context.startActivity(dialogIntent); - } catch (Throwable t) {} - return false; - } - - private Intent createCrashReportDialogIntent(Context context, CoreConfiguration config, File reportFile) { - if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Creating DialogIntent for " + reportFile); - final Intent dialogIntent = new Intent(context, Dialog.class); - dialogIntent.putExtra(EXTRA_REPORT_FILE, reportFile); - dialogIntent.putExtra(EXTRA_REPORT_CONFIG, config); - return dialogIntent; - } -} \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinGenerator.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinGenerator.java deleted file mode 100644 index a7678372..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinGenerator.java +++ /dev/null @@ -1,29 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; - -import com.github.jinatonic.confetti.ConfettoGenerator; -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.PrecipType; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -public class CoinGenerator implements ConfettoGenerator { - private final ConfettoInfo confettoInfo; - private final Context context; - - public CoinGenerator(Context ctx) { - super(); - this.context = ctx; - this.confettoInfo = new ConfettoInfo(PrecipType.CLEAR); - } - - public Confetto generateConfetto(Random random) { - return new CoinParticle(this.context, this.confettoInfo); - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinParticle.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinParticle.java deleted file mode 100644 index f6872d5d..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/CoinParticle.java +++ /dev/null @@ -1,110 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.view.Surface; -import android.view.WindowManager; - -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -import name.mikanoshi.customiuizer.R; - -@SuppressWarnings("FieldCanBeLocal") -public class CoinParticle extends Confetto { - private final Context mContext; - private float startX; - private float startY; - private int signX; - private int signY; - private int distance; - private int maxAlpha; - private final ConfettoInfo confettoInfo; - private final Bitmap coin; - private final float coinScale; - private final int[] coins = new int[] { - R.drawable.coin1, R.drawable.coin2, R.drawable.coin3, R.drawable.coin4, R.drawable.coin5, R.drawable.coin6, R.drawable.coin7, R.drawable.coin8, R.drawable.coin9, R.drawable.coin10, - R.drawable.coin11, R.drawable.coin12, R.drawable.coin13, R.drawable.coin14, R.drawable.coin15, R.drawable.coin16, R.drawable.coin17, R.drawable.coin18, R.drawable.coin19, R.drawable.coin20, - R.drawable.coin21, R.drawable.coin22 - }; - - private void randomizeStartPoint() { - int width = mContext.getResources().getDisplayMetrics().widthPixels; - int height = mContext.getResources().getDisplayMetrics().heightPixels; - float gapX = width / 20.0f; - float gapY = height / 15.0f; - - int rotation = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); - boolean isLandscape = rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270; - Random rand = new Random(); - float selector = rand.nextFloat(); - if (selector < 0.25f) { - startX = rand.nextFloat() * (isLandscape ? gapY : gapX); - startY = rand.nextFloat() * (isLandscape ? width : height); - } else if (selector >= 0.25f && selector < 0.5f) { - startX = width - rand.nextFloat() * (isLandscape ? gapY : gapX); - startY = rand.nextFloat() * (isLandscape ? width : height); - } else if (selector >= 0.5f && selector < 0.75f) { - startX = rand.nextFloat() * (isLandscape ? height : width); - startY = rand.nextFloat() * (isLandscape ? gapX : gapY); - } else { - startX = rand.nextFloat() * (isLandscape ? height : width); - startY = height - rand.nextFloat() * (isLandscape ? gapX : gapY); - } - signX = rand.nextInt(3) - 1; - signY = rand.nextInt(3) - 1; - maxAlpha = rand.nextInt(40) + 30; - distance = rand.nextInt(76) + 75; - } - - CoinParticle(Context context, ConfettoInfo confettoInfo) { - super(); - this.confettoInfo = confettoInfo; - mContext = context; - coinScale = 1.2f - new Random().nextFloat() * 0.2f; - coin = BitmapFactory.decodeResource(context.getResources(), coins[new Random().nextInt(coins.length)]); - randomizeStartPoint(); - } - - public int getHeight() { - return 0; - } - - public int getWidth() { - return 0; - } - - public void reset() { - super.reset(); - randomizeStartPoint(); - } - - protected void configurePaint(Paint paint) { - super.configurePaint(paint); - paint.setColor(-1); - paint.setAntiAlias(true); - } - - protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y, float rotation, float percentageAnimated) { - matrix.postScale(coinScale, coinScale); - matrix.postRotate(rotation, coin.getWidth() / 2f, coin.getHeight() / 2f); - matrix.postTranslate(startX + signX * distance * percentageAnimated, startY + signY * distance * percentageAnimated); - if (percentageAnimated < 0.1f) - paint.setAlpha(Math.round(maxAlpha * percentageAnimated / 0.1f)); - else if (percentageAnimated > 0.9f) - paint.setAlpha(Math.round(maxAlpha * (1.0f - percentageAnimated) / 0.1f)); - else - paint.setAlpha(maxAlpha); - canvas.drawBitmap(coin, matrix, paint); - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthGenerator.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthGenerator.java deleted file mode 100644 index 9c8edbe2..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthGenerator.java +++ /dev/null @@ -1,29 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; - -import com.github.jinatonic.confetti.ConfettoGenerator; -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.PrecipType; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -public class FilthGenerator implements ConfettoGenerator { - private final ConfettoInfo confettoInfo; - private final Context context; - - public FilthGenerator(Context ctx) { - super(); - this.context = ctx; - this.confettoInfo = new ConfettoInfo(PrecipType.CLEAR); - } - - public Confetto generateConfetto(Random random) { - return new FilthyParticle(this.context, this.confettoInfo); - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthyParticle.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthyParticle.java deleted file mode 100644 index 669c660d..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FilthyParticle.java +++ /dev/null @@ -1,106 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.view.Surface; -import android.view.WindowManager; - -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -import name.mikanoshi.customiuizer.R; - -@SuppressWarnings("FieldCanBeLocal") -public class FilthyParticle extends Confetto { - private final Context mContext; - private float startX; - private float startY; - private int signX; - private int signY; - private int distance; - private int maxAlpha; - private final ConfettoInfo confettoInfo; - private final Bitmap filth; - private final float filthScale; - private final int[] viruses = new int[] { R.drawable.virus1, R.drawable.virus2, R.drawable.virus3 }; - - private void randomizeStartPoint() { - int width = mContext.getResources().getDisplayMetrics().widthPixels; - int height = mContext.getResources().getDisplayMetrics().heightPixels; - float gapX = width / 20.0f; - float gapY = height / 15.0f; - - int rotation = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); - boolean isLandscape = rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270; - Random rand = new Random(); - float selector = rand.nextFloat(); - if (selector < 0.25f) { - startX = rand.nextFloat() * (isLandscape ? gapY : gapX); - startY = rand.nextFloat() * (isLandscape ? width : height); - } else if (selector >= 0.25f && selector < 0.5f) { - startX = width - rand.nextFloat() * (isLandscape ? gapY : gapX); - startY = rand.nextFloat() * (isLandscape ? width : height); - } else if (selector >= 0.5f && selector < 0.75f) { - startX = rand.nextFloat() * (isLandscape ? height : width); - startY = rand.nextFloat() * (isLandscape ? gapX : gapY); - } else { - startX = rand.nextFloat() * (isLandscape ? height : width); - startY = height - rand.nextFloat() * (isLandscape ? gapX : gapY); - } - signX = rand.nextInt(3) - 1; - signY = rand.nextInt(3) - 1; - maxAlpha = rand.nextInt(50) + 40; - distance = rand.nextInt(76) + 75; - } - - FilthyParticle(Context context, ConfettoInfo confettoInfo) { - super(); - this.confettoInfo = confettoInfo; - mContext = context; - filthScale = 0.65f - new Random().nextFloat() * 0.15f; - filth = BitmapFactory.decodeResource(context.getResources(), viruses[new Random().nextInt(viruses.length)]); - randomizeStartPoint(); - } - - public int getHeight() { - return 0; - } - - public int getWidth() { - return 0; - } - - public void reset() { - super.reset(); - randomizeStartPoint(); - } - - protected void configurePaint(Paint paint) { - super.configurePaint(paint); - paint.setColor(-1); - paint.setAntiAlias(true); - } - - protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y, float rotation, float percentageAnimated) { - matrix.postScale(filthScale, filthScale); - matrix.postRotate(rotation, filth.getWidth() / 2f, filth.getHeight() / 2f); - matrix.postTranslate(startX + signX * distance * percentageAnimated, startY + signY * distance * percentageAnimated); - if (percentageAnimated < 0.1f) - paint.setAlpha(Math.round(maxAlpha * percentageAnimated / 0.1f)); - else if (percentageAnimated > 0.9f) - paint.setAlpha(Math.round(maxAlpha * (1.0f - percentageAnimated) / 0.1f)); - else - paint.setAlpha(maxAlpha); - canvas.drawBitmap(filth, matrix, paint); - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java deleted file mode 100644 index f5850f0b..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerGenerator.java +++ /dev/null @@ -1,29 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; - -import com.github.jinatonic.confetti.ConfettoGenerator; -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.PrecipType; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -public class FlowerGenerator implements ConfettoGenerator { - private final ConfettoInfo confettoInfo; - private final Context context; - - public FlowerGenerator(Context ctx) { - super(); - this.context = ctx; - this.confettoInfo = new ConfettoInfo(PrecipType.SNOW); - } - - public Confetto generateConfetto(Random random) { - return new FlowerParticle(this.context, this.confettoInfo); - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java deleted file mode 100644 index babf4ee5..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/FlowerParticle.java +++ /dev/null @@ -1,70 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.view.Surface; -import android.view.WindowManager; - -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -import name.mikanoshi.customiuizer.R; - -@SuppressWarnings("FieldCanBeLocal") -public class FlowerParticle extends Confetto { - private final ConfettoInfo confettoInfo; - private final Bitmap petal; - private float petalScale; - private final int[] petals = new int[] { R.drawable.confetti1, R.drawable.confetti1, R.drawable.confetti2, R.drawable.confetti2, R.drawable.confetti3, R.drawable.confetti3, R.drawable.petal }; - - FlowerParticle(Context context, ConfettoInfo confettoInfo) { - super(); - this.confettoInfo = confettoInfo; - petalScale = 0.6f - (float)Math.random() * 0.15f; - petal = BitmapFactory.decodeResource(context.getResources(), petals[new Random().nextInt(petals.length)]); - - int rotation = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); - if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) petalScale *= 1.5; - } - - public int getHeight() { - return 0; - } - - public int getWidth() { - return 0; - } - - public void reset() { - super.reset(); - } - - protected void configurePaint(Paint paint) { - super.configurePaint(paint); - paint.setColor(-1); - paint.setAntiAlias(true); - } - - protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y, float rotation, float percentageAnimated) { - switch (confettoInfo.getPrecipType()) { - case CLEAR: - break; - case SNOW: - matrix.postScale(petalScale, petalScale); - matrix.postRotate(rotation, petal.getWidth() / 2f, petal.getHeight() / 2f); - matrix.postTranslate(x, y); - canvas.drawBitmap(petal, matrix, paint); - break; - } - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java deleted file mode 100644 index c0457469..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/HolidayHelper.java +++ /dev/null @@ -1,141 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.app.Activity; -import android.view.Surface; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.RelativeLayout; - -import com.github.jinatonic.confetti.ConfettiManager; -import com.github.jinatonic.confetti.ConfettoGenerator; - -import com.github.matteobattilana.weather.PrecipType; -import com.github.matteobattilana.weather.WeatherView; - -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; - -import name.mikanoshi.customiuizer.R; -import name.mikanoshi.customiuizer.utils.GravitySensor; -import name.mikanoshi.customiuizer.utils.Helpers; - -public class HolidayHelper { - - private static WeakReference weatherView; - private static WeakReference angleListener; - - public static void setWeatherGenerator(ConfettoGenerator generator) { - try { - ConfettiManager manager = weatherView.get().getConfettiManager(); - Field confettoGenerator = ConfettiManager.class.getDeclaredField("confettoGenerator"); - confettoGenerator.setAccessible(true); - confettoGenerator.set(manager, generator); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - public static void setup(Activity activity) { - Helpers.detectHoliday(); - - WeatherView view = activity.findViewById(R.id.weather_view); - ImageView header = activity.findViewById(R.id.holiday_header); - - view.setLayerType(View.LAYER_TYPE_HARDWARE, null); - weatherView = new WeakReference<>(view); - GravitySensor listener = null; - if (Helpers.currentHoliday == Helpers.Holidays.NEWYEAR) { - int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); - view.setPrecipType(PrecipType.SNOW); - view.setSpeed(50); - view.setEmissionRate(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 8 : 4); - view.setFadeOutPercent(0.75f); - view.setAngle(0); - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)view.getLayoutParams(); - lp.height = activity.getResources().getDisplayMetrics().heightPixels / (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 2 : 3); - view.setLayoutParams(lp); - setWeatherGenerator(new SnowGenerator(activity)); - view.resetWeather(); - view.setVisibility(View.VISIBLE); - view.getConfettiManager().setRotationalVelocity(0, 45); - - listener = new GravitySensor(activity, view); - listener.setOrientation(rotation); - listener.setSpeed(50); - listener.start(); - - header.setImageResource(R.drawable.newyear_header); - header.setVisibility(View.VISIBLE); - } else if (Helpers.currentHoliday == Helpers.Holidays.LUNARNEWYEAR) { - int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); - view.setPrecipType(PrecipType.SNOW); - view.setSpeed(35); - view.setEmissionRate(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 4 : 2); - view.setFadeOutPercent(0.75f); - view.setAngle(0); - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)view.getLayoutParams(); - lp.height = activity.getResources().getDisplayMetrics().heightPixels / (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270 ? 3 : 4); - view.setLayoutParams(lp); - setWeatherGenerator(new FlowerGenerator(activity)); - view.resetWeather(); - view.setVisibility(View.VISIBLE); - view.getConfettiManager().setRotationalVelocity(0, 45); - - listener = new GravitySensor(activity, view); - listener.setOrientation(rotation); - listener.setSpeed(35); - listener.start(); - - header.setImageResource(R.drawable.lunar_newyear_header); - header.setVisibility(View.VISIBLE); - } else if (Helpers.currentHoliday == Helpers.Holidays.PANDEMIC) { - view.setPrecipType(PrecipType.CLEAR); - view.setSpeed(0); - view.setEmissionRate(0.6f); - view.setFadeOutPercent(1.0f); - view.setAngle(0); - setWeatherGenerator(new FilthGenerator(activity)); - view.resetWeather(); - view.setVisibility(View.VISIBLE); - view.getConfettiManager().setRotationalVelocity(0, 15).setTTL(30000); - } else if (Helpers.currentHoliday == Helpers.Holidays.CRYPTO) { - view.setPrecipType(PrecipType.CLEAR); - view.setSpeed(0); - view.setEmissionRate(0.6f); - view.setFadeOutPercent(1.0f); - view.setAngle(0); - setWeatherGenerator(new CoinGenerator(activity)); - view.resetWeather(); - view.setVisibility(View.VISIBLE); - view.getConfettiManager().setRotationalVelocity(0, 15).setTTL(30000); - - header.setImageResource(R.drawable.crypto_header); - header.setVisibility(View.VISIBLE); - } else { - ((ViewGroup)view.getParent()).removeView(view); - ((ViewGroup)header.getParent()).removeView(header); - } - angleListener = new WeakReference<>(listener); - } - - public static void onPause() { - GravitySensor listener = angleListener.get(); - if (listener != null) listener.onPause(); - WeatherView view = weatherView.get(); - if (view != null) view.getConfettiManager().terminate(); - } - - public static void onResume() { - GravitySensor listener = angleListener.get(); - if (listener != null) listener.onResume(); - WeatherView view = weatherView.get(); - if (view != null) view.getConfettiManager().animate(); - } - - public static void onDestroy() { - GravitySensor listener = angleListener.get(); - if (listener != null) listener.stop(); - } - -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java deleted file mode 100644 index 5f52aeff..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowGenerator.java +++ /dev/null @@ -1,29 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; - -import com.github.jinatonic.confetti.ConfettoGenerator; -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.PrecipType; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import java.util.Random; - -public class SnowGenerator implements ConfettoGenerator { - private final ConfettoInfo confettoInfo; - private final Context context; - - public SnowGenerator(Context ctx) { - super(); - this.context = ctx; - this.confettoInfo = new ConfettoInfo(PrecipType.SNOW); - } - - public Confetto generateConfetto(Random random) { - return new SnowParticle(this.context, this.confettoInfo); - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java b/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java deleted file mode 100644 index c4b9f73a..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/holidays/SnowParticle.java +++ /dev/null @@ -1,84 +0,0 @@ -package name.mikanoshi.customiuizer.holidays; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; - -import com.github.jinatonic.confetti.confetto.Confetto; -import com.github.matteobattilana.weather.confetti.ConfettoInfo; - -import name.mikanoshi.customiuizer.R; - -public class SnowParticle extends Confetto { - private Float prevX; - private Float prevY; - private final ConfettoInfo confettoInfo; - private final Bitmap snowflake; - private final float snowScale; - //private float rainStretch; - - SnowParticle(Context context, ConfettoInfo confettoInfo) { - super(); - this.confettoInfo = confettoInfo; - snowScale = 0.6f - (float)Math.random() * 0.3f; - //rainStretch = 1.5f + (float)Math.random() - 0.5f; - snowflake = BitmapFactory.decodeResource(context.getResources(), R.drawable.snowflake); - } - - public int getHeight() { - return 0; - } - - public int getWidth() { - return 0; - } - - public void reset() { - super.reset(); - this.prevX = null; - this.prevY = null; - } - - protected void configurePaint(Paint paint) { - super.configurePaint(paint); - paint.setColor(-1); - paint.setAntiAlias(true); - } - - protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y, float rotation, float percentageAnimated) { - if (prevX == null || prevY == null) { - prevX = x; - prevY = y; - } - - switch (confettoInfo.getPrecipType()) { - case CLEAR: - break; -// case RAIN: -// float dX = x - prevX; -// float dY = y - prevY; -// float x1 = prevX - dX * rainStretch; -// float y1 = prevY - dY * rainStretch; -// float x2 = x + dX * rainStretch; -// float y2 = y + dY * rainStretch; -// paint.setShader(new LinearGradient(x1, y1, x2, y2, new int[] { Color.TRANSPARENT, 0xb29aa3ad, 0xb29aa3ad, Color.TRANSPARENT }, new float[] { 0f, 0.45f, 0.55f, 1f }, Shader.TileMode.CLAMP)); -// canvas.drawLine(x1, y1, x2, y2, paint); -// break; - case SNOW: - matrix.postScale(snowScale, snowScale); - matrix.postRotate(rotation, snowflake.getWidth() / 2f, snowflake.getHeight() / 2f); - matrix.postTranslate(x, y); - canvas.drawBitmap(snowflake, matrix, paint); - break; - } - prevX = x; - prevY = y; - } - - public final ConfettoInfo getConfettoInfo() { - return this.confettoInfo; - } -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 86fc1153..ef334480 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -735,12 +735,12 @@ public void run() { public static void miuizerHook(LoadPackageParam lpparam) { try { - XposedHelpers.setStaticBooleanField(findClass(Helpers.modulePkg + ".utils.Helpers", lpparam.classLoader), "miuizerModuleActive", true); - XposedHelpers.setStaticObjectField(findClass(Helpers.modulePkg + ".utils.Helpers", lpparam.classLoader), "xposedVersion", XposedBridge.getXposedVersion()); + XposedHelpers.setStaticBooleanField(findClass(Helpers.modulePackage + ".utils.Helpers", lpparam.classLoader), "miuizerModuleActive", true); + XposedHelpers.setStaticObjectField(findClass(Helpers.modulePackage + ".utils.Helpers", lpparam.classLoader), "xposedVersion", XposedBridge.getXposedVersion()); } catch (Throwable t) { XposedBridge.log(t); } - + Helpers.emptyFile(lpparam.appInfo.dataDir + "/files/uncaught_exceptions", false); } @@ -1001,7 +1001,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); } - + public static void setupSystemHelpers() { Helpers.findAndHookMethod(Application.class, "onCreate", new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 5ae04a15..398aefd0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -72,8 +72,7 @@ import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; -import miui.app.ActionBar; -import miui.app.AlertDialog; +import android.app.AlertDialog; import name.mikanoshi.customiuizer.MainModule; import name.mikanoshi.customiuizer.R; @@ -974,37 +973,7 @@ protected void before(MethodHookParam param) throws Throwable { )); public static void CollapseMIUITitlesHook(LoadPackageParam lpparam, XC_MethodHook.MethodHookParam param, int opt) { - Application app = (Application)param.thisObject; - String pkgName = app.getPackageName(); - boolean isMIUIapp = pkgName.startsWith("com.miui") || pkgName.startsWith("com.xiaomi") || miuiApps.contains(pkgName); - if (!isMIUIapp) isMIUIapp = app.checkSelfPermission("miui.permission.USE_INTERNAL_GENERAL_API") == PackageManager.PERMISSION_GRANTED; - if (!isMIUIapp) return; - - Class abvCls = XposedHelpers.findClassIfExists("com.miui.internal.widget.AbsActionBarView", lpparam.classLoader); - if (abvCls != null) - Helpers.hookAllConstructors(abvCls, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setIntField(param.thisObject, "mExpandState", ActionBar.STATE_COLLAPSE); - XposedHelpers.setIntField(param.thisObject, "mInnerExpandState", ActionBar.STATE_COLLAPSE); - if (opt == 3) XposedHelpers.setBooleanField(param.thisObject, "mResizable", false); - } - }); - - abvCls = XposedHelpers.findClassIfExists("miuix.appcompat.internal.app.widget.ActionBarView", lpparam.classLoader); - if (abvCls != null) - Helpers.hookAllConstructors(abvCls, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - try { - XposedHelpers.callMethod(param.thisObject, "setExpandState", ActionBar.STATE_COLLAPSE); - if (opt == 3) XposedHelpers.callMethod(param.thisObject, "setResizable", false); - } catch (Throwable ignore) { - XposedBridge.log(ignore); - } - } - }); } public static void GboardPaddingHook() { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java index 344edc12..f0d17e5c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java @@ -4,7 +4,7 @@ import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; -import android.preference.CheckBoxPreference; +import android.preference.SwitchPreference; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -13,7 +13,7 @@ import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.utils.Helpers; -public class CheckBoxPreferenceEx extends CheckBoxPreference implements PreferenceState { +public class CheckBoxPreferenceEx extends SwitchPreference implements PreferenceState { private final Resources res = getContext().getResources(); private final int primary = res.getColor(R.color.preference_primary_text, getContext().getTheme()); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java index cdaf75b3..2115e748 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java @@ -45,7 +45,7 @@ public View getView(View view, ViewGroup parent) { finalView.setBackground(null); finalView.setPadding( finalView.getPaddingLeft(), - finalView.getPaddingTop() + Math.round(getContext().getResources().getDisplayMetrics().density * 10), + Math.round(getContext().getResources().getDisplayMetrics().density * 10), finalView.getPaddingRight(), finalView.getPaddingBottom() ); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java index 5f8cddc1..b68ab35f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java @@ -131,8 +131,6 @@ protected View onCreateView(ViewGroup parent) { mSeekBar = view.findViewById(R.id.seekbar); mSeekBar.setMax(mSteppedMaxValue - mSteppedMinValue); - if (Helpers.is11()) mSeekBar.setPadding(0, mSeekBar.getPaddingTop(), 0, mSeekBar.getPaddingBottom()); - setValue(Helpers.prefs.getInt(getKey(), mDefaultValue)); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SpinnerEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SpinnerEx.java index dfd159d3..825ce2b9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SpinnerEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SpinnerEx.java @@ -6,13 +6,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.Spinner; +import androidx.appcompat.widget.AppCompatSpinner; import java.util.ArrayList; import name.mikanoshi.customiuizer.R; -public class SpinnerEx extends Spinner { +public class SpinnerEx extends AppCompatSpinner { public CharSequence[] entries; public int[] entryValues; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java index f54af72a..34d28d9a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java @@ -42,6 +42,7 @@ public class BTList extends SubFragment { List> btList = new ArrayList>(); Set addresses = new LinkedHashSet(); BroadcastReceiver devicesReceiver = new BroadcastReceiver() { + @SuppressLint("MissingPermission") @Override public void onReceive(Context context, Intent intent) { ArrayList deviceList = intent.getParcelableArrayListExtra("device_list"); @@ -235,6 +236,7 @@ public View getView(final int position, View convertView, ViewGroup parent) { row.setEnabled(true); boolean isBonded = false; + @SuppressLint("MissingPermission") Set bonded = BluetoothAdapter.getDefaultAdapter().getBondedDevices(); for (BluetoothDevice device: bonded) if (device.getAddress().equals(sr.first)) isBonded = true; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/ColorSelector.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/ColorSelector.java index 54f8523a..96d367ea 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/ColorSelector.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/ColorSelector.java @@ -6,7 +6,7 @@ import android.view.View; import android.widget.TextView; -import miui.widget.SeekBar; +import android.widget.SeekBar; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.utils.ColorCircle; @@ -20,6 +20,12 @@ public class ColorSelector extends SubFragment { TextView auto; View selColor; + @Override + public void onCreate(Bundle savedInstanceState) { + this.padded = false; + super.onCreate(savedInstanceState); + } + void updateSelColor(int color) { ((GradientDrawable)selColor.getBackground()).setColors(color == Color.TRANSPARENT ? new int[]{ Color.WHITE, Color.BLACK } : new int[]{ color, color }); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/MultiAction.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/MultiAction.java index eae046a3..9b834f1e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/MultiAction.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/MultiAction.java @@ -41,6 +41,12 @@ public enum Actions { NAVBAR, LAUNCHER, CONTROLS, RECENTS, LOCKSCREEN, LAUNCH, STATUSBAR } + @Override + public void onCreate(Bundle savedInstanceState) { + this.padded = false; + super.onCreate(savedInstanceState); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java index 74bd0348..10fac10a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java @@ -16,9 +16,6 @@ import java.util.Arrays; import java.util.UUID; -import miui.app.ActionBar; -import miui.util.AttributeResolver; - import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.utils.Helpers; @@ -42,8 +39,6 @@ public void onCreate(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) { supressMenu = true; super.onActivityCreated(savedInstanceState); - ActionBar actionBar = getActionBar(); - if (actionBar != null) try { actionBar.showSplitActionBar(true, true); } catch (Throwable ignore) {} Bundle args = getArguments(); key = args.getString("key"); @@ -146,15 +141,6 @@ public boolean onItemLongClick(AdapterView parent, View view, int position, l }); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_itemactions, menu); - //menu.getItem(0).setEnabled(listView.getChildCount() < 10); - menu.getItem(0).setIcon(AttributeResolver.resolveDrawable(getActivity(), getResources().getIdentifier("actionBarNewIcon", "attr", "miui"))); - menu.getItem(1).setIcon(AttributeResolver.resolveDrawable(getActivity(), getResources().getIdentifier("actionBarDeleteIcon", "attr", "miui"))); - return true; - } - private String createNewUUID() { return UUID.randomUUID().toString().replaceAll("-", "").toLowerCase(); } @@ -165,7 +151,6 @@ private void createNewItem(String uuid) { PreferenceAdapter adapter = (PreferenceAdapter)listView.getAdapter(); adapter.updateItems(); adapter.notifyDataSetChanged(); - invalidateOptionsMenu(); } private void deleteItem(int position) { @@ -174,7 +159,6 @@ private void deleteItem(int position) { Helpers.prefs.edit().putString(key, items.isEmpty() ? "" : items.replace(adapter.getItem(position), "").replace("||", "|").replaceAll("^\\|", "").replaceAll("\\|$", "")).apply(); adapter.updateItems(); adapter.notifyDataSetChanged(); - invalidateOptionsMenu(); } @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index dff87faf..8f397717 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -15,7 +15,7 @@ import java.util.Objects; -import miui.app.AlertDialog; +import android.app.AlertDialog; import name.mikanoshi.customiuizer.CredentialsLauncher; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SharedPrefsProvider; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java index 4966c1ec..500e3197 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java @@ -6,8 +6,8 @@ import java.util.Calendar; -import miui.app.TimePickerDialog; -import miui.widget.TimePicker; +import android.app.TimePickerDialog; +import android.widget.TimePicker; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.prefs.PreferenceEx; import name.mikanoshi.customiuizer.utils.Helpers; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java index 7e56b1be..1f913ffd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java @@ -6,8 +6,8 @@ import java.util.Calendar; -import miui.app.TimePickerDialog; -import miui.widget.TimePicker; +import android.app.TimePickerDialog; +import android.widget.TimePicker; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.prefs.PreferenceEx; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java deleted file mode 100644 index 885a9b59..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/GravitySensor.java +++ /dev/null @@ -1,104 +0,0 @@ -package name.mikanoshi.customiuizer.utils; - -import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.view.Surface; - -import com.github.matteobattilana.weather.WeatherView; - -public final class GravitySensor implements SensorEventListener { - private final SensorManager sensorManager; - private float[] magneticValues; - private float[] accelerometerValues; - private int orientation; - private int speed; - private boolean started; - private final Context context; - private final WeatherView weatherView; - - public GravitySensor(Context context, WeatherView weatherView) { - super(); - this.context = context; - this.weatherView = weatherView; - this.sensorManager = (SensorManager)this.context.getSystemService(Context.SENSOR_SERVICE); - } - - public final boolean getStarted() { - return this.started; - } - - public void setOrientation(int orient) { - this.orientation = orient; - } - - public void setSpeed(int spd) { - this.speed = spd; - } - - public void onAccuracyChanged(Sensor sensor, int accuracy) {} - - public void onSensorChanged(SensorEvent event) { - if (event == null || event.sensor == null) return; - switch (event.sensor.getType()) { - case 1: this.accelerometerValues = event.values; break; - case 2: this.magneticValues = event.values; break; - } - if (this.magneticValues == null || this.accelerometerValues == null) return; - - float[] rotationMatrix = new float[9]; - SensorManager.getRotationMatrix(rotationMatrix, null, this.accelerometerValues, this.magneticValues); - float[] remappedRotationMatrix = new float[9]; - SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remappedRotationMatrix); - float[] orientationAngles = new float[3]; - SensorManager.getOrientation(remappedRotationMatrix, orientationAngles); - //double pitch = Math.toDegrees((double)orientationAngles[1]); - double roll = Math.toDegrees(orientationAngles[2]) + Math.random() * 20 - 10; - if (this.orientation == Surface.ROTATION_90) roll += 90; - else if (this.orientation == Surface.ROTATION_270) roll -= 90; - else if (this.orientation == Surface.ROTATION_180) roll += roll > 0 ? 180 : -180; - if (roll > 90) roll -= 180; else if (roll < -90) roll += 180; - this.weatherView.setAngle((int)roll); - this.weatherView.setSpeed(this.speed + (int)Math.round(Math.random() * 20 - 10)); - } - - private void registerListener() { - this.sensorManager.registerListener(this, this.sensorManager.getDefaultSensor(1), 2); - this.sensorManager.registerListener(this, this.sensorManager.getDefaultSensor(2), 2); - } - - private void unregisterListener() { - this.sensorManager.unregisterListener(this); - } - - public final void start() { - this.started = true; - this.registerListener(); - } - - public final void stop() { - this.started = false; - this.unregisterListener(); - } - - public final void onResume() { - if (this.started) { - this.registerListener(); - } - } - - public final void onPause() { - this.unregisterListener(); - } - - public final Context getContext() { - return this.context; - } - - public final WeatherView getWeatherView() { - return this.weatherView; - } - -} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/GuidePopup.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/GuidePopup.java deleted file mode 100644 index 84456bdf..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/GuidePopup.java +++ /dev/null @@ -1,65 +0,0 @@ -package name.mikanoshi.customiuizer.utils; - -import android.content.Context; -import android.text.TextUtils; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; - -import miui.widget.ArrowPopupWindow; -import name.mikanoshi.customiuizer.R; - -public class GuidePopup extends ArrowPopupWindow { - private LinearLayout layout; - - public GuidePopup(Context context) { - super(context); - } - - private void setText(String text) { - if (TextUtils.isEmpty(text)) return; - - String[] txt = text.split("\n"); - if (txt.length == 0) return; - - LayoutInflater infalter = this.getLayoutInflater(); - for (String str: txt) { - TextView textView = (TextView)infalter.inflate(getContext().getResources().getIdentifier("guide_popup_text_view", "layout", "miui"), null); - textView.setText(str); - textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13.5f); - if (Helpers.isNightMode(getContext())) - textView.setTextColor(getContext().getResources().getColor(R.color.guide_popup_text, getContext().getTheme())); - textView.setSingleLine(true); - textView.setMaxHeight(Integer.MAX_VALUE); - textView.setMaxWidth(Integer.MAX_VALUE); - this.layout.addView(textView); - } - } - - protected void onPrepareWindow() { - super.onPrepareWindow(); - this.setFocusable(true); - this.layout = (LinearLayout)this.getLayoutInflater().inflate(getContext().getResources().getIdentifier("guide_popup_content_view", "layout", "miui"), null, false); - this.setContentView(this.layout); - this.mArrowPopupView.enableShowingAnimation(false); - } - - public void setGuideText(int resId) { - this.setGuideText(this.getContext().getString(resId)); - } - - private void setGuideText(String text) { - this.setText(text); - } - - public void show(View anchor) { - this.show(anchor, 0, 0); - } - - public void show(View anchor, int x, int y) { - super.show(anchor, x, y); - } -} - diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 841bb6cf..6a73dd93 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -100,8 +100,7 @@ import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; -import miui.app.AlertDialog; -import miui.os.SystemProperties; +import android.app.AlertDialog; import miui.util.HapticFeedbackUtil; import name.mikanoshi.customiuizer.MainModule; @@ -115,11 +114,12 @@ public class Helpers { @SuppressLint("StaticFieldLeak") public static Context mModuleContext = null; - public static final String modulePkg = "name.mikanoshi.customiuizer"; + public static final String modulePkg = "name.monwf.customiuizer"; + public static final String modulePackage = "name.mikanoshi.customiuizer"; public static final String prefsName = "customiuizer_prefs"; public static final String prefsPath = "/data/user_de/0/" + modulePkg + "/shared_prefs"; public static final String prefsFile = prefsPath + "/" + prefsName + ".xml"; - public static final String externalFolder = "/CustoMIUIzer/"; + public static final String externalFolder = "/Documents/CustoMIUIzer/"; public static final String backupFile = "settings_backup"; public static final String logFile = "xposed_log"; public static final String versionFile = "xposed_version"; @@ -163,17 +163,8 @@ protected int sizeOf(String key, Bitmap icon) { "pref_key_launcher_horizwidgetmargin" )); public static final HashMap l10nProgress = new HashMap() {{ - put("de", "86.6"); - put("es", "98.7"); - put("it", "98"); - put("pt-BR", "94.7"); put("ru-RU", "100"); - put("tr", "86.6"); - put("uk-UK", "87.6"); put("zh-CN", "98.1"); - put("fr", "24.9"); - put("id", "13.1"); - put("sk", "4.2"); }}; public static final HashSet xposedManagers = new HashSet(Arrays.asList( @@ -186,11 +177,6 @@ protected int sizeOf(String key, Bitmap icon) { )); public static final ArrayList shortcutIcons = new ArrayList(); - public static Holidays currentHoliday = Holidays.NONE; - - public enum Holidays { - NONE, NEWYEAR, LUNARNEWYEAR, PANDEMIC, CRYPTO - } public enum SettingsType { Preference, Edit @@ -225,20 +211,6 @@ public static int getSystemBackgroundColor(Context context) { return isNightMode(context) ? black : white; } - public static void setMiuiTheme(Activity act, int overrideTheme) { - setMiuiTheme(act, overrideTheme, false); - } - - public static void setMiuiTheme(Activity act, int overrideTheme, boolean noBackground) { - int themeResId = 0; - try { themeResId = act.getResources().getIdentifier("Theme.DayNight", "style", "miui"); } catch (Throwable ignore) {} - if (themeResId == 0) themeResId = act.getResources().getIdentifier(isNightMode(act) ? "Theme.Dark" : "Theme.Light", "style", "miui"); - act.setTheme(themeResId); - if (!is11()) act.getTheme().applyStyle(R.style.ActivityAnimation10, true); - act.getTheme().applyStyle(overrideTheme, true); - act.getWindow().setBackgroundDrawable(noBackground ? null : new ColorDrawable(getSystemBackgroundColor(act))); - } - public static void setMiuiCheckbox(CheckBox checkbox) { checkbox.setBackground(null); int btnResID = checkbox.getResources().getIdentifier(isNightMode(checkbox.getContext()) ? "btn_checkbox_dark" : "btn_checkbox_light", "drawable", "miui"); @@ -287,43 +259,20 @@ public static void setMiuiPrefItem(View item) { item.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); } - @SuppressWarnings("ConstantConditions") - public static void detectHoliday() { - currentHoliday = Holidays.NONE; - String opt = prefs.getString("pref_key_miuizer_holiday", "0"); - int holiday = Integer.parseInt(opt); - if (holiday > 0) currentHoliday = Holidays.values()[holiday]; - if (holiday == 0) { - Calendar cal = Calendar.getInstance(); - int month = cal.get(Calendar.MONTH); - int monthDay = cal.get(Calendar.DAY_OF_MONTH); - int year = cal.get(Calendar.YEAR); - - // Lunar NY - if ((month == 0 && monthDay > 15) || month == 1) currentHoliday = Holidays.LUNARNEWYEAR; - // NY - else if (month == 0 || month == 11) currentHoliday = Holidays.NEWYEAR; - // COVID19 - else if (year <= 2020) currentHoliday = Holidays.PANDEMIC; - // Crypto - else if (year == 2021 || year == 2022) currentHoliday = Holidays.CRYPTO; - } - } - public static boolean is10() { - return SystemProperties.getInt("ro.miui.ui.version.code", 7) <= 8; + return false; } public static boolean is11() { - return SystemProperties.getInt("ro.miui.ui.version.code", 8) >= 9; + return true; } public static boolean is12() { - return SystemProperties.getInt("ro.miui.ui.version.code", 9) >= 10; + return true; } public static boolean is125() { - return SystemProperties.getInt("ro.miui.ui.version.code", 10) >= 11; + return true; } public static boolean isNightMode(Context context) { @@ -360,38 +309,13 @@ public static boolean isDeviceEncrypted(Context context) { // } public static boolean isXposedInstallerInstalled(Context context) { - boolean skip = prefs.getBoolean("pref_key_miuizer_assumelsposed", false); - if (skip) return true; - - PackageManager pm = context.getPackageManager(); - - for (String manager: xposedManagers) try { - pm.getPackageInfo(manager, PackageManager.GET_ACTIVITIES); - return true; - } catch (PackageManager.NameNotFoundException e) {} - - return false; + return true; } public static String isLSPosedManagerInstalled(Context context) { - boolean lsposed = prefs.getBoolean("pref_key_miuizer_assumelsposed", false); - if (lsposed) return "Assumed LSPosed"; - try { - PackageInfo info = context.getPackageManager().getPackageInfo("org.lsposed.manager", 0); - return info.versionName + " (" + info.versionCode + ")"; - } catch (PackageManager.NameNotFoundException e) { - return null; - } + return "Assumed LSPosed"; } -// public static boolean isUnsupportedManager(Context context) { -// try { -// return context.getPackageManager().getPackageInfo("org.meowcat.edxposed.manager", 0).versionCode > 45700; -// } catch (PackageManager.NameNotFoundException e) { -// return true; -// } -// } - public static boolean areXposedResourceHooksDisabled() { File d1 = new File("/data/user_de/0/org.meowcat.edxposed.manager/conf/disable_resources"); File d2 = new File("/data/user_de/0/com.solohsu.android.edxp.manager/conf/disable_resources"); @@ -773,59 +697,10 @@ public static void applyNewMod(TextView title) { title.setText(ssb); } - public static void applyShimmer(TextView title) { - if (title.getPaint().getShader() != null) return; - int width = title.getResources().getDisplayMetrics().widthPixels; - Shader shimmer = new LinearGradient(0, 0, width, 0, new int[]{ 0xFF5DA5FF, 0xFF9B8AFB, 0xFFD176F2, 0xFFFE88B2, 0xFFD176F2, 0xFF9B8AFB }, new float[]{ 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }, Shader.TileMode.REPEAT); - Matrix matrix = new Matrix(); - matrix.setTranslate(0, 0); - shimmer.setLocalMatrix(matrix); - title.getPaint().setShader(shimmer); - - if (shimmerAnim != null) shimmerAnim.cancel(); - shimmerAnim = ValueAnimator.ofFloat(0, width, width / 1.8f, width * 1.3f); - shimmerAnim.removeAllUpdateListeners(); - shimmerAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - matrix.setTranslate((float)animation.getAnimatedValue(), 0); - Shader shader = title.getPaint().getShader(); - if (shader == null) - shimmerAnim.cancel(); - else - shader.setLocalMatrix(matrix); - title.invalidate(); - } - }); - shimmerAnim.removeAllListeners(); - shimmerAnim.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationEnd(Animator animation) { - title.getPaint().setShader(null); - title.invalidate(); - } - - @Override - public void onAnimationStart(Animator animation) {} - - @Override - public void onAnimationCancel(Animator animation) {} - - @Override - public void onAnimationRepeat(Animator animation) {} - }); - shimmerAnim.setStartDelay(0); - shimmerAnim.setDuration(10000); - shimmerAnim.start(); - } - public static void openURL(Context context, String url) { if (context == null) return; Intent uriIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - if (uriIntent.resolveActivity(context.getPackageManager()) != null) - context.startActivity(uriIntent); - else - showOKDialog(context, R.string.warning, R.string.no_browser); + context.startActivity(uriIntent); } public static void openAppInfo(Context context, String pkg, int user) { @@ -1883,7 +1758,7 @@ public void onChange(String name, int defValue) {} private static String getCallerMethod() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); for (StackTraceElement el: stackTrace) - if (el != null && el.getClassName().startsWith(modulePkg + ".mods")) return el.getMethodName(); + if (el != null && el.getClassName().startsWith(modulePackage + ".mods")) return el.getMethodName(); return stackTrace[4].getMethodName(); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java index 872bdf77..c515ce5a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java @@ -36,14 +36,18 @@ protected void onFinishInflate() { @Override protected void onLayout(boolean z, int i, int i2, int i3, int i4) { super.onLayout(z, i, i2, i3, i4); - setScrollingRange((int)((float)(-mHeaderView.getMeasuredHeight()) + mRangeOffset), 0); + if (mHeaderView != null) { + setScrollingRange((int)((float)(-mHeaderView.getMeasuredHeight()) + mRangeOffset), 0); + } } @Override protected void onScrollingProgressUpdated(int i) { super.onScrollingProgressUpdated(i); - mHeaderView.offsetTopAndBottom(i - mHeaderView.getTop()); - mScrollableView.offsetTopAndBottom(mHeaderView.getMeasuredHeight() + i - mScrollableView.getTop()); - mScrollableSearchView.setTop(mHeaderView.getMeasuredHeight()); + if (mHeaderView != null) { + mHeaderView.offsetTopAndBottom(i - mHeaderView.getTop()); + mScrollableView.offsetTopAndBottom(mHeaderView.getMeasuredHeight() + i - mScrollableView.getTop()); + mScrollableSearchView.setTop(mHeaderView.getMeasuredHeight()); + } } } diff --git a/app/src/main/res/layout-land/fragment_selectcolor.xml b/app/src/main/res/layout-land/fragment_selectcolor.xml index a56cb713..af7fbd78 100644 --- a/app/src/main/res/layout-land/fragment_selectcolor.xml +++ b/app/src/main/res/layout-land/fragment_selectcolor.xml @@ -28,13 +28,13 @@ android:layout_width="200dp" android:layout_height="100dp" /> - - + - + android:fitsSystemWindows="true" + android:orientation="vertical"> - - - + android:layout_height="?attr/actionBarSize" + android:elevation="4dp" + android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar" + /> - - + android:background="?android:attr/colorBackground" + /> - + diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml index 5747424e..43402a9b 100644 --- a/app/src/main/res/layout/fragment_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -1,7 +1,7 @@ + android:layout_height="match_parent"> - - + android:max="100" /> - + android:text="@string/snooze_empty" + android:textSize="14sp" + android:visibility="gone" /> diff --git a/app/src/main/res/layout/preference_seekbar12.xml b/app/src/main/res/layout/preference_seekbar12.xml index f288f7a3..bf5d7197 100644 --- a/app/src/main/res/layout/preference_seekbar12.xml +++ b/app/src/main/res/layout/preference_seekbar12.xml @@ -5,6 +5,8 @@ android:layout_gravity="center_vertical" android:gravity="center_vertical" android:baselineAligned="false" + android:paddingStart="15dp" + android:paddingEnd="10dp" android:clipChildren="false" android:clipToPadding="false"> @@ -41,8 +43,6 @@ android:id="@+id/seekbar_group" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginEnd="6dip" - android:layout_marginTop="10dip" android:layout_below="@android:id/summary" android:clipChildren="false" android:clipToPadding="false"> @@ -71,7 +71,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/seekbar_group" - android:layout_marginTop="10dip" + android:layout_marginTop="10dp" android:layout_alignStart="@id/seekbar_group" style="@style/TextAppearance.Secondary" /> diff --git a/app/src/main/res/layout/prefs_app_selector.xml b/app/src/main/res/layout/prefs_app_selector.xml index e99c7e88..1f48eadd 100644 --- a/app/src/main/res/layout/prefs_app_selector.xml +++ b/app/src/main/res/layout/prefs_app_selector.xml @@ -4,6 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" + android:paddingTop="20dp" android:animateLayoutChanges="true"> @@ -23,9 +24,9 @@ android:gravity="center" android:orientation="vertical"> - diff --git a/app/src/main/res/layout/prefs_bt_networks.xml b/app/src/main/res/layout/prefs_bt_networks.xml index 1e9a17e5..566616b4 100644 --- a/app/src/main/res/layout/prefs_bt_networks.xml +++ b/app/src/main/res/layout/prefs_bt_networks.xml @@ -61,7 +61,7 @@ android:orientation="vertical" android:layout_below="@id/bt_category2"> - - - - - - diff --git a/app/src/main/res/menu/menu_mods.xml b/app/src/main/res/menu/menu_mods.xml index fcd33e59..44fb93f6 100644 --- a/app/src/main/res/menu/menu_mods.xml +++ b/app/src/main/res/menu/menu_mods.xml @@ -1,23 +1,20 @@ -

+ + android:id="@+id/edit_confirm" + android:visible="false" + android:title="OK" + app:showAsAction="always"/> - + android:title="@string/soft_reboot" + app:showAsAction="never" /> + android:title="@string/backup_restore" + app:showAsAction="never" /> + android:title="@string/app_about" + app:showAsAction="never" /> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml deleted file mode 100644 index 08e53767..00000000 --- a/app/src/main/res/values-de/strings.xml +++ /dev/null @@ -1,917 +0,0 @@ - - - Über - Version %1$s - von Mikanoshi - Im Allgemeinen erfordern Mods einen Soft-Neustart, um aktiviert oder deaktiviert zu werden. Mods, die mit ⟲ gekennzeichnet sind benötigen nur einen Soft-Neustart, nachdem ihr Wert verändert wurde und anschließende Änderungen werden danach sofort angewendet. - Mods, die mit ⨯ markiert sind, werden auf diesem Gerät nicht unterstützt. - Eingeschlummerte Benachrichtigungen - Update - Aufwecken dieser Benachrichtigung - Als zurückgewiesen markiert - Als ausstehend markiert - Snoozed Benachrichtigungsliste kann nicht abgerufen werden - Keine schlummernden Benachrichtigungen - Nachrichten - Kanal - Erstellt - Aktualisiert - Erneut veröffentlicht - Mods - Aktionen - Aktiviere Mod - System - Bildschirm - Drehung - Hintergrundbeleuchtung - Lautstärke & Audio - Vibration - Popup-Mitteilungen (Toasts) - Verstecke Symbole - Sichtbarkeit der Statusleistensymbolen verwalten - Batterieprofil - Batterieladung in Prozent - Ladeindikator - Kann bei einigen ROMs über das Batteriesymbol gelegt werden - Alarm - Vollständig verstecken - Sichtbarkeit des selektiven Alarmsymbols - Das Alarmsymbol wird nur während der festgelegten Stunden vor dem nächsten Alarm angezeigt - Mobilfunksignal - Fehlende SIM-Karte - Hotspot - Arbeitsprofil - Ton-Profile - Nicht-stören-Modus - Kopfhörer - Anruf: ausgeschaltetes Mikrofon - Anruf: Freisprecheinrichtung - Anruf: Aufzeichnung - Batteriebalkenanzeige - Zeigt den Ladezustand des Akkus als farbigen Balken an - Eingeschränkte Sichtbarkeit - Wird nur in der Benachrichtigungsleiste und auf dem Sperrbildschirm angezeigt - Abgerundete Enden - Zentriert - Balkenhöhe - Horizontales Auffüllen - Farbe für aufgeladen - Farbe für gering aufgeladen - Farbe im Stromsparmodus - Farbe für ladend - Geringer Ladezustand - Test - Zeigt Animation der Batteriebalkenanzeige von 100 bis 0 Prozent (simuliert Entladung) - Höhe der Statusleiste - Hintergrundfarbe der Statusleiste - Hintergrundfarben von Statusleiste und Titelleiste nach Möglichkeit gleichsetzen - Blockierliste - App öffnen mittels Verknüpfungssymbol - Öffnet ausgewählte App, wenn auf das Verknüpfungssymbol (Einstellungen oder Suchen) in der Benachrichtigungsleiste getippt wird - App öffnen mittels Uhranzeige - Öffnet die ausgewählte App, wenn auf die Uhr in der Benachrichtigungsleiste getippt wird - App öffnen mittels Kalender-Anzeige - Öffnet die ausgewählte App, wenn auf das Datum in der Benachrichtigungsleiste getippt wird - Zeige Uhrzeit mit Sekunden - Zeigt Uhrzeit ergänzt mit Sekunden an - Mobilfunk-Typ ausblenden - Entfernet das Symbol für den Mobilfunk-Typ aus der Statusleiste - Zeige LTE-Symbol anstatt 4G-Symbol - Keine Anzeige für versteckte Symbole - 3-Punkte-Symbol nicht anzeigen, wenn ausgeblendete Benachrichtigungssymbole vorhanden sind - Kein Trennzeichen bei Anzeige der Netzwerkgeschwindigkeit - Bei Geräten mit Wassertropfen-Notches wird keine vertikale Linie zwischen Zeit und Netzwerkgeschwindigkeit angezeigt - Aktualisierungsintervall für die Netzwerkgeschwindigkeit - Detaillierte Netzwerkgeschwindigkeitsanzeige - Eingehende und ausgehende Netzwerkgeschwindigkeiten getrennt anzeigen - Schriftgröße - Indikatorsymbole - Symbole für eingehenden/ausgehenden Verkehr werden neben dem Geschwindigkeitswert angezeigt (Achtung: nicht jede benutzerdefinierte Schriftart besitzt jedes Symbol) - Niedrige Geschwindigkeit nicht anzeigen - Keine Anzeige bei Unterschreitung der Geschwindigkeitsschwelle - Geschwindigkeitsschwelle - Geschwindigkeitswerte unter diesem Wert gelten als niedrig und haben ein anderes Anzeigesymbol - Reduziert die Sichtbarkeit, wenn inaktiv - Setzt die Indikatorsymbole halbtransparent, wenn Up- und Download-Geschwindigkeiten beide null sind - Gestensteuerung - Führt ausgewählte Aktionen durch Wischen und Doppel-Tipp aus - Einstellen der Empfindlichkeit - Helligkeit - Lautstärke - Horizontales Wischen mit einem Finger - Horizontales Wischen mit zwei Fingern - Doppel-Tipp-Aktion - Abstand der Netzwerkgeschwindigkeitsanzeige - Erhöht die horizontalen Ränder für die Netzwerkgeschwindigkeitsanzeige - Kompakte Benachrichtigungen - Reduziert die vertikalen Auffüllungen der Benachrichtigungen - Benachrichtigungstitel färben - Wendet die Farbe des Symbols auf den Titeltext an (nur im Android-Benachrichtigungsstil) - Schaltfläche zum Löschen ausblenden - Entfernen Sie die Schaltfläche, mit der alle Benachrichtigungen gelöscht werden - Beleuchtungsstärke anzeigen - Zeigt den Wert für die Umgebungsbeleuchtung in Lux im Helligkeitsregler an - Alternativer Stil - Großer halbtransparenter Text - Helligkeitsprozentsatz anzeigen - Zeigt die Helligkeitsstufe in Prozent beim Ziehen der Helligkeitesregler an - Oberer Rand des Prozentbereiches - Sichtbarkeit des Helligkeitsreglers - Erweitertes Benachrichtigungsmenü - Öffnet die App-Info und erzwingt das Schließen der App aus dem Benachrichtigungsmenü (nach links wischen, um die Benachrichtigung zu öffnen) - Deaktiviert jede Benachrichtigung - Ermöglicht auch das Deaktivieren von Systembenachrichtigungen - Erweitert Benachrichtigungen - Benachrichtigungen werden vollständig erweitert angezeigt - Blockier- bzw. Positiv-Liste - Anzeigedauer einstellen - Verkürzt oder verlängert die Standard-Anzeigedauer - Die Anzeigedauer wird 1 Sekunde nicht unterschreiten - autom. Gruppenbenachrichtigungen - Anzahl der Benachrichtigungen von einer App, die eine automatische Gruppierung auslösen - Eingeschlummerter Benachrichtigungsmanager - Erhöht die Anzahl der Schlummerintervalle und fügt dem Launcher ein Symbol hinzu, das eine Liste der aktuell eingeschlafenen Benachrichtigungen öffnet - Schieberegler für die Medienposition - Fügt einen Schieberegler für Medienbenachrichtigungen hinzu, der die aktuelle Position angibt und deren Änderung ermöglicht - Verwendet den Systemstil - Wendet keinen benutzerdefinierten dünnen Stil auf den Schieberegler an - Benachrichtigungsleiste automatisch öffnen - Öffnet automatisch die Benachrichtigungsleiste bei Benachrichtigungen von ausgewählten Apps - Berücksichtigung bei Vollbild - Öffnet die Benachrichtigungsleiste nicht, wenn die Vollbild-App aktiv ist (gilt nicht für immersive Apps mit verstecktem Status und Navigationsleisten) - Ausgewählte Apps - Screenshots - Screenshot-Konfiguration - Anpassung von Format, Qualität und Speicherverzeichnisse für Screenshots - Format - Qualität - Speicherverzeichnis - Einblendungen/Overlays auf Screenshots ausblenden - Temporäres Ausblenden von Einblendungen/Overlays während der Aufnahme eines Screenshot - Anzeigezeit des Screenshots nach der Aufnahme - Verzögerung, bevor Voransichtsfenster nach erstelltem Screenshot ausgeblendet wird - Zeitlimit für Ladeanimation - Wie lange der Bildschirm nach dem Start der Ladeanimation eingeschaltet bleiben soll - USB-Verbindung schaltet Bildschirm nicht ein - Schaltet Bildschirm nicht ein, wenn ein USB-Gerät angeschlossen oder getrennt wird - Kopfhörer-Verbindung schaltet Bildschirm nicht ein - Schaltet Bildschirm nicht ein, wenn ein Kopfhörer angeschlossen oder getrennt wird - Zeitlimit für das Ausschalten des Sperrbildschirm - Abdunklungsdauer des Bildschirms - Wie lange der Bildschirm gedimmt bleiben soll, bevor er automatisch ausgeschaltet wird (in Prozent des gesamten Zeitlimits bis zum Ausschalten des Bildschirms) - Autom. Helligkeitsbereich - Festlegen der minimalen und maximalen Werte für die automatische Helligkeit - autom. Helligkeit (Minimum) - autom. Helligkeit (Maximum) - Verwendet stets einen nicht-linearen Maßstab - Aktivieren, wenn die Prozente der Helligkeitseinstellung in diesem Modul nicht mit den tatsächlichen übereinstimmt (in Android-Versionen unter 9) - Deaktiviert Warnung vor zu hoher Lautstärke - Gefahrenhinweis nicht anzeigen, wenn die Lautstärke einen bedenklichen Wert erreicht - Lautstärke absenken deaktivieren - Verringert nicht die Lautstärke der aktuell wiedergegebenen Musik, wenn ein Benachrichtigungston abgespielt wird - Sofortige Lautstärkeanpassung - Passt die Medien-Lautstärke beim ersten Druck der Lautstärketasten an - Getrennte Lautstärkeregler - Erweitert die Konfiguration für die separate Lautstärke von Klingeltönen, Benachrichtigungen und Systemtöne in den Einstellungen - Schieberegler für die Benachrichtigungslautstärke - Fügt dem Lautstärke-Dialogfeld einen weiteren Regler für die Benachrichtigungslautstärke hinzu - Timerfunktion hinzufügen - Fügt im Lautstärke-Dialogfeld einen Timer (Countdown) für die Modi \"Lautlos\" und \"Bitte nicht stören\" hinzu - Lautstärken-Schritte Multiplikator - Ändert die Anzahl der Lautstärken-Schritte für jeden Stream-Typ - Musikvisualisierer - Dynamische Darstellung von Grafiken und Animationen auf der Basis von Audiodaten - Visualisierer wird über das Hintergrundbild des Sperrbildschirms gelegt - Auf Sperrbildschirm anzeigen - Zeigt eine Visualisierung im oberen Bereich des benutzerdefinierten Sperrbildschirms - In Benachrichtungsleiste anzeigen - Zeigt zusätzlich eine Visualisierung in der Benachrichtigungsleiste - Nur anzeigen, wenn Audio Apps vorhanden sind - Audio Player erstellen normalerweise Benachrichtigungen mit Mediensteuerung - Animationsdauer - Transparenz - Rendering-Methode - Stil - Leuchtintensität - Farbverlauf - Benutzerdefinierte Farbe auswählen - Dynamisches Farbwechsel-Intervall - Ignoriere Anrufe - Hindert eingehende Anrufe daran, den Audiofokus bei ausgewählten Apps zu verstellen und beendet die Benachrichtigung über Änderungen des Anrufstatus - Kein Vibrationsfeedback - Vibriert nicht, wenn Klingelton auf lautlos gestellt oder Vibrationsmodus aktiviert wird - Gedämpfte Vibration - Reduziert die Vibrationsintensität während der ausgewählten Stunden - Vibrationsintensität - Ändert entweder die Dauer oder die Stärke der Vibration in Abhängigkeit von der Unterstützung der Amplitudensteuerung durch das Gerät - Anrufe - Benachrichtigungen - Alles andere - Zeitraum - Blockiere Vibrationen - Verhindert, dass ausgewählte Apps Vibrationen verwenden - Systemtöne - Zufällige Anzeige des PIN-Eingabefeldes - Ändert die Reihenfolge der PIN-Tasten nach dem Zufallsprinzip - Erweiterte Bildschirmsperre - Deaktiviert das Power-Menü, während Bildschirm gesperrt ist - Kein Passwort nach Neustart - Es wird kein Kennwort anstelle eines Fingerabdrucks nach erstem Start benötigt. Funktioniert wahrscheinlich nicht auf verschlüsselten Geräten. - Albumcover als Hintergrundbild - Zeigt das Albumcover des aktuell wiedergegebenen Titels als Hintergrundbild auf dem Sperrbildschirm an - Graustufen - Konvertiert Albumcover in schwarz/weiß-Bilder - Albumcover verschwommen darstellen - Albumcover skalieren - Anmeldeinformationen entsperren - Die Authentifizierung in einigen Apps erfordert den Zugriff auf Anmeldeinformationen, diese bleiben jedoch gesperrt, wenn PIN/Kennwort/Muster nach dem Start übersprungen wird. Die aktuelle Option fügt ein Startsymbol hinzu, mit dem Legitimation entsperrt wird. - Benutzerdefinierte Aktionen - Anpassbare Aktionen für Verknüpfungen und Wischbewegungen - Deaktiviert die Wischbewegung nach links - Wischbewegung nach links - Ändert rechtes Verknüpfungssymbol - Ersetzt das Kamerasymbol durch das CustoMIUIzer-Symbol - Ziehe das Symbol, um eine benutzerdefinierte Aktion auszuführen - Deaktiviert die Wischgeste nach rechts - Verknüpfungen auf dem linken Bildschirm - Verknüpfungen verwalten - Vertikale Ausrichtung - Entsperren nicht erforderlich - Auf gestartete Apps kann zugegriffen werden, während das Gerät noch gesperrt ist - Deaktiviert die Bildschirmsperre - Einige Geräte funktionieren möglicherweise nicht, ohne sie nach dem Start einmal zu entsperren - Bildschirmsperre selektiv deaktivieren (ändert nicht die Sicherheit einer App und entfernt keine Fingerabdruckdaten) - Sperrbildschirm überspringen - Sperrbildschirm überhaupt nicht anzeigen, wenn die Bildschirmsperre deaktiviert ist - Vertrauenswürdige Wi-Fi-Netzwerke - Während der Verbindung mit diesen Netzwerken wird vorübergehend die Bildschirmsperre deaktiviert - Vertrauenswürdige Bluetooth-Geräte - Während diese Geräte angeschlossen sind, wird vorübergehend die Bildschirmsperre deaktiviert - Sperrung erzwingen - Entsperrung erzwingen - nicht erzwingen - Bildschirm Ausschaltanimation - Konfiguriert die Animationslänge - Sehr niedrige Werte deaktivieren die Animation nahezu - Unschärfe des Hintergrundes - Intensität der Hintergrundunschärfe der zuletzt verwendeten Apps - Intensität der Hintergrundunschärfe in der Benachrichtigungsleiste - Themenhintergrund vorübergehend ausblenden - Hintergrund ausblenden, während die Helligkeit geändert wird - Hintergrunddeckkraft - Deckkraft des themenbezogenen Hintergrundes für die Benachrichtigungsleiste - Sperrbildschirm - Zusätzliche Funktionalität - Sicherheit - Zusätzliche Elemente - Fügt Symbol und/oder App-Namen den Popup-Meldungen hinzu - Blockiere Popup-Meldungen - Verhindert, dass ausgewählte Apps Popup-Meldungen anzeigen - Dark Mode - Ändert den Anzeige in dunkel, hell oder automatisch. Kein Neustart erforderlich. - Dark Mode-Kachel - Fügt eine Kachel den Schnelleinstellungen hinzu, um den Dark Mode ein-/auszuschalten. Kein Neustart erforderlich. - Erweitertes Power-Menü - Fügt dem Power-Menü neue Optionen hinzu (Fastboot-Modus, Wiederherstellungsmodus, Soft-Neustart, System-Benutzeroberfläche neu starten, Launcher neu starten) - Downgrade zulassen - Ermöglicht die Installation einer älteren App-Version über einer neueren - Signaturüberprüfung deaktivieren - Ermöglicht die Aktualisierung der App, auch wenn sich die APK-Signatur von der installierten unterscheidet - Textlupe - Zeigt vergrößerten Text an, wenn der Eingabecursor bewegt oder eine Auswahl getroffen wird - Weiterrollen (Overscroll) deaktivieren - Verhindert, das über das Ende einer Liste bzw. der Listenansicht hinaus gerollt werden kann - Deaktiviert den Schutz sicherer Inhalte - Erlaubt Screenshots und Videos von beliebigen Apps zu erstellen - Warnung vor niedrigem Batteriestand ausblenden - Die Aufforderung, den Batteriesparmodus einzuschlaten, wird deaktiviert - Versteckt Warnung, dass der Kopfhörerbereich von etwas bedeckt ist - Zeigt keine Warnung an, dass der Bereich des Ohrlautsprechers verdeckt ist - Frei skalierbares Widget - Entfernt alle Widget-Größenbeschränkungen - Entsperrt Launcherbeschränkung - Entfernt die Einschränkung, Launcher von Drittanbietern auf chinesischen ROMs zu installieren - Freigabemenü bereinigen - Entfernt ausgewählte Apps aus dem Freigabemenü - Test-Menü - Öffnen-mit-Menü bereinigen - Entfernt ausgewählte Apps aus dem Öffnen-mit-Menü - Wähle den Testdatentyp - Auszublendenden Datentyp auswählen - Standard USB-Konfiguration - Wendet die ausgewählte Konfiguration an, wenn ein USB-Gerät angeschlossen wird - Ignoriere Sperrung - Anwenden, auch wenn das Gerät noch gesperrt ist - RNDIS (USB Tethering) - Erzwungenes Schließen von Apps verhindern - Lässt nicht zu, dass MIUI-Aktionen ausgewählte Apps schließen - Rotationsanimation - Sämtliche Bildschirmdrehungen - Erlaubt sämtliche Bildschirmdrehungen einschließlich des umgekehrten Hochformats - Ausrichtungssperre - Fügt eine Kachel in den Schnelleinstellungen hinzu, mit der die Ausrichtung im Hoch- oder Querformat gesperrt werden kann - Benachrichtigungen behalten - Zeigt Benachrichtigungen auf dem Sperrbildschirm an, auch nachdem dieser geschlossen und dann wieder geöffnet wurde - Direkte Antwort ohne Entsperren - Das Entsperren des Geräts ist nicht erforderlich, um die direkte Antwortfunktion von Apps auf dem Sperrbildschirm zu benutzen - Benachrichtigungen auf Sperrbildschirm zulassen - Erzwingt, dass alle Benachrichtigungen von MIUI-Apps auf dem Sperrbildschirm angezeigt werden - Schwebende Benachrichtigungen auf Sperrbildschirm zulassen - Erzwingt, dass alle Benachrichtigungen von MIUI-Apps als schwebende Benachrichtigungen angezeigt werden - Oberen Block ausblenden - Entfernt den oberen Block mit Uhr, Datum und anderen Daten - Keine Notrufe - Deaktiviert die Notruftaste auf dem Sperrbildschirm - Bereinigt die Ansicht des erweiterten Modus - Schieberegler für Schnelleinstellungen und Helligkeit im erweiterten Benachrichtigungsmodus auf dem Sperrbildschirm ausblenden - Deaktiviert farbigen Hintergrund - Ändert den Hintergrund des Sperrbildschirms mit einer automatisch erzeugten Farbe aus dem Hintergrundbild in ein transparentes - Tippen, um zu entsperren - Entsperrt das Gerät durch Tippen im unteren Bereich des Sperrbildschirms - Doppelt tippen, um Display auszuschalten - Schaltet Bildschirm durch zweimaliges Tippen auf eine leere Stelle im Sperrbildschirm aus - Nächsten Alarm anzeigen - Zeigt die nächste Alarmzeit neben dem aktuellen Datum an - Formatierung anzeigen - Sämtliche Alarme anzeigen - Holt sich die nächste Alarmzeit über die Standard-Android-API, wenn MIUI-Alarm nicht eingestellt ist. Kann zu unerwarteten Ergebnissen führen. - Statusleiste und Benachrichtungsleiste - Statusleiste - Benachrichtungsleiste - Benachrichtigungen - Liste der zuletzt verwendeten Apps - Verwendet systemeigene Implementierung - Verwendet nicht die Liste der zuletzt verwendeten Apps vom MIUI Launcher - Entfernen-Schaltfläche nicht anzeigen - Schaltfläche zum Löschen der zuletzt verwendeten Apps ausblenden - Alles löschen - Stellt sicher, dass die Entfernen-Schaltfläche alle laufenden Apps und Aufgaben beendet - Apps aus der Liste der zuletzt geöffneten Apps ausblenden - Verstecke ausgewählte Apps aus der Liste der zuletzt geöffneten Apps/Aufgaben - Aktion für erste Verknüpfung - Aktion für den ersten Verknüpfungsvorschlag - Aktion für zweite Verknüpfung - Aktion für den zweiten Verknüpfungsvorschlag - Aktion für dritte Verknüpfung - Aktion für den dritten Verknüpfungsvorschlag - Aktion für vierte Verknüpfung - Aktion für den vierten Verknüpfungsvorschlag - Popup-Benachrichtigungen - Verzögerung beim autom. Ausblenden - Automatisches Ausblenden deaktivieren - Popups nicht automatisch schließen - Nach unten Wischen aktivieren - Öffnet Benachrichtungsleiste durch Wischgeste nach unten - App-Sperre - Weniger strenge App-Sperre - Bei gesperrtem Gerät werden Apps nicht gesperrt, wenn die Option \"App-Sperre\" ausgewählt ist - Zeitlimit für App-Sperre - Zeitintervall, in dem die App nach dem Beenden entsperrt bleibt - Liste der zu sperrenden Apps - Erweiterte Version der App-Sperroption, mit der jede installierte App gesperrt werden kann. - Schnelleinstellungen - Anzahl der Reihen - Beschriftungen werden ab 5 Zeilen im Hochformat und ab 3 Zeilen im Querformat ausgeblendet. - Anzahl der Spalten - Querformatausrichtung enthält eine zusätzliche Spalte. Wenn ROM über eine kompakte Layoutoption für die Schnelleinstellungen verfügt, wird in beiden Ausrichtungen eine weitere Spalte hinzugefügt. - Anzahl der Spalten im reduzierten Bereich - Die Querformatausrichtung erthält eine zusätzliche Spalte - Beschriftungen vollständig entfernen - Haptisches Feedback für Schnelleinstellungen - Beim Tippen auf Schnelleinstellungen vibrieren - Verschiedenes - Hintergrundunschärfe des Lautstärkedialogs - Eingeklappte Lautstärkeauswahl - Erweiterte Lautstärkeauswahl - Animationsumfang - Fenster - Übergänge - Animationswert - POCO Launcher - MIUI Launcher - Gesten - Aktion - Einstellung zum Umschalten - App zum Starten - Verknüpfung zum Starten auswählen - Aktivität zum Starten - Launcher - Mods für den ausgewählten Launcher anzeigen. Nur zur visuellen Unterstützung - hat keinen Einfluss auf Mods. - Kompatibilitätsmodus - Alternative Methode zum Anwenden aller Launcher-Mods - Unbegrenztes Scrollen - Springe vom Seitenende zum Seitenanfang und umgekehrt - Uhr nicht ausblenden - Versteckt nicht die Uhr in der Statusleiste auf Seiten mit Uhr-Widgets - Aktiviert Google Discover - Ersetzt \"App Vault\" durch Google Discover (erfordert die Installation der Google App) - \"Widget only\" Startbildschirme deaktivieren - Stellt sicher, dass auf Tablets jeder Startbildschirm sowohl Widgets als auch Apps unterstützt - Entfernt Entsperranimation - Wenn das Gerät entsperrt ist, werden keine Symbole animiert - Verwendet alte Launcheranimation - Setzt die Veränderung zum Öffnen der App auf vorherigen Wert zurück - Unterstützung für umgekehrtes Porträt - Lässt das Rotieren der Porträtausrichtung des Launchers zu - Dynamische Seitenanzeige - Seitenanzeige nur während des Bildlaufs anzeigen - Nur im Bearbeitungsmodus anzeigen - Schaltet Rastergrößen frei - Stellt alle Rastergrößen von 3x4 bis 10x10 in der Layouteinstellung des Startbildschirms zur Verfügung - Weitere Symbole im Dock - Unbegrenzte Anzahl von Dock-Symbolen - Skalierung von Symbolen - Horizontaler Gitterrand - Oberer Gitterrand - Unterer Gitterand (Dock) - Höhe der Seitenanzeige - Ordner - Anzahl der Spalten in Ordnern - Verwendet die gesamte Ordnerbreite - Seitenauffüllung reduzieren - Statusleistenmodus korrigieren - Passt die Farbe der Statusleiste für helle/dunkle Hintergrundbilder des Launchers in der Developer-Version an - Animation korrigieren - Wendet die Dauer des Animationswertes auf einige Launcher-Animationen an - App-Info korrigieren - Öffnet immer App-Infos im MIUI-Stil durch langes Drücken der Menü-Taste - Farbschicht - Hintergrund abdunkeln oder aufhellen - Farbintensität - Verwischen - Optionen für Hintergrund- und Hintergrundbildunschärfe. Launcher muss Unschärfe in Ordnern unterstützen. - Unschärfe des Hintergrundes - Unschärfe des Hintergrundbildes - Sichtbarkeit - Radius - Beeinflusst auch die Hintergrundbildunschärfe im Bearbeitungsmodus - Ordner automatisch schließen - Schließt den Ordner aus dem die App gestartet wurde - App-Namen - Titel ausblenden - Namen im Dock anzeigen - Schriftgröße - Zusätzlicher oberer Rand - Dunklerer Schatten - Macht den Titelschatten weniger transparent - Benutzerdefinierte App-Namen - Geänderte App-Titel - Geänderter Titel - Versteckte Apps - Erforderliche Berechtigungen wurden nicht erteilt - Kein versteckter Apps Ordner - Deaktiviert die Zwei-Finger-Geste, mit der der versteckte Apps Ordner geöffnet wird - Liste der versteckten Apps - Erweitert die \"Versteckte Apps-Option\", mit der jede installierte App ausgeblendet werden kann. Es ist kein Neustart erforderlich. - Nach unten wischen (1 Finger) - Aktion auswählen - anzuwenden auf beliebigem Startbildschirm - Nach unten wischen (2 Finger) - Aktion auswählen - anzuwenden auf beliebigem Startbildschirm - Nach oben wischen (1 Finger) - Aktion auswählen - anzuwenden auf beliebigem Startbildschirm - Nach oben wischen (2 Finger) - Aktion auswählen - anzuwenden auf beliebigem Startbildschirm - Nach rechts wischen - Aktion beim Wischen nach rechts auf dem Launcher-Dock - Nach links wischen - Aktion beim Wischen nach links auf dem Launcher-Dock - Schütteln - Aktion beim Schütteln des Geräts auf einem beliebigen Startbildschirm - Doppelt tippen - Aktion beim doppelten Tippen auf den leeren Bereich eines Startbildschirms - Fehlerkorrektur - Steuerung - Doppelt drücken-Aktion - Ersetzt die Funktion \"Kamera-App starten durch zweimaliges Drücken der Ein-/Aus-Taste\". Diese Funktion muss in den Systemeinstellungen aktiviert sein. - Screenshot deaktivieren - Keine Bildschirmaufnahme erstellen, wenn die Ein-/Aus-Taste zusammen mit der Lautstärketaste gedrückt wird - Taschenlampe - Bei ausgeschaltetem Bildschirm die Ein-/Aus-Taste lange drücken, um Taschenlampe einzuschalten - Start des Einschalten der Taschenlampe verzögern - Verzögert den Start der Taschenlampe beim Drücken der Ein-/Aus-Taste - Fingerabdruck-Scanner - Einzeltipp-Aktion - Aktion für ein einzelnes Tippen, wenn der Bildschirm eingeschaltet ist - Doppeltipp-Aktion - Aktion für ein doppeltes Tippen, wenn der Bildschirm eingeschaltet ist - Doppeltipp-Verzögerung - Einzeltipp-Aktion wird um diesen Wert verzögert - Lange drücken-Aktion - Aktion für langes Drücken, wenn der Bildschirm eingeschaltet ist - Lange drücken-Verzögerung - Obige Aktionen in Kamera-App deaktivieren - Aktivieren, wenn Fingerabdrucksensor als Aufnahmetaste dienen soll - Keine Aktionen während Anruf - Führt keine Aktionen aus, wenn ein Anruf aktiv ist - Eingehenden Anruf annehmen - Eingehenden Anruf ablehnen - Anruf beenden - Annehmen und Ablehnen von Aktionen kann nicht dieselbe Kombination haben. - Aktion annehmen wurde deaktiviert. - Aktion ablehnen wurde deaktiviert. - Bildschirm einschalten nach Fehler - Bildschirm wird bei fehlgeschlagener Authentifizierung eingeschaltet - Benötigt hinterlegte Fingerabdrücke - Schaltet Bildschirm nur ein, wenn tatsächlich Fingerabdrücke gespeichert sind - Vibriert bei erfolgreichem Login - Stärke des haptischen Feedback bei erfolgreicher Authentifizierung - Ignoriere Systemeinstellungen - Haptische Rückmeldung werden nicht deaktiviert, wenn \"Vibration bei Berührung\" deaktiviert ist - Keine Vibration bei Fehler - Bei Authentifizierungsfehler haptisches Feedback entfernen - Ein-/Aus-Taste - Lautstärketasten - Textcursor steuern - Textcursor mittels Lautstärketasten in Textfeldern steuern - Richtung ändern - Tauscht Richtung der Cursorbewegungen - Mediensteuerung durch Lautstärketaste (Vol+) - Aktion bei gedrückter Lautstärketaste (lauter), wenn der Bildschirm ausgeschaltet ist - Mediensteuerung durch Lautstärketaste (Vol-) - Aktion bei gedrückter Lautstärketaste (leiser), wenn der Bildschirm ausgeschaltet ist - Vibration bei langem Druck - Vibriert, wenn ein langer Druck ausgeführt wird - Navigationsleiste - Navigationsleiste ausblenden - Zurück-Taste - Wechselt im Eingabemodus das Symbol der Zurück-Taste in ein alternatives Symbol - Höhe der Navigationsleiste - Aktion Zurück-Taste (lange gedrückt) - Aktion Home-Taste (lange gedrückt) - Aktion Menü-Taste (lange gedrückt) - Aktion der zusätzlichen linken Taste in der Navigationsleiste (einfacher Druck) - Zusätzliche linke Taste - Aktion der zusätzlichen linken Taste in der Navigationsleiste (langer Druck) - Zusätzliche linke Taste (lange gedrückt) - Aktion der zusätzlichen rechten Taste in der Navigationsleiste (einfacher Druck) - Zusätzliche rechte Taste - Aktion der zusätzlichen rechten Taste in der Navigationsleiste (langer Druck) - Zusätzliche rechte Taste (lange gedrückt) - Zusätzlicher Spielraum - Erhöht den Abstand von den Bildschirmkanten für zusätzliche Schaltflächen - Keine Aktion definiert - Vollbild-Navigationsgesten - Feldhöhe für Zurück-Geste - Feldbreite für Zurück-Geste - Horizontale Gesten - Aktiviert sowohl horizontale Gesten als auch die Navigationsleiste - Verschiedenes - Xiaomi System Updater App - Die App ist nicht mehr Bestandteil einiger ROMs und muss vor Nutzung manuell installiert werden. Danach kann sie hier geöffnet und konfiguriert werden. - Vorsicht beim Updaten von System-Apps auf Custom ROMs. Dies führt möglicherweise zu Verlust hinzugefügter Funktionalitäten. - Verwende MIUI Packetinstaller - Xiaomi-Paketinstaller als Standard-Installer definieren und ihn System-Apps aktualisieren lassen - Erforderliche App ist nicht installiert. Lange drücken für Download. - App-Infos im Packetinstaller - Zeigt Informationen über die App an, die installiert werden soll - Paket - Versionsname - Versionscode - Unterstütztes SDK - Aktuell - Wecker Kompatibilität - Stellt sicher, dass auswählbare Apps die Alarmzeiten korrekt anzeigen, die von der serienmäßigen Wecker-App eingestellt wurden - Anruf-Benutzeroberfläche anzeigen - Legt fest, wann die Benutzeroberfläche für eingehende Anrufe anstelle einer Popup-Benachrichtigung angezeigt werden soll - Bildschirmhelligkeit während Anruf - Anruftypen - Helligkeitswert - Nacht-Modus - Ändert nachts nicht die Helligkeit - Start - Ende - Erinnerung für verpasste Anrufe - Definiert Sound, Vibration und Intervall der Erinnerung - Intervall - Töne - Kein Ton - Eigenes Muster - Format: Verzögerung, Vibration, Verzögerung, Vibration, … - App-Status erweitern - Ermöglicht das Deaktivieren fast jeder App auf ihrer Infoseite (App-Info) - Zusätzliche App-Details anzeigen - Fügt neue Felder zu App-Infos hinzu:\n(> Einstellungen > Apps > Apps verwalten > App auswählen > (i) oben rechts)\n- Option zum Starten einer App\n- vollständiger Pfad zur Apk\n- Pfad zu App-Data\n- User ID\n- Ziel-SDK-Version - Sortierreihenfolge installierter Apps - App deaktivieren? - Wenn dies eine wichtige System-App ist, kann das Deaktivieren zu Problemen führen :-) - Das ist eine schlechte Idee! :-) - App-Status konnte nicht geändert werden - Im Playstore öffnen - Start - App hat keine standardmäßige startfähige Aktivität - APK Dateiname - Datenverzeichnis - UserID - Ziel SDK-Version - Status (Standard) - App-Name - Nutzungshäufigkeit - Verwendeter Speicher - Installationszeitpunkt - Anrufe - Einstellungen - Standard - System - Keine Aktion - Erweitert/zeigt Benachrichtigungsleiste - Erweitert/zeigt Schnelleinstellungen - Sperrt das Gerät - Ruhezustand - Screenshot erstellen - Menü anzeigen - Zuletzt verwendete Apps - Lautstärkeauswahl - Lautstärke erhöhen - Lautstärke verringern - App starten - Verknüpfung starten - App-Aktivität starten - Funktion umschalten - Zur vorherigen App wechseln - Power-Menü - Power Menü - Speicher löschen - Farben umkehren - Keyboard wechseln - Gehe zurück - Einhandmodus (links) - Einhandmodus (rechts) - Bluetooth - Ton-Profil - Automatische Helligkeit - Automatische Drehung - Taschenlampe - Mobile Daten - Symbol - App-Name - Symbol und App-Name - Keine - Verblassen - Keine Änderung - Play/Pause - Nächster Titel - Vorheriger Titel - Alle Ladeereignisse - Nur Ereignisse ohne Animation - System - Vollständig deaktivieren - Nach dem Start ist eine Authentifizierung erforderlich - In vertrauenswürdigen Netzwerken deaktivieren - Nicht erforderlich - schwach (Fingerabdruck) - stark (PIN/Passwort/Muster) - Keine Unschärfe - Keine Symbole - Gesamter Hintergrund - Nur in der Mitte - Für alle Apps außer den ausgewählten - Für alle ausgewählte Apps - Nur ausblenden, wenn keine Verbindung besteht - Vollständig ausblenden - Nicht gruppieren - Leichte Vibration - Starke Vibration - Zulassen - Deaktiviert - Weiter oben - In der Mitte - Am Ende - Maximum - Groß - Normal - Klein - Niedrig - Durchschnittlich - Hoch - Passt die Farben entsprechend dem Albumcover oder Hintergrundbild ans - - benutzerdefinierte Farben - Regenbogenfarben (horizontal) - Regenbogenfarben (vertikal) - Regenbogen - dynamische Farben - getrennt - übergehend - volle Balken - volle und abgerundete Balken - gestrichelte Balken - Kreise - Linie - Niemals - Für 1 Tag nach dem Update - Für 3 Tage nach dem Update - Für 1 Woche nach dem Update - Immer - Foto - Audio - Video - Dokument - Archiv - Link - Alle - Verschiedenes - Wenn nicht im Vollbildmodus - Eingehend - Ausgehend - Beide - Keine Vibration - Einfach (kurz) - Einfach (lang) - Ticktock - Herzschlag - Walzer - Zig-Zig-Zig - Eigenes Muster - Vollbild - Deckt gesamten Bildschirm ab - Oben - Unten - Helligkeit anpassen - Lautstärke anpassen - Reguläre Zeit - Relative Zeit - Einmal tippen - Doppelt tippen - Lange drücken - Neujahr - Chinesisches Neujahr - Anzeigen - Ausblenden - automatisch erkennen - Anhängen - Voranstellen - Als neue Zeile einfügen - Ausgewähltes Verzeichnis - Wi-Fi aktiviert - Wi-Fi deaktiviert - Bluetooth aktiviert - Bluetooth deaktiviert - GPS aktiviert - GPS deaktiviert - NFC aktiviert - NFC deaktiviert - Ton-Profil: Normal - Ton-Profil: Lautlos - Ton-Profil: Vibration - Automatische Helligkeit aktiviert - Automatische Helligkeit deaktiviert - Automatische Drehung aktiviert - Automatische Drehung deaktiviert - Taschenlampe aus - Taschenlampe an - Mobile Daten aktiviert - Mobile Daten deaktiviert - Rotationssperre - Uneingeschränkt - Hochformat - Querformat - Dark Mode - CustoMIUIzer hat keine Berechtigung, den Dark Mode zu ändern - CustoMIUIzer Einstellungen - Markiere neue Mods - Zeigt \"Neu!\"-Hinweis für Mods, die in der aktuellen Version hinzugefügt wurden - Neu! - CustoMIUIzer Symbol im Launcher - Zeige Symbol in Launchern - Position des CustoMIUIzer Symbols - Zeige Symbol in den Einstellungen - Spracheinstellungen - Zeigt CustoMIUIzer in der ausgewählten Sprache - Darstellungsschema - Oberfläche je nach Anlass dekorieren - Fehlerbehebung - Detaillierten Bericht senden - Sammelt Geräte- und Umgebungsinformationen, Logcat und Xposed-Protokoll und sendet sie an den Entwickler. Eine Internetverbindung ist erforderlich. - Kontaktinformationen eingeben, damit diese in detaillierten Absturzberichten aufgenommen werden - Kontaktinformationen - Es ist unbedingt erforderlich dies auszufüllen, wenn Antworten auf Absturzberichte erwartet werden. Verwendung von E-Mail, ICQ, XDA- oder 4PDA-Accountname. - Support - CustoMIUIzer Repo - Git-Repository mit Modulquellen und Distributionen - XDA Thread - Modul Thread im XDA-Forum - 4PDA Thread - Modul Thread im 4PDA-Forum - Technischen Fehler melden - Sendet einen Fehlerbericht oder eine Funktionserweiterungsanfrage über den offiziellen Fehler-Tracker - Spende $%1$d - Spenden - Der beste Weg, um die Dankbarkeit für dieses großartige Modul auszudrücken :-) - App-intern - Google erledigt alles - Kryptowährungen - Geld der Zukunft :-) - Veraltete Währungen - Vielen Dank für Ihre Spende! - Vielen Dank für deine großzügige Spende! - Vielen Dank für deine wahnsinnig großzügige Spende! 😮 - Rechnungsinformationen konnten nicht abgerufen werden. Überprüfe deine Internetverbindung! - Meinung geändert? ;-) - CustoMIUIzer ist soeben abgestürzt! - Alle notwendigen Daten wurden gesammelt - Generierte Größe des Berichtes - Problembeschreibung (wenn möglich in Englisch): - Hergang beschreiben, der zu diesem Absturz geführt hat\n(wenn möglich auf Englisch): - Kontaktinformationen werden nicht übermittelt, es werden keine Antworten auf diesen Bericht erfolgen! - Eine Internetverbindung ist erforderlich - Beschreibung darf nicht leer sein - Ignorieren - Sende Bericht - Ergebnis senden - Bericht wurde erfolgreich gesendet! - Fehler beim Senden des Berichtes - Bestätigung - Bericht wird generiert… - Bericht wird gesendet… - Automatisch - Dunkel - Hell - MIUI SDK kann nicht initialisiert werden.\nKein Xiaomi Gerät? - nichts ausgewählt - Warnung! - Die Option \"black/white list\" ist in (Ed)Xposed Framework aktiv und kann verhindern, dass Mods ordnungsgemäß funktionieren. - Öffne (Ed)Xposed Module - Soft-Neustart - Soft-Neustart jetzt ausführen? - Restart Launcher - Einstellungen verwalten - Einstellungen sichern/wiederherstellen - Sichern - Wiederherstellen - Externer Speicher ist schreibgeschützt - Zugriff auf einen geeigneten Speicher nicht möglich - Sicherungsverzeichnis konnte nicht erstellt werden - Fehler beim Erstellen der Sicherungsdatei - Keine Sicherung gefunden - Einstellungen wurden erfolgreich gesichert! - Einstellungen wurden erfolgreich wiederhergestellt! - Einstellungen wurden über Google Cloud Backup wiederhergestellt. Nach dem Aktivieren des Xposed-Moduls ist ein Soft-Neustart durchzuführen. - Update ist verfügbar ⚠ - Wähle App(s) aus - Wähle App(s) aus - Aktivität auswählen - Keine Aktivitäten gefunden - Verknüpfung auswählen - Durchsuche Mods - Wi-Fi Netzwerke - Standorteinstellungen - Für Apps ist ein Standortzugriff erforderlich, um eine Liste der Wi-Fi-Netzwerke in Android Pie abzurufen - Vertrauenswürdige Netzwerke - Verfügbare Netzwerke - Geräteliste abrufen - Liste der zwischengespeicherten Bluetooth-Geräte vom System abrufen - Vertrauenswürdige Geräte - Verfügbare Geräte - Bluetooth-Geräte - Bluetooth wird auf diesem Gerät nicht unterstützt - Schalte erst Bluetooth ein - Schalte erst Wi-Fi ein - Ohne Standortzugriff kann nicht gescannt werden - Erzwungenes Schließen %s - Berechtigungen sind bereits freigeschaltet - Berechtigungen freischalten - Berechtigungen freigeschaltet! - (Ed)Xposed App wurde nicht gefunden - Es sieht so aus, als wäre das (Ed)Xposed Framework nicht installiert.\nMods funktionieren nur mit Xposed! - Ressourcen-Hooks sind deaktiviert - Ressourcen-Hooks sind in den Xposed Installer-Einstellungen deaktiviert, das Modul wird nicht aktiviert! - CustoMIUIzer-Modul ist nicht aktiviert! -\nÖffne (Ed)Xposed App, aktiviere Modul und starte Gerät neu (Reboot). - Browser-App muss vorhanden sein, um URLs zu öffnen - Okay - Abbruch - Hinzufügen - Löschen - Lange drücken um zu Löschen - Symbol ändern - Suche Mods nach Name.\nLange drücken, um eine Liste der neuen Mods anzuzeigen. - Nicht vergessen, Mods durch Soft-Neustart zu aktivieren.\nDynamische Mods ⟲ benötigen nur einen Neustart. Weitere Informationen befinden sich unter <Über>. - New mods since previous update -\ncan be marked for better visibility - Backup ertellen? - Backup wiederherstellen? - Liste der Netzwerke/Geräte erhalten? - Du musst die Berechtigung für diese Option jetzt manuell aktivieren. Gut gemacht! - %d ms - %d s - %d m - %d KB/s - 1 KB/s - B/s - KMGTPE - %s lux - Aus - 30 Minuten - 1 Stunde - 2 Stunden - 3 Stunden - 4 Stunden - 5 Stunden - 6 Stunden - 8 Stunden - 10 Stunden - 12 Stunden - weiß - schwarz - Farbe der Statusleiste - \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml deleted file mode 100644 index 4150d91a..00000000 --- a/app/src/main/res/values-es/strings.xml +++ /dev/null @@ -1,1048 +0,0 @@ - - - Acerca de - Versión %1$s - por Mikanoshi - En general, las modificaciones requieren un reinicio completo para activarse o desactivarse, pero las que están marcadas con ⟲ solo requieren un reinicio suave una vez cambiado de predeterminado a personalizado, los cambios posteriores se aplican inmediatamente. - Las modificaciones marcadas con un ⨯ no son compatibles con este dispositivo. - Notificaciones pospuestas - Actualizar - Anular esta notificación - Marcar como cancelada - Marcar como pendiente - No se puede recuperar la lista de notificaciones pospuestas - No hay notificaciones pospuestas - Mensajes - Canal - Creado - Actualizado - Volver a publicar - Modificaciones - Acciones - Activar modificación - Sistema - Pantalla - Rotación - Iluminación de pantalla - Audio - Vibración - Notificaciones flotantes - Ocultar iconos - Administrar la visibilidad de los iconos de la barra de estado - Imagen de la batería - Porcentaje de carga de la batería - Indicador de carga - Se puede superponer sobre la imagen de la batería en algunas ROMs - Alarma - Ocultar completamente - Visibilidad selectiva del icono de alarma - Muestra el icono de alarma solo durante el número definido de horas antes de la próxima alarma - Ocultar icono señal de red móvil - No hay SIM card - Punto de acceso - Perfil de trabajo - Perfiles de sonido - Modo No Molestar - Auriculares - Llamada: Micrófono silenciado - Llamada: Altavoz - Llamada: Grabando - Indicador de barra de batería - Muestra el nivel de carga de la batería como una barra de color - Visibilidad limitada - Mostrar solo en el cajón de notificaciones y en la pantalla de bloqueo - Extremos redondeados - Centrado - Altura de la barra - Espaciado horizontal - Color de carga completa - Color de carga baja - Color de ahorro de batería - Color de carga - Nivel de carga bajo - Prueba - Animar barra de 100% a 0% en estado de descarga - Altura de la barra de estado - Color de fondo de la barra de estado - Hace que los colores de fondo de la barra de estado y de la barra de navegación de la aplicación sean los mismos siempre que sea posible - Lista negra - Acceso directo de la aplicación - Abrir la aplicación seleccionada cuando se toca el ícono de acceso directo en el encabezado del cajón de notificaciones - Aplicación de reloj - Abrir la aplicación seleccionada cuando se toca el reloj en el encabezado del cajón de notificaciones - Aplicación de calendario - Abrir la aplicación seleccionada cuando se toca la fecha en la barra de notificaciones - Mostrar segundos en el reloj - Muestra los segundos en el reloj de la barra de estado - Límite de iconos de notificación - Número de iconos de notificación para mostrar antes de convertirlos en puntos - Ocultar el tipo de red - Elimina el icono de tipo de red de la barra de estado - Mostrar icono LTE para 4G - Ocultar indicador de iconos ocultos - No mostrar el icono de 3 puntos cuando los iconos de notificación están ocultos - Sin separador de velocidad de red - No mostrar una línea vertical entre el tiempo y el indicador de velocidad de red en dispositivos con un notch tipo gota - Intervalo de actualización de velocidad de red - Indicador de velocidad de red detallado - Mostrar las velocidades de red entrantes y salientes por separado - Tamaño de la fuente - Indicador de iconos - Los íconos de tráfico entrante/saliente se muestran junto al valor de la velocidad (no todas las fuentes personalizadas tienen todos los íconos) - Ocultar baja velocidad - No mostrar el indicador si la velocidad es baja - Nivel de baja velocidad - Los valores de velocidad por debajo de este nivel se considerarán bajos y tendrán un ícono de indicación diferente - Reduce la visibilidad cuando está inactivo - Hace que el indicador sea semitransparente cuando ambas velocidades dan cero - Controles por gestos - Realizar acciones seleccionadas al deslizar y tocar dos veces - Ajustar sensibilidad - Brillo - Volumen - Deslizamiento horizontal con un dedo - Deslizamiento horizontal con dos dedos - Acción de doble toque - Espaciado de velocidad de red - Aumenta los márgenes horizontales para el indicador de velocidad de red - Compactar notificaciones - Reduce el espaciado vertical de las notificaciones - Colorear el título de la notificación - Aplica el color del icono al texto del título (solo estilo de notificación de Android) - Recuperar la vista minimalista colapsada - Las notificaciones de importancia mínima podrían colapsarse en la vista de una línea nuevamente - Abrir ajustes de canal - Abrir la configuración desde el menú de notificaciones que conduce a la configuración del canal en lugar de la configuración de notificación común de la aplicación - Máxima cantidad de líneas en estilo de mensajería - Limitar el número de líneas mostradas en las notificaciones de estilo de mensajería - Ocultar botón de borrar notificaciones - Oculta el icono de borrar todas las notificaciones - Mostrar nivel de luminosidad - Muestra el valor de luz ambiental en lux dentro del control deslizante de brillo - Estilo alternativo - Texto semitransparente grande - Mostrar porcentaje de brillo - Mostrar el nivel de brillo en porcentajes mientras desliza el control deslizante de brillo - Porcentajes del margen superior del panel - Desactivar barra de brillo - Menú de notificaciones extendido - Añade \"información de la aplicación\" y \"forzar el cierre de la aplicación\" desde el menú de notificaciones (desliza la notificación hacia la izquierda para mostrar las opciones) - Deshabilitar cualquier notificación - Permitir deshabilitar las notificaciones del sistema también - Expandir notificaciones - Mostrar notificaciones completamente expandidas - Lista negra/blanca - Modificación del tiempo de visualización - Cambia tanto las duraciones cortas como las largas - La duración resultante no será inferior a 1 segundo - Agrupar notificaciones automáticamente - Número de notificaciones de una aplicación que activa la agrupación automática - Administrador de notificaciones pospuestas - Aumente el número de intervalos de repetición y agregue un icono al launcher que abra una lista de notificaciones pospuestas actualmente - Silenciar si es visible - No reproducir el sonido de notificación si la pantalla está encendida - Control deslizante de posición de medios - Agregar control deslizante de notificación de medios que indica la posición actual y permite cambiarla - Usar estilo de sistema - No aplique un estilo delgado personalizado para deslizar - Abrir barra de notificaciones automáticamente - Abre barra de notificaciones automáticamente en las notificaciones de las aplicaciones seleccionadas - Respetar pantalla completa - No abre barra de notificaciones cuando la aplicación de pantalla completa está activa (no se aplica a aplicaciones inmersivas con estado oculto y barras de navegación) - Aplicaciones seleccionadas - Contraer títulos de MIUI - Configurar el estado del título de la barra de acción en todas las aplicaciones MIUI 12 - Capturas de pantalla - Configuración de captura de pantalla - Personalice el formato, la calidad y dónde guardar las capturas de pantalla - Formato - Calidad - Guardar carpeta - Ocultar superposiciones en capturas de pantalla - Ocultar temporalmente superposiciones mientras toma una captura de pantalla - Tiempo de visualización de captura de pantalla flotante - Retraso antes de que desaparezca una ventana flotante con una captura de pantalla recién creada - Tiempo de espera de la animación de carga en pantalla - Cuánto tiempo se debe mantener la pantalla encendida después de comenzar la animación de carga - No despertar la pantalla al cargar - No enciende la pantalla cuando detecta la conexión o desconexión de un cargador - No encender la pantalla cuando se conecta un auricular - No encender la pantalla cuando detecta la conexión de un auricular - Pantalla apagada en pantalla bloqueada - Duración de la atenuación de iluminación - Cuánto tiempo debe permanecer atenuada la pantalla antes de apagarse automáticamente (en porcentaje del tiempo de espera total de la pantalla apagada) - Rango de brillo automático - Definir valores mínimos y máximos de brillo automático - Brillo automático mínimo - Brillo automático máximo - Siempre use escala no lineal - Habilítelo si los porcentajes de brillo en la modificación no coinciden con los reales en las versiones de Android inferiores a 9 - Silenciador de audio - Silencia cualquier sonido que pueda identificarse de forma única - Actualizar lista - Recuperar lista de sonidos recientemente reproducidos - Sonidos silenciados - Sonidos reproducidos - Deshabilitar advertencia de volumen alto - No mostrar diálogo cuando el volumen alcanza un nivel inseguro - Desactivar la reducción del volumen - No baja el volumen de la música que se está reproduciendo en ese momento para reproducir el sonido de notificación - Ajuste de volumen inmediato - Ajuste el volumen multimedia al presionar la primera vez - Controles de volumen separados - Permite configurar el volumen por separado para tonos de llamada/notificaciones/sonidos del sistema en Ajustes - Control deslizante de volumen de notificaciones - Agregar control deslizante de notificaciones al diálogo de volumen expandido - No silenciar medios - No establecer el volumen de los medios en cero en el modo No Molestar - Ajuste rápido de Modo no Molestar - Hacer que el botón en el cuadro de diálogo de volumen contraído alterne el modo No molestar en lugar del modo Silencioso - Temporizadores extendidos - Agregar más intervalos a los temporizadores para los modos Silencioso y No molestar - Retraso de ocultación automática del diálogo de volumen - Minimizado - Expandido - Multiplicador de pasos de volumen - Cambiar el número de pasos de volumen para cada tipo de transmisión - Visualizador de música - Muestra la densidad espectral de bandas de frecuencia de audio discretas - El visualizador se dibuja sobre el fondo de la pantalla de bloqueo - Mostrar en la pantalla de bloqueo personalizada - Dibuje el visualizador encima de la pantalla de bloqueo personalizada - Mostrar en el cajón de notificaciones - Dibujar también el visualizador en un cajón de notificaciones ampliado - Mostrar solo si existe un controlador de medios - Los reproductores de audio generalmente lo crean para notificaciones con controles multimedia - Duración de la animación - Transparencia - Método de renderizado - Estilo - Resplandor - Color - Seleccionar color personalizado - Intervalo dinámico de cambio de color - Ignorar llamadas - Previene que las llamadas entrantes enfoquen el audio cuando esté en las aplicaciones seleccionadas y anula las notificaciones sobre cambios en el estado de las llamadas - Sin prueba de vibración - No vibrar cuando cambie el modo de timbre a silencio o activa la vibración en este modo - Vibración amortiguada - Reduce la intensidad de la vibración durante las horas seleccionadas - Intensidad de vibración - Cambia la duración o la fuerza de la vibración dependiendo de la amplitud soportada por el dispositivo - Llamadas - Notificaciones - Todo lo demás - Periodo de tiempo - Bloquear vibración - Evitar que las aplicaciones seleccionadas usen vibración - Sonidos del sistema - Mezclar PIN - Cambiar aleatoriamente el orden de los botones PIN - Bloqueo de pantalla mejorado - Desactiva el menú de encendido mientras el bloqueo de pantalla está activo - Centro de control de seguridad - Deshabilitar centro de control mientras la pantalla de bloqueo está activa - Configuración Rápida de seguridad - Desactiva los mosaicos sensibles a la seguridad mientras el bloqueo de pantalla está activo - Todos los mosaicos de terceros - Edición de mosaicos - No aplicar al centro de control - Mantener abierto - No cerrar el panel luego de desbloquear - Mosaicos seguros - Modo avión - Ubicación - Sincronización - Sin contraseña después del arranque - No requiere contraseña en lugar de una huella digital la primera vez después del arranque. Es poco probable que funcione en dispositivos cifrados. - Arte del álbum como fondo de pantalla - Muestra la carátula del álbum de la pista que se está reproduciendo actualmente como fondo de pantalla - Escala de grises - Convertir la carátula del álbum a una imagen en blanco y negro - Desenfoque de la carátula del álbum - Escala de arte del álbum - Desbloquear credenciales - La autenticación en algunas aplicaciones requiere acceso a las credenciales, pero permanecen bloqueadas si se omite el PIN / contraseña / patrón después del arranque. La opción actual agrega un ícono de launcher que permite desbloquear credenciales. - Acciones personalizadas - Acciones personalizables para accesos directos y deslizamientos - Deshabilitar deslizar gesto izquierdo - Acción de deslizar a la izquierda - Cambiar icono a la derecha - Reemplace el ícono de la cámara con el ícono CustoMIUIzer - Arrastre el icono para ejecutar una acción personalizada - Deshabilitar el gesto de deslizar hacia la derecha - Atajos de la pantalla izquierda - Administrar lista de accesos directos - Alineamiento vertical - Centrar horizontalmente - No requiere desbloqueo - Se puede acceder a las aplicaciones iniciadas mientras el dispositivo aún está bloqueado - Deshabilitar bloqueo de pantalla - Algunos dispositivos pueden no funcionar sin desbloquear tras el inicio - Deshabilita selectivamente el bloqueo de pantalla (no cambia la seguridad de ninguna aplicación y no elimina los datos de huellas digitales) - Saltar pantalla de bloqueo - No mostrar la pantalla de bloqueo en absoluto cuando el bloqueo de pantalla está desactivado - Saltar desloqueo facial - No iniciar desbloqueo facial cuando el bloqueo de pantalla está deshabilitado - Redes wifi de confianza - Desactiva temporalmente el bloqueo de pantalla mientras estás conectado a estas redes - Dispositivos Bluetooth de confianza - Desactiva temporalmente el bloqueo de pantalla mientras estos dispositivos están conectados - Bloqueo forzado - Desbloqueo forzado - No forzar - Desactivar animación - Configurar la duración de la animación - Los valores muy bajos prácticamente deshabilitarán la animación - Desenfoque de fondo - Intensidad de desenfoque de fondo en aplicaciones recientes - Intensidad de desenfoque de fondo en el cajón de notificaciones - Ocultar temporalmente el fondo tematizado - Ocultar fondo mientras se cambia el brillo - Opacidad de fondo tematizado - Opacidad del fondo de cajón de notificaciones tematizado - Bloquear pantalla - Funcionalidad adicional - Seguridad - Elementos adicionales - Agregue el icono y la etiqueta de las aplicaciones a los toasts - Bloquear toasts - Evitar que las aplicaciones seleccionadas muestren toasts - Modo de interfaz - Cambia el modo a oscuro, claro o automático. No se requiere reiniciar. - Mosaico de \"Modo Oscuro\" - Agregue el mosaico en Configuración Rápida para alternar el \"Modo Oscuro\". No se requiere reiniciar. - Desactivar modo oscuro forzado - No invertir algunos colores en el modo oscuro - Opciones extendidas de menú de apagado - Agregue nuevas opciones de reinicio al menú de apagado (modo de arranque rápido, modo de recuperación, reinicio suave, reinicio de la interfaz de usuario del sistema, reinicio del launcher) - Permitir instalar aplicaciones de versiones inferiores - Habilitar la instalación de una versión anterior de la aplicación sobre una más actual - Deshabilitar la verificación de firma - Permitir la actualización de la aplicación incluso cuando la firma del APK difiere de la instalada - Lupa de texto - Mostrar texto ampliado al mover el cursor de entrada o al hacer una selección - Deshabilitar desplazamiento excesivo - Evitar que las vistas de lista se deslicen - Deshabilitar la protección segura de contenido - Permitir capturar y grabar video de cualquier aplicación - Ocultar advertencia sobre bajo nivel de batería - No mostrar cuadro de diálogo de advertencia para activar Ahorro de batería - Ocultar advertencia sobre toques desactivados - No muestre una advertencia de que el área de los auriculares está cubierta - Cambiar el tamaño del widget libremente - Eliminar cualquier limitación de tamaño de widget - Desbloquear launchers - Eliminar la restricción de los launchers de terceros en las ROMs chinas - Lmpiar menú \"compartir\" - Eliminar aplicaciones seleccionadas del menú \"compartir\" - Menú de prueba - Limpiar menú \"Abrir con\" - Eliminar aplicaciones seleccionadas de menú \"Abrir con\" - Seleccionar tipo de datos de prueba - Seleccione el tipo de datos para ocultar - Configuración USB predeterminada - Aplicar la configuración seleccionada cuando otro dispositivo está conectado - Ignorar bloqueo - Aplicar incluso si el dispositivo aún está bloqueado - RNDIS (conexión USB) - Evitar el cierre forzado de la aplicación - No permitir acciones de MIUI stock para cerrar aplicaciones seleccionadas - Animación de rotación - Todas las rotaciones - Permitir todas las rotaciones de pantalla, incluido el retrato inverso - Bloqueo de orientación - Agregar el mosaico de Configuración Rápida que puede bloquear la orientación en modo vertical u horizontal - Mantener notificaciones - Mostrar notificaciones en la pantalla de bloqueo incluso después de que se descarta y luego se abre nuevamente - Más notificaciones - Aumente el límite de notificaciones activas para una sola aplicación de 10 a 24 - Respuesta directa sin desbloqueo - No es necesario desbloquear el dispositivo para usar la respuesta directa en la pantalla de bloqueo - Permitir en la pantalla de bloqueo - Forzar que todas las notificaciones de las aplicaciones MIUI puedan aparecer en la pantalla de bloqueo - Permitir como notificaciones flotantes - Forzar que todas las notificaciones de las aplicaciones MIUI puedan aparecer como flotantes - Ocultar barra de estado - Eliminar la barra de estado de la pantalla de bloqueo - Ocultar bloque superior - Eliminar el bloque superior que contiene el reloj, la fecha y otros datos - Ocultar pista de desbloqueo - Quitar la pista \"Deslizar hacia arriba para desbloquear\" - No llamadas de emergencia - Deshabilitar botón de llamada emergencia en pantalla de bloqueo - Vista de modo expandido limpio - Ocultar Ajustes Rápidos y control deslizante de brillo en el modo de notificaciones expandidas en la pantalla de bloqueo - Desactivar fondo de color - Cambie el fondo con color autogenerado del fondo de pantalla a uno transparente mientras está en la pantalla de bloqueo - Toca para desbloquear - Inicie el desbloqueo del dispositivo tocando el área inferior de la pantalla de bloqueo - Toca dos veces para apagar pantalla - Apague la pantalla tocando dos veces en cualquier espacio vacío en la pantalla de bloqueo - Mostrar datos de carga - Mostrar información adicional de carga en la parte inferior de la pantalla de bloqueo - Cómo mostrar - Corriente de carga - Voltaje de batería - Consumo de energía - Temperatura de batería - Mostrar próxima alarma - Mostrar la hora de alarma más cercana a la fecha actual - Formato de pantalla - Mostrar todas las alarmas - Obtenga la próxima hora de alarma utilizando la API de Android predeterminada cuando la alarma MIUI no está configurada. (Podría producir resultados inesperados). - Barra de estado y cajón de notificaciones - Barra de estado - Cajón de notificaciones - Notificaciones - Lista de aplicaciones recientes - Usar implementación nativa - No usar la lista de aplicaciones recientes de MIUI Launcher. Funciona mal con gestos de pantalla completa. - Eliminar botón de limpiador - Ocultar botón que borra aplicaciones recientes y limpia memoria - Limpiar todo - El botón limpiar elimina todas las tareas en ejecución - Ocultar de recientes - Ocultar aplicaciones seleccionadas de la lista de tareas recientes - Primera acción de acceso directo - Acción para el primer atajo sugerido - Segunda acción de acceso directo - Acción para el segundo atajo sugerido - Tercera acción de acceso directo - Acción para el tercer atajo sugerido - Cuarta acción de acceso directo - Acción para el cuarto atajo sugerido - Notificaciones emergentes - Retardo de ocultación automática - Sin ocultación automática - No descartar las ventanas emergentes automáticamente - Permitir ventana flotante - Abrir la aplicación en una ventana flotante con el gesto de deslizar hacia abajo si la notificación tiene definida una acción de clic adecuada - Habilitar deslizar hacia abajo - Abrir el cajón de notificaciones en el gesto de deslizar hacia abajo - Ventana flotante - Deshabilitar lista negra - Permitir que cualquier aplicación sea abierta en ventana flotante - Recordar estado - Seguir abriendo aplicaciones en ventanas flotantes hasta que se vuelvan a cambiar a pantalla completa manualmente - Multiventana+ - Permitir usar la pantalla dividida y las ventanas flotantes al mismo tiempo - Bloqueo de aplicación - Bloqueo de aplicaciones menos estricto - No bloquee las aplicaciones cuando el dispositivo está bloqueado si se selecciona la opción con bloqueo de la aplicación después de salir - Tiempo de espera de bloqueo de aplicación - Intervalo de tiempo durante el cual la aplicación permanece desbloqueada después de salir - Lista de aplicaciones para bloquear - Versión mejorada de la opción de bloqueo de aplicaciones que permite bloquear cualquier aplicación instalada. No se requiere reiniciar. - Saltar bloqueo de aplicación - Permitir que las actividades seleccionadas pasen por encima del bloqueo de aplicación - Actividades seleccionadas - Ajustes rápidos - Número de filas - Las etiquetas se ocultarán con 5 filas en orientación vertical. El número de filas está limitado a 3 con etiquetas ocultas en una orientación horizontal. - Número de columnas - La orientación horizontal tendrá una columna adicional. Si su ROM tiene una opción compacta de diseño de Configuración Pápida, agregará otra columna en ambas orientaciones. - Número de columnas en el panel contraído - La orientación horizontal tendrá una columna adicional. - Eliminar etiquetas por completo - Configuración rápida de retroalimentación háptica - Vibrar en la configuración rápida cuando toque mosaico - Otros - Desenfoque de fondo del diálogo de volumen - Cuadro de diálogo contraído - Cuadro de diálogo ampliado - Escala de animación - Ventanas - Transiciones - Valor de animación - POCO Launcher - MIUI Launcher - Gestos - Acciones - Configuración para alternar - Aplicación para abrir - Atajo para abrir - Actividad para abrir - Launcher - Mostrar mods para el launcher seleccionado. Solo para ayuda visual, no tiene ningún efecto en las modificaciones. - Modo rendimiento - Método alternativo para aplicar todas las modificaciones del launcher - Desplazamiento infinito - Salta de la última página a la primera y viceversa - No ocultar reloj - No ocultar el reloj de la barra de estado en páginas con widgets de reloj - Habilitar el interruptor de pantalla -1 - Mostrar un switch entre App Vault y Google Discover en la configuración de la pantalla de inicio - Requiere ROM global (internacional) - Habilitar Google Discover - Reemplazar App Vault con Google Discover (requiere que la aplicación Google esté instalada) - Deshabilitar la pantalla de solo widgets - Haga que todas las pantallas sean compatibles con widgets y aplicaciones en tabletas - Eliminar la animación de desbloqueo - No animar iconos cuando el dispositivo está desbloqueado - Usar animación de ejecución antigua - Revertir la transición de apertura de la aplicación a una anterior - Soporte de retrato inverso - Girar la orientación vertical del launcher - Indicador dinámico de página - Mostrar el indicador de página solo durante el desplazamiento - Mostrar solo en modo edición - Desbloquear tamaños de cuadrícula - Haga que todos los tamaños de cuadrícula de 3x4 a 10x10 estén disponibles en la configuración de diseño de la pantalla de inicio - Más iconos en el escitorio - Número ilimitado de iconos en escritorio - Cerrar automáticamente cajón de aplicaciones - Cerrar cajón de aplicaciones luego de ejecutar - Escala de iconos - Márgenes horizontales de la cuadrícula - Margen superior de la cuadrícula - Margen inferior de la pantalla - Altura del indicador de página - Carpetas - Número de columnas en carpetas - Use el ancho de toda la carpeta - Reduce el acolchado lateral - Arreglar el modo de barra de estado - Ajuste el color del contenido de la barra de estado para los fondos de pantalla claros/oscuros en la versión de desarrollo del launcher - Arreglar animación - Aplique la escala de duración de animación a algunas animaciones del launcher - Arreglar info de la aplicación - Siempre abra la información de la aplicación estilo MIUI desde el menú de pulsación larga - Superposición de color - Oscurecer o aclarar el fondo - Intensidad de color - Difuminar - Opciones de desenfoque de fondo y fondo de pantalla. El launcher debe admitir desenfoque en las carpetas. - Desenfoque de fondo - Desenfoque de fondo de pantalla - Visibilidad - Radio - También afecta el modo de edición de desenfoque del fondo de pantalla - Auto cerrar carpetas - Cerrar la carpeta de la aplicación después de abrir - Títulos de aplicaciones - Ocultar títulos - Mostrar títulos en el dock - Tamaño de la fuente - Margen superior adicional - Oscurecer sombra - Hace que la sombra del título sea menos transparente - Títulos de aplicaciones personalizadas - Títulos modificados - Título modificado - Aplicaciones ocultas - No se han otorgado los permisos necesarios - Carpeta no oculta - Deshabilita el gesto con dos dedos que abre la carpeta de aplicaciones ocultas - Lista de aplicaciones para ocultar - Opción de versión mejorada de aplicaciones ocultas que permite ocultar cualquier aplicación instalada. No se requiere reiniciar. - Acción deslizar hacia abajo (1 dedo) - Acción para deslizar hacia abajo con un dedo en cualquier pantalla de inicio - Acción de deslizar hacia abajo (2 dedos) - Acción para deslizar hacia abajo con dos dedos en cualquier pantalla de inicio - Acción de deslizar hacia arriba (1 dedo) - Acción para deslizar hacia arriba con un dedo en cualquier pantalla de inicio - Acción de deslizar hacia arriba (2 dedos) - Acción para deslizar hacia arriba con 2 dedos en cualquier pantalla de inicio - Acción de deslizar hacia la derecha - Acción de deslizar el gesto hacia la derecha en inicio - Acción de deslizar hacia la izquierda - Acción para deslizar el gesto hacia la izquierda en inicio - Acción de sacudida - Acción para sacudir el dispositivo en cualquier pantalla de inicio - Acción de doble toque - Acción para tocar dos veces el espacio vacío de cualquier pantalla de inicio - Corrección de errores - Controles - Acción de doble toque - Reemplazar inicio de cámara al presionar dos veces la tecla. Requiere que se habilite el acceso directo del botón de stock. - Deshabilitar combinación de captura de pantalla - No realizar captura de pantalla cuando se presiona la tecla de encendido junto con la tecla para bajar el volumen - Linterna rápida - Mantenga presionado el botón de encendido mientras la pantalla está apagada para encender la linterna - Mayor retraso de la linterna rápida - Aumentar el retraso de pulsación prolongada del botón de apagado - Escáner de huellas digitales - Acción de un solo toque - Acción para un solo toque cuando la pantalla está encendida - Acción de doble toque - Acción para un doble toque cuando la pantalla está encendida - Retraso de doble toque - La acción de un solo toque se retrasará en esta cantidad - Acción de pulsación prolongada - Acción de una pulsación prolongada cuando la pantalla está encendida - Retraso de pulsación prolongada - No hay acciones en la cámara - Habilite esto si usa la opción de obturador con el sensor de huellas - No hay acciones durante las llamadas - No ejecutar acciones cuando la llamada está activa - Aceptar llamada entrante - Rechazar llamada entrante - Finalizar llamada actual - Las acciones de aceptar y rechazar no pueden tener la misma combinación. - Acción \"aceptar\" fue deshabilitada. - Acción \"rechazar\" fue deshabilitada. - Encender la pantalla después del fallo - Encender pantalla en caso de autenticación fallida - Requerir huellas reales - No encender la pantalla si no hay huellas registradas - Vibrar si fue exitoso - Comentarios hápticos sobre autenticación exitosa - Ignorar la configuración del sistema - No desactivar la retroalimentación háptica cuando la vibración al tocar esté desactivada - No vibrar en caso de falla - Eliminar comentarios hápticos en caso de falla de autenticación - Tecla de encendido - Teclas de volumen - Control de cursor de entrada - Mover el cursor de entrada de texto usando las teclas de volumen - Cambiar direcciones - Cambiar direcciones de movimientos del cursor - Acción de pulsación prolongada de \"Subir Volumen\" - Acción de pulsación prolongada de \"Subir Volumen\" si la pantalla está apagada - Acción de pulsación prolongada en \"Bajar Volumen\" - Acción de pulsación prolongada en \"Bajar Volumen\" mientras la pantalla está apagada - Vibración en pulsación prolongada - Vibrar cuando se ejecuta una acción de pulsación prolongada - Barra de navegación - Ocultar barra de navegación - Botón Atrás reactivo - Cambie el icono del botón de Atrás a uno alternativo en el modo de entrada - Altura de la barra de navegación - Acción de pulsación prolongada en botón Atrás - Acción de pulsación prolongada en botón Inicio - Acción de pulsación prolongada en botón Menú - Acción de pulsación en botón adicional izquierdo - Acción del botón izquierdo - Acción de pulsación prolongada en botón adicional izquierdo - Acción de pulsación prolongada en botón izquierdo - Acción de pulsación en botón adicional derecho - Acción de pulsación en botón derecho - Acción de pulsación prolongada en botón adicional derecho - Acción de pulsación prolongada en botón derecho - Margen adicional - Aumente la distancia desde los bordes de la pantalla para botones adicionales - Ninguna acción definida - Gestos de navegación a pantalla completa - Altura del área del gesto hacia atrás - Ancho del área del gesto hacia atrás - Gestos horizontales - Habilita tanto los gestos horizontales como la barra de navegación - Acción de deslizamiento de esquina - Realizar la acción seleccionada en lugar de abrir el Asistente de Google - Varios - Abrir \"Actualizador de aplicaciones de sistema\" - La aplicación ya no forma parte de algunas ROMs y debe instalarse manualmente - Tenga cuidado al actualizar las aplicaciones modificadas del sistema en ROMs personalizadas, puede perder la funcionalidad agregada - Desbloquear FPS - Haga que los FPS hasta 90 estén disponibles en la aplicación Screen Recorder. Si los FPS más altos funcionarán realmente depende del dispositivo y del controlador de video. - Utilizar el instalador de paquetes MIUI - Hacer que el instalador de paquetes de Xiaomi sea el predeterminado y permitir que actualice las aplicaciones del sistema - La aplicación requerida no está instalada. Mantenga pulsado para descargar. - Información de la aplicación en el instalador - Mostrar información sobre la aplicación que se está instalando - Paquete - Nombre de la versión - Código de versión - SDK compatible - Actual - Compatibilidad reloj despertador - Hacer que las aplicaciones seleccionadas muestren la hora de la próxima alarma correcta establecida por la aplicación de reloj MIUI - Acolchado inferior en vertical - Acolchado inferior en horizontal - Mostrar visualización de llamada - Defina cuándo se debe mostrar la visualización para la llamada entrante en lugar de la notificación emergente - Brillo de pantalla durante la llamada - Tipos de llamadas - Valor de brillo - Modo nocturno - No cambiar el brillo durante la noche - Inicio - Fin - Recordatorio de llamada perdida - Definir sonido, vibración e intervalo para recordatorio - Intervalo - Sonido - Sin sonido - Patrón propio - Formato: retraso, vibración, retraso, vibración, … - Control de estado de la aplicación - Permite deshabilitar casi cualquier aplicación desde su página de información - Mostrar detalles adicionales de la aplicación - Agregar nuevos campos a la página de información de la aplicación:\n- código de versión\n- ruta completa a apk\n- ruta de datos\n- ID de usuario\n- versión de SDK de destino\n- enlace a la página de Play Store\n- lanzar una aplicación - Orden de clasificación inicial de aplicaciones instaladas - ¿Deshabilitar aplicación? - Si esta es una aplicación de sistema esencial, deshabilitarla puede romper cosas :) - Esa es una mala idea! :) - Error al cambiar el estado de la aplicación - Abrir en Play Store - Ejecutar - La aplicación no tiene actividad de inicio predeterminada - Nombre de archivo APK - Código de versión APK - Ruta de datos - ID de usuario - Versión del SDK preferido - Estado (predeterminado) - Nombre de la aplicación - Frecuencia de uso - Almacenamiento usado - Tiempo de instalación - Teclado de Google - Llamadas - Configuraciones - por Defecto - Sistema - Ninguna acción - Expandir el cajón de notificaciones - Expandir el panel de Configuración Rápida - Bloquear dispositivo - Apagar pantalla (Dormir dispositivo) - Tomar captura de pantalla - Abrir menú - Abrir recientes - Abrir dialogo de volumen - Subir volumen - Bajar volumen - Ejecutar aplicación - Ejecutar acceso directo - Ejecutar actividad - Función \"alternar\" - Cambiar a la aplicación anterior - Forzar cierre de la aplicación actual - Abrir el menú de apagado - Menú de apagado - Limpiar memoria - invertir colores - Cambiar teclado - Regresar - Modo con una mano (izquierda) - Modo con una mano (derecha) - Bluetooth - Perfil de sonido - Brillo automático - Rotación automática - Linterna - Datos móviles - Icono - Etiqueta - Icono y etiqueta - Ninguno - Desvanecerse - Ningún cambio - Reproducir/Pausar - Siguiente pista - Pista anterior - Todos los eventos de carga - Solo eventos sin animación - Sistema por defecto - Deshabilitar completamente - Requerir autenticación después de iniciar - Deshabilitar en redes/dispositivos confiables - No requerir - Débil (huella digital) - Fuerte (PIN/contraseña/patrón) - Sin desenfoque - Sin iconos - Fondo completo - Solo en el medio - Para todas las aplicaciones excepto las enumeradas - Solo para aplicaciones enumeradas - Ocultar solo cuando no está conectado - Ocultar completamente - No agrupar - Vibración ligera - Vibración fuerte - Habilitar - Inhabilitar - Más cerca del borde superior - En el medio - Cerca del borde inferior - Máximo - Grande - Normal - Pequeño - Bajo - Promedio - Alto - Hacer coincidir la carátula o el fondo de pantallas - - Color personalizado - Colores del arco iris (horizontal) - Colores del arco iris (vertical) - Arco iris - Color dinámico - Discreto - Gradual - Barras sólidas - Barras redondeadas sólidas - Barras discontinuas - Círculos - Línea - Nunca - Por 1 día después de la actualización - Por 3 días después de la actualización - Por una semana después de la actualización - Siempre - Imagen - Audio - Video - Documento - Archivo - Enlace - Cualquiera - Otros - Cuando no está en modo pantalla completa - Entrante - Saliente - Ambos - Sin vibración - Simple (corto) - Simple (largo) - Ticktock - Latido (pulso) - Vals - Zig-zig-zig - Patrón propio - Ajustar a pantalla - Cubrir toda la pantalla - Parte superior - Parte inferior - Ajustar brillo - Ajustar volumen - Tiempo normal - Tiempo relativo - Toque simple - Doble toque - Toque largo - Año Nuevo - Año Nuevo Chino - Coronavirus anti-vacaciones - Sólo mostrar - Ocultar - Detectar automáticamente - Adjuntar - Anteponer - Insertar como nueva línea - Ruta seleccionada - Inicialmente - Permanentemente - Ilimitado - Wi-Fi habilitado - Wi-Fi deshabilitado - Bluetooth habilitado - Bluetooth deshabilitado - GPS habilitado - GPS deshabilitado - Punto de acceso habilitado - Punto de acceso deshabilitado - NFC habilitado - NFC deshabilitado - Perfil de sonido: Normal - Perfil de sonido: Silencio - Perfil de sonido: Vibración - Brillo automático activado - Brillo automático desactivado - Auto rotación habilitada - Auto rotación deshabilitada - Linterna: Apagada - Linterna: Encendida - Datos móviles habilitados - Datos móviles deshabilitados - Bloqueo de rotación - Sin restricción - Retrato - Paisaje - Modo oscuro - CustoMIUIzer no tiene permiso para cambiar el modo oscuro - Configuraciones de CustoMIUIzer - Marcar nuevas modificaciones - Mostrar \"¡Nuevo!\" etiqueta en el título para las modificaciones agregadas en la versión actual - ¡Nuevo! - Icono en launcher - Mostrar icono en launchers - Icono de acceso rápido - Mostrar icono en Configuración - Repositorio propio - Agregar un repositorio personalizado a EdXposed Manager para cargar la información de CustoMIUIzer de manera más confiable - Se utiliza un repositorio adicional - Idioma de la interfaz - Mostrar siempre la interfaz del módulo en el idioma seleccionado - Diseño de días festivos - Decora la interfaz del módulo según la ocasión - Solución de problemas - Enviar informe detallado - Recopilar información del dispositivo y del entorno, \"logcat\" y \"log\" de Xposed y envíar al desarrollador. -\nSe requiere conexión a internet - Ingrese su información de contacto y se incluirá en informes detallados y de fallas - Información de contacto - Es absolutamente necesario completar esto si espera recibir respuestas a sus informes de fallas. Use el apodo de correo electrónico, ICQ, XDA o 4PDA. - Soporte - Repositorio de CustoMIUIzer - Repositorio de Git con fuentes y distribuciones de módulos - Tema de XDA - Tema del módulo en foros XDA - Tema de 4DA - Tema del módulo en foros 4PDA - Reportar una falla - Envíenos un informe de error o una solicitud de función a través del rastreador oficial de problemas - Donar $%1$d - Donar - La mejor manera de expresar tu gratitud por este increíble módulo :) - En la aplicación - Dejar que Google se encargue de todo - Criptomonedas - Moneda del futuro :) - Monedas desactualizadas - ¡Gracias por tu donación! - ¡Gracias por tu generosa donación! - ¡Gracias por su increíblemente generosa donación! 😮 - No se pudo obtener la información de facturación, verifique su conexión a Internet - ¿Cambiaste de idea? ;) - ¡CustoMIUIzer acaba de fallar! - Todos los datos necesarios se han recopilado - Tamaño del informe generado - Describa su problema (en inglés si es posible): - Describir las acciones que llevaron a este fallo -\n(en inglés si es posible): - No se proporciona información de contacto, ¡no recibirá una respuesta a este reporte! - Se requiere conexión a Internet - La descripción no puede estar en blanco - Ignorar - Enviar reporte - Enviando resultado - ¡El reporte se envió con éxito! - Fallo al enviar reporte - Confirmación - Creando reporte… - Enviando reporte… - Automático - Oscuro - Claro - No se puede inicializar MIUI SDK. \n¿No es una ROM Miui? - No seleccionado - ¡Advertencia! - La opción de lista negra/blanca está activa en Xposed Framework, puede evitar que las modificaciones funcionen correctamente. - Además, la versión del módulo instalado es de Google Play y tiene más limitaciones. Considere reinstalarlo desde cualquier otra fuente. - Administrar módulos Xposed - Reinicio suave - ¿Realizar reinicio suave ahora? - Reiniciar launcher - Gestión de configuraciones - Elige la rutina deseada - Respaldo - Restaurar - Tu almacenamiento externo es de solo lectura - No se puede acceder a ningún almacenamiento adecuado - Error al crear el directorio de respaldo - Error al crear el archivo de respaldo - No se encontró copia de seguridad de configuración - ¡Las configuraciones fueron respaldadas con éxito! - ¡La configuración se restauró con éxito! - Su configuración se ha restaurado a través de Google Cloud Backup. Realice un reinicio suave después de habilitar el módulo Xposed. - La configuración del módulo se migró con éxito para trabajar con la nueva versión de LSPosed/EdXposed. Reiniciar para aplicar los cambios. - No se pudo migrar la configuración del módulo para que funcione con la nueva versión de LSPosed/EdXposed. Tendrá que usar la función de restauración o configurar mods desde cero. - La actualización está disponible ⚠ - Seleccionar aplicación - Seleccionar aplicaciones - Seleccione la actividad - No se encontraron actividades - Seleccionar acceso directo - Buscar mods - Redes Wi-Fi - Ajustes de ubicación - Se requiere acceso a la ubicación para que las aplicaciones obtengan una lista de redes Wi-Fi en Android Pie - Redes de confianza - Redes disponibles - Obtener la lista de dispositivos - Recuperar la lista de dispositivos Bluetooth en caché del sistema - Dispositivos de confianza - Dispositivos disponibles - Dispositivos Bluetooth - Bluetooth no es compatible con este dispositivo - Encender Bluetooth primero - Encender Wi-Fi primero - No se puede escanear sin acceso a la ubicación - Cierre forzado %s - Las credenciales ya están desbloqueadas - Desbloquear credenciales - ¡Credenciales desbloqueadas! - Aplicación Xposed no encontrada - Parece que no tiene instalado Xposed Framework.\n\n¡Tenga en cuenta que las modificaciones solo funcionarán con Xposed! - Los ganchos de recursos están deshabilitados - Tiene deshabilitados los ganchos de recursos en la configuración del instalador Xposed, ¡el módulo no se activará! - ¡El módulo CustoMIUIzer no está activo! \nAbra la aplicación Xposed, active el módulo y reinicie. - Se requiere la aplicación de navegador para abrir URLs - OK - Cancelar - Añadir - Borrar - Mantenga pulsado el elemento para eliminar - Cambiar icono - Buscar mods por nombre. \nMantenga presionado para mostrar una lista de nuevas modificaciones. - No olvide aplicar modificaciones mediante el reinicio suave. \nLas modificaciones dinámicas ⟲ lo requieren solo una vez. \nMás información en la página Acerca de. - Nuevas modificaciones desde la actualización anterior -\nse pueden marcar para una mejor visibilidad - ¿Quiere escribir copia de seguridad o no? - ¿Desea restaurar la copia de seguridad o no? - ¿Desea obtener una lista de redes/dispositivos o no? - Tendrá que habilitar manualmente el permiso para esta opción ahora. ¡Buen trabajo! - %d ms - %d s - %d m - %d KB/s - 1 KB/s - B/s - KMGTPE - %s lux - Apagado - 30 minutos - 1 hora - 2 horas - 3 horas - 4 horas - 5 horas - 6 horas - 8 horas - 10 horas - 12 horas - Blanco - Negro - Color de barra de estado - archivo - recurso - Sincronización - Intentar actualizar el valor en un momento específico - Inicio de un segundo - Fin de un segundo - Tiempo normal y relativo - Una versión no soportada de EdXposed Manager está instalada - El alcance de activación está activo para este módulo, puede evitar que algunas modificaciones funcionen correctamente. - Indicadores de actividad de red - Configurar indicador de tráfico en redes móviles y Wi-Fi - Estilo de control deslizante de brillo constante - Eliminar la sombra y el fondo adicional del control deslizante mientras cambia el brillo - Configuración del modo avión - Definir las comunicaciones permitidas en modo avión. No es necesario reiniciar. - El mod solo cambia la configuración del sistema existente, algunas opciones pueden no funcionar - Aplicar wallpaper usando cualquier aplicación - Hacer que las aplicaciones de terceros puedan configurar el fondo de pantalla de bloqueo. La aplicación Temas debe estar instalada y tener permiso de acceso al almacenamiento. - Mostrar centrado - Mostrar popups en el medio de la pantalla - Acción al pellizcar - Acción para mover 2 dedos uno hacia el otro en cualquier pantalla de inicio - Acción al expandir - Acción para alejar 2 dedos entre sí en cualquier pantalla de inicio - Redes celulares y datos móviles - Mantener como está - Apagar - Apagar y deshabilitar - Restricciones completas - Permite que se configure el ahorro de batería y acceso Wi-Fi para las aplicaciones de sistema - ‎Margen de widget horizontal‎ - ‎Funciona solo en las últimas versiones del launcher con posicionamiento dinámico de widgets‎ - Modo LSPosed - Se asume que LSPosed Framework está instalado para funcionar correctamente con su administrador‎ - Yo uso LSPosed - ‎Android ‎%1$s‎ no es compatible, es posible que los mods no funcionen correctamente. - \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml deleted file mode 100644 index 8079ddae..00000000 --- a/app/src/main/res/values-fr/strings.xml +++ /dev/null @@ -1,917 +0,0 @@ - - - A propos - Version %1$s - Par Mikanoshi - Généralement, les mods nécessitent un redémarrage doux pour être activés ou désactivés, mais ceux marqués avec ⟲ ne nécessitent qu\'un redémarrage doux après que leur valeur ait été changée de par défaut à personnalisée, les modifications suivantes sont appliquées immédiatement. - Les mods marqués d\'un ⨯ ne sont pas supportés sur cet appareil. - Notifications mises en attente - Mise à jour - Annuler la mise en attente de cette notification - Marquer comme rejeté - Marquer comme en attente - Impossible de récupérer la liste des notifications mises en attente - Aucune notification mise en attente - Messages - Canal - "Créé(e-s) " - Mis à jour - Republier - Modifications - Actions - Activer la modification - Système - Écran - Rotation - Rétroéclairage - Audio - Vibration - Toasts - Cacher les icônes - Gérer les icônes visibles dans la barre de statut - Icône de la batterie - Pourcentage de la charge de batterie - Indicateur de charge - Peut se placer au dessus de l\'icône de batterie pour certaines ROMs - Alarme - Cacher complètement - Sélectionner la visibilité de l\'icône d\'alarme - Afficher l\'icône d\'alarme uniquement durant le délai définit avant la prochaine alarme - Signal réseaux téléphonique - Pas de carte SIM - Relai - Profile de travail - Profils de son - Mode \"Ne pas déranger\" - Casque - Appel : micro éteint - Appel : haut-parleur - Appel : enregistrement en cours - Barre indicatrice de batterie - Afficher le niveau de charge de la batterie sous forme de barre - Visibilité limitée - Afficher uniquement dans le panneau de notification et sur l\'écran de verrouillage - Bords arrondis - Centré - Hauteur de la barre - Déplacement horizontal - Couleur de charge complète - Couleur de batterie faible - Couleur d\'économie de batterie - Couleur de chargement de la batterie - Niveau de batterie faible - Test - Animer la barre de 100% à 0% en déchargement - Hauteur de la barre de statut - Couleur de fond de la barre de statut - Faire en sorte que la couleur de fond de la barre de statut et de la barre d\'action d\'application soit la même lorsque possible - Liste noire - Raccourci d\'application - Ouvrir l\'application sélectionnée lorsque l\'icône de raccourci dans le haut du panneau de notification est touchée - Horloge - Ouvrir l\'application sélectionnée lorsque l\'horloge dans le haut du panneau de notification est tapée - Calendrier - "Ouvrir l\'application sélectionnée lorsque l\'utilisateur appuie sur la date dans le haut du panneau de notification " - Afficher les secondes - Afficher les secondes pour l\'horloge dans la barre de status - Limite d\'icônes de notification - "Nombre d'icônes de notification à afficher avant de les changer en '...' " - Cacher le type de réseau mobile - Enlever l\'icône de type de réseau mobile dans la barre de statut - Afficher l\'icône LTE pour la 4G - "Pas d'indicateur d'icônes cachées " - "Ne pas afficher l'icône avec 3 points lorsque des icônes de notifications sont cachées " - "Pas de séparateur de vitesse de connexion " - Ne pas afficher la barre verticale entre l\'horloge et la vitesse de connexion sur les appareil avec une encoche goutte-d\'eau - Interval de rafraîchissement de la vitesse de connexion - "Indicateur détaillé de vitesse de connexion " - "Afficher la vitesse de connexion entrante et sortante séparément " - Táille de police - Icônes d\'indicateur - "Icônes pour la connexion entrante/sortante affichées a côté de la vitesse (toutes les polices customises n'ont pas toutes les icones) " - Cacher les basses vitesses - Ne pas afficher l\'indicateur si la vitesse est basse - Niveau de vitesse bas - "Les vitesses en dessous de cette valeur seront considérées basse et seront de ce fait affichées différemment " - Réduire la visibilité lorsque inactif - Rendre les indicateurs semi-transparents lorsque les deux vitesses valent 0 - Contrôles par gestes - Produire l\'action sélectionnée lors d\'un glissement sur l\'écran et d\'un double tap - Sensibilité d\'ajustement - "Luminosité " - Volume - Glissement horizontal avec un doigt - Glissement horizontal avec deux doigts - Action de double tap - Espacement des vitesses de connexion - Augmenter la marge horizontale pour l\'indicateur de vitesse de connexion - Notifications compactes - Réduire le déplacement vertical des notifications - Colorer le titre des notifications - "Appliquer la couleur de l\'icône au titre (uniquement pour le style de notification Android) " - Retourner à la vue compacte minimaliste - Les notifications d\'importance minimale pourraient de nouveau être réduites en une seule ligne - Ouvrir les paramètres du canal - Cacher le bouton effacer - "Enlever le bouton pour effacer toutes les notifications " - "Afficher le niveau d'éclairage " - "Afficher la valeur d'éclairage ambiant en lux dans la barre de luminosité " - Style alternatif - "Large texte semi-transparent " - Afficher le pourcentage de luminosité - "Afficher le niveau de luminosité en pourcentages lors du réglage de la luminosité " - Pourcentages de marge haute du panneau - "Désactiver la barre de réglage de la luminosité " - "Menu de notification étendu " - "Ouvrir les infos d'application et forcer la fermeture depuis le menu de notification (déplacer la notification vers la gauche pour l'ouvrir) " - "Désactiver toutes les notifications " - "Autoriser à désactiver aussi les notifications systèmes " - "Étendre les notifications " - "Afficher les notifications pleinement étendues " - Liste noire et blanche - Afficher la date de modification - Changer à la fois la durée courte et longue - La durée qui en résultent ne descendra pas en dessous de 1 seconde - "Grouper automatiquement les notifications " - Nombre de notifications d\'une application déclenchant le groupement automatique - Gérer les notifications en attente - Augmenter les intervalles d\'attente et ajouter l\'icône qui ouvre une liste des notifications actuellement en attentes au lanceur d\'application - "Curseur de position du média " - Ajouter un curseur de notification de média indiquant la position actuelle et autorisant sa modification - "Utiliser le style système " - Ne pas appliquer le style fin personnalisé au curseur - "Ouvrir automatiquement le panneau de notification " - "Ouvrir automatiquement le panneau de notification pour les notifications des applications sélectionnées " - "Respecter le plein écran " - Ne pas ouvrir le panneau de notification quand le mode plein écran est actif (ne s\'applique pas aux applications immersives avec la barre de statut et de navigation cachées) - "Applications sélectionnées " - "Capture d'écran " - "Configuration des captures d'écran " - Personnaliser le format, la qualité et le dossier de sauvegarde pour les captures d\'ecran - Format - "Qualité " - Dossier de sauvegarde - "Cacher l'aperçu pour les captures d'écran " - Désactiver temporairement les superpositions pendant la capture d\'ecran - "Temps d'affichage de l'aperçu de capture d'écran " - "Délai avant qu'une fenêtre flottante d'une capture d'écran fraîchement crée ne disparaisse " - "Délai de désactivation de l'écran d'animation de charge " - Durée de maintient de l\'écran allumé après le début de l\'animation de charge - Ne pas allumer l\'écran lors de la charge - Ne pas allumer l\'écran lors de la (dé)connexion d\'un chargeur - "Ne pas allumer l'écran lors du branchement d'un casque " - Ne pas allumer l\'écran lors du branchement d\'un casque - "Délai avant extinction de l'écran de verrouillage " - Durée de rétro-éclairage - "Durée de maintient de l'écran allumé avant de s'éteindre automatiquement (en pourcentage du délai total d'extinction de l'écran) " - "Intervalle de luminosité automatique " - "Définir les valeurs minimum et maximum de la luminosité automatique " - "Luminosité automatique minimum " - Luminosité automatique maximum - "Toujours utiliser une échelle non linéaire " - Activer si le pourcentage de luminosité dans les mods ne correspond pas à celui d\'android pour des versions strictement inférieures à 9 - Désactiver l\'alerte de volume fort - "Ne pas afficher la boîte de dialogue l'orque le volume atteint un niveau possiblement dangereux " - "Désactiver l'effet 'ducking' " - Ne pas baisser le volume de la musique en cours pour jouer le son de notification - Ajustement immédiat du volume - Ajuster le volume du média en cours au premier appui - Contrôles de volume séparés - "Autoriser la configuration séparée du volume pour les sonneries/notifications/sons systèmes dans les Paramètres " - Curseur de volume de notifications - Ajouter un curseur dans les notifications pour étendre la boîte de dialogue du volume - "Minuterie prolongée " - "Ajouter plus d'intervalles aux minuteries pour les modes Silencieux et Ne Pas Déranger " - "Multiplicateur de palier de volume " - Modifier le nombre de paliers de volume pour chaque type de sortie son - Visualisateur de musique - Afficher la densité spectrale des bandes de fréquences des son discrets - "Le visualisateur est dessiné au dessus du fond d'écran de verrouillage " - "Afficher sur l'écran de verrouillage personnalisé " - "Dessiner le visualisateur au dessus de l'écran de verrouillage personnalisé " - Afficher dans le panneau de notification - Dessiner le visualisateur aussi dans le panneau de notification étendu - "Afficher uniquement si un contrôleur de média existe " - Les applications jouant du son le créer habituellement pour les notifications avec des contrôles de media - Durée de l\'animation - Transparence - Méthode de rendu - Style - Brille - Couleur - "Sélectionner une couleur personnalisée " - Interval de changement de couleur dynamique - Ignorer les appels - Empêcher les appels entrant de voler le focus audio dans les applications sélectionnées et de notifier à propos du changement de statut d\'appel - Pas de vibration de test - Ne pas vibrer lors du changement de mode de sonnerie vers silencieux ou vibration dans ce mode - Vibration atténuée - "Réduire l'intensité des vibrations durant la période sélectionnée " - Intensité des vibrations - Modifier soit la durée soit la force des vibrations, en fonction du support des contrôles d\'amplitude sur ce telephone - Appels - "Notifications " - Tous les autres - "Période de temps " - Bloquer les vibrations - "Empêcher les applications sélectionner d'utiliser les vibrations " - "Sons systèmes " - Mélanger le PIN - Changer aléatoirement l\'ordre des chiffres pour le PIN - "Écran de verrouillage amélioré " - Désactiver le menu d\'extinction tant que l\'écran de verrouillage est actif - Pas de mot de basse après allumage - Ne pas demander le mot de passe à la place des empreintes digitales la première fois après allumage. Risque de ne pas marcher sur les appareils encryptés. - "Couverture de l'album en tant que fond d'écran " - "Afficher la couverture d'album de la musique jouée en tant que fond d'écran de verrouillage " - Échelles de gris - Convertir la couverture d\'album en noir&blanc - Flouter la couverture d\'album - Échelle de la couverture d\'album - "Déverrouiller les informations d'identification " - L\'authentification pour certaines applications requiert l\'accès aux identifiants, mais ceux-ci restent bloqués si le PIN/Mot de passe/Schéma est sauté après démarrage. Cette option ajoute une icone permettant de débloquer les identifiants. - Actions personnalisées - Actions personnalisées pour les raccourcis et les swipes - Désactivé le geste de défilement gauche - Action de défilement gauche - "Changer l'icône droite " - Remplacer l\'icône de caméra par l\'icône de CustoMIUIzer - "Faites glisser l'icône pour exécuter une action personnalisée " - Désactiver le geste de défilement droit - "Raccourcis de la gauche de l'écran " - Gérer la liste des raccourcis - Alignement vertical - Déverrouillage non requis - "Les applications lancées seraient accessibles avec l'appareil toujours verrouillé " - Désactiver l\'écran de verouillage - "Certain appareil ne fonctionneront pas sans un déverrouillage préalable après démarrage " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Attention ! - Synchronisation - Configurer les indicateurs de données mobiles et de trafic Wi-Fi - \ No newline at end of file diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml deleted file mode 100644 index 23c95c45..00000000 --- a/app/src/main/res/values-id/strings.xml +++ /dev/null @@ -1,1041 +0,0 @@ - - - Tentang - Versi %1$s - oleh Mikanoshi - Pada dasarnya, modifikasi dalam aplikasi ini membutuhkan reboot setelah pengaktifan ataupun pe-non-aktifan fitur. - Tanda ⨯ pada modifikasi menandakan bahwa perangkat anda tidak didukung. - Penundaan notifikasi - Pembaruan - Hilangkan penundaan notifikasi - Tandai sudah selesai - Tandai untuk tunda - Gagal mendapat daftar pemberitahuan tertunda - Tidak ada notifikasi tertunda - Pesan - Channel - Dibuat - Diperbarui - Pos ulang - Modifikasi - Aksi - Aktifkan modifikasi - Sistem - Tampilan - Rotasi - Lampu latar - Suara - Getaran - Toasts - Sembunyikan ikon - Atur penampilan ikon status bar - Gambar baterai - Presentasi pengisian baterai - Indikator pengisian - Dapat muncul diatas gambar baterai pada beberapa ROM - Alarm - Sembunyikan seluruhnya - Visibilitas ikon alarm selektif - Tampilkan ikon alarm hanya selama jumlah jam yang ditentukan sebelum alarm berikutnya - Sinyal jaringan - Tidak ada kartu SIM - Hotspot - Profil kerja - Profil suara - Mode jangan ganggu - Headset - Panggilan: diamkan mikrofon - Panggilan: speaker - Panggilan: rekaman - Indikator bar baterai - Tampilkan level pengisian baterai seperti bilah berwarna - Visibilitas terbatas - Tampilkan hanya di laci notifikasi dan di layar kunci - Ujung lengkung - Tengah - Tinggi bar - Padding horizontal - Warna pengisian penuh - Warna daya lemah - Warna penghemat baterai - Warna isi daya - Tingkatan daya lemah - Uji - Animasikan bar dari 100% ke 0% ketika tidak mengisi daya - Tinggi status bar - Warna latar status bar - Samakan warna status bar dengan latar warna bar aksi aplikasi - Daftar hitam - Pintasan apl - Buka aplikasi yang terpilih ketika ikon pintasan pada panel pemberitahuan diketuk - Apl jam - Buka aplikasi terpilih ketika jam pada panel pemberitahuan diketuk - Apl kalender - Buka aplikasi terpilih ketika tanggal pada panel pemberitahuan diketuk - Tampilkan detik - Tampilkan detik pada jam status bar - Pembatasan ikon notifikasi - Jumlah ikon notifikasi yang ditampilkan sebelum mengubahnya menjadi titik - Sembunyikan tipe jaringan - Hilangkan tipe jaringan pada status bar - Tampilkan LTE untuk 4G - Sembunyikan indikator ikon - Menyembunyikan ikon 3 titik ketika ada pemberitahuan yang disembunyikan - Tidak ada pemisah kecepatan jaringan - Sembunyikan garis vertikal antara waktu dan kecepatan jaringan pada perangkat berponi/tompel - Kecepatan pembaruan jaringan - Tampilkan detail kecepatan jaringan - Tampilkan kecepatan jaringan masuk dan keluar secara terpisah - Ukuran font - Ikon indikator - Ikon lalu lintas masuk/keluar ditampilkan di sebelah nilai kecepatan (tidak semua font khusus memiliki setiap ikon) - Sembunyikan kecepatan rendah - Sembunyikan indikator ketika jaringan lemah - Level jaringan terendah - Nilai kecepatan di bawah level ini akan dianggap rendah dan akan memiliki ikon indikasi yang berbeda - Kurangi visibilitas saat tidak aktif - Buat indikator menjadi semitransparan jika kedua kecepatan sama dengan nol - Kontrol gerakan - Lakukan tindakan yang dipilih pada slide dan ketuk 2x - Penyesuaian sensitifitas - Kecerahan - Volume - Geser horizontal dengan satu jari - Geser horizontal dengan dua jari - Aksi ketuk 2x - Jarak kecepatan jaringan - Tingkatkan margin horizontal untuk indikator kecepatan jaringan - Notifikasi ringkas - Kurangi padding vertikal notifikasi - Warnai judul notifikasi - Terapkan warna ikon ke teks judul (khusus gaya notifikasi Android) - Sembunyikan tombol hapus - Hilangkan tombol -hapus seluruh pemberitahuan- - Tunjukkan tingkat iluminasi - Tampilkan nilai iluminasi ambien dalam lux di dalam slider kecerahan - Gaya alternatif - Teks semitransparan besar - Tampilkan persentase kecerahan - Menampilkan presentase tingkat kecerahan ketika menyeret slider kecerahan - Presentase margin panel atas - Nonaktifkan slider kecerahan - Menu pemberitahuan detail - Buka info aplikasi dan tutup paksa aplikasi dari menu notifikasi (geser notifikasi ke kiri untuk membukanya) - Matikan notifikasi apa pun - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml deleted file mode 100644 index 35fcbcb1..00000000 --- a/app/src/main/res/values-it/strings.xml +++ /dev/null @@ -1,1040 +0,0 @@ - - - Informazioni - Versione %1$s - di Mikanoshi - Generalmente, le modifiche richiedono un riavvio veloce per essere attivate o disattivate, tuttavia quelle contrassegnate con ⟲ richiedono un riavvio veloce solo la prima volta dopo che il loro valore è stato modificato da predefinito a personalizzato. Le modifiche successive verranno applicate istantaneamente. - Le modifiche contrassegnate con ⨯ non sono supportate su questo dispositivo. - Notifiche posticipate - Aggiorna - Deposticipa questa notifica - Segna come annullato - Segna come in sospeso - Impossibile recuperare l\'elenco delle notifiche posticipate - Nessuna notifica posticipata - Messaggi - Canale - Creato - Aggiornato - Ripubblicato - Modifiche - Azioni - Attiva modifica - Sistema - Schermo - Rotazione - Retroilluminazione - Audio - Vibrazione - Toast - Nascondi icone - Gestisci la visibilità delle icone nella barra di stato - Immagine della batteria - Percentuale della batteria - Indicatore di carica - Su alcune ROM può essere coperto dall\'immagine della batteria - Sveglia - Nascondi completamente - Visibilità selettiva dell\'icona della sveglia - Mostra l\'icona della sveglia soltanto nel numero di ore stabilite prima della sveglia successiva - Segnale di rete mobile - Nessuna scheda SIM - Hotspot - Profilo di lavoro - Profili audio - Modalità non disturbare - Cuffie - Chiamata: microfono mutato - Chiamata: speaker del telefono - Chiamata: registrazione - Indicatore barra della batteria - Mostra il livello di carica con una barra colorata - Visibilità limitata - Mostra solo nel riquadro delle notifiche e nella schermata di blocco - Angoli arrotondati - Centrato - Altezza della barra - Spaziatura orizzontale - Colore carica completa - Colore carica bassa - Colore risparmio energetico - Colore di ricarica - Basso livello di carica - Test - Anima la barra dal 100% allo 0% durante lo stato di scarica - Altezza della barra di stato - Colore di sfondo della barra di stato - Rendi la barra di stato e i colori di sfondo della barra delle azioni dell\'app uguali, dove possibile - Blacklist - Scorciatoia app - Apri l\'app selezionata quando tocchi l\'icona scorciatoia nella parte superiore del riquadro delle notifiche - App orologio - Apri l\'app selezionata quando tocchi l\'orologio nella parte superiore del riquadro delle notifiche - App calendario - Apri l\'app selezionata quando tocchi la data nella parte superiore del riquadro delle notifiche - Mostra secondi - Mostra i secondi nell\'orario della barra di stato - Limite delle icone di notifica - Numero icone di notifica da visualizzare prima di trasformarle in punti - Nascondi il tipo di rete mobile in uso - Rimuovi l\'icona del tipo di rete mobile in uso dalla barra di stato - Mostra l\'icona LTE al posto di 4G - Nessun indicatore di icone nascoste - Non mostrare l\'icona con i 3 punti quando le icone di notifica sono nascoste - Nessun separatore per la velocità di rete - Nascondi la linea verticale tra l\'orario e la velocità della rete sui dispositivi con notch - Frequenza di aggiornamento della velocità di rete - Indicatore dettagliato della velocità di rete - Mostra separatamente le velocità di rete in entrata e in uscita - Dimensioni carattere - Icone dell\'indicatore - Mostra icone delle connessioni in entrata/uscita accanto all\'indicatore di velocità (non tutti i caratteri personalizzati hanno tutte le icone) - Nascondi bassa velocità - Non mostrare l\'indicatore se la velocità è bassa - Livello di velocità basso - I valori di velocità al di sotto di questa soglia saranno considerati come bassi ed avranno un indicatore differente - Riduci la visibilità quando inattivo - Rendi l\'indicatore semitrasparente quando entrambe le velocità sono uguali a 0 - Controlli gestuali - Esegui le azioni selezionate sul cursore e tocca due volte - Sensibilità della regolazione - Luminosità - Volume - Scorrimento orizzontale con un dito - Scorrimento orizzontale con due dita - Azione doppio tocco - Intervallo della velocità di rete - Aumenta i margini orizzontali per l\'indicatore della velocità di rete - Notifiche compatte - Riduci la spaziatura verticale delle notifiche - Colora il titolo della notifica - Applica il colore dell\'icona al testo del titolo (solo stile di notifica Android) - Riporta la visualizzazione compressa minimalista - Le notifiche di importanza minima potrebbero essere nuovamente compresse in una visualizzazione su una riga - Apri le impostazioni del canale - L\'apertura delle impostazioni dal menu di notifica porta alle impostazioni del canale invece delle impostazioni di notifica comuni dell\'app - Numero massimo di righe nello stile di messaggistica - Limita il numero di righe visualizzate nelle notifiche in stile messaggistica - Nascondi il tasto pulisci - Rimuovi il pulsante che cancella tutte le notifiche - Mostra il livello di illuminazione - Visualizza il valore di illuminamento ambientale all\'interno del cursore della luminosità - Stile alternativo - Testo semitrasparente grande - Mostra la percentuale della luminosità - Visualizza la percentuale del livello di luminosità mentre trascini il cursore della luminosità - Margine superiore del pannello delle percentuali - Disattiva il cursore della luminosità - Menù di notifica esteso - Apri le informazioni sull\'app e forza la chiusura dell\'app dal menù di notifica (scorri la notifica verso sinistra per aprirla) - Disabilita qualsiasi notifica - Consenti di disabilitare anche le notifiche di sistema - Espandi le notifiche - Mostra le notifiche completamente espanse - Black & white list - Modifica il tempo di visualizzazione - Cambia sia la breve che la lunga durata - La durata risultante non scenderà sotto 1 secondo - Raggruppamento automatico delle notifiche - Numero di notifiche da un\'app che attiva il raggruppamento automatico - Gestore delle notifiche posticipate - Aumenta il numero di intervalli di posticipazione e aggiungi l\'icona al launcher che apre un elenco delle notifiche attualmente posticipate - Muta se visibile - Non riprodurre il suono di notifica quando lo schermo è acceso - Posizione del cursore multimediale - Aggiungi un cursore di notifica multimediale che indica la posizione corrente e consente di cambiarla - Usa stile di sistema - Non applicare uno stile sottile personalizzato al cursore - Apri automaticamente il riquadro delle notifiche - Apri automaticamente il riquadro delle notifiche sulle notifiche dalle app selezionate - Forza schermo intero - Non aprire il riquadro delle notifiche quando è attiva l\'app a schermo intero (non si applica alle app immersive con stato e barre di navigazione nascosti) - App selezionate - Comprimi i titoli MIUI - Configura lo stato del titolo della barra delle azioni in tutte le app MIUI 12 - Screenshot - Configurazione screenshot - Personalizza il formato, la qualità e la cartella di salvataggio degli screenshot - Formato - Qualità - Cartella di salvataggio - Nascondi le sovrapposizioni sugli screenshot - Nascondi temporaneamente le sovrapposizioni durante l\'acquisizione di uno screenshot - Tempo di visualizzazione dello screenshot fluttuante - Ritardo prima che la finestra fluttuante con lo screenshot appena creato scompaia - Durata dell\'animazione di ricarica - Per quanto tempo lo schermo deve rimanere acceso dopo l\'avvio dell\'animazione di ricarica - Non accendere lo schermo durante la ricarica - Non accendere lo schermo quando si collega o scollega il caricabatterie - Lo schermo non si accende al collegamento delle cuffie - Non accendere lo schermo quando colleghi le cuffie - Durata prima dello spegnimento dello schermo sulla schermata di blocco - Durata oscuramento - Per quanto tempo lo schermo deve rimanere oscurato prima di spegnersi automaticamente (in percentuale alla durata di spegnimento totale dello schermo) - Intensità della luminosità automatica - Definisci i valori della luminosità automatica minima e massima - Luminosità automatica minima - Luminosità automatica massima - Usa sempre una scala non lineare - Abilita se le percentuali di luminosità della modifica non corrispondono a quelle reali sulle versioni di Android inferiori a 9 - Silenziatore audio - Muta qualsiasi suono che possa essere identificato in modo univoco - Aggiorna la lista - Recupera un elenco dei suoni riprodotti di recente - Suoni silenziati - Suoni riprodotti - Disabilita l\'avviso di volume elevato - Non mostrare la finestra di dialogo quando il volume raggiunge un livello non sicuro - Disabilita ducking - Non ridurre il volume della musica attualmente in ascolto per riprodurre l\'audio delle notifiche - Regolazione immediata del volume - Regola il volume della riproduzione multimediale alla prima pressione del tasto - Controlli del volume separati - Consenti di configurare un volume separato per suonerie/notifiche/suoni di sistema nelle Impostazioni - Cursore del volume delle notifiche - Aggiungi il cursore delle notifiche al menù esteso del volume - Nessun muto multimediale - Non impostare il volume multimediale su zero in modalità Non disturbare - Interruttore modalità DND - Il pulsante nella finestra di dialogo del volume attiva la modalità Non disturbare invece della modalità Silenziosa - Timer estesi - Aggiungi più intervalli ai timer per le modalità Silenzioso e Non disturbare - Ritardo per la scomparsa della finestra di dialogo del volume - Compresso - Esteso - Moltiplicatore delle regolazioni del volume - Aumenta il numero di tacche del volume per ciascun tipo di cursore - Visualizzatore musicale - Visualizza la densità spettrale delle bande con linee di frequenza discrete - Il visualizzatore è disegnato sopra lo sfondo della schermata di blocco - Mostra sulla schermata di blocco personalizzata - Mostra il visualizzatore nella parte superiore della schermata di blocco personalizzata - Mostra nel riquadro delle notifiche - Visualizzatore addizionale nel riquadro esteso delle notifiche - Mostra solo se esiste un controller multimediale - I lettori audio di solito lo creano per le notifiche con i controlli multimediali - Durata dell\'animazione - Trasparenza - Metodo di rendering - Stile - Calore - Colore - Seleziona colore personalizzato - Intervallo del cambio colore dinamico - Ignora chiamate - Impedisci alle chiamate in arrivo di interrompere la riproduzione dell\'audio quando proviene da una delle app selezionate e smetti di avvisarle delle modifiche allo stato delle chiamate - Nessuna vibrazione di prova - Non vibrare quando si cambia la modalità della suoneria in silenziosa o si attiva la vibrazione in questa modalità - Vibrazione leggera - Ridurre l\'intensità della vibrazione durante le ore selezionate - Intensità della vibrazione - Cambia la durata o l\'intensità della vibrazione in base al supporto del controllo dell\'ampiezza da parte del dispositivo - Chiamate - Notifiche - Tutto il resto - Periodo di tempo - Blocca la vibrazione - Impedisci alle app selezionate di utilizzare la vibrazione - Suoni di sistema - PIN alla rinfusa - Cambia casualmente l\'ordine dei pulsanti del PIN - Schermata di blocco avanzata - Disabilita il menù di spegnimento quando il blocco schermo è attivo - Centro di controllo sicuro - Disabilita il Centro di controllo quando il blocco dello schermo è attivo - Impostazioni rapide sicure - Disabilita i tile sensibili alla sicurezza quando il blocco dello schermo è attivo - Tutti i tile di terze parti - Modifica dei tile - Non si applica al Centro di controllo - Mantieni aperto - Non comprimere il pannello dopo lo sblocco - Tile sicuri - Modalità aereo - Posizione - Sincronizzazione - Nessuna password dopo il riavvio - Non richiedere la password al posto dello sblocco con impronta dopo il riavvio. Non funziona su dispositivi crittografati. - Copertina dell\'album come sfondo - Mostra la copertina album della traccia attualmente in riproduzione come sfondo della schermata di blocco - Scala di grigi - Converti le copertine degli album in bianco e nero - Copertina dell\'album sfocata - Scala delle copertine degli album - Sblocca credenziali - L\'autenticazione in alcune app richiede l\'accesso alle credenziali, ma rimangono bloccate se PIN/password/sequenza viene saltato dopo l\'avvio. Questa opzione aggiunge l\'icona di avvio che consente di sbloccare le credenziali. - Azioni personalizzate - Azioni personalizzate per scorciatoie e swipe - Disabilita lo scorrimento verso sinistra - Azione scorrimento verso sinistra - Cambia l\'icona a destra - Sostituisci l\'icona della fotocamera con l\'icona di CustoMIUIzer - Trascina l\'icona per eseguire l\'azione personalizzata - Disabilita lo scorrimento verso destra - Scorciatoie a sinistra dello schermo - Gestisci l\'elenco delle scorciatoie - Allineamento verticale - Centra orizzontalmente - Non richiede lo sblocco - È possibile accedere alle app avviate mentre il dispositivo è ancora bloccato - Disabilita schermata di blocco - Alcuni dispositivi potrebbero non funzionare senza sbloccarli una volta dopo l\'avvio - Disattiva selettivamente il blocco dello schermo (non modifica la sicurezza delle app e non rimuove i dati delle impronte digitali) - Salta schermata di blocco - Non mostrare la schermata di blocco quando il blocco dello schermo è disabilitato - Salta sblocco facciale - Non avviare lo sblocco facciale quando il blocco dello schermo è disabilitato - Reti Wi-Fi affidabili - Disabilita temporaneamente il blocco dello schermo quando sei connesso a queste reti - Dispositivi bluetooth affidabili - Disabilita temporaneamente il blocco dello schermo quando sono collegati questi dispositivi - Blocca forzamento - Sblocca forzamento - Non forzare - Disattiva le animazioni - Configura la durata dell\'animazione - Valori molto bassi praticamente disabiliteranno l\'animazione - Sfocatura dello sfondo - Intensità della sfocatura dello sfondo nelle app recenti - Intensità della sfocatura dello sfondo nel riquadro delle notifiche - Nascondi temporaneamente lo sfondo a tema - Nascondi lo sfondo durante la modifica della luminosità - Opacità dello sfondo a tema - Opacità dello sfondo a tema nel riquadro delle notifiche - Schermata di blocco - Funzionalità aggiuntive - Sicurezza - Elementi aggiuntivi - Aggiungi l\'icona dell\'applicazione e l\'etichetta ai suoi toast - Blocca i toast - Impedisci alle app selezionate di mostrare i toast - Modalità interfaccia - Cambia modalità in scura, chiara o automatica. Non è richiesto il riavvio. - Tile modalità scura - Aggiungi il tile per attivare la modalità scura nelle impostazioni rapide. Non è richiesto il riavvio. - Disabilita la modalità scura forzata - Non invertire alcuni colori in modalità scura - Menù di spegnimento esteso - Aggiungi nuove opzioni di riavvio al menù di spegnimento (modalità Fastboot, modalità Recovery, Riavvio veloce, Riavvio System UI, Riavvio Launcher) - Consenti downgrade - Rendi possibile l\'installazione di una versione precedente dell\'app su una più recente - Disabilita la verifica della firma - Permetti l\'aggiornamento delle app anche quando la firma dell\'APK è diversa da quella installata - Lente d\'ingrandimento del testo - Visualizza il testo ingrandito quando si sposta un cursore di input o si effettua una selezione - Disabilita overscroll - Impedisci lo scorrimento eccessivo delle visualizzazioni elenco - Disabilita la protezione dei contenuti sicuri - Consenti screenshot e registrazione video di qualsiasi app - Nascondi avviso sul livello di batteria scarica - Non visualizzare la finestra di avviso che chiede di attivare il Risparmio energetico - Nascondi avviso sui tocchi disabilitati - Non visualizzare l\'avviso che indica che l\'area degli auricolari è coperta - Ridimensionamento libero dei widget - Rimuovi qualsiasi limite sulla dimensione dei widget - Sblocca i launcher - Elimina le restrizioni dei launcher di terze parti sulle ROM cinesi - Pulisci il menù di condivisione - Rimuovi le app selezionate dal menù di condivisione - Menù di prova - Pulisci il menù \"Apri con\" - Rimuovi le app selezionate dal menù \"Apri con\" - Seleziona il tipo di dati di prova - Seleziona il tipo di dati da nascondere - Modalità USB predefinita - Applica la configurazione selezionata quando è collegato un altro dispositivo - Ignora blocco - Applica anche se il dispositivo è ancora bloccato - RNDIS (Tethering USB) - Impedisci la chiusura forzata delle app - Non consentire alla MIUI di chiudere le app selezionate - Animazione di rotazione - Tutte le rotazioni - Consenti tutte le rotazioni dello schermo, incluso verticale capovolto - Blocco della rotazione - Aggiungi nelle impostazioni rapide il tile per bloccare la rotazione in modalità verticale o orizzontale - Mantieni le notifiche - Mostra le notifiche sulla schermata di blocco anche dopo che è stata rimossa e poi riaperta - Altre notifiche - Aumenta il limite di notifiche attive per una singola app da 10 a 24 - Risposta diretta senza sblocco - Non è necessario sbloccare il dispositivo per utilizzare la risposta diretta sulla schermata di blocco - Consenti nella schermata di blocco - Forza la visualizzazione di tutte le notifiche delle app MIUI sulla schermata di blocco - Consenti come notifiche fluttuanti - Forza la visualizzazione di tutte le notifiche delle app MIUI come fluttuanti - Nascondi barra di stato - Rimuovi la barra di stato dalla schermata di blocco - Nascondi il blocco superiore - Rimuovi il blocco superiore contenente orologio, data e altre informazioni - Nascondi suggerimento di sblocco - Rimuovi il suggerimento \"Scorri verso l\'alto per sbloccare\" - Nessuna chiamata di emergenza - Disabilita il pulsante di chiamata di emergenza sulla schermata di blocco - Pulisci la visualizzazione in modalità estesa - Nascondi le impostazioni rapide e il cursore della luminosità nella modalità di notifiche estesa sulla schermata di blocco - Disabilita lo sfondo colorato - Cambia il colore di sfondo generato automaticamente dallo sfondo del telefono in trasparente mentre sei sulla schermata di blocco - Tocca per sbloccare - Inizia lo sblocco del dispositivo toccando l\'area inferiore della schermata di blocco - Doppio tocco per spegnere - Spegni lo schermo toccando due volte su un qualsiasi spazio vuoto nella schermata di blocco - Visualizza i dati di ricarica - Mostra ulteriori informazioni sulla ricarica nella parte inferiore della schermata di blocco - Come visualizzare - Ricarica attuale - Voltaggio della batteria - Consumo energetico - Temperatura della batteria - Visualizza prossima sveglia - Mostra l\'ora della sveglia più vicina alla data attuale - Formato di visualizzazione - Mostra tutte le sveglie - Ottieni l\'ora della prossima sveglia utilizzando l\'API Android predefinito quando la sveglia MIUI non è impostata. Potrebbe produrre risultati inaspettati. - Barra di stato e riquadro delle notifiche - Barra di stato - Riquadro delle notifiche - Notifiche - Elenco delle app recenti - Usa l\'implementazione nativa - Non utilizzare l\'elenco delle app recenti di MIUI Launcher. Funziona male con i gesti a schermo intero. - Rimuovi il pulsante \"Pulisci\" - Nascondi il pulsante che chiude le app recenti e svuota la memoria - Cancella tutto - Fai in modo che il pulsante \"Pulisci\" chiuda tutte le attività in esecuzione - Nascondi dai recenti - Nascondi le app selezionate dall\'elenco delle attività recenti - Azione del primo tasto di scelta rapida - Azione per la prima scorciatoia di suggerimento - Azione del secondo tasto di scelta rapida - Azione per la seconda scorciatoia di suggerimento - Azione del terzo tasto di scelta rapida - Azione per la terza scorciatoia di suggerimento - Azione del quarto tasto di scelta rapida - Azione per la quarta scorciatoia di suggerimento - Notifiche popup - Ritardo nascondimento automatico - Non nascondere automaticamente - Non eliminare automaticamente i popup - Consenti finestra fluttuante - Apri l\'app in una finestra fluttuante al gesto di scorrimento verso il basso se per la notifica è stata definita un\'azione di clic appropriata - Abilita lo scorrimento verso il basso - Apri il riquadro delle notifiche con lo scorrimento verso il basso - Finestre fluttuanti - Disabilita la blacklist - Consenti a qualsiasi app di essere aperta in una finestra fluttuante - Ricorda lo stato - Continua ad aprire le app in finestre fluttuanti finché non vengono ripristinate manualmente a schermo intero - Multiwindow+ - Consenti l\'utilizzo di schermo diviso e finestre fluttuanti insieme - Blocco app - Blocco delle app meno stringente - Non bloccare le app quando il dispositivo è bloccato se è selezionata l\'opzione con il blocco delle app dopo la chiusura - Durata blocco app - Intervallo di tempo durante il quale l\'app rimane sbloccata dopo l\'uscita - Elenco delle app da bloccare - Versione avanzata dell\'opzione Blocco app che consente di bloccare qualsiasi app installata. Non è richiesto il riavvio. - Salta blocco app - Consenti alle attività selezionate di ignorare il blocco dell\'app - Attività selezionate - Impostazioni rapide - Numero di righe - Per avere 5 righe le etichette verranno nascoste nell\'orientamento verticale. Il numero di righe sarà limitato a 3 con etichette nascoste nell\'orientamento orizzontale. - Numero di colonne - L\'orientamento orizzontale avrà una colonna aggiuntiva. Se la tua ROM ha l\'opzione del layout compatto per le impostazioni rapide, aggiungerà un\'altra colonna in entrambi gli orientamenti. - Numero di colonne nel riquadro compresso - L\'orientamento orizzontale avrà una colonna aggiuntiva. - Rimuovi completamente le etichette - Feedback aptico sulle impostazioni rapide - Vibra al tocco dei tile nelle impostazioni rapide - Altro - Sfocatura dello sfondo della finestra di dialogo del volume - Finestra di dialogo compressa - Finestra di dialogo estesa - Scala delle animazioni - Finestre - Transizioni - Valore delle animazioni - POCO Launcher - MIUI Launcher - Gesture - Azioni - Impostazione per l\'interruttore - App da avviare - Scorciatoia da avviare - Attività da avviare - Launcher - Mostra le mod per il launcher selezionato. Solo per aiuto visivo, non ha alcun effetto sulle mod. - Modalità prestazioni - Metodo alternativo per applicare tutte le mod del launcher - Scorrimento infinito - Passa dall\'ultima pagina alla prima e viceversa - Non nascondere l\'orario - Non nascondere l\'orologio della barra di stato sulle pagine con il widget dell\'orologio - Abilita interruttore schermo -1 - Visualizza un interruttore tra App Vault e Google Discover nelle impostazioni della schermata Home - Richiede la ROM Global (internazionale) - Forza Google Discover - Sostituisci App Vault con Google Discover (richiede l\'installazione dell\'app Google) - Disabilita la schermata solo widget - Fai in modo che tutte le schermate supportino sia widget che app sui tablet - Rimuovi l\'animazione di sblocco - Non animare le icone quando il dispositivo è sbloccato - Usa la vecchia animazione di avvio - Ripristina la transizione di apertura dell\'app a una precedente - Supporto per il verticale capovolto - Ruota il launcher per l\'orientamento verticale - Indicatore dinamico della pagina - Mostra l\'indicatore della pagina solo durante lo scorrimento - Mostra solo in modalità modifica - Sblocca le dimensioni della griglia - Rendi disponibili tutte le dimensioni della griglia da 3x4 a 10x10 nelle impostazioni del layout della schermata principale - Altre icone nel dock - Numero illimitato di icone nel dock - Chiudi automaticamente il drawer - Chiudi il drawer dopo l\'avvio - Ridimensionamento delle icone - Margini della griglia orizzontale - Margine superiore della griglia - Margine inferiore del dock - Altezza dell\'indicatore della pagina - Cartelle - Numero di colonne nelle cartelle - Usa l\'intera larghezza della cartella - Riduci la spaziatura laterale - Correggi la modalità della barra di stato - Regola il colore dei contenuti della barra di stato per gli sfondi chiari/scuri nella versione sviluppatore del launcher - Correggi l\'animazione - Applica il ridimensionamento del valore della durata dell\'animazione ad alcune animazioni del launcher - Correggi le informazioni sull\'app - Apri sempre le informazioni sull\'app in stile MIUI dal menù con pressione prolungata - Colore di sovrapposizione - Scurire o schiarire lo sfondo - Intensità del colore - Sfocatura - Opzioni di sfocatura del colore di sfondo e dello sfondo del telefono. Il launcher deve supportare la sfocatura nelle cartelle. - Sfocatura dello sfondo - Sfocatura dello sfondo del telefono - Visibilità - Raggio - Influisce anche sulla sfocatura dello sfondo del telefono nella modalità di modifica - Chiudi automaticamente le cartelle - Chiudi la cartella dell\'app dopo l\'avvio - Titoli delle app - Nascondi i titoli - Mostra i titoli nel dock - DImensione carattere - Margine superiore aggiuntivo - Ombra più scura - Rende l\'ombra del titolo meno trasparente - Titoli delle app personalizzati - Titoli modificati - Titolo modificato - App nascoste - Le autorizzazioni necessarie non sono state concesse - Nessuna cartella nascosta - Disabilita il gesto con due dita che apre la cartella delle app nascoste - Elenco delle app da nascondere - Versione avanzata dell\'opzione App nascoste che consente di nascondere qualsiasi app installata. Non è richiesto il riavvio. - Azione di scorrimento verso il basso (1 dito) - Azione di scorrimento verso il basso con 1 dito nella schermata principale - Azione di scorrimento verso il basso (2 dita) - Azione di scorrimento verso il basso con 2 dita nella schermata principale - Azione di scorrimento verso l\'alto (1 dito) - Azione di scorrimento verso l\'alto con 1 dito nella schermata principale - Azione di scorrimento verso l\'alto (2 dita) - Azione di scorrimento verso l\'alto con 2 dita nella schermata principale - Azione di scorrimento verso destra - Azione di scorrimento verso destra sul dock del launcher - Azione di scorrimento verso sinistra - Azione di scorrimento verso sinistra sul dock del launcher - Azione scuoti - Azione per lo scuotimento del dispositivo sulla schermata principale - Azione doppio tocco - Azione per doppio tocco su uno spazio vuoto della schermata principale - Correzioni di bug - Controlli - Azione doppia pressione - Sostituisci l\'avvio della fotocamera premendo due volte il tasto di accensione. Richiede l\'attivazione della scorciatoia predefinita del pulsante. - Disabilita la combinazione dello screenshot - Non effettuare una cattura dello schermo quando si premono insieme il tasto di accensione e quello di riduzione del volume - Torcia veloce - Premi a lungo il pulsante di accensione mentre lo schermo è spento per accendere la torcia - Ritardo per l\'attivazione della torcia - Aumenta i tempi di risposta della pressione prolungata del tasto di accensione - Scanner dell\'impronta digitale - Azione singolo tocco - Azione per un singolo tocco quando lo schermo è acceso - Azione doppio tocco - Azione per un doppio tocco quando lo schermo è acceso - Ritardo doppio tocco - L\'azione del tocco singolo verrà ritardata di - Azione pressione prolungata - Azione per una pressione prolungata quando lo schermo è acceso - Ritardo pressione prolungata - Nessuna azione nella Fotocamera - Abilita questa opzione se utilizzi l\'opzione dell\'impronta digitale per attivare l\'otturatore - Nessuna azione durante le chiamate - Non eseguire azioni quando è in corso una chiamata - Accetta la chiamata in arrivo - Rifiuta la chiamata in arrivo - Termina la chiamata attuale - Le azioni di accettazione e rifiuto non possono avere la stessa combinazione. - L\'azione di accettazione è stata disabilitata. - L\'azione di rifiuto è stata disabilitata. - Accendi lo schermo dopo un errore - Accendi lo schermo dopo un\'autenticazione fallita - Richiedi le impronte digitali registrate - Non accendere lo schermo quando non sono registrate le impronte digitali - Vibra all\'autenticazione - Feedback aptico in caso di autenticazione riuscita - Ignora le impostazioni di sistema - Non disabilitare il feedback aptico quando la vibrazione al tocco è disabilitata - Non vibrare in caso di autenticazione fallita - Rimuovi il feedback aptico in caso di errore di autenticazione - Tasto di accensione - Tasti del volume - Controlla il cursore di input - Sposta il cursore di immissione del testo usando i tasti del volume - Cambia direzione - Scambia la direzione dei movimenti del cursore - Pressione prolungata Volume Su - Azione per la pressione prolungata di Volume Su quando lo schermo è spento - Pressione prolungata Volume Giù - Azione per la pressione prolungata di Volume Giù quando lo schermo è spento - Vibrazione alla pressione prolungata - Vibra quando viene eseguita un\'azione di pressione prolungata - Barra di navigazione - Nascondi la barra di navigazione - Pulsante indietro reattivo - Cambia l\'icona del pulsante indietro con quella alternativa nella modalità di input - Altezza della barra di navigazione - Azione pressione prolungata tasto Indietro - Azione pressione prolungata tasto Home - Azione pressione prolungata tasto Menù - Azione pressione tasto di navigazione aggiuntivo a sinistra - Azione tasto sinistro - Azione pressione prolungata tasto di navigazione aggiuntivo a sinistra - Azione pressione prolungata del tasto sinistro - Azione pressione tasto di navigazione aggiuntivo a destra - Azione tasto destro - Azione pressione tasto di navigazione aggiuntivo a destra - Azione pressione prolungata del tasto destro - Margine aggiuntivo - Aumenta la distanza dai bordi dello schermo per i tasti aggiuntivi - Nessuna azione definita - Gesture a tutto schermo - Altezza dell\'area della gesture Indietro - Larghezza dell\'area della gesture Indietro - Gesture orizzontali - Abilita sia le gesture orizzontali che la barra di navigazione - Azione di scorrimento dell\'angolo - Esegui l\'azione selezionata invece di aprire l\'Assistente Google - Varie - Apri \"Aggiornamenti app di sistema\" - L\'app non fa più parte di alcune ROM e deve essere installata manualmente - Fai attenzione quando aggiorni app di sistema modificate su ROM personalizzate, potresti perdere le funzionalità aggiuntive - Utilizza il programma di installazione dei pacchetti MIUI - Imposta il programma di installazione dei pacchetti di Xiaomi come predefinito e consentigli di aggiornare le app di sistema - L\'app richiesta non è installata. Premi a lungo per scaricarla. - Informazioni sull\'app nel programma di installazione - Visualizza le informazioni sull\'app che si sta installando - Pacchetto - Nome della versione - Codice versione - SDK supportato - attuale - Compatibilità sveglia - Fai in modo che le app selezionate visualizzino l\'ora corretta della prossima sveglia impostata nell\'app Orologio MIUI - Spaziatura inferiore in verticale - Spaziatura inferiore in orizzontale - Mostra interfaccia di chiamata - Definisci quando visualizzare l\'interfaccia per la chiamata in arrivo invece della notifica popup - Luminosità dello schermo durante le chiamate - Tipi di chiamate - Valore di luminosità - Modalità notturna - Non cambiare la luminosità durante la notte - Inizio - Fine - Promemoria chiamate perse - Definisci suono, vibrazione e intervallo per il promemoria - Intervallo - Suono - Nessun suono - Proprio modello - Formato: ritardo,vibrazione,ritardo,vibrazione,… - Controllo dello stato dell\'app - Consente di disattivare quasi tutte le app dalla loro pagina delle informazioni - Mostra dettagli aggiuntivi delle app - Aggiungi nuovi campi alla pagina delle informazioni dell\'app:\n- codice versione\n- percorso completo dell\'apk\n- percorso dati\n- ID utente\n- versione SDK di destinazione\n- collegamento alla pagina nel Play Store\n- avvia un\'app - Ordinamento iniziale delle app installate - Disattivare l\'app? - Se questa è un\'app di sistema essenziale, disattivarla può causare problemi :) - Non è una buona idea! :) - Impossibile modificare lo stato dell\'app - Apri nel Play Store - Avvia - L\'app non ha un\'attività di avvio predefinita - Nome file APK - Codice versione APK - Percorso dati - ID utente - Versione SDK di destinazione - Stato (Predefinito) - Nome app - Frequenza di utilizzo - Spazio utilizzato - Data di installazione - Tastiera Google - Chiamate - Impostazioni - Predefinito - Sistema - Nessuna azione - Espandi il riquadro delle notifiche - Espandi il riquadro delle impostazioni rapide - Blocca il dispositivo - Metti in stand-by - Cattura uno screenshot - Apri il menù - Apri i recenti - Apri la finestra di dialogo del volume - Aumenta il volume - Volume più basso - Avvia l\'app - Avvia scorciatoia - Avvia attività - Interruttore funzionalità - Torna all\'app precedente - Forza la chiusura dell\'app corrente - Apri il menù di spegnimento - Menù di spegnimento - Pulisci la memoria - Inverti i colori - Cambia tastiera - Torna indietro - Modalità a una mano (sinistra) - Modalità a una mano (destra) - Bluetooth - Profilo audio - Luminosità automatica - Rotazione automatica - Torcia - Rete dati - Icona - Etichetta - Icona ed etichetta - Nessuna - Dissolvenza - Nessuna modifica - Riproduci/Pausa - Traccia successiva - Traccia precedente - Tutti gli eventi di ricarica - Solo gli eventi senza animazione - Predefinite di sistema - Disabilita completamente - Richiedi l\'autenticazione dopo l\'avvio - Disabilita su reti/dispositivi attendibili - Non richiedere - Debole (impronta digitale) - Forte (PIN/password/sequenza) - Nessuna sfocatura - Nessuna icona - L\'intero sfondo - Solo al centro - Per tutte le app eccetto quelle elencate - Solo per le app elencate - Nascondi solo quando non connesso - Nascondi completamente - Non raggruppare - Vibrazione leggera - Vibrazione forte - Abilita - Disabilita - Vicino alla cima - Al centro - Vicino al fondo - Massimo - Grande - Normale - Piccolo - Bassa - Media - Alta - Abbina la copertina dell\'album o lo sfondos - - Colore personalizzato - Colori dell\'arcobaleno (orizzontale) - Colori dell\'arcobaleno (verticale) - Arcobaleno - Colore dinamico - Discreto - Graduale - Barre piene - Barre piene rotonde - Barre tratteggiate - Cerchi - Linea - Mai - Per 1 giorno dopo l\'aggiornamento - Per 3 giorni dopo l\'aggiornamento - Per 1 settimana dopo l\'aggiornamento - Sempre - Immagine - Audio - Video - Documento - Archivio - Collegamento - Qualsiasi - Altri - Quando non è in modalità a schermo intero - In entrata - In uscita - Entrambe - Nessuna vibrazione - Singolo (breve) - Singolo (lungo) - Ticktock - Battito cardiaco - Valzer - Zig-zig-zig - Proprio modello - Adatta allo schermo - Copri l\'intero schermo - Superiore - Inferiore - Regola la luminosità - Regola il volume - Durata normale - Durata relativa - Singolo tocco - Doppio tocco - Pressione prolunga - Nuovo anno - Capodanno cinese - Coronavirus anti-vacanza - Solo display - Nascondi - Rileva automaticamente - Aggiungi - Anteponi - Inserisci come nuova riga - Percorso selezionato - Inizialmente - Permanentemente - Illimitato - Wi-Fi attivo - Wi-Fi disattivo - Bluetooth attivo - Bluetooth disattivo - GPS attivo - GPS disattivo - Hotspot attivo - Hotspot disattivo - NFC attivo - NFC disattivo - Profilo audio: Normale - Profilo audio: Silenzioso - Profilo audio: Vibrazione - Luminosità automatica attiva - Luminosità automatica disattiva - Rotazione automatica attiva - Rotazione automatica disattiva - Torcia: spenta - Torcia: accesa - Rete dati attiva - Rete dati disattiva - Blocco rotazione - Senza restrizioni - Ritratto - Orizzontale - Modalità scura - CustoMIUIzer non dispone dell\'autorizzazione per cambiare la modalità scura - Impostazioni CustoMIUIzer - Contrassegna le nuove mod - Mostra l\'etichetta \"Nuovo!\" nel titolo per le mod aggiunte nella versione corrente - Nuovo! - Icona nel launcher - Mostra l\'icona nel launcher - Icona di accesso rapido - Mostra l\'icona nelle Impostazioni - Repository personale - Aggiungi repository personalizzato a EdXposed Manager per caricare le informazioni di CustoMIUIzer in modo più affidabile - Viene utilizzato un repository aggiuntivo - Lingua dell\'interfaccia - Visualizza sempre l\'interfaccia del modulo nella lingua selezionata - Design delle vacanze - Decora l\'interfaccia del modulo in base all\'occasione - Risoluzione dei problemi - Invia un rapporto dettagliato - Raccogli le informazioni sul dispositivo, logcat e log di Xposed, e inviali allo sviluppatore.\nÈ necessaria una connessione a Internet - Inserisci i tuoi dati di contatto e saranno inclusi nei rapporti dettagliati e sugli arresti anomali - Informazioni di contatto - È assolutamente necessario compilare questo campo se ti aspetti di ricevere risposte ai tuoi rapporti sugli arresti anomali. Usa email, nickname ICQ, XDA o 4PDA. - Supporto - Repository CustoMIUIzer - Repository Git con sorgenti e distribuzioni di moduli - Thread XDA - Thread del modulo sul forum XDA - Thread 4PDA - Thread del modulo sul forum 4PDA - Segnala un bug - Inviaci una segnalazione di bug o una richiesta di funzionalità tramite il tracker ufficiale dei problemi - Dona $%1$d - Dona - Il modo migliore per esprimere la tua gratitudine verso questo fantastico modulo :) - In-app - Lascia che sia Google a gestire tutto - Criptovalute - La moneta del futuro :) - Valute obsolete - Grazie per la tua donazione! - Grazie per la tua generosa donazione! - Grazie per la tua mostruosa donazione! 😮 - Impossibile ottenere i dati di fatturazione, controlla la tua connessione Internet - Cambiato idea? ;) - CustoMIUIzer è andato in crash! - Tutti i dati necessari sono stati raccolti - Dimensione del rapporto generato - Descrivi il tuo problema (in inglese se possibile): - Descrivi le azioni che hanno portato al crash -\n(possibilmente in inglese): - Le informazioni di contatto non sono state fornite, non riceverai una risposta a questo rapporto! - È necessaria una connessione ad internet - La descrizione non può essere vuota - Ignora - Invia rapporto - Invio del risultato - Il rapporto è stato inviato con successo! - Impossibile inviare il rapporto - Conferma - Costruzione del rapporto… - Invio del rapporto… - Automatico - Scuro - Chiaro - Impossibile inizializzare l\'SDK MIUI.\nNon è una ROM MIUI? - Non selezionato - Attenzione! - L\'opzione Black/White list è attiva in Xposed Framework, può impedire il corretto funzionamento delle mod. - Inoltre, la versione del modulo installato proviene da Google Play e presenta ulteriori limitazioni. Considera l\'idea di reinstallarlo da una qualsiasi altra fonte. - Gestisci i moduli Xposed - Riavvio veloce - Eseguire un riavvio veloce adesso? - Riavvia il launcher - Backup delle impostazioni - Scegli l\'opzione desiderata - Backup - Ripristino - La tua memoria esterna è di sola lettura - Impossibile accedere a un qualsiasi spazio di archiviazione adatto - Impossibile creare la directory di backup - Impossibile creare il file di backup - Nessun backup delle impostazioni trovato - Il backup delle impostazioni è stato eseguito con successo! - Le impostazioni sono state ripristinate con successo! - Le tue impostazioni sono state ripristinate tramite Google Cloud Backup. Effettua un riavvio veloce dopo aver abilitato il modulo Xposed. - Le impostazioni del modulo sono state migrate con successo per funzionare con la nuova versione di EdXposed. Riavvia per applicare le modifiche. - Impossibile migrare le impostazioni del modulo per funzionare con la nuova versione di EdXposed. Dovrai utilizzare la funzione di ripristino o configurare le mod da zero. - Aggiornamento disponibile ⚠ - Seleziona app - App selezionate - Seleziona attività - Nessuna attività trovata - Seleziona scorciatoia - Cerca mod - Reti Wi-Fi - Impostazioni di geolocalizzazione - L\'accesso alla posizione è necessario affinché le app ottengano un elenco delle reti Wi-Fi su Android Pie - Reti attendibili - Reti disponibili - Recupera l\'elenco dei dispositivi - Recupera l\'elenco dei dispositivi bluetooth memorizzati nella cache dal sistema - Dispositivi attendibili - Dispositivi disponibili - Dispositivi bluetooth - Il bluetooth non è supportato su questo dispositivo - Prima attiva il bluetooth - Prima attiva il Wi-Fi - Impossibile eseguire la scansione senza accesso alla posizione - Chiusura forzata %s - Le credenziali sono già sbloccate - Sblocca credenziali - Credenziali sbloccate! - App Xposed non trovata - Sembra che tu non abbia installato Xposed Framework.\n\nTieni presente che le mod funzionano solo con Xposed! - Gli hook delle risorse sono disabilitati - Gli hook delle risorse sono disabilitati nelle impostazioni di Xposed Installer, il modulo non verrà attivato! - Il modulo CustoMIUIzer non è attivo!\nApri l\'app di Xposed, attiva il modulo e riavvia. - È necessaria un\'app browser per aprire gli URL - Okay - Annulla - Aggiungi - Elimina - Premi a lungo l\'elemento per eliminare - Cambia icona - Cerca le mod per nome.\nPremi a lungo per visualizzare l\'elenco delle nuove mod. - Non dimenticare di applicare le mod utilizzando il riavvio veloce.\nLe mod dinamiche ⟲ lo richiedono solo una volta.\nUlteriori informazioni sono disponibili nella pagina Informazioni. - Le nuove mod introdotte dall\'ultimo aggiornamento\npossono essere contrassegnate per una maggiore visibilità - Vuoi effettuare il backup o no? - Vuoi ripristinare il backup o no? - Vuoi ottenere l\'elenco di reti/dispositivi o no? - Ora dovrai abilitare manualmente l\'autorizzazione per questa opzione. Buon lavoro! - %d ms - %d s - %d m - %d KB/s - 1 KB/s - B/s - KMGTPE - %s lux - Spento - 30 minuti - 1 ora - 2 ore - 3 ore - 4 ore - 5 ore - 6 ore - 8 ore - 10 ore - 12 ore - Bianco - Nero - Colore della barra di stato - file - fonte - Sblocca frame rate - Rendi disponibili fps fino a 90 nell\'app Screen Recorder. L\'effettivo funzionamento di fps più alti dipende dal dispositivo e dal driver video. - Sincronizzazione - Prova ad aggiornare il valore in un momento specifico - Inizio di un secondo - Fine di un secondo - Tempo regolare e relativo - È installata una versione non supportata di EdXposed Manager - Lo scope di attivazione è attivo per questo modulo, può impedire ad alcune mod di funzionare correttamente. - Indicatori attività di rete - Configura gli indicatori dei dati mobili e del traffico Wi-Fi - Stile del cursore della luminosità coerente - Rimuovi l\'ombra e lo sfondo aggiuntivo dal cursore durante la modifica della luminosità - Configurazione modalità aereo - Definisci le comunicazioni consentite in modalità aereo. Non è richiesto il riavvio. - Mod che cambia solo l\'impostazione di sistema esistente, alcune opzioni potrebbero non funzionare - Cambia lo sfondo da qualsiasi app - Permetti alle app di terze parti di impostare lo sfondo della schermata di blocco. L\'app Temi deve essere installata e deve possedere il permesso di accedere allo spazio di archiviazione. - Mostra centrato - Visualizza i popup al centro dello schermo - Azione pizzica - Azione di spostare 2 dita l\'una verso l\'altra su qualsiasi schermata iniziale - Azione diffusione - Azione di allontanare 2 dita l\'una dall\'altra su qualsiasi schermata iniziale - Rete cellulare e dati mobili - Mantieni così com\'è - Spegni - Spegni e disattiva - Restrizioni complete - Consente di configurare il risparmio energetico e l\'accesso al Wi-Fi per le app di sistema - \ No newline at end of file diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index 668881e5..e2773e2b 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -1,6 +1,6 @@ - + - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a10f0cb1..4a6eb45a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -5,10 +5,10 @@ #99000000 #33808080 - #ff58a1ff + #ff0d84ff @color/highlight_normal_light - #80000000 + #ff8c93b0 #ff000000 #4d000000 #ff000000 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index eec83472..107848c2 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -4,7 +4,7 @@ 15dp 15.16dp 15.19dp - 25dp + 20dp 15dp 14sp 12.36sp diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 19a1f27b..413fc29d 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -6,6 +6,8 @@ true @null @style/DropDownItemStyle + @color/highlight_normal_light + @color/highlight_normal_light - + + - + From 92f3b333350f96adaeb199c8eb01baa7d12625e1 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 17 Jun 2022 17:44:17 +0800 Subject: [PATCH 015/627] fix: sticky float window --- app/build.gradle | 4 +-- .../mikanoshi/customiuizer/mods/System.java | 35 +++++++++---------- app/src/main/res/values-zh-rCN/strings.xml | 2 +- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5a31b468..0e69a64f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { minSdkVersion 30 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 30 - versionCode 5 - versionName "3.2.1.220614" + versionCode 6 + versionName "3.2.1.220617" resConfigs 'ru-rRU', 'zh-rCN' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d44ad392..b77b8b8a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -3239,10 +3239,10 @@ protected void after(MethodHookParam param) throws Throwable { try { if (param.args[0] == null) return; Intent origIntent = (Intent)param.args[0]; - Intent intent = (Intent)origIntent.clone(); - String action = intent.getAction(); + String action = origIntent.getAction(); if (action == null) return; if (!action.equals(Intent.ACTION_SEND) && !action.equals(Intent.ACTION_SENDTO) && !action.equals(Intent.ACTION_SEND_MULTIPLE)) return; + Intent intent = (Intent)origIntent.clone(); if (intent.getDataString() != null && intent.getDataString().contains(":")) return; if (intent.hasExtra("CustoMIUIzer") && intent.getBooleanExtra("CustoMIUIzer", false)) return; Set selectedApps = MainModule.mPrefs.getStringSet("system_cleanshare_apps"); @@ -3258,7 +3258,9 @@ protected void after(MethodHookParam param) throws Throwable { boolean hasDual = false; try { hasDual = XposedHelpers.callMethod(pm, "getPackageInfoAsUser", resolveInfo.activityInfo.packageName, 0, 999) != null; - } catch (Throwable ignore) {} + } catch (Throwable ignore) { + XposedBridge.log(ignore); + } if ((removeOriginal && !hasDual) || removeOriginal && hasDual && removeDual) itr.remove(); } param.setResult(resolved); @@ -7131,11 +7133,11 @@ public static String getTaskPackageName(Object thisObject, int taskId, ActivityO } public static String getTaskPackageName(Object thisObject, int taskId, boolean withOptions, ActivityOptions options) { - Object mRootActivityContainer = XposedHelpers.getObjectField(thisObject, "mRootActivityContainer"); - if (mRootActivityContainer == null) return null; + Object mRootWindowContainer = XposedHelpers.getObjectField(thisObject, "mRootWindowContainer"); + if (mRootWindowContainer == null) return null; Object task = withOptions ? - XposedHelpers.callMethod(mRootActivityContainer, "anyTaskForId", taskId, 2, options, true) : - XposedHelpers.callMethod(mRootActivityContainer, "anyTaskForId", taskId, 0); + XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 2, options, true) : + XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 0); if (task == null) return null; Intent intent = (Intent)XposedHelpers.getObjectField(task, "intent"); return intent == null ? null : intent.getComponent().getPackageName(); @@ -7185,7 +7187,7 @@ protected void after(MethodHookParam param) throws Throwable { int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); String pkgName = intent.getComponent().getPackageName(); if (windowingMode != 5 && fwApps.containsKey(pkgName)) try { - Class mmwuCls = findClassIfExists("android.util.MiuiMultiWindowUtils", null); + Class mmwuCls = findClassIfExists("android.util.MiuiMultiWindowUtils", lpparam.classLoader); if (mmwuCls == null) { Helpers.log("StickyFloatingWindowsHook", "Cannot find MiuiMultiWindowUtils class"); return; @@ -7210,7 +7212,9 @@ protected void after(MethodHookParam param) throws Throwable { try { Object injector = XposedHelpers.callMethod(options, "getActivityOptionsInjector"); XposedHelpers.callMethod(injector, "setFreeformScale", scale); - } catch (Throwable ignore) {} + } catch (Throwable ignore) { + XposedBridge.log(ignore); + } param.setResult(options); } catch (Throwable t) { @@ -7219,7 +7223,7 @@ protected void after(MethodHookParam param) throws Throwable { } }); - Helpers.hookAllMethods("com.android.server.wm.ActivityStackSupervisor", lpparam.classLoader, "startActivityFromRecents", new MethodHook() { + Helpers.hookAllMethods("com.android.server.wm.ActivityTaskSupervisor", lpparam.classLoader, "startActivityFromRecents", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { Object safeOptions = param.args[3]; @@ -7237,20 +7241,13 @@ protected void after(MethodHookParam param) throws Throwable { Helpers.hookAllMethods("com.android.server.wm.MiuiFreeFormGestureController", lpparam.classLoader, "notifyFullScreenWidnowModeStart", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - String pkgName = (String)XposedHelpers.getObjectField(param.thisObject, "mFreeFormPackageName"); + if (param.args.length != 3) return; + String pkgName = (String)XposedHelpers.callMethod(param.args[1], "getStackPackageName"); if (fwApps.remove(pkgName) != null) storeFwAppsInSetting((Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext")); } }); -// Helpers.hookAllMethods("com.android.server.wm.MiuiFreeFormGesturePointerEventListener", lpparam.classLoader, "startShowFullScreenWindow", new MethodHook() { -// @Override -// protected void before(MethodHookParam param) throws Throwable { -// Object mGestureController = XposedHelpers.getObjectField(param.thisObject, "mGestureController"); -// XposedBridge.log("FULLSCREEN: " + XposedHelpers.getObjectField(mGestureController, "mFreeFormPackageName")); -// } -// }); - Helpers.findAndHookMethod("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "onSystemReady", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 8697b400..a4833028 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1009,7 +1009,7 @@ 尝试在指定时间更新值 开始秒 结束秒 - 定期和相对时间 + 定时和相对时间 不支持的EdXposed Manager版本已安装 此模块的激活范围已激活,可能会阻止某些模块正常运行。 网络活动指示器 From b9bd680e7fb9142472cc49fd31e34d2b450975b1 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 20 Jun 2022 18:23:42 +0800 Subject: [PATCH 016/627] fix: Extended notification menu --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 3 +- .../mikanoshi/customiuizer/MainModule.java | 2 +- .../mikanoshi/customiuizer/mods/Controls.java | 2 +- .../mikanoshi/customiuizer/mods/System.java | 277 +++++++----------- .../subs/System_AutoBrightness.java | 2 - app/src/main/res/values-zh-rCN/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + .../res/xml/prefs_system_autobrightness.xml | 6 - 9 files changed, 123 insertions(+), 177 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0e69a64f..674d78bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { minSdkVersion 30 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 30 - versionCode 6 - versionName "3.2.1.220617" + versionCode 7 + versionName "3.2.1.220620" resConfigs 'ru-rRU', 'zh-rCN' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 993c3d9c..a3403a64 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,7 +4,8 @@ package="name.mikanoshi.customiuizer"> - + + diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 117b9833..05e98df1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -427,7 +427,7 @@ private void handleLoadLauncher(final LoadPackageParam lpparam) { if (mPrefs.getInt("controls_fsg_width", 100) > 100) Controls.BackGestureAreaWidthHook(lpparam, false); if (mPrefs.getBoolean("controls_fsg_horiz")) Launcher.FSGesturesHook(lpparam); if (mPrefs.getBoolean("system_removecleaner")) System.HideMemoryCleanHook(lpparam, true); - if (mPrefs.getBoolean("system_fw_sticky")) System.StickyFloatingWindowsLauncherHook(lpparam); +// if (mPrefs.getBoolean("system_fw_sticky")) System.StickyFloatingWindowsLauncherHook(lpparam); if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); //if (mPrefs.getBoolean("launcher_fixstatusbarmode")) Launcher.FixStatusBarModeHook(lpparam); if (mPrefs.getBoolean("launcher_fixanim")) Launcher.FixAnimHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java index 5fef23f5..5df45a5e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java @@ -186,7 +186,7 @@ public void run() { } public static void VolumeMediaButtonsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "interceptKeyBeforeQueueing", KeyEvent.class, int.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.server.policy.MiuiPhoneWindowManager", lpparam.classLoader, "interceptKeyBeforeQueueing", KeyEvent.class, int.class, new MethodHook() { @Override @SuppressLint("MissingPermission") protected void before(final MethodHookParam param) throws Throwable { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index b77b8b8a..bb2bf031 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -131,6 +131,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.NetworkInterface; @@ -158,6 +159,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import static java.lang.System.currentTimeMillis; import static java.lang.System.nanoTime; @@ -172,8 +174,6 @@ import static de.robv.android.xposed.XposedHelpers.findClassIfExists; import static de.robv.android.xposed.XposedHelpers.findMethodExactIfExists; -import miui.os.SystemProperties; - import name.mikanoshi.customiuizer.MainModule; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.utils.AudioVisualizer; @@ -1403,7 +1403,7 @@ private static int constrainValue(int val) { int range, min, max; range = maxBrightnessLevel - minBrightnessLevel; - if (maxBrightnessLevel != 255 || MainModule.mPrefs.getBoolean("system_autobrightness_hlg")) { + if (maxBrightnessLevel != 255) { min = Helpers.convertGammaToLinear(minBrightnessLevel + (int)(range * min_pct / 100f), minBrightnessLevel, maxBrightnessLevel); max = Helpers.convertGammaToLinear(minBrightnessLevel + (int)(range * max_pct / 100f), minBrightnessLevel, maxBrightnessLevel); } else { @@ -1417,71 +1417,72 @@ private static int constrainValue(int val) { return val; } + private static boolean floatEquals(float a, float b) { + if (a == b) { + return true; + } else if (Float.isNaN(a) && Float.isNaN(b)) { + return true; + } else if (Math.abs(a - b) < 0.001f) { + return true; + } else { + return false; + } + } + public static void AutoBrightnessRangeHook(LoadPackageParam lpparam) { Class bmsCls = findClassIfExists("com.android.server.display.BrightnessMappingStrategy", lpparam.classLoader); if (bmsCls != null) { Helpers.hookAllConstructors("com.android.server.display.BrightnessMappingStrategy$SimpleMappingStrategy", lpparam.classLoader, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - int[] values = (int[])param.args[1]; - for (int i = 0; i < values.length; i++) - values[i] = constrainValue(values[i]); - param.args[1] = values; + int[] values = (int[])param.args[1]; + for (int i = 0; i < values.length; i++) + values[i] = constrainValue(values[i]); + param.args[1] = values; } }); Helpers.hookAllConstructors("com.android.server.display.BrightnessMappingStrategy$PhysicalMappingStrategy", lpparam.classLoader, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - int[] values = (int[])param.args[2]; - for (int i = 0; i < values.length; i++) - values[i] = constrainValue(values[i]); - param.args[2] = values; - } - }); - } - - if (!Helpers.isPiePlus()) - Helpers.findAndHookMethod("com.android.server.display.AutomaticBrightnessController", lpparam.classLoader, "updateAutoBrightness", boolean.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - int val = XposedHelpers.getIntField(param.thisObject, "mScreenAutoBrightness"); - int newVal = constrainValue(val); - if (val >= 0 && val != newVal) { - //XposedBridge.log("updateAutoBrightness: " + val + " -> " + newVal); - XposedHelpers.setIntField(param.thisObject, "mScreenAutoBrightness", newVal); - if ((boolean)param.args[0]) { - //XposedHelpers.callStaticMethod(findClass("com.android.server.display.AutomaticBrightnessControllerInjector", lpparam.classLoader), "recordAutoBrightnessChange", newVal); - Object mCallbacks = XposedHelpers.getObjectField(param.thisObject, "mCallbacks"); - XposedHelpers.callMethod(mCallbacks, "updateBrightness"); - } + float[] values = (float[])param.args[2]; + for (int i = 0; i < values.length; i++) { + if (floatEquals(values[i], -1.0f)) { + values[i] = -1.0f; + } else if (Float.isNaN(values[i])) { + values[i] = -1 ; + } else { + values[i] = (float) (constrainValue(Math.round(values[i] * 255)) / 255); } } - }); - else - Helpers.hookAllMethods("com.android.server.display.AutomaticBrightnessControllerInjector", lpparam.classLoader, "changeBrightness", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - int val = (int)param.getResult(); - if (val >= 0) param.setResult(constrainValue(val)); + param.args[2] = values; } }); + } + + Helpers.hookAllMethods("com.android.server.display.AutomaticBrightnessControllerImpl", lpparam.classLoader, "changeBrightness", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + int val = (int)param.getResult(); + if (val >= 0) param.setResult(constrainValue(val)); + } + }); Helpers.hookAllConstructors("com.android.server.display.AutomaticBrightnessController", lpparam.classLoader, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { - XposedHelpers.setLongField(param.thisObject, "mBrighteningLightDebounceConfig", 500L); - XposedHelpers.setLongField(param.thisObject, "mDarkeningLightDebounceConfig", 500L); + XposedHelpers.setLongField(param.thisObject, "mBrighteningLightDebounceConfig", 500L); + XposedHelpers.setLongField(param.thisObject, "mDarkeningLightDebounceConfig", 500L); } }); Helpers.hookAllConstructors("com.android.server.display.DisplayPowerController", lpparam.classLoader, new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { - Context context = (Context)param.args[0]; - Resources res = context.getResources(); - minBrightnessLevel = res.getInteger(res.getIdentifier("config_screenBrightnessSettingMinimum", "integer", "android")); - maxBrightnessLevel = res.getInteger(res.getIdentifier("config_screenBrightnessSettingMaximum", "integer", "android")); + Context context = (Context)param.args[0]; + Resources res = context.getResources(); + minBrightnessLevel = res.getInteger(res.getIdentifier("config_screenBrightnessSettingMinimum", "integer", "android")); + maxBrightnessLevel = res.getInteger(res.getIdentifier("config_screenBrightnessSettingMaximum", "integer", "android")); } }); } @@ -2224,150 +2225,100 @@ protected void after(final MethodHookParam param) throws Throwable { } private static int appInfoIconResId; + private static int appInfoDescId; private static int forceCloseIconResId; + private static int forceCloseDescId; public static void NotificationRowMenuRes() { - appInfoIconResId = MainModule.resHooks.addResource("ic_appinfo", Helpers.is12()? R.drawable.ic_appinfo12 : R.drawable.ic_appinfo); - forceCloseIconResId = MainModule.resHooks.addResource("ic_forceclose", Helpers.is12()? R.drawable.ic_forceclose12 : R.drawable.ic_forceclose); - if (!Helpers.is12()) - MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "notification_menu_icon_size", 36); + appInfoIconResId = MainModule.resHooks.addResource("ic_appinfo", R.drawable.ic_appinfo12); + forceCloseIconResId = MainModule.resHooks.addResource("ic_forceclose", R.drawable.ic_forceclose12); + appInfoDescId = MainModule.resHooks.addResource("miui_notification_menu_appinfo_title", R.string.system_notifrowmenu_appinfo); + forceCloseDescId = MainModule.resHooks.addResource("miui_notification_menu_forceclose_title", R.string.system_notifrowmenu_forceclose); MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "notification_menu_icon_padding", 0); } public static void NotificationRowMenuHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMenuRow", lpparam.classLoader, "createMenuViews", boolean.class, new MethodHook() { + MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "miui_notification_modal_menu_margin_left_right", 8); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow", lpparam.classLoader, "createMenuViews", boolean.class, boolean.class, new MethodHook() { @Override @SuppressWarnings("unchecked") protected void after(final MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); ArrayList mMenuItems = (ArrayList)XposedHelpers.getObjectField(param.thisObject, "mMenuItems"); - Class nmiCls = findClass("com.android.systemui.statusbar.NotificationMenuRow.NotificationMenuItem", lpparam.classLoader); + Class nmiCls = findClass("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow.MiuiNotificationMenuItem", lpparam.classLoader); Object infoBtn = null; Object forceCloseBtn = null; - int nInfoResId = mContext.getResources().getIdentifier("notification_info", "layout", lpparam.packageName); + Constructor MenuItem = nmiCls.getConstructors()[0]; try { - infoBtn = XposedHelpers.newInstance(nmiCls, mContext, "Application info", nInfoResId, appInfoIconResId); - forceCloseBtn = XposedHelpers.newInstance(nmiCls, mContext, "Force close", nInfoResId, forceCloseIconResId); + infoBtn = MenuItem.newInstance(param.thisObject, mContext, appInfoDescId, null, appInfoIconResId); + forceCloseBtn = MenuItem.newInstance(param.thisObject, mContext, forceCloseDescId, null, forceCloseIconResId); } catch (Throwable t1) { - try { - infoBtn = XposedHelpers.newInstance(nmiCls, mContext, "Application info", LayoutInflater.from(mContext).inflate(nInfoResId, null, false), appInfoIconResId); - forceCloseBtn = XposedHelpers.newInstance(nmiCls, mContext, "Force close", LayoutInflater.from(mContext).inflate(nInfoResId, null, false), forceCloseIconResId); - } catch (Throwable t2) { - XposedBridge.log(t2); - } + XposedBridge.log(t1); } if (infoBtn == null || forceCloseBtn == null) return; - + Object notification = XposedHelpers.getObjectField(param.thisObject, "mSbn"); + String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); + int menuMargin = (int) XposedHelpers.getObjectField(param.thisObject, "mMenuMargin"); mMenuItems.add(infoBtn); mMenuItems.add(forceCloseBtn); XposedHelpers.setObjectField(param.thisObject, "mMenuItems", mMenuItems); - FrameLayout mMenuContainer = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mMenuContainer"); - if (mMenuContainer != null) - if (Helpers.is12()) { - View mInfoBtn = (View)XposedHelpers.callMethod(infoBtn, "getMenuView"); - View mForceCloseBtn = (View)XposedHelpers.callMethod(forceCloseBtn, "getMenuView"); - mInfoBtn.setOnClickListener((View.OnClickListener)param.thisObject); - mForceCloseBtn.setOnClickListener((View.OnClickListener)param.thisObject); - XposedHelpers.callMethod(mMenuContainer, "addMenuView", mInfoBtn); - XposedHelpers.callMethod(mMenuContainer, "addMenuView",mForceCloseBtn); - } else { - XposedHelpers.callMethod(param.thisObject, "addMenuView", infoBtn, mMenuContainer); - XposedHelpers.callMethod(param.thisObject, "addMenuView", forceCloseBtn, mMenuContainer); - //XposedHelpers.callMethod(param.thisObject, "setMenuLocation"); - } - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMenuRow", lpparam.classLoader, "onClick", View.class, new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - View view = (View)param.args[0]; - if (view == null || view.getTag() == null || !(view.getTag() instanceof Integer)) return; + LinearLayout mMenuContainer = (LinearLayout)XposedHelpers.getObjectField(param.thisObject, "mMenuContainer"); + if (mMenuContainer != null) { + View mInfoBtn = (View) XposedHelpers.callMethod(infoBtn, "getMenuView"); + View mForceCloseBtn = (View) XposedHelpers.callMethod(forceCloseBtn, "getMenuView"); - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Object mParent = XposedHelpers.getObjectField(param.thisObject, "mParent"); - Object notification = XposedHelpers.callMethod(mParent, "getStatusBarNotification"); - String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); - int uid = (int)XposedHelpers.callMethod(notification, "getAppUid"); - int user = 0; - try { - user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); - } catch (Throwable t) { - XposedBridge.log(t); - } - - int iconResId = (int)view.getTag(); - if (iconResId == appInfoIconResId) { - param.setResult(null); - Helpers.openAppInfo(mContext, pkgName, user); - mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - } else if (iconResId == forceCloseIconResId) { - param.setResult(null); - ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); - if (user != 0) - XposedHelpers.callMethod(am, "forceStopPackageAsUser", pkgName, user); - else - XposedHelpers.callMethod(am, "forceStopPackage", pkgName); - CharSequence appName = pkgName; - try { - appName = mContext.getPackageManager().getApplicationLabel(mContext.getPackageManager().getApplicationInfo(pkgName, 0)); - } catch (Throwable ignore) {} - Toast.makeText(mContext, Helpers.getModuleRes(mContext).getString(R.string.force_closed, appName), Toast.LENGTH_SHORT).show(); - } - } - }); - - if (!Helpers.is12()) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMenuRow", lpparam.classLoader, "onHeightUpdate", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - FrameLayout mMenuContainer = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mMenuContainer"); - if (mMenuContainer != null) mMenuContainer.setTranslationY(0); - } - }); + View.OnClickListener itemClick = new View.OnClickListener() { + @Override + public void onClick(View view) { + if (view == null) return; + int uid = (int)XposedHelpers.callMethod(notification, "getAppUid"); + int user = 0; + try { + user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); + } catch (Throwable t) { + XposedBridge.log(t); + } - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMenuRow", lpparam.classLoader, "setMenuLocation", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - param.setResult(null); - float mHorizSpaceForIcon = XposedHelpers.getFloatField(param.thisObject, "mHorizSpaceForIcon"); - boolean mSnapping = XposedHelpers.getBooleanField(param.thisObject, "mSnapping"); - FrameLayout mMenuContainer = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mMenuContainer"); - Object mParent = XposedHelpers.getObjectField(param.thisObject, "mParent"); - if (mMenuContainer == null || mParent == null) return; - int width = (int)XposedHelpers.callMethod(mParent, "getWidth"); - int height = (int)XposedHelpers.callMethod(mParent, "getIntrinsicHeight"); - boolean hasExtraTopPadding = (boolean)XposedHelpers.callMethod(mParent, "hasExtraTopPadding"); - int extraTopPadding = hasExtraTopPadding ? (int)XposedHelpers.callMethod(mParent, "getPaddingTop") : 0; - float density = mMenuContainer.getResources().getDisplayMetrics().density; - float padding = 10 * density; - float startingHeight = height / 2.0f - mHorizSpaceForIcon - padding - extraTopPadding; - Object sbNotification = XposedHelpers.callMethod(mParent, "getStatusBarNotification"); - int mImportance = XposedHelpers.getIntField(sbNotification, "mImportance"); - if (!mSnapping && mMenuContainer.isAttachedToWindow()) { - int childCount = mMenuContainer.getChildCount(); - int row = 0; - int col = 0; - if (mImportance == 1) mHorizSpaceForIcon = 24 * density; - for (int i = 0; i < childCount; i++) - if (mImportance == 1) { - View childAt = mMenuContainer.getChildAt(i); - childAt.setX((float)width - padding - (mHorizSpaceForIcon + padding) * (col + 1)); - childAt.setY(height / 2.0f - mHorizSpaceForIcon / 2.0f - padding / 2.0f - extraTopPadding); - col++; - } else { - View childAt = mMenuContainer.getChildAt(i); - childAt.setX((float)width - (mHorizSpaceForIcon + (col == 0 ? 2 * padding : 1.5f * padding)) * (col + 1)); - childAt.setY(startingHeight + mHorizSpaceForIcon * row + padding); - col++; - if (i % 2 == 1) { - col = 0; - row++; - } + if (view == mInfoBtn) { + Helpers.openAppInfo(mContext, pkgName, user); + mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + } else if (view == mForceCloseBtn) { + ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); + if (user != 0) + XposedHelpers.callMethod(am, "forceStopPackageAsUser", pkgName, user); + else + XposedHelpers.callMethod(am, "forceStopPackage", pkgName); + try { + CharSequence appName = mContext.getPackageManager().getApplicationLabel(mContext.getPackageManager().getApplicationInfo(pkgName, 0)); + Toast.makeText(mContext, Helpers.getModuleRes(mContext).getString(R.string.force_closed, appName), Toast.LENGTH_SHORT).show(); + } catch (Throwable ignore) {} } + } + }; + mInfoBtn.setOnClickListener(itemClick); + mForceCloseBtn.setOnClickListener(itemClick); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(-2, -2); + layoutParams.leftMargin = menuMargin; + layoutParams.rightMargin = menuMargin; + XposedHelpers.callMethod(mMenuContainer, "addView", mInfoBtn, layoutParams); + XposedHelpers.callMethod(mMenuContainer, "addView", mForceCloseBtn, layoutParams); + int size = mMenuItems.size(); + int dimensionPixelOffset = mContext.getResources().getDimensionPixelSize(mContext.getResources().getIdentifier("notification_panel_width", "dimen", lpparam.packageName)); + if (dimensionPixelOffset <= 0) { + dimensionPixelOffset = mContext.getResources().getDisplayMetrics().widthPixels; } + int menuWidth = (dimensionPixelOffset / size) - (menuMargin * 2); + int titleId = mContext.getResources().getIdentifier("modal_menu_title", "id", lpparam.packageName); + mMenuItems.forEach(new Consumer() { + @Override + public void accept(Object obj) { + View menuView = (View) XposedHelpers.callMethod(obj, "getMenuView"); + ((TextView) menuView.findViewById(titleId)).setMaxWidth(menuWidth); + } + }); } - }); - } + } + }); } @SuppressWarnings("unchecked") @@ -3258,9 +3209,7 @@ protected void after(MethodHookParam param) throws Throwable { boolean hasDual = false; try { hasDual = XposedHelpers.callMethod(pm, "getPackageInfoAsUser", resolveInfo.activityInfo.packageName, 0, 999) != null; - } catch (Throwable ignore) { - XposedBridge.log(ignore); - } + } catch (Throwable ignore) {} if ((removeOriginal && !hasDual) || removeOriginal && hasDual && removeDual) itr.remove(); } param.setResult(resolved); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AutoBrightness.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AutoBrightness.java index 2bdd49fb..c28e9fdb 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AutoBrightness.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AutoBrightness.java @@ -31,8 +31,6 @@ public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); - - findPreference("pref_key_system_autobrightness_hlg").setEnabled(!Helpers.isPiePlus()); } } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a4833028..d6551f8e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1047,4 +1047,6 @@ 假定已安装LSPosed框架以使用其管理器 正在运行的服务 双击锁屏 + 应用信息 + 强制关闭 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f2401363..20173ae2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -141,6 +141,8 @@ Deactivate brightness slider Extended notification menu Open app info and force close app from notification menu (swipe notification to the left to open it) + App info + Force close Disable any notification Allow to disable system notifications too Expand notifications diff --git a/app/src/main/res/xml/prefs_system_autobrightness.xml b/app/src/main/res/xml/prefs_system_autobrightness.xml index 1cd45c06..75bade2a 100644 --- a/app/src/main/res/xml/prefs_system_autobrightness.xml +++ b/app/src/main/res/xml/prefs_system_autobrightness.xml @@ -41,12 +41,6 @@ miuizer:stepValue="1" miuizer:format="%d%%" /> - - \ No newline at end of file From 7da74456bd8cb10265c9726d651051c7af0f3b2e Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 21 Jun 2022 17:04:08 +0800 Subject: [PATCH 017/627] fix: battery indicator and hide statusbar icon --- app/build.gradle | 4 +- .../mikanoshi/customiuizer/MainModule.java | 25 ++-- .../mikanoshi/customiuizer/mods/System.java | 108 ++++++++---------- .../customiuizer/utils/BatteryIndicator.java | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 4 +- 5 files changed, 64 insertions(+), 79 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 674d78bd..b5075d0b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { minSdkVersion 30 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 30 - versionCode 7 - versionName "3.2.1.220620" + versionCode 8 + versionName "3.2.1.220621" resConfigs 'ru-rRU', 'zh-rCN' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 05e98df1..6d601c43 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -256,11 +256,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_mutevisiblenotif")) System.MuteVisibleNotificationsHook(lpparam); if (mPrefs.getBoolean("launcher_nounlockanim")) System.NoUnlockAnimationHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery1")) System.HideIconsBattery1Hook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_battery2")) System.HideIconsBattery2Hook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_battery3")) System.HideIconsBattery3Hook(lpparam); + if (mPrefs.getBoolean("system_statusbaricons_battery3") || mPrefs.getBoolean("system_statusbaricons_battery2")) System.HideIconsBattery2Hook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_signal")) System.HideIconsSignalHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_nosims")) System.HideIconsNoSIMsHook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_wifi")) System.HideIconsNoWiFiHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_volte")) System.HideIconsVoLTEHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_vowifi")) System.HideIconsVoWiFiHook(lpparam); if (!mPrefs.getBoolean("system_statusbaricons_alarm") && mPrefs.getInt("system_statusbaricons_alarmn", 0) > 0) System.HideIconsSelectiveAlarmHook(lpparam); @@ -276,17 +274,18 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { boolean hideIconsActive = + mPrefs.getBoolean("system_statusbaricons_wifi") || mPrefs.getBoolean("system_statusbaricons_alarm") || - mPrefs.getBoolean("system_statusbaricons_profile") || - mPrefs.getBoolean("system_statusbaricons_sound") || - mPrefs.getBoolean("system_statusbaricons_dnd") || - mPrefs.getBoolean("system_statusbaricons_headset") || - mPrefs.getBoolean("system_statusbaricons_mute") || - mPrefs.getBoolean("system_statusbaricons_speaker") || - mPrefs.getBoolean("system_statusbaricons_record") || - mPrefs.getBoolean("system_statusbaricons_nfc") || - mPrefs.getBoolean("system_statusbaricons_vpn") || - mPrefs.getBoolean("system_statusbaricons_hotspot"); + mPrefs.getBoolean("system_statusbaricons_profile") || + mPrefs.getBoolean("system_statusbaricons_sound") || + mPrefs.getBoolean("system_statusbaricons_dnd") || + mPrefs.getBoolean("system_statusbaricons_headset") || + mPrefs.getBoolean("system_statusbaricons_mute") || + mPrefs.getBoolean("system_statusbaricons_speaker") || + mPrefs.getBoolean("system_statusbaricons_record") || + mPrefs.getBoolean("system_statusbaricons_nfc") || + mPrefs.getBoolean("system_statusbaricons_vpn") || + mPrefs.getBoolean("system_statusbaricons_hotspot"); if (hideIconsActive) System.HideIconsHook(lpparam); if (Helpers.is12()) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bb2bf031..38e5c192 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2178,26 +2178,26 @@ public static void AutoGroupNotificationsHook(LoadPackageParam lpparam) { @Override @SuppressWarnings({"unchecked", "SuspiciousMethodCalls"}) protected void before(final MethodHookParam param) throws Throwable { - int opt = Integer.parseInt(MainModule.mPrefs.getString("system_autogroupnotif", "1")); - if (opt == 2) { - param.setResult(null); - return; - } - Map>> mUngroupedNotifications = (Map>>)XposedHelpers.getObjectField(param.thisObject, "mUngroupedNotifications"); - Map> obj = mUngroupedNotifications.get(param.args[0]); - if (obj != null) { - LinkedHashSet list = obj.get(param.args[1]); - if (list != null && list.size() < opt) param.setResult(null); - } + int opt = Integer.parseInt(MainModule.mPrefs.getString("system_autogroupnotif", "1")); + if (opt == 2) { + param.setResult(null); + return; + } + Map>> mUngroupedNotifications = (Map>>)XposedHelpers.getObjectField(param.thisObject, "mUngroupedNotifications"); + Map> obj = mUngroupedNotifications.get(param.args[0]); + if (obj != null) { + LinkedHashSet list = obj.get(param.args[1]); + if (list != null && list.size() < opt) param.setResult(null); + } } }); Helpers.findAndHookMethod("com.android.server.notification.GroupHelper", lpparam.classLoader, "adjustNotificationBundling", List.class, boolean.class, new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { - List list = (List)param.args[0]; - int opt = Integer.parseInt(MainModule.mPrefs.getString("system_autogroupnotif", "1")); - if (opt == 2 || (list != null && list.size() < opt)) param.setResult(null); + List list = (List)param.args[0]; + int opt = Integer.parseInt(MainModule.mPrefs.getString("system_autogroupnotif", "1")); + if (opt == 2 || (list != null && list.size() < opt)) param.setResult(null); } }); } @@ -3721,7 +3721,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void HideIconsBattery1Hook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.BatteryMeterView", lpparam.classLoader, "update", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.views.MiuiBatteryMeterView", lpparam.classLoader, "initMiuiView", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { ImageView mBatteryIconView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mBatteryIconView"); @@ -3731,25 +3731,21 @@ protected void after(MethodHookParam param) throws Throwable { } public static void HideIconsBattery2Hook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.BatteryMeterView", lpparam.classLoader, "update", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.views.MiuiBatteryMeterView", lpparam.classLoader, "updateChargeAndText", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - TextView mBatteryTextDigitView = (TextView)XposedHelpers.getObjectField(param.thisObject, "mBatteryTextDigitView"); - mBatteryTextDigitView.setVisibility(View.GONE); - } - }); - } - - public static void HideIconsBattery3Hook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.BatteryMeterView", lpparam.classLoader, "updateChargingIconView", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - ImageView mBatteryChargingView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mBatteryChargingView"); - mBatteryChargingView.setVisibility(View.GONE); - try { - ImageView mBatteryChargingInView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mBatteryChargingInView"); - mBatteryChargingInView.setVisibility(View.GONE); - } catch (Throwable ignore) {} + if (MainModule.mPrefs.getBoolean("system_statusbaricons_battery2")) { + TextView mBatteryTextDigitView = (TextView)XposedHelpers.getObjectField(param.thisObject, "mBatteryTextDigitView"); + mBatteryTextDigitView.setVisibility(View.GONE); + } + if (MainModule.mPrefs.getBoolean("system_statusbaricons_battery3")) { + ImageView mBatteryChargingView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mBatteryChargingView"); + mBatteryChargingView.setVisibility(View.GONE); + try { + ImageView mBatteryChargingInView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mBatteryChargingInView"); + mBatteryChargingInView.setVisibility(View.GONE); + } catch (Throwable ignore) {} + } } }); } @@ -3815,17 +3811,17 @@ public void onReceive(Context context, Intent intent) { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.PhoneStatusBarPolicy", lpparam.classLoader, "updateAlarm", boolean.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.PhoneStatusBarPolicy", lpparam.classLoader, "updateAlarm", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - lastState = (boolean)param.args[0]; + lastState = (boolean)XposedHelpers.getObjectField(param.thisObject, "mHasAlarm"); updateAlarmVisibility(param.thisObject, lastState); } }); } public static void HideIconsBluetoothHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.PhoneStatusBarPolicy", lpparam.classLoader, "updateBluetooth", String.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarPolicy", lpparam.classLoader, "updateBluetooth", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { int opt = Integer.parseInt(MainModule.mPrefs.getString("system_statusbaricons_bluetooth", "1")); @@ -3863,16 +3859,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void HideIconsNoWiFiHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.SignalClusterView", lpparam.classLoader, "apply", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - View mWifiGroup = (View)XposedHelpers.getObjectField(param.thisObject, "mWifiGroup"); - if (mWifiGroup != null) mWifiGroup.setVisibility(View.GONE); - } - }); - } - public static void HideIconsVoWiFiHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.systemui.statusbar.SignalClusterView", lpparam.classLoader, "apply", new MethodHook() { @Override @@ -3897,6 +3883,7 @@ private static boolean checkSlot(String slotName) { "managed_profile".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_profile") || "vpn".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_vpn") || "nfc".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nfc") || + "wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_wifi") || "hotspot".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_hotspot"); } catch (Throwable t) { XposedBridge.log(t); @@ -3919,14 +3906,14 @@ protected void before(MethodHookParam param) throws Throwable { } public static void BatteryIndicatorHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - FrameLayout mStatusBarWindow = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mStatusBarWindow"); + FrameLayout mStatusBarWindow = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mPhoneStatusBarWindow"); BatteryIndicator indicator = new BatteryIndicator(mContext); View panel = mStatusBarWindow.findViewById(mContext.getResources().getIdentifier("notification_panel", "id", lpparam.packageName)); - mStatusBarWindow.addView(indicator, panel != null ? mStatusBarWindow.indexOfChild(panel) + 1 : Math.max(mStatusBarWindow.getChildCount() - 1, 8)); + mStatusBarWindow.addView(indicator, panel != null ? mStatusBarWindow.indexOfChild(panel) + 1 : Math.max(mStatusBarWindow.getChildCount() - 1, 2)); indicator.setAdjustViewBounds(false); indicator.init(param.thisObject); XposedHelpers.setAdditionalInstanceField(param.thisObject, "mBatteryIndicator", indicator); @@ -3936,7 +3923,7 @@ protected void after(final MethodHookParam param) throws Throwable { XposedHelpers.setAdditionalInstanceField(mBatteryController, "mBatteryIndicator", indicator); XposedHelpers.callMethod(mBatteryController, "fireBatteryLevelChanged"); XposedHelpers.callMethod(mBatteryController, "firePowerSaveChanged"); - XposedHelpers.callMethod(mBatteryController, "fireExtremePowerSaveChanged"); +// XposedHelpers.callMethod(mBatteryController, "fireExtremePowerSaveChanged"); } }); @@ -3959,7 +3946,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateKeyguardState", boolean.class, boolean.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateKeyguardState", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); @@ -3976,7 +3963,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BatteryControllerImpl", lpparam.classLoader, "fireBatteryLevelChanged", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiBatteryControllerImpl", lpparam.classLoader, "fireBatteryLevelChanged", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); @@ -3991,17 +3978,17 @@ protected void after(final MethodHookParam param) throws Throwable { @Override protected void after(final MethodHookParam param) throws Throwable { BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onPowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mIsPowerSaveMode")); + if (indicator != null) indicator.onPowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mPowerSave")); } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BatteryControllerImpl", lpparam.classLoader, "fireExtremePowerSaveChanged", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onExtremePowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mIsExtremePowerSaveMode")); - } - }); +// Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BatteryControllerImpl", lpparam.classLoader, "fireExtremePowerSaveChanged", new MethodHook() { +// @Override +// protected void after(final MethodHookParam param) throws Throwable { +// BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); +// if (indicator != null) indicator.onExtremePowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mIsExtremePowerSaveMode")); +// } +// }); } private static boolean obtainMagnifierShowCoordinates(Object mEditor, int type, final MotionEvent event, final PointF showPosInView) { @@ -5350,8 +5337,7 @@ public static void HideIconsVoLTERes() { } public static void HideIconsVoLTEHook(LoadPackageParam lpparam) { - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently("com.android.systemui.MCCUtils", lpparam.classLoader, "isHideVolte", Context.class, String.class, XC_MethodReplacement.returnConstant(true)); + Helpers.findAndHookMethodSilently("com.android.systemui.MiuiOperatorCustomizedPolicy$MiuiOperatorConfig", lpparam.classLoader, "getHideVolte", XC_MethodReplacement.returnConstant(true)); } public static void HideLockScreenClockHook(LoadPackageParam lpparam) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/BatteryIndicator.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/BatteryIndicator.java index ba3174ed..dd6bb4ab 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/BatteryIndicator.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/BatteryIndicator.java @@ -26,7 +26,7 @@ import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; -public class BatteryIndicator extends ImageView { +public class BatteryIndicator extends androidx.appcompat.widget.AppCompatImageView { protected int mDisplayWidth; protected boolean mIsBeingCharged; protected boolean mIsExtremePowerSave; diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d6551f8e..f5e58620 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -51,13 +51,13 @@ 将电池电量显示为彩色条 限制可见性 仅在通知抽屉中和锁屏上显示 - 圆形 + 圆角 居中 电量条高度 水平边距 满电颜色 低电量颜色 - 电池保护程序颜色 + 省电模式颜色 充电颜色 低电量水平 测试 From fece8f025381a8a9f3321f1ae9efbe0cbf0fccba Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 21 Jun 2022 19:53:38 +0800 Subject: [PATCH 018/627] feat: add menus(restart systemui and launcher) --- .../customiuizer/PreferenceFragmentBase.java | 934 +++++++++--------- .../customiuizer/mods/GlobalActions.java | 208 ++-- .../mikanoshi/customiuizer/subs/Launcher.java | 28 - app/src/main/res/menu/menu_itemactions.xml | 7 +- app/src/main/res/menu/menu_launcher.xml | 6 - app/src/main/res/menu/menu_mods.xml | 8 + app/src/main/res/values-zh-rCN/strings.xml | 3 +- app/src/main/res/values/strings.xml | 1 + 8 files changed, 544 insertions(+), 651 deletions(-) delete mode 100644 app/src/main/res/menu/menu_launcher.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java index 2539c213..d78581dd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java @@ -1,465 +1,471 @@ -package name.mikanoshi.customiuizer; - -import android.animation.Animator; -import android.animation.ValueAnimator; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.LayerDrawable; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.util.TypedValue; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.ActionBar; - -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.text.SimpleDateFormat; -import java.util.Map; -import java.util.Set; - -import name.mikanoshi.customiuizer.mods.GlobalActions; -import name.mikanoshi.customiuizer.utils.Helpers; - -public class PreferenceFragmentBase extends PreferenceFragment { - - private Context actContext = null; - public boolean isAnimating = false; - public boolean supressMenu = false; - public int animDur = 350; - - public static final int PICK_BACKFILE = 11; - public boolean isCustomActionBar = false; - - protected ActionBar getActionBar() { - AppCompatActivity act = (AppCompatActivity) getActivity(); - return act.getSupportActionBar(); - } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (supressMenu) { - inflater.inflate(R.menu.menu_mods, menu); - } - if (isCustomActionBar) { - MenuItem item = null; - for (int i = 0; i < menu.size(); i++) { - item = menu.getItem(i); - item.setVisible(item.getItemId() == R.id.edit_confirm); - } - MenuItem confirmMenu = menu.findItem(R.id.edit_confirm); - int applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_confirm_dark" : "action_mode_title_button_confirm_light", "drawable", "miui"); - if (applyResId == 0) - applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_done_dark" : "action_mode_immersion_done_light", "drawable", "miui"); - confirmMenu.setIcon(applyResId); - } - } - - public void confirmEdit() {} - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - Activity act = getActivity(); - switch (item.getItemId()) { - case R.id.edit_confirm: - confirmEdit(); - return true; - case R.id.backuprestore: - showBackupRestoreDialog(); - return true; - case R.id.softreboot: - if (!Helpers.miuizerModuleActive) { - showXposedDialog(getActivity()); - return true; - } - - AlertDialog.Builder alert = new AlertDialog.Builder(getValidContext()); - alert.setTitle(R.string.soft_reboot); - alert.setMessage(R.string.soft_reboot_ask); - alert.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "FastReboot")); - } - }); - alert.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) {} - }); - alert.show(); - return true; - case R.id.about: - Bundle args = new Bundle(); - args.putInt("baseResId", R.layout.fragment_about); - openSubFragment(new AboutFragment(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.app_about, R.xml.prefs_about); - return true; - } - return false; - } - - public void showXposedDialog(Activity act) { - try { - AlertDialog.Builder builder = new AlertDialog.Builder(act); - builder.setTitle(R.string.warning); - builder.setMessage(R.string.module_not_active); - builder.setCancelable(true); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){} - }); - AlertDialog dlg = builder.create(); - dlg.show(); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - public void showBackupRestoreDialog() { - final Activity act = getActivity(); - - AlertDialog.Builder alert = new AlertDialog.Builder(act); - alert.setTitle(R.string.backup_restore); - alert.setMessage(R.string.backup_restore_choose); - alert.setPositiveButton(R.string.do_restore, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - restoreSettings(act); - } - }); - alert.setNegativeButton(R.string.do_backup, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - backupSettings(act); - } - }); - alert.show(); - } - - private void initFragment() { - setHasOptionsMenu(supressMenu); - ActionBar actionBar = getActionBar(); - actionBar.setTitle(R.string.app_name); - - boolean showBack = false; - if (this instanceof MainFragment) { - ActivityInfo appInfo; - try { - Activity act = getActivity(); - appInfo = act.getPackageManager().getActivityInfo(act.getComponentName(), PackageManager.GET_META_DATA); - showBack = appInfo.metaData != null && appInfo.metaData.containsKey("from.settings"); - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - } - } else showBack = !(this instanceof SnoozedFragment); - - actionBar.setDisplayHomeAsUpEnabled(showBack); - } - - @SuppressLint("WorldReadableFiles") - public void onCreate(Bundle savedInstanceState, int pref_defaults) { - super.onCreate(savedInstanceState); - try { - getPreferenceManager().setSharedPreferencesName(Helpers.prefsName); - getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); - getPreferenceManager().setStorageDeviceProtected(); - PreferenceManager.setDefaultValues(Helpers.getProtectedContext(getValidContext()), pref_defaults, false); - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - initFragment(); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - setViewBackground(view); - } - - public void setViewBackground(View view) { - view.setBackgroundColor(Helpers.getSystemBackgroundColor(getValidContext())); - } - - public void setActionModeStyle(View searchView) { - boolean isNight = Helpers.isNightMode(getValidContext()); - if (searchView != null) try { - searchView.setSaveFromParentEnabled(false); - Drawable drawable = getResources().getDrawable(getResources().getIdentifier(isNight ? "search_mode_bg_dark" : "search_mode_bg_light", "drawable", "miui"), getValidContext().getTheme()); - try { - int colorResId = getResources().getIdentifier(isNight ? "primary_color_dark" : "primary_color_light", "color", "miui"); - if (colorResId != 0 && drawable instanceof LayerDrawable) { - drawable = ((LayerDrawable)drawable).getDrawable(0); - if (drawable instanceof GradientDrawable) - ((GradientDrawable)drawable).setColor(getResources().getColor(colorResId, getValidContext().getTheme())); - } - } catch (Throwable ignore) {} - searchView.setBackground(drawable); - LinearLayout inputArea = searchView.findViewById(android.R.id.inputArea); - inputArea.setBackgroundResource(getResources().getIdentifier(isNight ? "search_mode_edit_text_bg_dark" : "search_mode_edit_text_bg_light", "drawable", "miui")); - if (Helpers.is11()) { - ViewGroup.LayoutParams lp1 = searchView.getLayoutParams(); - int resId = getResources().getIdentifier("action_bar_default_height", "dimen", "miui"); - lp1.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.secondary_text_size : resId); - searchView.setLayoutParams(lp1); - FrameLayout.LayoutParams lp2 = (FrameLayout.LayoutParams)inputArea.getLayoutParams(); - resId = getResources().getIdentifier("searchbar_bg_height", "dimen", "miui"); - lp2.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.searchbar_bg_height : resId); - inputArea.setLayoutParams(lp2); - } - ImageView inputIcon = searchView.findViewById(R.id.inputIcon); - inputIcon.setImageResource(getResources().getIdentifier(isNight ? "edit_text_search_dark" : "edit_text_search", "drawable", "miui")); - TextView input = searchView.findViewById(android.R.id.input); - int fontSize = getResources().getIdentifier(Helpers.is11() ? "edit_text_font_size" : "secondary_text_size", "dimen", "miui"); - input.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(fontSize == 0 ? R.dimen.secondary_text_size : fontSize)); - input.setHintTextColor(getResources().getColor(getResources().getIdentifier(isNight ? "edit_text_search_hint_color_dark" : "edit_text_search_hint_color_light", "color", "miui"), getValidContext().getTheme())); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType settingsType, Helpers.ActionBarType abType, int titleResId, int contentResId) { - if (args == null) args = new Bundle(); - args.putInt("settingsType", settingsType.ordinal()); - args.putInt("abType", abType.ordinal()); - args.putInt("titleResId", titleResId); - args.putInt("contentResId", contentResId); - float order = 100.0f; - try { - if (getView() != null) order = getView().getTranslationZ(); - } catch (Throwable t) {} - args.putFloat("order", order); - if (fragment.getArguments() == null) { - fragment.setArguments(args); - } else { - fragment.getArguments().clear(); - fragment.getArguments().putAll(args); - } - getFragmentManager().beginTransaction().setCustomAnimations(R.animator.fragment_open_enter, R.animator.fragment_open_exit, R.animator.fragment_close_enter, R.animator.fragment_close_exit) - .replace(R.id.fragment_container, fragment).addToBackStack(null).commitAllowingStateLoss(); - getFragmentManager().executePendingTransactions(); - } - - @Override - public Animator onCreateAnimator(int transit, boolean enter, final int nextAnim) { - if (nextAnim == 0) return null; - Configuration config = getResources().getConfiguration(); - float density = getResources().getDisplayMetrics().density; - final float scrWidth = config.screenWidthDp * density; - - final View top = getView(); - if (top == null) return null; - final View content = top.findViewById(android.R.id.list); - - //ValueAnimator.setFrameDelay(17); - ValueAnimator valAnimator = new ValueAnimator(); - valAnimator.setDuration(animDur); - valAnimator.setFloatValues(0.0f, 1.0f); - valAnimator.setInterpolator(new DecelerateInterpolator(2.5f)); - - if (nextAnim == R.animator.fragment_open_enter || nextAnim == R.animator.fragment_open_exit) - valAnimator.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { -// Log.e("animation", "start on: " + PreferenceFragmentBase.this.getClass().getCanonicalName()); - isAnimating = true; - } - - @Override - public void onAnimationEnd(Animator animation) { -// Log.e("animation", "end on: " + PreferenceFragmentBase.this.getClass().getCanonicalName()); - isAnimating = false; - } - - @Override - public void onAnimationCancel(Animator animation) {} - - @Override - public void onAnimationRepeat(Animator animation) {} - }); else isAnimating = false; - - valAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - if (content == null) return; - float val = (float)animation.getAnimatedValue(); - if (nextAnim == R.animator.fragment_open_enter) { - top.setX(scrWidth * (1.0f - val)); - content.setAlpha(0.6f + val * 0.4f); - } else if (nextAnim == R.animator.fragment_open_exit) { - top.setX(-scrWidth / 4.0f * val); - top.setAlpha(1.0f - val * 0.4f); - } else if (nextAnim == R.animator.fragment_close_enter) { - top.setX(-scrWidth / 4.0f * (1.0f - val)); - top.setAlpha(0.6f + val * 0.4f); - } else if (nextAnim == R.animator.fragment_close_exit) { - top.setX(scrWidth * val); - content.setAlpha(1.0f - val * 0.4f); - } - } - }); - - return valAnimator; - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - this.actContext = context; - } - - @Override - public void onDetach() { - super.onDetach(); - this.actContext = null; - } - -// @Override -// public void onResume() { -// super.onResume(); -// setupImmersiveMenu(); -// } - - public Context getValidContext() { - if (actContext != null) return actContext; - return getActivity() == null ? getContext() : getActivity().getApplicationContext(); - } - - public void backupSettings(Activity act) { - String backupPath = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; - if (!Helpers.preparePathForBackup(act, backupPath)) return; - ObjectOutputStream output = null; - try { - output = new ObjectOutputStream(new FileOutputStream(backupPath + Helpers.backupFile + new SimpleDateFormat("-MMddHHmmss").format(new java.util.Date()))); - output.writeObject(Helpers.prefs.getAll()); - - AlertDialog.Builder alert = new AlertDialog.Builder(act); - alert.setTitle(R.string.do_backup); - alert.setMessage(R.string.backup_ok); - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) {} - }); - alert.show(); - } catch (Throwable e) { - e.printStackTrace(); - AlertDialog.Builder alert = new AlertDialog.Builder(act); - alert.setTitle(R.string.warning); - alert.setMessage(getString(R.string.storage_cannot_backup) + "\n" + e.getMessage()); - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) {} - }); - alert.show(); - } finally { - try { - if (output != null) { - output.flush(); - output.close(); - } - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, - Intent resultData) { - if (requestCode == MainFragment.PICK_BACKFILE - && resultCode == Activity.RESULT_OK) { - Uri uri = null; - if (resultData != null) { - uri = resultData.getData(); - doRestoreSettings(uri); - } - } - } - - public void restoreSettings(final Activity act) { - if (!Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_RESTORE)) return; - if (!Helpers.checkStorageReadable(act)) return; - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType("application/octet-stream"); - startActivityForResult(intent, PICK_BACKFILE); - } - - public void doRestoreSettings(Uri uri) { - ObjectInputStream input = null; - final Activity act = getActivity(); - try { - input = new ObjectInputStream(act.getContentResolver().openInputStream(uri)); - Map entries = (Map)input.readObject(); - if (entries == null || entries.isEmpty()) throw new RuntimeException("Cannot read entries"); - - SharedPreferences.Editor prefEdit = Helpers.prefs.edit(); - prefEdit.clear(); - for (Map.Entry entry: entries.entrySet()) { - Object val = entry.getValue(); - String key = entry.getKey(); - - if (val instanceof Boolean) - prefEdit.putBoolean(key, (Boolean)val); - else if (val instanceof Float) - prefEdit.putFloat(key, (Float)val); - else if (val instanceof Integer) - prefEdit.putInt(key, (Integer)val); - else if (val instanceof Long) - prefEdit.putLong(key, (Long)val); - else if (val instanceof String) - prefEdit.putString(key, ((String)val)); - else if (val instanceof Set) - prefEdit.putStringSet(key, ((Set)val)); - } - prefEdit.apply(); - - AlertDialog.Builder alert = new AlertDialog.Builder(act); - alert.setTitle(R.string.do_restore); - alert.setMessage(R.string.restore_ok); - alert.setCancelable(false); - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - act.finish(); - act.startActivity(act.getIntent()); - } - }); - alert.show(); - } catch (Throwable t) { - t.printStackTrace(); - AlertDialog.Builder alert = new AlertDialog.Builder(act); - alert.setTitle(R.string.warning); - alert.setMessage(R.string.storage_cannot_restore); - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) {} - }); - alert.show(); - } finally { - try { - if (input != null) input.close(); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - } +package name.mikanoshi.customiuizer; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.LayerDrawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.util.TypedValue; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.DecelerateInterpolator; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.ActionBar; + +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.text.SimpleDateFormat; +import java.util.Map; +import java.util.Set; + +import name.mikanoshi.customiuizer.mods.GlobalActions; +import name.mikanoshi.customiuizer.utils.Helpers; + +public class PreferenceFragmentBase extends PreferenceFragment { + + private Context actContext = null; + public boolean isAnimating = false; + public boolean supressMenu = false; + public int animDur = 350; + + public static final int PICK_BACKFILE = 11; + public boolean isCustomActionBar = false; + + protected ActionBar getActionBar() { + AppCompatActivity act = (AppCompatActivity) getActivity(); + return act.getSupportActionBar(); + } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + if (supressMenu) { + inflater.inflate(R.menu.menu_mods, menu); + } + if (isCustomActionBar) { + MenuItem item = null; + for (int i = 0; i < menu.size(); i++) { + item = menu.getItem(i); + item.setVisible(item.getItemId() == R.id.edit_confirm); + } + MenuItem confirmMenu = menu.findItem(R.id.edit_confirm); + int applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_confirm_dark" : "action_mode_title_button_confirm_light", "drawable", "miui"); + if (applyResId == 0) + applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_done_dark" : "action_mode_immersion_done_light", "drawable", "miui"); + confirmMenu.setIcon(applyResId); + } + } + + public void confirmEdit() {} + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + Activity act = getActivity(); + switch (item.getItemId()) { + case R.id.edit_confirm: + confirmEdit(); + return true; + case R.id.restartlauncher: + getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "RestartLauncher")); + return true; + case R.id.restartsystemui: + getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "RestartSystemUI")); + return true; + case R.id.backuprestore: + showBackupRestoreDialog(); + return true; + case R.id.softreboot: + if (!Helpers.miuizerModuleActive) { + showXposedDialog(getActivity()); + return true; + } + + AlertDialog.Builder alert = new AlertDialog.Builder(getValidContext()); + alert.setTitle(R.string.soft_reboot); + alert.setMessage(R.string.soft_reboot_ask); + alert.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "FastReboot")); + } + }); + alert.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) {} + }); + alert.show(); + return true; + case R.id.about: + Bundle args = new Bundle(); + args.putInt("baseResId", R.layout.fragment_about); + openSubFragment(new AboutFragment(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.app_about, R.xml.prefs_about); + return true; + } + return false; + } + + public void showXposedDialog(Activity act) { + try { + AlertDialog.Builder builder = new AlertDialog.Builder(act); + builder.setTitle(R.string.warning); + builder.setMessage(R.string.module_not_active); + builder.setCancelable(true); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){} + }); + AlertDialog dlg = builder.create(); + dlg.show(); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public void showBackupRestoreDialog() { + final Activity act = getActivity(); + + AlertDialog.Builder alert = new AlertDialog.Builder(act); + alert.setTitle(R.string.backup_restore); + alert.setMessage(R.string.backup_restore_choose); + alert.setPositiveButton(R.string.do_restore, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + restoreSettings(act); + } + }); + alert.setNegativeButton(R.string.do_backup, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + backupSettings(act); + } + }); + alert.show(); + } + + private void initFragment() { + setHasOptionsMenu(supressMenu); + ActionBar actionBar = getActionBar(); + actionBar.setTitle(R.string.app_name); + + boolean showBack = false; + if (this instanceof MainFragment) { + ActivityInfo appInfo; + try { + Activity act = getActivity(); + appInfo = act.getPackageManager().getActivityInfo(act.getComponentName(), PackageManager.GET_META_DATA); + showBack = appInfo.metaData != null && appInfo.metaData.containsKey("from.settings"); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } else showBack = !(this instanceof SnoozedFragment); + + actionBar.setDisplayHomeAsUpEnabled(showBack); + } + + @SuppressLint("WorldReadableFiles") + public void onCreate(Bundle savedInstanceState, int pref_defaults) { + super.onCreate(savedInstanceState); + try { + getPreferenceManager().setSharedPreferencesName(Helpers.prefsName); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + getPreferenceManager().setStorageDeviceProtected(); + PreferenceManager.setDefaultValues(Helpers.getProtectedContext(getValidContext()), pref_defaults, false); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + initFragment(); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + setViewBackground(view); + } + + public void setViewBackground(View view) { + view.setBackgroundColor(Helpers.getSystemBackgroundColor(getValidContext())); + } + + public void setActionModeStyle(View searchView) { + boolean isNight = Helpers.isNightMode(getValidContext()); + if (searchView != null) try { + searchView.setSaveFromParentEnabled(false); + Drawable drawable = getResources().getDrawable(getResources().getIdentifier(isNight ? "search_mode_bg_dark" : "search_mode_bg_light", "drawable", "miui"), getValidContext().getTheme()); + try { + int colorResId = getResources().getIdentifier(isNight ? "primary_color_dark" : "primary_color_light", "color", "miui"); + if (colorResId != 0 && drawable instanceof LayerDrawable) { + drawable = ((LayerDrawable)drawable).getDrawable(0); + if (drawable instanceof GradientDrawable) + ((GradientDrawable)drawable).setColor(getResources().getColor(colorResId, getValidContext().getTheme())); + } + } catch (Throwable ignore) {} + searchView.setBackground(drawable); + LinearLayout inputArea = searchView.findViewById(android.R.id.inputArea); + inputArea.setBackgroundResource(getResources().getIdentifier(isNight ? "search_mode_edit_text_bg_dark" : "search_mode_edit_text_bg_light", "drawable", "miui")); + if (Helpers.is11()) { + ViewGroup.LayoutParams lp1 = searchView.getLayoutParams(); + int resId = getResources().getIdentifier("action_bar_default_height", "dimen", "miui"); + lp1.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.secondary_text_size : resId); + searchView.setLayoutParams(lp1); + FrameLayout.LayoutParams lp2 = (FrameLayout.LayoutParams)inputArea.getLayoutParams(); + resId = getResources().getIdentifier("searchbar_bg_height", "dimen", "miui"); + lp2.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.searchbar_bg_height : resId); + inputArea.setLayoutParams(lp2); + } + ImageView inputIcon = searchView.findViewById(R.id.inputIcon); + inputIcon.setImageResource(getResources().getIdentifier(isNight ? "edit_text_search_dark" : "edit_text_search", "drawable", "miui")); + TextView input = searchView.findViewById(android.R.id.input); + int fontSize = getResources().getIdentifier(Helpers.is11() ? "edit_text_font_size" : "secondary_text_size", "dimen", "miui"); + input.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(fontSize == 0 ? R.dimen.secondary_text_size : fontSize)); + input.setHintTextColor(getResources().getColor(getResources().getIdentifier(isNight ? "edit_text_search_hint_color_dark" : "edit_text_search_hint_color_light", "color", "miui"), getValidContext().getTheme())); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType settingsType, Helpers.ActionBarType abType, int titleResId, int contentResId) { + if (args == null) args = new Bundle(); + args.putInt("settingsType", settingsType.ordinal()); + args.putInt("abType", abType.ordinal()); + args.putInt("titleResId", titleResId); + args.putInt("contentResId", contentResId); + float order = 100.0f; + try { + if (getView() != null) order = getView().getTranslationZ(); + } catch (Throwable t) {} + args.putFloat("order", order); + if (fragment.getArguments() == null) { + fragment.setArguments(args); + } else { + fragment.getArguments().clear(); + fragment.getArguments().putAll(args); + } + getFragmentManager().beginTransaction().setCustomAnimations(R.animator.fragment_open_enter, R.animator.fragment_open_exit, R.animator.fragment_close_enter, R.animator.fragment_close_exit) + .replace(R.id.fragment_container, fragment).addToBackStack(null).commitAllowingStateLoss(); + getFragmentManager().executePendingTransactions(); + } + + @Override + public Animator onCreateAnimator(int transit, boolean enter, final int nextAnim) { + if (nextAnim == 0) return null; + Configuration config = getResources().getConfiguration(); + float density = getResources().getDisplayMetrics().density; + final float scrWidth = config.screenWidthDp * density; + + final View top = getView(); + if (top == null) return null; + final View content = top.findViewById(android.R.id.list); + + //ValueAnimator.setFrameDelay(17); + ValueAnimator valAnimator = new ValueAnimator(); + valAnimator.setDuration(animDur); + valAnimator.setFloatValues(0.0f, 1.0f); + valAnimator.setInterpolator(new DecelerateInterpolator(2.5f)); + + if (nextAnim == R.animator.fragment_open_enter || nextAnim == R.animator.fragment_open_exit) + valAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { +// Log.e("animation", "start on: " + PreferenceFragmentBase.this.getClass().getCanonicalName()); + isAnimating = true; + } + + @Override + public void onAnimationEnd(Animator animation) { +// Log.e("animation", "end on: " + PreferenceFragmentBase.this.getClass().getCanonicalName()); + isAnimating = false; + } + + @Override + public void onAnimationCancel(Animator animation) {} + + @Override + public void onAnimationRepeat(Animator animation) {} + }); else isAnimating = false; + + valAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + if (content == null) return; + float val = (float)animation.getAnimatedValue(); + if (nextAnim == R.animator.fragment_open_enter) { + top.setX(scrWidth * (1.0f - val)); + content.setAlpha(0.6f + val * 0.4f); + } else if (nextAnim == R.animator.fragment_open_exit) { + top.setX(-scrWidth / 4.0f * val); + top.setAlpha(1.0f - val * 0.4f); + } else if (nextAnim == R.animator.fragment_close_enter) { + top.setX(-scrWidth / 4.0f * (1.0f - val)); + top.setAlpha(0.6f + val * 0.4f); + } else if (nextAnim == R.animator.fragment_close_exit) { + top.setX(scrWidth * val); + content.setAlpha(1.0f - val * 0.4f); + } + } + }); + + return valAnimator; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + this.actContext = context; + } + + @Override + public void onDetach() { + super.onDetach(); + this.actContext = null; + } + +// @Override +// public void onResume() { +// super.onResume(); +// setupImmersiveMenu(); +// } + + public Context getValidContext() { + if (actContext != null) return actContext; + return getActivity() == null ? getContext() : getActivity().getApplicationContext(); + } + + public void backupSettings(Activity act) { + String backupPath = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; + if (!Helpers.preparePathForBackup(act, backupPath)) return; + ObjectOutputStream output = null; + try { + output = new ObjectOutputStream(new FileOutputStream(backupPath + Helpers.backupFile + new SimpleDateFormat("-MMddHHmmss").format(new java.util.Date()))); + output.writeObject(Helpers.prefs.getAll()); + + AlertDialog.Builder alert = new AlertDialog.Builder(act); + alert.setTitle(R.string.do_backup); + alert.setMessage(R.string.backup_ok); + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) {} + }); + alert.show(); + } catch (Throwable e) { + e.printStackTrace(); + AlertDialog.Builder alert = new AlertDialog.Builder(act); + alert.setTitle(R.string.warning); + alert.setMessage(getString(R.string.storage_cannot_backup) + "\n" + e.getMessage()); + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) {} + }); + alert.show(); + } finally { + try { + if (output != null) { + output.flush(); + output.close(); + } + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, + Intent resultData) { + if (requestCode == MainFragment.PICK_BACKFILE + && resultCode == Activity.RESULT_OK) { + Uri uri = null; + if (resultData != null) { + uri = resultData.getData(); + doRestoreSettings(uri); + } + } + } + + public void restoreSettings(final Activity act) { + if (!Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_RESTORE)) return; + if (!Helpers.checkStorageReadable(act)) return; + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("application/octet-stream"); + startActivityForResult(intent, PICK_BACKFILE); + } + + public void doRestoreSettings(Uri uri) { + ObjectInputStream input = null; + final Activity act = getActivity(); + try { + input = new ObjectInputStream(act.getContentResolver().openInputStream(uri)); + Map entries = (Map)input.readObject(); + if (entries == null || entries.isEmpty()) throw new RuntimeException("Cannot read entries"); + + SharedPreferences.Editor prefEdit = Helpers.prefs.edit(); + prefEdit.clear(); + for (Map.Entry entry: entries.entrySet()) { + Object val = entry.getValue(); + String key = entry.getKey(); + + if (val instanceof Boolean) + prefEdit.putBoolean(key, (Boolean)val); + else if (val instanceof Float) + prefEdit.putFloat(key, (Float)val); + else if (val instanceof Integer) + prefEdit.putInt(key, (Integer)val); + else if (val instanceof Long) + prefEdit.putLong(key, (Long)val); + else if (val instanceof String) + prefEdit.putString(key, ((String)val)); + else if (val instanceof Set) + prefEdit.putStringSet(key, ((Set)val)); + } + prefEdit.apply(); + + AlertDialog.Builder alert = new AlertDialog.Builder(act); + alert.setTitle(R.string.do_restore); + alert.setMessage(R.string.restore_ok); + alert.setCancelable(false); + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + act.finish(); + act.startActivity(act.getIntent()); + } + }); + alert.show(); + } catch (Throwable t) { + t.printStackTrace(); + AlertDialog.Builder alert = new AlertDialog.Builder(act); + alert.setTitle(R.string.warning); + alert.setMessage(R.string.storage_cannot_restore); + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) {} + }); + alert.show(); + } finally { + try { + if (input != null) input.close(); + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 68d86ebc..0ed4e603 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -149,63 +149,61 @@ public void onReceive(final Context context, Intent intent) { String action = intent.getAction(); if (action == null) return; -// if (action.equals(ACTION_PREFIX + "ShowQuickRecents")) { -// if (floatSel == null) floatSel = new FloatingSelector(context); -// floatSel.show(); -// } else if (action.equals(ACTION_PREFIX + "HideQuickRecents")) { -// if (floatSel != null) floatSel.hide(); -// } - if (action.equals(ACTION_PREFIX + "RestartSystemUI")) { Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL); } + else if (action.equals(ACTION_PREFIX + "CopyToExternal")) { + try { + String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; + new File(dir).mkdirs(); - if (action.equals(ACTION_PREFIX + "CopyToExternal")) try { - String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; - new File(dir).mkdirs(); - - int copyAction = intent.getIntExtra("action", 0); - if (copyAction == 1) { - Helpers.copyFile(intent.getStringExtra("from"), dir + Helpers.wallpaperFile); - Intent lockIntent = new Intent("miui.intent.action.SET_LOCK_WALLPAPER"); - lockIntent.setPackage("com.android.thememanager"); - lockIntent.putExtra("lockWallpaperPath", dir + Helpers.wallpaperFile); - context.sendBroadcast(lockIntent); - } else if (copyAction == 2) { - File xposedVersion = new File(dir + Helpers.versionFile); - xposedVersion.createNewFile(); - try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(xposedVersion, false))) { - out.write(intent.getStringExtra("data")); + int copyAction = intent.getIntExtra("action", 0); + if (copyAction == 1) { + Helpers.copyFile(intent.getStringExtra("from"), dir + Helpers.wallpaperFile); + Intent lockIntent = new Intent("miui.intent.action.SET_LOCK_WALLPAPER"); + lockIntent.setPackage("com.android.thememanager"); + lockIntent.putExtra("lockWallpaperPath", dir + Helpers.wallpaperFile); + context.sendBroadcast(lockIntent); + } else if (copyAction == 2) { + File xposedVersion = new File(dir + Helpers.versionFile); + xposedVersion.createNewFile(); + try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(xposedVersion, false))) { + out.write(intent.getStringExtra("data")); + } } + } catch (Throwable t) { + XposedBridge.log(t); } - } catch (Throwable t) { - XposedBridge.log(t); } - - if (action.equals(ACTION_PREFIX + "CollectXposedLog")) try { - String errorLogPath = Helpers.getXposedInstallerErrorLog(context); - if (errorLogPath != null) - try (InputStream in = new FileInputStream(errorLogPath)) { - String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; - new File(dir).mkdirs(); - File sdcardLog = new File(dir + Helpers.logFile); - sdcardLog.createNewFile(); - try (OutputStream out = new FileOutputStream(sdcardLog, false)) { - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) out.write(buf, 0, len); - } + else if (action.equals(ACTION_PREFIX + "CollectXposedLog")) { + try { + String errorLogPath = Helpers.getXposedInstallerErrorLog(context); + if (errorLogPath != null) + try (InputStream in = new FileInputStream(errorLogPath)) { + String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; + new File(dir).mkdirs(); + File sdcardLog = new File(dir + Helpers.logFile); + sdcardLog.createNewFile(); + try (OutputStream out = new FileOutputStream(sdcardLog, false)) { + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) out.write(buf, 0, len); + } + } + } catch (Throwable t) { + XposedBridge.log(t); } - } catch (Throwable t) { - XposedBridge.log(t); } - - if (action.equals(ACTION_PREFIX + "ClearMemory")) { + else if (action.equals(ACTION_PREFIX + "ClearMemory")) { Intent clearIntent = new Intent("com.android.systemui.taskmanager.Clear"); clearIntent.putExtra("show_toast", true); //clearIntent.putExtra("clean_type", -1); context.sendBroadcast(clearIntent); } + else if (action.equals(ACTION_PREFIX + "RestartLauncher")) { + ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); + XposedHelpers.callMethod(am, "forceStopPackage", "com.miui.home"); + } if (mStatusBar != null) { if (action.equals(ACTION_PREFIX + "ExpandNotifications")) try { @@ -328,28 +326,20 @@ public void run() { XposedHelpers.callMethod(mHotspotController, "setHotspotEnabled", !mHotspotEnabled); } - Object mToggleManager = XposedHelpers.getObjectField(mStatusBar, "mToggleManager"); - if (mToggleManager == null) return; - if (action.equals(ACTION_PREFIX + "ToggleGPS")) { - boolean mGpsEnable = (boolean)XposedHelpers.getObjectField(mToggleManager, "mGpsEnable"); - if (mGpsEnable) - Toast.makeText(context, modRes.getString(R.string.toggle_gps_off), Toast.LENGTH_SHORT).show(); - else - Toast.makeText(context, modRes.getString(R.string.toggle_gps_on), Toast.LENGTH_SHORT).show(); - XposedHelpers.callMethod(mToggleManager, "toggleGps"); - } if (action.equals(ACTION_PREFIX + "ToggleFlashlight")) { - boolean mTorchEnable = (boolean)XposedHelpers.getObjectField(mToggleManager, "mTorchEnable"); - if (mTorchEnable) - Toast.makeText(context, modRes.getString(R.string.toggle_flash_off), Toast.LENGTH_SHORT).show(); - else - Toast.makeText(context, modRes.getString(R.string.toggle_flash_on), Toast.LENGTH_SHORT).show(); - XposedHelpers.callMethod(mToggleManager, "toggleTorch"); + XposedHelpers.callStaticMethod(findClass("com.miui.systemui.util.CommonUtil", context.getClassLoader()), "toggleTorch"); } - - //Intent intent = new Intent("com.miui.app.ExtraStatusBarManager.action_TRIGGER_TOGGLE"); - //intent.putExtra("com.miui.app.ExtraStatusBarManager.extra_TOGGLE_ID", 10); - //mContext.sendBroadcast(intent); + // @todo fix gps toggle +// Object mToggleManager = XposedHelpers.getObjectField(mStatusBar, "mToggleManager"); +// if (mToggleManager == null) return; +// if (action.equals(ACTION_PREFIX + "ToggleGPS")) { +// boolean mGpsEnable = (boolean)XposedHelpers.getObjectField(mToggleManager, "mGpsEnable"); +// if (mGpsEnable) +// Toast.makeText(context, modRes.getString(R.string.toggle_gps_off), Toast.LENGTH_SHORT).show(); +// else +// Toast.makeText(context, modRes.getString(R.string.toggle_gps_on), Toast.LENGTH_SHORT).show(); +// XposedHelpers.callMethod(mToggleManager, "toggleGps"); +// } } } catch (Throwable t) { XposedBridge.log(t); @@ -936,33 +926,6 @@ protected void after(MethodHookParam param) throws Throwable { } }); - Helpers.hookAllMethods("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "init", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - IntentFilter intentfilter = new IntentFilter(); - intentfilter.addAction(ACTION_PREFIX + "SaveLastMusicPausedTime"); -// intentfilter.addAction(ACTION_PREFIX + "RestartLauncher"); - mContext.registerReceiver(new BroadcastReceiver() { - public void onReceive(final Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) return; - - try { - if (action.equals(ACTION_PREFIX + "SaveLastMusicPausedTime")) { - Settings.System.putLong(context.getContentResolver(), "last_music_paused_time", currentTimeMillis()); - } else if (action.equals(ACTION_PREFIX + "RestartLauncher")) { - ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); - XposedHelpers.callMethod(am, "forceStopPackage", "com.miui.home"); - } - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }, intentfilter); - } - }); - Helpers.hookAllMethods("com.android.server.policy.BaseMiuiPhoneWindowManager", lpparam.classLoader, "initInternal", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -970,6 +933,7 @@ protected void after(MethodHookParam param) throws Throwable { IntentFilter intentfilter = new IntentFilter(); intentfilter.addAction(ACTION_PREFIX + "SimulateMenu"); intentfilter.addAction(ACTION_PREFIX + "ForceClose"); + intentfilter.addAction(ACTION_PREFIX + "SaveLastMusicPausedTime"); final Object thisObject = param.thisObject; mContext.registerReceiver(new BroadcastReceiver() { public void onReceive(final Context context, Intent intent) { @@ -1002,40 +966,14 @@ public void onReceive(final Context context, Intent intent) { } catch (Throwable t) { XposedBridge.log(t); } + + if (action.equals(ACTION_PREFIX + "SaveLastMusicPausedTime")) { + Settings.System.putLong(context.getContentResolver(), "last_music_paused_time", currentTimeMillis()); + } } }, intentfilter); } }); - -// Helpers.hookAllMethods("com.android.server.policy.MiuiPhoneWindowManager", lpparam.classLoader, "init", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); -// IntentFilter intentfilter = new IntentFilter(); -// intentfilter.addAction(ACTION_PREFIX + "OpenFingerprintActionDialog"); -// final Object thisObject = param.thisObject; -// mContext.registerReceiver(new BroadcastReceiver() { -// public void onReceive(final Context context, Intent intent) { -// String action = intent.getAction(); -// if (action == null) return; -// -// try { -// XposedHelpers.callMethod(thisObject, "bringUpActionChooseDlg"); -// } catch (Throwable t) { -// XposedBridge.log(t); -// } -// } -// }, intentfilter); -// } -// }); - -// Helpers.hookAllMethods("com.android.server.am.ActivityStackSupervisor", lpparam.classLoader, "getComponentRestrictionForCallingPackage", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// ActivityInfo ai = (ActivityInfo)param.args[0]; -// if (ai != null && ai.name.equals("com.miui.privacyapps.ui.PrivacyAppsOperationTutorialActivity")) param.setResult(0); -// } -// }); } public static void setupStatusBar(LoadPackageParam lpparam) { @@ -1060,40 +998,12 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "ClearMemory"); intentfilter.addAction(ACTION_PREFIX + "CollectXposedLog"); intentfilter.addAction(ACTION_PREFIX + "RestartSystemUI"); + intentfilter.addAction(ACTION_PREFIX + "RestartLauncher"); intentfilter.addAction(ACTION_PREFIX + "CopyToExternal"); mStatusBarContext.registerReceiver(mSBReceiver, intentfilter); } }); - -// Helpers.findAndHookMethod("com.android.systemui.statusbar.HeaderView", lpparam.classLoader, "onFinishInflate", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// TextView mClock = (TextView)XposedHelpers.getObjectField(param.thisObject, "mClock"); -// RelativeLayout.LayoutParams clp = (RelativeLayout.LayoutParams)mClock.getLayoutParams(); -// clp.height = 0; -// mClock.setLayoutParams(clp); -// -// RelativeLayout heaverView = (RelativeLayout)param.thisObject; -// TextView temp = new TextView(heaverView.getContext()); -// RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); -// lp.addRule(RelativeLayout.ABOVE, heaverView.getContext().getResources().getIdentifier("date_time", "id", "com.android.systemui")); -// lp.addRule(RelativeLayout.ALIGN_LEFT); -// lp.setMarginStart(heaverView.getContext().getResources().getDimensionPixelSize(heaverView.getContext().getResources().getIdentifier("expanded_notification_weather_temperature_right", "dimen", "com.android.systemui"))); -// temp.setLayoutParams(lp); -// temp.setText("CPU 666° Battery 999° PCB 333°"); -// temp.setTextAppearance(heaverView.getContext().getResources().getIdentifier("TextAppearance.StatusBar.Expanded.Weather", "style", "com.android.systemui")); -// heaverView.setGravity(Gravity.TOP); -// heaverView.addView(temp); -// } -// }); -// -// Helpers.findAndHookMethod("com.android.systemui.CustomizedUtils", lpparam.classLoader, "getNotchExpandedHeaderViewHeight", Context.class, int.class, new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// param.setResult((int)param.getResult() + 65); -// } -// }); } // Actions diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java index 80bbfb82..8e88d23f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java @@ -133,32 +133,4 @@ private boolean checkPermissions() { return pm.checkPermission(Helpers.ACCESS_SECURITY_CENTER, Helpers.modulePkg) == PackageManager.PERMISSION_GRANTED; } -// public boolean onCreateOptionsMenu(Menu menu) { -// getMenuInflater().inflate(R.menu.menu_launcher, menu); -// return true; -// } -// -// @Override -// public boolean onOptionsItemSelected(MenuItem item) { -// if (item.getItemId() == R.id.restartlauncher) -// try { -// getActivity().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "RestartLauncher")); -// } catch (Throwable e) { -// e.printStackTrace(); -// } -// return super.onOptionsItemSelected(item); -// } -// -// private void setupImmersiveMenu() { -// ActionBar actionBar = getActionBar(); -// if (actionBar != null) actionBar.showSplitActionBar(false, false); -// setImmersionMenuEnabled(true); -// } -// -// @Override -// public void onResume() { -// super.onResume(); -// setupImmersiveMenu(); -// } - } \ No newline at end of file diff --git a/app/src/main/res/menu/menu_itemactions.xml b/app/src/main/res/menu/menu_itemactions.xml index cfb91a3c..c47d41aa 100644 --- a/app/src/main/res/menu/menu_itemactions.xml +++ b/app/src/main/res/menu/menu_itemactions.xml @@ -1,10 +1,11 @@ - + diff --git a/app/src/main/res/menu/menu_launcher.xml b/app/src/main/res/menu/menu_launcher.xml deleted file mode 100644 index 44dfca07..00000000 --- a/app/src/main/res/menu/menu_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/app/src/main/res/menu/menu_mods.xml b/app/src/main/res/menu/menu_mods.xml index f0cc9c36..ec698547 100644 --- a/app/src/main/res/menu/menu_mods.xml +++ b/app/src/main/res/menu/menu_mods.xml @@ -11,6 +11,14 @@ android:visible="false" android:title="" app:showAsAction="always"/> + + 管理Xposed模块 软重启 现在执行软重启吗? - 重启启动器 + 重启桌面 设置管理 请选择所需操作 备份 @@ -1049,4 +1049,5 @@ 双击锁屏 应用信息 强制关闭 + 重启系统界面 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 20173ae2..84dca0d2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1006,6 +1006,7 @@ Soft reboot Perform soft reboot now? Restart launcher + Restart systemui Settings management Choose the desired routine Backup From c0ce2c390233a2dbb41d6485febc69b9ed874df5 Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 21 Jun 2022 20:39:08 +0800 Subject: [PATCH 019/627] remove systemui and launcher from extended power menu --- app/src/main/res/raw/extended_power_menu | Bin 88533 -> 87452 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/src/main/res/raw/extended_power_menu b/app/src/main/res/raw/extended_power_menu index 0e9c43f5076ef7b7b08f38bf8c8734f4046f86b6..e886767de8cace171ca85ed356e83ac5692145cf 100644 GIT binary patch literal 87452 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 U!0tWh>H`0!Nl+;6FpQh>FU44#vj6}9 delta 73851 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 ZXnTMKxMOguX{GIFQfQf! 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 Date: Mon, 27 Jun 2022 21:01:48 +0800 Subject: [PATCH 020/627] migrate to androidx --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 3 +- .../mikanoshi/customiuizer/AboutFragment.java | 20 +- .../mikanoshi/customiuizer/Credentials.java | 4 +- .../customiuizer/CredentialsLauncher.java | 4 +- .../customiuizer/CredentialsShortcut.java | 5 +- .../customiuizer/GateWayLauncher.java | 4 +- .../customiuizer/GateWaySettings.java | 4 +- .../mikanoshi/customiuizer/MainActivity.java | 395 ++++----- .../customiuizer/MainApplication.java | 64 +- .../mikanoshi/customiuizer/MainFragment.java | 786 ++++++++--------- .../customiuizer/PreferenceFragmentBase.java | 137 ++- .../customiuizer/SnoozedActivity.java | 7 +- .../customiuizer/SnoozedFragment.java | 6 +- .../mikanoshi/customiuizer/SubFragment.java | 790 +++++++++--------- .../customiuizer/SubFragmentWithSearch.java | 52 +- .../prefs/CheckBoxPreferenceEx.java | 34 +- .../customiuizer/prefs/ListPreferenceEx.java | 56 +- .../customiuizer/prefs/ListViewEx.java | 2 + .../prefs/PreferenceCategoryEx.java | 28 +- .../customiuizer/prefs/PreferenceEx.java | 49 +- .../customiuizer/prefs/SeekBarPreference.java | 31 +- .../customiuizer/subs/AppSelector.java | 3 +- .../mikanoshi/customiuizer/subs/BTList.java | 8 - .../customiuizer/subs/CategorySelector.java | 13 +- .../mikanoshi/customiuizer/subs/Controls.java | 15 +- .../mikanoshi/customiuizer/subs/Launcher.java | 16 +- .../customiuizer/subs/SortableList.java | 4 +- .../mikanoshi/customiuizer/subs/System.java | 23 +- .../subs/System_AirplaneModeConfig.java | 4 +- .../subs/System_BatteryIndicator.java | 2 +- .../subs/System_NoScreenLock.java | 6 +- .../subs/System_ScreenshotConfig.java | 2 +- .../subs/System_VibrationAmp.java | 2 +- .../customiuizer/subs/System_Visualizer.java | 2 +- .../mikanoshi/customiuizer/subs/Various.java | 2 +- .../subs/Various_CallReminder.java | 5 +- .../subs/Various_CallUIBright.java | 2 +- .../subs/Various_HiddenFeatures.java | 10 +- .../mikanoshi/customiuizer/subs/WiFiList.java | 8 - .../customiuizer/tasker/UnlockSettings.java | 4 +- .../mikanoshi/customiuizer/utils/Helpers.java | 84 +- .../customiuizer/utils/ModSearchAdapter.java | 1 - .../utils/NestedHeaderLayout.java | 53 -- app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/layout/applist_item.xml | 7 +- app/src/main/res/layout/applist_item11.xml | 7 +- app/src/main/res/layout/fragment_about.xml | 236 ------ .../main/res/layout/fragment_about_head.xml | 174 ++++ .../main/res/layout/fragment_about_tail.xml | 31 + app/src/main/res/layout/pref_header.xml | 4 +- app/src/main/res/layout/pref_item.xml | 18 +- .../main/res/layout/pref_item_detailed.xml | 6 +- .../main/res/layout/preference_category.xml | 8 +- .../main/res/layout/preference_seekbar.xml | 78 -- .../main/res/layout/preference_seekbar12.xml | 164 ++-- app/src/main/res/layout/prefs_bt_networks.xml | 1 - .../main/res/layout/prefs_fragment_base.xml | 26 + app/src/main/res/layout/prefs_main.xml | 31 - app/src/main/res/layout/prefs_main12.xml | 36 +- .../res/layout/prefs_system_audiosilencer.xml | 2 +- .../main/res/layout/prefs_wifi_networks.xml | 1 - app/src/main/res/layout/search_stub.xml | 2 +- app/src/main/res/menu/menu_itemoptions.xml | 7 +- app/src/main/res/values/arrays.xml | 5 - app/src/main/res/values/dimens.xml | 17 +- app/src/main/res/values/styles.xml | 50 +- app/src/main/res/xml/prefs_launcher.xml | 7 - app/src/main/res/xml/prefs_main.xml | 2 +- gradle.properties | 1 + 70 files changed, 1753 insertions(+), 1922 deletions(-) delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java delete mode 100644 app/src/main/res/layout/fragment_about.xml create mode 100644 app/src/main/res/layout/fragment_about_head.xml create mode 100644 app/src/main/res/layout/fragment_about_tail.xml delete mode 100644 app/src/main/res/layout/preference_seekbar.xml create mode 100644 app/src/main/res/layout/prefs_fragment_base.xml delete mode 100644 app/src/main/res/layout/prefs_main.xml diff --git a/app/build.gradle b/app/build.gradle index b5075d0b..6f3a6ce8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -82,7 +82,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') // implementation "ch.acra:acra-core:$acraVersion" // noinspection DifferentStdlibGradleVersion -// implementation "androidx.preference:preference:1.2.0" + implementation "androidx.preference:preference:1.2.0" // implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10' implementation 'com.github.jinatonic.confetti:confetti:1.1.2' compileOnly 'de.robv.android.xposed:api:82' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a3403a64..7f9f7675 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,7 +4,8 @@ package="name.mikanoshi.customiuizer"> - + diff --git a/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java index 0754ab28..d0ac4619 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/AboutFragment.java @@ -3,14 +3,32 @@ import android.app.Activity; import android.content.res.Configuration; import android.os.Bundle; -import android.preference.Preference; import android.view.View; +import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.preference.Preference; + import name.mikanoshi.customiuizer.utils.Helpers; public class AboutFragment extends SubFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + headLayoutId = R.layout.fragment_about_head; + tailLayoutId = R.layout.fragment_about_tail; + } + + @Override + protected void fixStubLayout(View view, int postion) { + if (postion == 2) { + RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams(); + lp.addRule(RelativeLayout.BELOW, android.R.id.list_container); + view.setLayoutParams(lp); + } + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/Credentials.java b/app/src/main/java/name/mikanoshi/customiuizer/Credentials.java index d512277d..d82d3ad8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/Credentials.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/Credentials.java @@ -10,9 +10,11 @@ import android.security.keystore.KeyProperties; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; + import javax.crypto.KeyGenerator; -public class Credentials extends Activity { +public class Credentials extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/CredentialsLauncher.java b/app/src/main/java/name/mikanoshi/customiuizer/CredentialsLauncher.java index 39e0b034..35b18ed0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/CredentialsLauncher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/CredentialsLauncher.java @@ -1,5 +1,5 @@ package name.mikanoshi.customiuizer; -import android.app.Activity; +import androidx.appcompat.app.AppCompatActivity; -public class CredentialsLauncher extends Activity {} +public class CredentialsLauncher extends AppCompatActivity {} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/CredentialsShortcut.java b/app/src/main/java/name/mikanoshi/customiuizer/CredentialsShortcut.java index 6f3d003c..9dfa1e88 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/CredentialsShortcut.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/CredentialsShortcut.java @@ -1,10 +1,11 @@ package name.mikanoshi.customiuizer; -import android.app.Activity; import android.content.Intent; import android.os.Bundle; -public class CredentialsShortcut extends Activity { +import androidx.appcompat.app.AppCompatActivity; + +public class CredentialsShortcut extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/GateWayLauncher.java b/app/src/main/java/name/mikanoshi/customiuizer/GateWayLauncher.java index a52dc954..0236f1e9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/GateWayLauncher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/GateWayLauncher.java @@ -1,5 +1,5 @@ package name.mikanoshi.customiuizer; -import android.app.Activity; +import androidx.appcompat.app.AppCompatActivity; -public class GateWayLauncher extends Activity {} +public class GateWayLauncher extends AppCompatActivity {} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/GateWaySettings.java b/app/src/main/java/name/mikanoshi/customiuizer/GateWaySettings.java index e3787e9c..ad69b3ae 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/GateWaySettings.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/GateWaySettings.java @@ -1,5 +1,5 @@ package name.mikanoshi.customiuizer; -import android.app.Activity; +import androidx.appcompat.app.AppCompatActivity; -public class GateWaySettings extends Activity {} +public class GateWaySettings extends AppCompatActivity {} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java index cb6e7ed0..36b5cc94 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java @@ -1,198 +1,199 @@ -package name.mikanoshi.customiuizer; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.Fragment; -import android.app.backup.BackupManager; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.FileObserver; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MenuItem; -import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; - -import java.util.Set; - -import name.mikanoshi.customiuizer.utils.Helpers; - -public class MainActivity extends AppCompatActivity { - - MainFragment mainFrag = null; - SharedPreferences.OnSharedPreferenceChangeListener prefsChanged; - FileObserver fileObserver; - - @Override - protected void attachBaseContext(Context base) { - try { - super.attachBaseContext(Helpers.getLocaleContext(base)); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - prefsChanged = new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) { - Log.i("prefs", "Changed: " + key); - requestBackup(); - Object val = sharedPrefs.getAll().get(key); - String path = ""; - if (val instanceof String) - path = "string/"; - else if (val instanceof Set) - path = "stringset/"; - else if (val instanceof Integer) - path = "integer/"; - else if (val instanceof Boolean) - path = "boolean/"; - getContentResolver().notifyChange(Uri.parse("content://" + SharedPrefsProvider.AUTHORITY + "/" + path + key), null); - if (!path.equals("")) - getContentResolver().notifyChange(Uri.parse("content://" + SharedPrefsProvider.AUTHORITY + "/pref/" + path + key), null); - } - }; - Helpers.prefs.registerOnSharedPreferenceChangeListener(prefsChanged); - Helpers.fixPermissionsAsync(getApplicationContext()); - - try { - fileObserver = new FileObserver(Helpers.getSharedPrefsPath(), FileObserver.CLOSE_WRITE) { - @Override - public void onEvent(int event, String path) { - Helpers.fixPermissionsAsync(getApplicationContext()); - } - }; - fileObserver.startWatching(); - } catch (Throwable t) { - Log.e("prefs", "Failed to start FileObserver!"); - } - -// Helpers.updateNewModsMarking(this); - - - Toolbar myToolbar = findViewById(R.id.mainActionBar); - setSupportActionBar(myToolbar); - - if (savedInstanceState != null) - mainFrag = (MainFragment)getFragmentManager().getFragment(savedInstanceState, "mainFrag"); - if (mainFrag == null) { - mainFrag = new MainFragment(); - getFragmentManager().beginTransaction().replace(R.id.fragment_container, mainFrag).commit(); - } - } - - @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - getFragmentManager().putFragment(savedInstanceState, "mainFrag", mainFrag); - super.onSaveInstanceState(savedInstanceState); - } - - @SuppressLint("ApplySharedPref") - protected void onDestroy() { - try { - if (prefsChanged != null) Helpers.prefs.unregisterOnSharedPreferenceChangeListener(prefsChanged); - if (fileObserver != null) fileObserver.stopWatching(); - } catch (Throwable t) { - t.printStackTrace(); - } - super.onDestroy(); - } - - @Override - public void onBackPressed() { - Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container); - if (fragment == null) { - super.onBackPressed(); - return; - } - if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); - if (fragment instanceof SubFragment) - ((SubFragment)fragment).finish(); - else - super.onBackPressed(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container); - if (fragment == null) { - finish(); - return true; - } - if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); - if (fragment instanceof MainFragment) - finish(); - else { - ((SubFragment)fragment).finish(); - } - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_MENU) { - return true; - } - return super.onKeyDown(keyCode, event); - } - - public void requestBackup() { - new BackupManager(getApplicationContext()).dataChanged(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - if (grantResults.length == 0) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - return; - } - - switch (requestCode) { - case Helpers.REQUEST_PERMISSIONS_BACKUP: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) - mainFrag.backupSettings(this); - else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) - Toast.makeText(this, R.string.permission_save, Toast.LENGTH_SHORT).show(); - else - Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); - break; - case Helpers.REQUEST_PERMISSIONS_RESTORE: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) - mainFrag.restoreSettings(this); - else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) - Toast.makeText(this, R.string.permission_restore, Toast.LENGTH_SHORT).show(); - else - Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); - break; - case Helpers.REQUEST_PERMISSIONS_WIFI: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - Fragment frag = getFragmentManager().findFragmentById(R.id.fragment_container); - if (frag instanceof name.mikanoshi.customiuizer.subs.System_NoScreenLock) - ((name.mikanoshi.customiuizer.subs.System_NoScreenLock)frag).openWifiNetworks(); - } else if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) - Toast.makeText(this, R.string.permission_scan, Toast.LENGTH_LONG).show(); - else - Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); - break; - case Helpers.REQUEST_PERMISSIONS_REPORT: - Toast.makeText(this, ":(", Toast.LENGTH_SHORT).show(); - break; - default: - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - } +package name.mikanoshi.customiuizer; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.backup.BackupManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.FileObserver; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MenuItem; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; + +import java.io.File; +import java.util.Set; + +import name.mikanoshi.customiuizer.utils.Helpers; + +public class MainActivity extends AppCompatActivity { + + MainFragment mainFrag = null; + SharedPreferences.OnSharedPreferenceChangeListener prefsChanged; + FileObserver fileObserver; + + @Override + protected void attachBaseContext(Context base) { + try { + super.attachBaseContext(Helpers.getLocaleContext(base)); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + prefsChanged = new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) { + Log.i("prefs", "Changed: " + key); + Object val = sharedPrefs.getAll().get(key); + String path = ""; + if (val instanceof String) + path = "string/"; + else if (val instanceof Set) + path = "stringset/"; + else if (val instanceof Integer) + path = "integer/"; + else if (val instanceof Boolean) + path = "boolean/"; + getContentResolver().notifyChange(Uri.parse("content://" + SharedPrefsProvider.AUTHORITY + "/" + path + key), null); + if (!path.equals("")) { + getContentResolver().notifyChange(Uri.parse("content://" + SharedPrefsProvider.AUTHORITY + "/pref/" + path + key), null); + } + requestBackup(); + } + }; + Helpers.prefs.registerOnSharedPreferenceChangeListener(prefsChanged); + Helpers.fixPermissionsAsync(getApplicationContext()); + + try { + fileObserver = new FileObserver(new File(Helpers.getSharedPrefsPath()), FileObserver.CLOSE_WRITE) { + @Override + public void onEvent(int event, String path) { + Helpers.fixPermissionsAsync(getApplicationContext()); + } + }; + fileObserver.startWatching(); + } catch (Throwable t) { + Log.e("prefs", "Failed to start FileObserver!"); + } + +// Helpers.updateNewModsMarking(this); + + Toolbar myToolbar = findViewById(R.id.mainActionBar); + setSupportActionBar(myToolbar); + + if (savedInstanceState != null) { + mainFrag = (MainFragment) getSupportFragmentManager().getFragment(savedInstanceState, "mainFrag"); + } + else if (mainFrag == null) { + mainFrag = new MainFragment(); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, mainFrag).commit(); + } + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + getSupportFragmentManager().putFragment(savedInstanceState, "mainFrag", mainFrag); + super.onSaveInstanceState(savedInstanceState); + } + + @SuppressLint("ApplySharedPref") + protected void onDestroy() { + try { + if (prefsChanged != null) Helpers.prefs.unregisterOnSharedPreferenceChangeListener(prefsChanged); + if (fileObserver != null) fileObserver.stopWatching(); + } catch (Throwable t) { + t.printStackTrace(); + } + super.onDestroy(); + } + + @Override + public void onBackPressed() { + Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); + if (fragment == null) { + super.onBackPressed(); + return; + } + if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); + if (fragment instanceof SubFragment) + ((SubFragment)fragment).finish(); + else + super.onBackPressed(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); + if (fragment == null) { + finish(); + return true; + } + if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); + if (fragment instanceof MainFragment) + finish(); + else { + ((SubFragment)fragment).finish(); + } + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_MENU) { + return true; + } + return super.onKeyDown(keyCode, event); + } + + public void requestBackup() { + new BackupManager(getApplicationContext()).dataChanged(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (grantResults.length == 0) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + return; + } + + switch (requestCode) { + case Helpers.REQUEST_PERMISSIONS_BACKUP: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) + mainFrag.backupSettings(this); + else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) + Toast.makeText(this, R.string.permission_save, Toast.LENGTH_SHORT).show(); + else + Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); + break; + case Helpers.REQUEST_PERMISSIONS_RESTORE: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) + mainFrag.restoreSettings(this); + else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) + Toast.makeText(this, R.string.permission_restore, Toast.LENGTH_SHORT).show(); + else + Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); + break; + case Helpers.REQUEST_PERMISSIONS_WIFI: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { +// Fragment frag = getSupportFragmentManager().findFragmentById(R.id.fragment_container); +// if (frag instanceof name.mikanoshi.customiuizer.subs.System_NoScreenLock) +// ((name.mikanoshi.customiuizer.subs.System_NoScreenLock)frag).openWifiNetworks(); + } else if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) + Toast.makeText(this, R.string.permission_scan, Toast.LENGTH_LONG).show(); + else + Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); + break; + case Helpers.REQUEST_PERMISSIONS_REPORT: + Toast.makeText(this, ":(", Toast.LENGTH_SHORT).show(); + break; + default: + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java b/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java index 6f9d3441..d8bc48da 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java @@ -1,32 +1,32 @@ -package name.mikanoshi.customiuizer; - -import android.app.Application; -import android.content.Context; -import android.util.Log; - -import java.util.Locale; - -import name.mikanoshi.customiuizer.utils.Helpers; - - -public class MainApplication extends Application { - - public boolean mStarted = false; - - @Override - protected void attachBaseContext(Context base) { - Context pContext; - try { - pContext = Helpers.getProtectedContext(base); - Helpers.prefs = Helpers.getSharedPrefs(pContext, false); - String locale = Helpers.prefs.getString("pref_key_miuizer_locale", "auto"); - if (locale != null && !"auto".equals(locale) && !"1".equals(locale)) Locale.setDefault(Locale.forLanguageTag(locale)); - } catch (Throwable t) { - pContext = base; - Log.e("miuizer", "Failed to use protected storage!"); - } - super.attachBaseContext(pContext); - mStarted = true; - } - -} +package name.mikanoshi.customiuizer; + +import android.app.Application; +import android.content.Context; +import android.util.Log; + +import java.util.Locale; + +import name.mikanoshi.customiuizer.utils.Helpers; + + +public class MainApplication extends Application { + + public boolean mStarted = false; + + @Override + protected void attachBaseContext(Context base) { + Context pContext; + try { + pContext = Helpers.getProtectedContext(base); + Helpers.prefs = Helpers.getSharedPrefs(pContext, false); + String locale = Helpers.prefs.getString("pref_key_miuizer_locale", "auto"); + if (locale != null && !"auto".equals(locale) && !"1".equals(locale)) Locale.setDefault(Locale.forLanguageTag(locale)); + } catch (Throwable t) { + pContext = base; + Log.e("miuizer", "Failed to use protected storage!"); + } + super.attachBaseContext(pContext); + mStarted = true; + } + +} diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java index a179fdf3..ff101d3e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java @@ -1,387 +1,401 @@ -package name.mikanoshi.customiuizer; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.DialogInterface; -import android.content.pm.PackageManager; -import android.graphics.Paint; -import android.os.Bundle; -import android.os.Handler; -import android.preference.CheckBoxPreference; -import android.preference.Preference; -import android.preference.PreferenceCategory; -import android.preference.PreferenceScreen; -import android.text.Layout; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.AlignmentSpan; -import android.text.style.LineHeightSpan; -import android.view.ActionMode; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; - -import androidx.appcompat.widget.SearchView; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; - -import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; -import name.mikanoshi.customiuizer.prefs.PreferenceEx; -import name.mikanoshi.customiuizer.subs.CategorySelector; -import name.mikanoshi.customiuizer.subs.Controls; -import name.mikanoshi.customiuizer.subs.Launcher; -import name.mikanoshi.customiuizer.subs.System; -import name.mikanoshi.customiuizer.subs.Various; -import name.mikanoshi.customiuizer.utils.Helpers; -import name.mikanoshi.customiuizer.utils.ModData; -import name.mikanoshi.customiuizer.utils.ModSearchAdapter; - -public class MainFragment extends PreferenceFragmentBase { - - private final CategorySelector catSelector = new CategorySelector(); - public System prefSystem = new System(); - public Launcher prefLauncher = new Launcher(); - public Controls prefControls = new Controls(); - public Various prefVarious = new Various(); - private Menu mActionMenu; - private ListView listView = null; - private ListView resultView = null; - private LinearLayout search = null; - boolean isSearchFocused = false; - int inSearchView = 0; - String lastFilter; - - private final Runnable showUpdateNotification = new Runnable() { - @Override - public void run() { - if (getView() != null) try { - ImageView alert = getView().findViewById(R.id.update_alert); - if (alert != null) alert.setVisibility(View.VISIBLE); - } catch (Throwable e) {} - } - }; - - private final Runnable hideUpdateNotification = new Runnable() { - @Override - public void run() { - if (getView() != null) try { - ImageView alert = getView().findViewById(R.id.update_alert); - if (alert != null) alert.setVisibility(View.GONE); - } catch (Throwable e) {} - } - }; - - private boolean isFragmentReady(Activity act) { - return act != null && !act.isFinishing() && MainFragment.this.isAdded(); - } - @Override - public View onCreateView(LayoutInflater inflater, - ViewGroup container, - Bundle savedInstanceState) { - return LayoutInflater.from(getActivity()).inflate(R.layout.prefs_main12, container, false); - } - - @Override - @SuppressLint("MissingSuperCall") - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState, R.xml.prefs_main); - addPreferencesFromResource(R.xml.prefs_main); - - final Activity act = getActivity(); - - // Preventing launch delay - new Thread(new Runnable() { - public void run() { - if (isFragmentReady(act) && !Helpers.miuizerModuleActive) { - act.runOnUiThread(new Runnable() { - public void run() { - showXposedDialog(act); - } - }); - } - - Helpers.getAllMods(act, savedInstanceState != null); - } - }).start(); - - if (Helpers.prefs.getBoolean("pref_key_was_restore", false)) { - Helpers.prefs.edit().putBoolean("pref_key_was_restore", false).apply(); - showRestoreInfoDialog(); - } - } - - private static class SetLineOverlap implements LineHeightSpan { - private int originalBottom = 15; - private int originalDescent = 13; - private final Boolean overlap; - private Boolean overlapSaved = false; - - SetLineOverlap(Boolean overlap) { - this.overlap = overlap; - } - - @Override - public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) { - if (overlap) { - if (!overlapSaved) { - originalBottom = fm.bottom; - originalDescent = fm.descent; - overlapSaved = true; - } - fm.bottom += fm.top; - fm.descent += fm.top; - } else { - fm.bottom = originalBottom; - fm.descent = originalDescent; - overlapSaved = false; - } - } - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - mActionMenu = menu; - MenuItem searchMenuItem = mActionMenu.findItem(R.id.search_btn); - - SearchView searchView = (SearchView) searchMenuItem.getActionView(); - searchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { - @Override - public boolean onMenuItemActionCollapse(MenuItem searchItem) { - MenuItem item = null; - for (int i = 0; i < mActionMenu.size(); i++) { - item = mActionMenu.getItem(i); - item.setVisible(item.getItemId() != R.id.edit_confirm); - } - return true; - } - - @Override - public boolean onMenuItemActionExpand(MenuItem searchItem) { - MenuItem item = null; - for (int i = 0; i < mActionMenu.size(); i++) { - item = mActionMenu.getItem(i); - item.setVisible(item.getItemId() == R.id.search_btn); - } - return true; - } - }); - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - if (newText.length() > 0) { - inSearchView = 1; - } - findMod(newText); - return false; - } - }); - searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - isSearchFocused = hasFocus; - } - }); - if (inSearchView == 2) { - searchMenuItem.expandActionView(); - searchView.setQuery(lastFilter, false); - searchView.clearFocus(); - } - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - supressMenu = true; - super.onActivityCreated(savedInstanceState); - - if (getView() == null) return; - - resultView = getView().findViewById(android.R.id.custom); - resultView.setAdapter(new ModSearchAdapter(getActivity())); - resultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - inSearchView = 2; - ModData mod = (ModData)parent.getAdapter().getItem(position); - openModCat(mod.cat.name(), mod.sub, mod.key); - } - }); - resultView.setOnTouchListener(new View.OnTouchListener() { - @Override - @SuppressLint("ClickableViewAccessibility") - public boolean onTouch(View v, MotionEvent event) { - if (isSearchFocused) { - isSearchFocused = false; - Handler handler = new Handler(v.getContext().getMainLooper()); - handler.postDelayed(new Runnable() { - @Override - public void run() { - Helpers.hideKeyboard(getActivity(), getView()); - } - }, getResources().getInteger(android.R.integer.config_shortAnimTime)); - resultView.requestFocus(); - } - return false; - } - }); - setViewBackground(resultView); - - listView = getView().findViewById(android.R.id.list); - final Activity act = getActivity(); - - PreferenceEx warning = (PreferenceEx)findPreference("pref_key_warning"); - if (warning != null) { - getPreferenceScreen().removePreference(warning); - } - - findPreference("pref_key_miuizer_launchericon").setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - PackageManager pm = act.getPackageManager(); - if ((Boolean)newValue) - pm.setComponentEnabledSetting(new ComponentName(act, GateWayLauncher.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); - else - pm.setComponentEnabledSetting(new ComponentName(act, GateWayLauncher.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); - return true; - } - }); - - String[] locales = new String[] { "ru-RU", "zh-CN" }; - - ArrayList localesArr = new ArrayList(Arrays.asList(locales)); - ArrayList localeNames = new ArrayList(); - localesArr.add(0, "en"); - for (String locale: localesArr) try { - Locale loc = Locale.forLanguageTag(locale); - StringBuilder locStr = new StringBuilder(loc.getDisplayLanguage(loc)); - locStr.setCharAt(0, Character.toUpperCase(locStr.charAt(0))); - SpannableString locSpanString; - if (!locale.equals("en")) { - String locStrPct = locStr + "\n" + Helpers.l10nProgress.get(locale) + "%"; - int fullTextLength = locStrPct.length(); - locSpanString = new SpannableString(locStrPct); - locSpanString.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE), locStr.toString().length(), fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - locSpanString.setSpan(new SetLineOverlap(true), 1, fullTextLength - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - locSpanString.setSpan(new SetLineOverlap(false), fullTextLength - 1, fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } else locSpanString = new SpannableString(locStr.toString()); - localeNames.add(locSpanString); - } catch (Throwable t) { - localeNames.add(new SpannableString(Locale.getDefault().getDisplayLanguage(Locale.getDefault()))); - } - - localesArr.add(0, "auto"); - localeNames.add(0, new SpannableString(getString(R.string.array_system_default))); - - ListPreferenceEx locale = (ListPreferenceEx)findPreference("pref_key_miuizer_locale"); - locale.setEntries(localeNames.toArray(new CharSequence[0])); - locale.setEntryValues(localesArr.toArray(new CharSequence[0])); - locale.setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - getActivity().recreate(); - return true; - } - }); - - findPreference("pref_key_github").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - @SuppressWarnings("deprecation") - public boolean onPreferenceClick(Preference pref) { - Helpers.openURL(act, "https://github.com/MonwF/customiuizer"); - return true; - } - }); - } - - void findMod(String filter) { - if (inSearchView == 2) return; - lastFilter = filter; - resultView.setVisibility(filter.equals("") ? View.GONE : View.VISIBLE); - listView.setEnabled(filter.equals("")); - ListAdapter adapter = resultView.getAdapter(); - if (adapter == null) return; - ((ModSearchAdapter)resultView.getAdapter()).getFilter().filter(filter); - } - - // PreferenceScreens management - private boolean openModCat(String cat) { - return openModCat(cat, null, null); - } - - private boolean openModCat(String cat, String sub, String mod) { - Bundle bundle = new Bundle(); - bundle.putString("cat", cat); - bundle.putString("sub", sub); - bundle.putString("mod", mod); - catSelector.setTargetFragment(this, 0); - switch (cat) { - case "pref_key_system": - if (sub == null) - openSubFragment(catSelector, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system_cat); - else - openSubFragment(prefSystem, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system); - return false; - case "pref_key_launcher": - if (sub == null) - openSubFragment(catSelector, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_title, R.xml.prefs_launcher_cat); - else - openSubFragment(prefLauncher, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_title, R.xml.prefs_launcher); - return true; - case "pref_key_controls": - if (sub == null) - openSubFragment(catSelector, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls_cat); - else - openSubFragment(prefControls, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls); - return false; - case "pref_key_various": - openSubFragment(prefVarious, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.various_mods, R.xml.prefs_various); - return false; - default: - return false; - } - } - - @Override - public boolean onPreferenceTreeClick(PreferenceScreen parentPreferenceScreen, Preference preference) { - if (preference != null) { - PreferenceCategory modsCat = (PreferenceCategory)findPreference("prefs_cat"); - if (modsCat.findPreference(preference.getKey()) != null) - if (openModCat(preference.getKey())) return true; - } - return super.onPreferenceTreeClick(parentPreferenceScreen, preference); - } - - private void showRestoreInfoDialog() { - try { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.warning); - builder.setMessage(R.string.backup_restore_info); - builder.setCancelable(true); - builder.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){} - }); - AlertDialog dlg = builder.create(); - dlg.show(); - } catch (Throwable t) { - t.printStackTrace(); - } - } +package name.mikanoshi.customiuizer; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.graphics.Paint; +import android.os.Bundle; +import android.os.Handler; +import android.text.Layout; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.AlignmentSpan; +import android.text.style.LineHeightSpan; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ImageView; +import android.widget.ListAdapter; +import android.widget.ListView; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SearchView; +import androidx.core.view.MenuItemCompat; +import androidx.preference.CheckBoxPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Locale; + +import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; +import name.mikanoshi.customiuizer.prefs.PreferenceEx; +import name.mikanoshi.customiuizer.subs.CategorySelector; +import name.mikanoshi.customiuizer.subs.Controls; +import name.mikanoshi.customiuizer.subs.Launcher; +import name.mikanoshi.customiuizer.subs.System; +import name.mikanoshi.customiuizer.subs.Various; +import name.mikanoshi.customiuizer.utils.Helpers; +import name.mikanoshi.customiuizer.utils.ModData; +import name.mikanoshi.customiuizer.utils.ModSearchAdapter; + +public class MainFragment extends PreferenceFragmentBase { + + private final CategorySelector catSelector = new CategorySelector(); + public System prefSystem = new System(); + public Launcher prefLauncher = new Launcher(); + public Controls prefControls = new Controls(); + public Various prefVarious = new Various(); + private Menu mActionMenu; + private RecyclerView listView = null; + private ListView resultView = null; + boolean isSearchFocused = false; + int inSearchView = 0; + String lastFilter; + + private final Runnable showUpdateNotification = new Runnable() { + @Override + public void run() { + if (getView() != null) try { + ImageView alert = getView().findViewById(R.id.update_alert); + if (alert != null) alert.setVisibility(View.VISIBLE); + } catch (Throwable e) {} + } + }; + + private final Runnable hideUpdateNotification = new Runnable() { + @Override + public void run() { + if (getView() != null) try { + ImageView alert = getView().findViewById(R.id.update_alert); + if (alert != null) alert.setVisibility(View.GONE); + } catch (Throwable e) {} + } + }; + + private boolean isFragmentReady(AppCompatActivity act) { + return act != null && !act.isFinishing() && MainFragment.this.isAdded(); + } + + @Override + @SuppressLint("MissingSuperCall") + public void onCreate(Bundle savedInstanceState) { + supressMenu = true; + super.onCreate(savedInstanceState, R.xml.prefs_main); + tailLayoutId = R.layout.prefs_main12; + final AppCompatActivity act = (AppCompatActivity) getActivity(); + + // Preventing launch delay + new Thread(new Runnable() { + public void run() { + if (isFragmentReady(act) && !Helpers.miuizerModuleActive) { + act.runOnUiThread(new Runnable() { + public void run() { + showXposedDialog(act); + } + }); + } + + Helpers.getAllMods(act, savedInstanceState != null); + } + }).start(); + + if (Helpers.prefs.getBoolean("pref_key_was_restore", false)) { + Helpers.prefs.edit().putBoolean("pref_key_was_restore", false).apply(); + showRestoreInfoDialog(); + } + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + setPreferencesFromResource(R.xml.prefs_main, rootKey); + } + + private static class SetLineOverlap implements LineHeightSpan { + private int originalBottom = 15; + private int originalDescent = 13; + private final Boolean overlap; + private Boolean overlapSaved = false; + + SetLineOverlap(Boolean overlap) { + this.overlap = overlap; + } + + @Override + public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) { + if (overlap) { + if (!overlapSaved) { + originalBottom = fm.bottom; + originalDescent = fm.descent; + overlapSaved = true; + } + fm.bottom += fm.top; + fm.descent += fm.top; + } else { + fm.bottom = originalBottom; + fm.descent = originalDescent; + overlapSaved = false; + } + } + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + mActionMenu = menu; + MenuItem searchMenuItem = mActionMenu.findItem(R.id.search_btn); + + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem); + MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() { + @Override + public boolean onMenuItemActionCollapse(MenuItem searchItem) { + MenuItem item = null; + for (int i = 0; i < mActionMenu.size(); i++) { + item = mActionMenu.getItem(i); + item.setVisible(item.getItemId() != R.id.edit_confirm); + } + return true; + } + + @Override + public boolean onMenuItemActionExpand(MenuItem searchItem) { + MenuItem item = null; + for (int i = 0; i < mActionMenu.size(); i++) { + item = mActionMenu.getItem(i); + item.setVisible(item.getItemId() == R.id.search_btn); + } + return true; + } + }); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + if (newText.length() > 0) { + inSearchView = 1; + } + findMod(newText); + return false; + } + }); + searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + isSearchFocused = hasFocus; + } + }); + if (inSearchView == 2) { + MenuItemCompat.expandActionView(searchMenuItem); + searchView.setQuery(lastFilter, false); + searchView.clearFocus(); + } + } + + @Override + protected void fixStubLayout(View view, int postion) { + if (postion == 2) { + ViewGroup.LayoutParams lp = view.getLayoutParams(); + lp.height = ViewGroup.LayoutParams.MATCH_PARENT; + view.setLayoutParams(lp); + } + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + ActionBar actionBar = getActionBar(); + actionBar.setTitle(R.string.app_name); + + if (getView() == null) return; + + resultView = getView().findViewById(R.id.custom); + resultView.setDivider(null); + resultView.setDividerHeight(0); + resultView.setAdapter(new ModSearchAdapter(getActivity())); + resultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + inSearchView = 2; + ModData mod = (ModData)parent.getAdapter().getItem(position); + openModCat(mod.cat.name(), mod.sub, mod.key); + } + }); + resultView.setOnTouchListener(new View.OnTouchListener() { + @Override + @SuppressLint("ClickableViewAccessibility") + public boolean onTouch(View v, MotionEvent event) { + if (isSearchFocused) { + isSearchFocused = false; + Handler handler = new Handler(v.getContext().getMainLooper()); + handler.postDelayed(new Runnable() { + @Override + public void run() { + Helpers.hideKeyboard((AppCompatActivity) getActivity(), getView()); + } + }, getResources().getInteger(android.R.integer.config_shortAnimTime)); + resultView.requestFocus(); + } + return false; + } + }); + setViewBackground(resultView); + + listView = getListView(); + final Activity act = getActivity(); + + PreferenceEx warning = findPreference("pref_key_warning"); + if (warning != null) { + getPreferenceScreen().removePreference(warning); + } + + findPreference("pref_key_miuizer_launchericon").setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + PackageManager pm = act.getPackageManager(); + if ((Boolean)newValue) + pm.setComponentEnabledSetting(new ComponentName(act, GateWayLauncher.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); + else + pm.setComponentEnabledSetting(new ComponentName(act, GateWayLauncher.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); + return true; + } + }); + + String[] locales = new String[] { "ru-RU", "zh-CN" }; + + ArrayList localesArr = new ArrayList(Arrays.asList(locales)); + ArrayList localeNames = new ArrayList(); + localesArr.add(0, "en"); + for (String locale: localesArr) try { + Locale loc = Locale.forLanguageTag(locale); + StringBuilder locStr = new StringBuilder(loc.getDisplayLanguage(loc)); + locStr.setCharAt(0, Character.toUpperCase(locStr.charAt(0))); + SpannableString locSpanString; + if (!locale.equals("en")) { + String locStrPct = locStr + "\n" + Helpers.l10nProgress.get(locale) + "%"; + int fullTextLength = locStrPct.length(); + locSpanString = new SpannableString(locStrPct); + locSpanString.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE), locStr.toString().length(), fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + locSpanString.setSpan(new SetLineOverlap(true), 1, fullTextLength - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + locSpanString.setSpan(new SetLineOverlap(false), fullTextLength - 1, fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } else locSpanString = new SpannableString(locStr.toString()); + localeNames.add(locSpanString); + } catch (Throwable t) { + localeNames.add(new SpannableString(Locale.getDefault().getDisplayLanguage(Locale.getDefault()))); + } + + localesArr.add(0, "auto"); + localeNames.add(0, new SpannableString(getString(R.string.array_system_default))); + + ListPreferenceEx locale = findPreference("pref_key_miuizer_locale"); + locale.setEntries(localeNames.toArray(new CharSequence[0])); + locale.setEntryValues(localesArr.toArray(new CharSequence[0])); + locale.setOnPreferenceChangeListener(new CheckBoxPreference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + getActivity().recreate(); + return true; + } + }); + + findPreference("pref_key_github").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + @SuppressWarnings("deprecation") + public boolean onPreferenceClick(Preference pref) { + Helpers.openURL(act, "https://github.com/MonwF/customiuizer"); + return true; + } + }); + } + + void findMod(String filter) { + if (inSearchView == 2) return; + lastFilter = filter; + resultView.setVisibility(filter.equals("") ? View.GONE : View.VISIBLE); + listView.setEnabled(filter.equals("")); + ListAdapter adapter = resultView.getAdapter(); + if (adapter == null) return; + ((ModSearchAdapter)resultView.getAdapter()).getFilter().filter(filter); + } + + // PreferenceScreens management + private boolean openModCat(String cat) { + return openModCat(cat, null, null); + } + + private boolean openModCat(String cat, String sub, String mod) { + Bundle bundle = new Bundle(); + bundle.putString("cat", cat); + bundle.putString("sub", sub); + bundle.putString("mod", mod); + catSelector.setTargetFragment(this, 0); + switch (cat) { + case "pref_key_system": + if (sub == null) + openSubFragment(catSelector, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system_cat); + else + openSubFragment(prefSystem, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system); + return false; + case "pref_key_launcher": + if (sub == null) + openSubFragment(catSelector, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_title, R.xml.prefs_launcher_cat); + else + openSubFragment(prefLauncher, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_title, R.xml.prefs_launcher); + return true; + case "pref_key_controls": + if (sub == null) + openSubFragment(catSelector, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls_cat); + else + openSubFragment(prefControls, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls); + return false; + case "pref_key_various": + openSubFragment(prefVarious, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.various_mods, R.xml.prefs_various); + return false; + default: + return false; + } + } + + @Override + public boolean onPreferenceTreeClick(Preference preference) { + if (preference != null) { + PreferenceCategory modsCat = findPreference("prefs_cat"); + if (modsCat.findPreference(preference.getKey()) != null && openModCat(preference.getKey())) { + return true; + } + } + return super.onPreferenceTreeClick(preference); + } + + private void showRestoreInfoDialog() { + try { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.warning); + builder.setMessage(R.string.backup_restore_info); + builder.setCancelable(true); + builder.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){} + }); + AlertDialog dlg = builder.create(); + dlg.show(); + } catch (Throwable t) { + t.printStackTrace(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java index d78581dd..e3a9980c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java @@ -4,8 +4,6 @@ import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.Activity; -import android.app.AlertDialog; -import android.app.Fragment; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -13,28 +11,23 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.LayerDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.util.TypedValue; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; +import android.view.ViewStub; import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import androidx.appcompat.app.AppCompatActivity; +import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; import java.io.FileOutputStream; import java.io.ObjectInputStream; @@ -46,7 +39,7 @@ import name.mikanoshi.customiuizer.mods.GlobalActions; import name.mikanoshi.customiuizer.utils.Helpers; -public class PreferenceFragmentBase extends PreferenceFragment { +public class PreferenceFragmentBase extends PreferenceFragmentCompat { private Context actContext = null; public boolean isAnimating = false; @@ -55,6 +48,8 @@ public class PreferenceFragmentBase extends PreferenceFragment { public static final int PICK_BACKFILE = 11; public boolean isCustomActionBar = false; + protected int headLayoutId = 0; + protected int tailLayoutId = 0; protected ActionBar getActionBar() { AppCompatActivity act = (AppCompatActivity) getActivity(); @@ -66,7 +61,7 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_mods, menu); } if (isCustomActionBar) { - MenuItem item = null; + MenuItem item; for (int i = 0; i < menu.size(); i++) { item = menu.getItem(i); item.setVisible(item.getItemId() == R.id.edit_confirm); @@ -81,9 +76,15 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void confirmEdit() {} + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + getPreferenceManager().setSharedPreferencesName(Helpers.prefsName); + getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); + getPreferenceManager().setStorageDeviceProtected(); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { - Activity act = getActivity(); switch (item.getItemId()) { case R.id.edit_confirm: confirmEdit(); @@ -99,33 +100,31 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.softreboot: if (!Helpers.miuizerModuleActive) { - showXposedDialog(getActivity()); + showXposedDialog((AppCompatActivity) getActivity()); return true; } AlertDialog.Builder alert = new AlertDialog.Builder(getValidContext()); alert.setTitle(R.string.soft_reboot); alert.setMessage(R.string.soft_reboot_ask); - alert.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "FastReboot")); } }); - alert.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) {} }); alert.show(); return true; case R.id.about: - Bundle args = new Bundle(); - args.putInt("baseResId", R.layout.fragment_about); - openSubFragment(new AboutFragment(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.app_about, R.xml.prefs_about); + openSubFragment(new AboutFragment(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.app_about, R.xml.prefs_about); return true; } return false; } - public void showXposedDialog(Activity act) { + public void showXposedDialog(AppCompatActivity act) { try { AlertDialog.Builder builder = new AlertDialog.Builder(act); builder.setTitle(R.string.warning); @@ -142,7 +141,7 @@ public void onClick(DialogInterface dialog, int whichButton){} } public void showBackupRestoreDialog() { - final Activity act = getActivity(); + final AppCompatActivity act = (AppCompatActivity) getActivity(); AlertDialog.Builder alert = new AlertDialog.Builder(act); alert.setTitle(R.string.backup_restore); @@ -163,13 +162,12 @@ public void onClick(DialogInterface dialog, int whichButton) { private void initFragment() { setHasOptionsMenu(supressMenu); ActionBar actionBar = getActionBar(); - actionBar.setTitle(R.string.app_name); boolean showBack = false; if (this instanceof MainFragment) { ActivityInfo appInfo; try { - Activity act = getActivity(); + AppCompatActivity act = (AppCompatActivity) getActivity(); appInfo = act.getPackageManager().getActivityInfo(act.getComponentName(), PackageManager.GET_META_DATA); showBack = appInfo.metaData != null && appInfo.metaData.containsKey("from.settings"); } catch (PackageManager.NameNotFoundException e) { @@ -184,73 +182,48 @@ private void initFragment() { public void onCreate(Bundle savedInstanceState, int pref_defaults) { super.onCreate(savedInstanceState); try { - getPreferenceManager().setSharedPreferencesName(Helpers.prefsName); - getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE); - getPreferenceManager().setStorageDeviceProtected(); PreferenceManager.setDefaultValues(Helpers.getProtectedContext(getValidContext()), pref_defaults, false); } catch (Throwable throwable) { throwable.printStackTrace(); } } - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - initFragment(); + protected void fixStubLayout(View view, int postion) { + } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); + if (headLayoutId > 0) { + ViewStub vs = view.findViewById(R.id.head_stub); + vs.setLayoutResource(headLayoutId); + View renderView = vs.inflate(); + fixStubLayout(renderView, 1); + } + if (tailLayoutId > 0) { + ViewStub vs = view.findViewById(R.id.tail_stub); + vs.setLayoutResource(tailLayoutId); + View renderView = vs.inflate(); + fixStubLayout(renderView, 2); + } setViewBackground(view); + initFragment(); } public void setViewBackground(View view) { view.setBackgroundColor(Helpers.getSystemBackgroundColor(getValidContext())); } - public void setActionModeStyle(View searchView) { - boolean isNight = Helpers.isNightMode(getValidContext()); - if (searchView != null) try { - searchView.setSaveFromParentEnabled(false); - Drawable drawable = getResources().getDrawable(getResources().getIdentifier(isNight ? "search_mode_bg_dark" : "search_mode_bg_light", "drawable", "miui"), getValidContext().getTheme()); - try { - int colorResId = getResources().getIdentifier(isNight ? "primary_color_dark" : "primary_color_light", "color", "miui"); - if (colorResId != 0 && drawable instanceof LayerDrawable) { - drawable = ((LayerDrawable)drawable).getDrawable(0); - if (drawable instanceof GradientDrawable) - ((GradientDrawable)drawable).setColor(getResources().getColor(colorResId, getValidContext().getTheme())); - } - } catch (Throwable ignore) {} - searchView.setBackground(drawable); - LinearLayout inputArea = searchView.findViewById(android.R.id.inputArea); - inputArea.setBackgroundResource(getResources().getIdentifier(isNight ? "search_mode_edit_text_bg_dark" : "search_mode_edit_text_bg_light", "drawable", "miui")); - if (Helpers.is11()) { - ViewGroup.LayoutParams lp1 = searchView.getLayoutParams(); - int resId = getResources().getIdentifier("action_bar_default_height", "dimen", "miui"); - lp1.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.secondary_text_size : resId); - searchView.setLayoutParams(lp1); - FrameLayout.LayoutParams lp2 = (FrameLayout.LayoutParams)inputArea.getLayoutParams(); - resId = getResources().getIdentifier("searchbar_bg_height", "dimen", "miui"); - lp2.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.searchbar_bg_height : resId); - inputArea.setLayoutParams(lp2); - } - ImageView inputIcon = searchView.findViewById(R.id.inputIcon); - inputIcon.setImageResource(getResources().getIdentifier(isNight ? "edit_text_search_dark" : "edit_text_search", "drawable", "miui")); - TextView input = searchView.findViewById(android.R.id.input); - int fontSize = getResources().getIdentifier(Helpers.is11() ? "edit_text_font_size" : "secondary_text_size", "dimen", "miui"); - input.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(fontSize == 0 ? R.dimen.secondary_text_size : fontSize)); - input.setHintTextColor(getResources().getColor(getResources().getIdentifier(isNight ? "edit_text_search_hint_color_dark" : "edit_text_search_hint_color_light", "color", "miui"), getValidContext().getTheme())); - } catch (Throwable t) { - t.printStackTrace(); - } + public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType settingsType, Helpers.ActionBarType abType, int titleResId, int contentResId) { + openSubFragment(fragment, args, settingsType, abType, getResources().getString(titleResId), contentResId); } - public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType settingsType, Helpers.ActionBarType abType, int titleResId, int contentResId) { + public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType settingsType, Helpers.ActionBarType abType, String title, int contentResId) { if (args == null) args = new Bundle(); args.putInt("settingsType", settingsType.ordinal()); args.putInt("abType", abType.ordinal()); - args.putInt("titleResId", titleResId); + args.putString("titleResId", title); args.putInt("contentResId", contentResId); float order = 100.0f; try { @@ -263,9 +236,10 @@ public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType fragment.getArguments().clear(); fragment.getArguments().putAll(args); } - getFragmentManager().beginTransaction().setCustomAnimations(R.animator.fragment_open_enter, R.animator.fragment_open_exit, R.animator.fragment_close_enter, R.animator.fragment_close_exit) + getParentFragmentManager().beginTransaction() + .setCustomAnimations(R.animator.fragment_open_enter, R.animator.fragment_open_exit, R.animator.fragment_close_enter, R.animator.fragment_close_exit) .replace(R.id.fragment_container, fragment).addToBackStack(null).commitAllowingStateLoss(); - getFragmentManager().executePendingTransactions(); + getParentFragmentManager().executePendingTransactions(); } @Override @@ -277,8 +251,7 @@ public Animator onCreateAnimator(int transit, boolean enter, final int nextAnim) final View top = getView(); if (top == null) return null; - final View content = top.findViewById(android.R.id.list); - + final View content = getListView(); //ValueAnimator.setFrameDelay(17); ValueAnimator valAnimator = new ValueAnimator(); valAnimator.setDuration(animDur); @@ -342,18 +315,12 @@ public void onDetach() { this.actContext = null; } -// @Override -// public void onResume() { -// super.onResume(); -// setupImmersiveMenu(); -// } - public Context getValidContext() { if (actContext != null) return actContext; return getActivity() == null ? getContext() : getActivity().getApplicationContext(); } - public void backupSettings(Activity act) { + public void backupSettings(AppCompatActivity act) { String backupPath = Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder; if (!Helpers.preparePathForBackup(act, backupPath)) return; ObjectOutputStream output = null; @@ -394,7 +361,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent resultData) { if (requestCode == MainFragment.PICK_BACKFILE && resultCode == Activity.RESULT_OK) { - Uri uri = null; + Uri uri; if (resultData != null) { uri = resultData.getData(); doRestoreSettings(uri); @@ -402,7 +369,7 @@ public void onActivityResult(int requestCode, int resultCode, } } - public void restoreSettings(final Activity act) { + public void restoreSettings(final AppCompatActivity act) { if (!Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_RESTORE)) return; if (!Helpers.checkStorageReadable(act)) return; Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); @@ -413,7 +380,7 @@ public void restoreSettings(final Activity act) { public void doRestoreSettings(Uri uri) { ObjectInputStream input = null; - final Activity act = getActivity(); + final AppCompatActivity act = (AppCompatActivity) getActivity(); try { input = new ObjectInputStream(act.getContentResolver().openInputStream(uri)); Map entries = (Map)input.readObject(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java index 1f9706fa..2ec8cfdc 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedActivity.java @@ -1,13 +1,14 @@ package name.mikanoshi.customiuizer; -import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; + import name.mikanoshi.customiuizer.utils.Helpers; -public class SnoozedActivity extends Activity { +public class SnoozedActivity extends AppCompatActivity { @Override protected void attachBaseContext(Context base) { @@ -30,7 +31,7 @@ protected void onCreate(Bundle savedInstanceState) { return; } - getFragmentManager().beginTransaction().replace(R.id.fragment_container, new SnoozedFragment()).commit(); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SnoozedFragment()).commit(); } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java index c1fe6a26..ec82043d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java @@ -9,7 +9,6 @@ import android.os.Handler; import android.view.LayoutInflater; import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; @@ -17,13 +16,12 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; + import java.util.ArrayList; import java.util.HashMap; -import android.app.AlertDialog; -import miui.util.AttributeResolver; import miui.widget.ProgressBar; - import name.mikanoshi.customiuizer.mods.GlobalActions; import name.mikanoshi.customiuizer.utils.SnoozeData; import name.mikanoshi.customiuizer.utils.SnoozedAdapter; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java index 040d74c7..0536c62d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java @@ -1,390 +1,402 @@ -package name.mikanoshi.customiuizer; - -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.os.Bundle; -import android.preference.Preference; -import android.preference.PreferenceScreen; -import android.provider.Settings; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.FrameLayout; -import android.widget.ListView; -import android.widget.TextView; - -import androidx.appcompat.app.ActionBar; - -import java.util.ArrayList; - -import miui.widget.ClearableEditText; -import name.mikanoshi.customiuizer.prefs.PreferenceCategoryEx; -import name.mikanoshi.customiuizer.prefs.SpinnerEx; -import name.mikanoshi.customiuizer.prefs.SpinnerExFake; -import name.mikanoshi.customiuizer.subs.AppSelector; -import name.mikanoshi.customiuizer.subs.ColorSelector; -import name.mikanoshi.customiuizer.subs.MultiAction; -import name.mikanoshi.customiuizer.subs.SortableList; -import name.mikanoshi.customiuizer.utils.ColorCircle; -import name.mikanoshi.customiuizer.utils.Helpers; - -public class SubFragment extends PreferenceFragmentBase { - - private int baseResId = 0; - private int resId = 0; - public int titleId = 0; - private float order = 100.0f; - public boolean padded = true; - Helpers.SettingsType settingsType = Helpers.SettingsType.Preference; - Helpers.ActionBarType abType = Helpers.ActionBarType.Edit; - - @Override - public void onCreate(Bundle savedInstanceState) { - settingsType = Helpers.SettingsType.values()[getArguments().getInt("settingsType")]; - abType = Helpers.ActionBarType.values()[getArguments().getInt("abType")]; - baseResId = getArguments().getInt("baseResId"); - resId = getArguments().getInt("contentResId"); - titleId = getArguments().getInt("titleResId"); - order = getArguments().getFloat("order") + 10.0f; - - if (resId == 0) { - getActivity().finish(); - return; - } - - if (settingsType == Helpers.SettingsType.Preference) { - super.onCreate(savedInstanceState, resId); - addPreferencesFromResource(resId); - } else { - super.onCreate(savedInstanceState); - } - if (abType == Helpers.ActionBarType.Edit) { - isCustomActionBar = true; - } - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - supressMenu = supressMenu || abType == Helpers.ActionBarType.Edit; - super.onActivityCreated(savedInstanceState); - loadSharedPrefs(); - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setTitle(titleId); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, - ViewGroup container, - Bundle savedInstanceState) { - LayoutInflater crtInflator = LayoutInflater.from(getActivity()); - if (settingsType == Helpers.SettingsType.Preference) { - if (baseResId != 0) { - return LayoutInflater.from(getActivity()).inflate(baseResId, container, false); - } - else { - return super.onCreateView(crtInflator, container, savedInstanceState); - } - } - View view = crtInflator.inflate(padded ? R.layout.prefs_common_padded : R.layout.prefs_common, container, false); - crtInflator.inflate(resId, (FrameLayout)view); - return view; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - view.setTranslationZ(order); - } - - public void saveSharedPrefs() { - if (getView() == null) Log.e("miuizer", "View not yet ready!"); - ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); - for (View nView : nViews) - if (nView != null) try { - if (nView.getTag() != null) - if (nView instanceof TextView) - Helpers.prefs.edit().putString((String)nView.getTag(), ((TextView)nView).getText().toString()).apply(); - else if (nView instanceof SpinnerExFake) { - Helpers.prefs.edit().putString((String)nView.getTag(), ((SpinnerExFake)nView).getValue()).apply(); - ((SpinnerExFake)nView).applyOthers(); - } else if (nView instanceof SpinnerEx) - Helpers.prefs.edit().putInt((String)nView.getTag(), ((SpinnerEx)nView).getSelectedArrayValue()).apply(); - else if (nView instanceof ColorCircle) - Helpers.prefs.edit().putInt((String)nView.getTag(), ((ColorCircle)nView).getColor()).apply(); - } catch (Throwable e) { - Log.e("miuizer", "Cannot save sub preference!"); - } - } - - public void loadSharedPrefs() { - if (getView() == null) Log.e("miuizer", "View not yet ready!"); - ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); - for (View nView: nViews) - if (nView != null) try { - if (nView.getTag() != null) - if (nView instanceof TextView) { - ((TextView)nView).setText(Helpers.prefs.getString((String)nView.getTag(), "")); - if (nView instanceof ClearableEditText) nView.setBackgroundResource(getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "edit_text_bg_dark" : "edit_text_bg_light", "drawable", "miui")); - } - } catch (Throwable e) { - Log.e("miuizer", "Cannot load sub preference!"); - } - } - - public Preference.OnPreferenceClickListener openAppsEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openApps(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openAppsBWEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openAppsBW(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openShareEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openShare(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openOpenWithEdit = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openOpenWith(preference.getKey()); - return true; - } - }; - - public Preference.OnPreferenceClickListener openLauncherActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.LAUNCHER); - return true; - } - }; - - public Preference.OnPreferenceClickListener openControlsActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.CONTROLS); - return true; - } - }; - - public Preference.OnPreferenceClickListener openNavbarActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.NAVBAR); - return true; - } - }; - - public Preference.OnPreferenceClickListener openRecentsActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.RECENTS); - return true; - } - }; - - public Preference.OnPreferenceClickListener openStatusbarActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.STATUSBAR); - return true; - } - }; - - public Preference.OnPreferenceClickListener openLockScreenActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.LOCKSCREEN); - return true; - } - }; - - public Preference.OnPreferenceClickListener openLaunchActions = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openMultiAction(preference, MultiAction.Actions.LAUNCH); - return true; - } - }; - - public Preference.OnPreferenceClickListener openSortableList = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openSortableItemList(preference); - return true; - } - }; - - public Preference.OnPreferenceClickListener openActivitiesList = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openActivitiesItemList(preference); - return true; - } - }; - - public Preference.OnPreferenceClickListener openColorSelector = new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openColorSelector(preference); - return true; - } - }; - - void openApps(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openAppsBW(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - args.putBoolean("bw", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openShare(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - args.putBoolean("share", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openOpenWith(String key) { - Bundle args = new Bundle(); - args.putString("key", key); - args.putBoolean("multi", true); - args.putBoolean("openwith", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(this, 0); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - void openMultiAction(Preference pref, MultiAction.Actions actions) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putInt("actions", actions.ordinal()); - openSubFragment(new MultiAction(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitleRes(), R.layout.prefs_multiaction); - } - - public void openStandaloneApp(Preference pref, Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putBoolean("standalone", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_app, R.layout.prefs_app_selector); - } - - public void openPrivacyAppEdit(Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putBoolean("privacy", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - public void openLockedAppEdit(Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putBoolean("applock", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); - } - - public void openLaunchableList(Preference pref, Fragment targetFrag, int resultId) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putBoolean("custom_titles", true); - AppSelector appSelector = new AppSelector(); - appSelector.setTargetFragment(targetFrag, resultId); - openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.launcher_renameapps_list_title, R.layout.prefs_app_selector); - } - - public void openColorSelector(Preference pref) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - openSubFragment(new ColorSelector(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitleRes(), R.layout.fragment_selectcolor); - } - - public void openSortableItemList(Preference pref) { - Bundle args = new Bundle(); - args.putString("key", pref.getKey()); - args.putInt("titleResId", pref.getTitleRes()); - openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitleRes(), R.layout.prefs_sortable_list); - } - - public void openActivitiesItemList(Preference pref) { - Bundle args = new Bundle(); - args.putBoolean("activities", true); - args.putString("key", pref.getKey()); - args.putInt("titleResId", pref.getTitleRes()); - openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitleRes(), R.layout.prefs_sortable_list); - } - - public void selectSub(String cat, String sub) { - PreferenceScreen screen = (PreferenceScreen)findPreference(cat); - int cnt = screen.getPreferenceCount(); - for (int i = cnt - 1; i >= 0; i--) { - Preference pref = screen.getPreference(i); - if (!pref.getKey().equals(sub)) - screen.removePreference(pref); - else { - PreferenceCategoryEx category = (PreferenceCategoryEx)pref; - if (category.isDynamic()) - getActionBar().setTitle(pref.getTitle() + " ⟲"); - else - getActionBar().setTitle(pref.getTitleRes()); - category.hide(); - } - } - } - - public void finish() { - //View view = getView(); - //if (isAnimating && view != null) ((ViewGroup)view.getParent()).removeView(view); - if (isAnimating) return; - if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); - Helpers.hideKeyboard(getActivity(), getView()); - FragmentManager fragmentManager = getFragmentManager(); - if (fragmentManager == null || !isResumed()) { - Activity act = getActivity(); - if (act != null) act.getFragmentManager().popBackStack(); - } else { - fragmentManager.popBackStackImmediate(); - } - } - - @Override - public void confirmEdit() { - saveSharedPrefs(); - finish(); - } +package name.mikanoshi.customiuizer; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import java.util.ArrayList; + +import miui.widget.ClearableEditText; +import name.mikanoshi.customiuizer.prefs.PreferenceCategoryEx; +import name.mikanoshi.customiuizer.prefs.SpinnerEx; +import name.mikanoshi.customiuizer.prefs.SpinnerExFake; +import name.mikanoshi.customiuizer.subs.AppSelector; +import name.mikanoshi.customiuizer.subs.ColorSelector; +import name.mikanoshi.customiuizer.subs.MultiAction; +import name.mikanoshi.customiuizer.subs.SortableList; +import name.mikanoshi.customiuizer.utils.ColorCircle; +import name.mikanoshi.customiuizer.utils.Helpers; + +public class SubFragment extends PreferenceFragmentBase { + private int contentResId = 0; + public String titleId = ""; + protected String sub; + private float order = 100.0f; + public boolean padded = true; + Helpers.SettingsType settingsType = Helpers.SettingsType.Preference; + Helpers.ActionBarType abType = Helpers.ActionBarType.Edit; + + @Override + public void onCreate(Bundle savedInstanceState) { + settingsType = Helpers.SettingsType.values()[getArguments().getInt("settingsType")]; + abType = Helpers.ActionBarType.values()[getArguments().getInt("abType")]; + contentResId = getArguments().getInt("contentResId"); + titleId = getArguments().getString("titleResId"); + order = getArguments().getFloat("order") + 10.0f; + sub = getArguments().getString("sub"); + + if (contentResId == 0) { + getActivity().finish(); + return; + } + + if (settingsType == Helpers.SettingsType.Preference) { + super.onCreate(savedInstanceState, contentResId); + } else { + super.onCreate(savedInstanceState); + } + if (abType == Helpers.ActionBarType.Edit) { + isCustomActionBar = true; + } + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + supressMenu = supressMenu || abType == Helpers.ActionBarType.Edit; + super.onActivityCreated(savedInstanceState); + loadSharedPrefs(); + ActionBar actionBar = getActionBar(); + if (actionBar != null) { + Bundle args = getArguments(); + String sub = args.getString("sub"); + if (sub != null) { + PreferenceScreen screen = getPreferenceScreen(); + PreferenceCategoryEx category = (PreferenceCategoryEx)screen.getPreference(0); + if (category.isDynamic()) + getActionBar().setTitle(category.getTitle() + " ⟲"); + else + getActionBar().setTitle(category.getTitle()); + } + else { + actionBar.setTitle(titleId); + } + } + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + if (settingsType == Helpers.SettingsType.Preference) { + super.onCreatePreferences(savedInstanceState, rootKey); + setPreferencesFromResource(contentResId, rootKey); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + LayoutInflater crtInflator = inflater.cloneInContext(requireContext()); + if (settingsType == Helpers.SettingsType.Preference) { + return super.onCreateView(crtInflator, container, savedInstanceState); + } + View view = crtInflator.inflate(padded ? R.layout.prefs_common_padded : R.layout.prefs_common, container, false); + crtInflator.inflate(contentResId, (FrameLayout)view); + return view; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + view.setTranslationZ(order); + } + + public void saveSharedPrefs() { + if (getView() == null) Log.e("miuizer", "View not yet ready!"); + ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); + for (View nView : nViews) + if (nView != null) try { + if (nView.getTag() != null) + if (nView instanceof TextView) + Helpers.prefs.edit().putString((String)nView.getTag(), ((TextView)nView).getText().toString()).apply(); + else if (nView instanceof SpinnerExFake) { + Helpers.prefs.edit().putString((String)nView.getTag(), ((SpinnerExFake)nView).getValue()).apply(); + ((SpinnerExFake)nView).applyOthers(); + } else if (nView instanceof SpinnerEx) + Helpers.prefs.edit().putInt((String)nView.getTag(), ((SpinnerEx)nView).getSelectedArrayValue()).apply(); + else if (nView instanceof ColorCircle) + Helpers.prefs.edit().putInt((String)nView.getTag(), ((ColorCircle)nView).getColor()).apply(); + } catch (Throwable e) { + Log.e("miuizer", "Cannot save sub preference!"); + } + } + + public void loadSharedPrefs() { + if (getView() == null) Log.e("miuizer", "View not yet ready!"); + ArrayList nViews = Helpers.getChildViewsRecursive(getView().findViewById(R.id.container), false); + for (View nView: nViews) + if (nView != null) try { + if (nView.getTag() != null) + if (nView instanceof TextView) { + ((TextView)nView).setText(Helpers.prefs.getString((String)nView.getTag(), "")); + if (nView instanceof ClearableEditText) nView.setBackgroundResource(getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "edit_text_bg_dark" : "edit_text_bg_light", "drawable", "miui")); + } + } catch (Throwable e) { + Log.e("miuizer", "Cannot load sub preference!"); + } + } + + public Preference.OnPreferenceClickListener openAppsEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openApps(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openAppsBWEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openAppsBW(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openShareEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openShare(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openOpenWithEdit = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openOpenWith(preference.getKey()); + return true; + } + }; + + public Preference.OnPreferenceClickListener openLauncherActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.LAUNCHER); + return true; + } + }; + + public Preference.OnPreferenceClickListener openControlsActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.CONTROLS); + return true; + } + }; + + public Preference.OnPreferenceClickListener openNavbarActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.NAVBAR); + return true; + } + }; + + public Preference.OnPreferenceClickListener openRecentsActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.RECENTS); + return true; + } + }; + + public Preference.OnPreferenceClickListener openStatusbarActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.STATUSBAR); + return true; + } + }; + + public Preference.OnPreferenceClickListener openLockScreenActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.LOCKSCREEN); + return true; + } + }; + + public Preference.OnPreferenceClickListener openLaunchActions = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openMultiAction(preference, MultiAction.Actions.LAUNCH); + return true; + } + }; + + public Preference.OnPreferenceClickListener openSortableList = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openSortableItemList(preference); + return true; + } + }; + + public Preference.OnPreferenceClickListener openActivitiesList = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openActivitiesItemList(preference); + return true; + } + }; + + public Preference.OnPreferenceClickListener openColorSelector = new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openColorSelector(preference); + return true; + } + }; + + void openApps(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openAppsBW(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + args.putBoolean("bw", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openShare(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + args.putBoolean("share", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openOpenWith(String key) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putBoolean("multi", true); + args.putBoolean("openwith", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(this, 0); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + void openMultiAction(Preference pref, MultiAction.Actions actions) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putInt("actions", actions.ordinal()); + openSubFragment(new MultiAction(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitle().toString(), R.layout.prefs_multiaction); + } + + public void openStandaloneApp(Preference pref, Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putBoolean("standalone", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_app, R.layout.prefs_app_selector); + } + + public void openPrivacyAppEdit(Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putBoolean("privacy", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + public void openLockedAppEdit(Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putBoolean("applock", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_apps, R.layout.prefs_app_selector); + } + + public void openLaunchableList(Preference pref, Fragment targetFrag, int resultId) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putBoolean("custom_titles", true); + AppSelector appSelector = new AppSelector(); + appSelector.setTargetFragment(targetFrag, resultId); + openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.launcher_renameapps_list_title, R.layout.prefs_app_selector); + } + + public void openColorSelector(Preference pref) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + openSubFragment(new ColorSelector(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, pref.getTitle().toString(), R.layout.fragment_selectcolor); + } + + public void openSortableItemList(Preference pref) { + Bundle args = new Bundle(); + args.putString("key", pref.getKey()); + args.putString("titleResId", pref.getTitle().toString()); + openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitle().toString(), R.layout.prefs_sortable_list); + } + + public void openActivitiesItemList(Preference pref) { + Bundle args = new Bundle(); + args.putBoolean("activities", true); + args.putString("key", pref.getKey()); + args.putString("titleResId", pref.getTitle().toString()); + openSubFragment(new SortableList(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitle().toString(), R.layout.prefs_sortable_list); + } + + public void selectSub() { + PreferenceScreen screen = getPreferenceScreen(); + int cnt = screen.getPreferenceCount(); + for (int i = cnt - 1; i >= 0; i--) { + Preference pref = screen.getPreference(i); + if (!pref.getKey().equals(sub)) + screen.removePreference(pref); + else { + PreferenceCategoryEx category = (PreferenceCategoryEx)pref; + if (category.isDynamic()) + getActionBar().setTitle(pref.getTitle() + " ⟲"); + else + getActionBar().setTitle(pref.getTitle()); + category.hide(); + } + } + } + + public void finish() { + //View view = getView(); + //if (isAnimating && view != null) ((ViewGroup)view.getParent()).removeView(view); + if (isAnimating) return; + if (Helpers.shimmerAnim != null) Helpers.shimmerAnim.cancel(); + AppCompatActivity act = (AppCompatActivity) getActivity(); + Helpers.hideKeyboard(act, getView()); + FragmentManager fragmentManager = getParentFragmentManager(); + if (fragmentManager == null || !isResumed()) { + if (act != null) act.getSupportFragmentManager().popBackStack(); + } else { + fragmentManager.popBackStackImmediate(); + } + } + + @Override + public void confirmEdit() { + saveSharedPrefs(); + finish(); + } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java index b632f3b6..94f98d80 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java @@ -1,18 +1,26 @@ package name.mikanoshi.customiuizer; import android.annotation.SuppressLint; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.LayerDrawable; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; -import android.view.ActionMode; +import android.util.TypedValue; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; + import name.mikanoshi.customiuizer.utils.AppDataAdapter; import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.LockedAppAdapter; @@ -27,6 +35,44 @@ public class SubFragmentWithSearch extends SubFragment { boolean isSearchFocused = false; TextView textInput = null; + public void setActionModeStyle(View searchView) { + boolean isNight = Helpers.isNightMode(getValidContext()); + if (searchView != null) try { + searchView.setSaveFromParentEnabled(false); + Drawable drawable = getResources().getDrawable(getResources().getIdentifier(isNight ? "search_mode_bg_dark" : "search_mode_bg_light", "drawable", "miui"), getValidContext().getTheme()); + try { + int colorResId = getResources().getIdentifier(isNight ? "primary_color_dark" : "primary_color_light", "color", "miui"); + if (colorResId != 0 && drawable instanceof LayerDrawable) { + drawable = ((LayerDrawable)drawable).getDrawable(0); + if (drawable instanceof GradientDrawable) + ((GradientDrawable)drawable).setColor(getResources().getColor(colorResId, getValidContext().getTheme())); + } + } catch (Throwable ignore) {} + searchView.setBackground(drawable); + LinearLayout inputArea = searchView.findViewById(android.R.id.inputArea); + inputArea.setBackgroundResource(getResources().getIdentifier(isNight ? "search_mode_edit_text_bg_dark" : "search_mode_edit_text_bg_light", "drawable", "miui")); + if (Helpers.is11()) { + ViewGroup.LayoutParams lp1 = searchView.getLayoutParams(); + int resId = getResources().getIdentifier("action_bar_default_height", "dimen", "miui"); + lp1.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.secondary_text_size : resId); + searchView.setLayoutParams(lp1); + FrameLayout.LayoutParams lp2 = (FrameLayout.LayoutParams)inputArea.getLayoutParams(); + resId = getResources().getIdentifier("searchbar_bg_height", "dimen", "miui"); + lp2.height = getResources().getDimensionPixelSize(resId == 0 ? R.dimen.searchbar_bg_height : resId); + inputArea.setLayoutParams(lp2); + } + ImageView inputIcon = searchView.findViewById(R.id.inputIcon); + inputIcon.setImageResource(getResources().getIdentifier(isNight ? "edit_text_search_dark" : "edit_text_search", "drawable", "miui")); + TextView input = searchView.findViewById(android.R.id.input); + int fontSize = getResources().getIdentifier(Helpers.is11() ? "edit_text_font_size" : "secondary_text_size", "dimen", "miui"); + input.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(fontSize == 0 ? R.dimen.secondary_text_size : fontSize)); + input.setHintTextColor(getResources().getColor(getResources().getIdentifier(isNight ? "edit_text_search_hint_color_dark" : "edit_text_search_hint_color_light", "color", "miui"), getValidContext().getTheme())); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -54,7 +100,7 @@ public void onClick(View v) { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { - Helpers.hideKeyboard(getActivity(), v); + Helpers.hideKeyboard((AppCompatActivity) getActivity(), v); listView.requestFocus(); return true; } @@ -81,7 +127,7 @@ public void afterTextChanged(Editable s) { public boolean onTouch(View v, MotionEvent event) { if (isSearchFocused) { isSearchFocused = false; - Helpers.hideKeyboard(getActivity(), v); + Helpers.hideKeyboard((AppCompatActivity) getActivity(), v); } return false; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java index f0d17e5c..b1726e36 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java @@ -1,13 +1,13 @@ package name.mikanoshi.customiuizer.prefs; -import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; -import android.preference.SwitchPreference; + +import androidx.preference.PreferenceViewHolder; +import androidx.preference.SwitchPreference; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; import name.mikanoshi.customiuizer.R; @@ -19,7 +19,6 @@ public class CheckBoxPreferenceEx extends SwitchPreference implements Preference private final int primary = res.getColor(R.color.preference_primary_text, getContext().getTheme()); private final int secondary = res.getColor(R.color.preference_secondary_text, getContext().getTheme()); private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final int[] paddings = new int[] {0, 0, 0, 0}; private final boolean child; private final boolean dynamic; @@ -32,38 +31,29 @@ public CheckBoxPreferenceEx(Context context, AttributeSet attrs) { dynamic = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_dynamic, false); child = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_child, false); xmlAttrs.recycle(); + setIconSpaceReserved(false); } - @Override - @SuppressLint("SetTextI18n") - public View getView(View view, ViewGroup parent) { - View finalView = super.getView(view, parent); + public void getView(View finalView) { TextView title = finalView.findViewById(android.R.id.title); title.setTextColor(isEnabled() ? primary : secondary); title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - if (paddings[0] == 0) paddings[0] = finalView.getPaddingLeft(); - if (paddings[1] == 0) paddings[1] = finalView.getPaddingTop(); - if (paddings[2] == 0) paddings[2] = finalView.getPaddingRight(); - if (paddings[3] == 0) paddings[3] = finalView.getPaddingBottom(); - finalView.setPadding(paddings[0] + (child ? childpadding : 0), paddings[1], paddings[2], paddings[3]); - - return finalView; + int hrzPadding = childpadding + (child ? childpadding : 0); + finalView.setPadding(hrzPadding, 0, childpadding, 0); } @Override - protected View onCreateView(ViewGroup parent) { - View view = super.onCreateView(parent); - - TextView title = view.findViewById(android.R.id.title); + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + TextView title = (TextView) view.findViewById(android.R.id.title); title.setMaxLines(3); title.setTextColor(primary); - TextView summary = view.findViewById(android.R.id.summary); + TextView summary = (TextView) view.findViewById(android.R.id.summary); summary.setTextColor(secondary); - - return view; + getView(view.itemView); } public void setUnsupported(boolean value) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java index 260c8f9f..891e8a9b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java @@ -1,18 +1,15 @@ package name.mikanoshi.customiuizer.prefs; -import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; -import android.os.Bundle; -import android.preference.ListPreference; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceViewHolder; + import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; -import android.view.Window; -import android.widget.CheckedTextView; -import android.widget.ListView; import android.widget.TextView; import name.mikanoshi.customiuizer.R; @@ -25,7 +22,6 @@ public class ListPreferenceEx extends ListPreference implements PreferenceState private final int primary = res.getColor(R.color.preference_primary_text, getContext().getTheme()); private final int secondary = res.getColor(R.color.preference_secondary_text, getContext().getTheme()); private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final int[] paddings = new int[] {0, 0, 0, 0}; private final boolean child; private final boolean dynamic; @@ -40,6 +36,7 @@ public ListPreferenceEx(Context context, AttributeSet attrs) { dynamic = xmlAttrs.getBoolean(R.styleable.ListPreferenceEx_dynamic, false); valueAsSummary = xmlAttrs.getBoolean(R.styleable.ListPreferenceEx_valueAsSummary, false); xmlAttrs.recycle(); + setIconSpaceReserved(false); } @Override @@ -55,10 +52,7 @@ public void setUnsupported(boolean value) { setEnabled(!value); } - @Override - @SuppressLint("SetTextI18n") - public View getView(View view, ViewGroup parent) { - View finalView = super.getView(view, parent); + public void getView(View finalView) { TextView title = finalView.findViewById(android.R.id.title); TextView summary = finalView.findViewById(android.R.id.summary); TextView valSummary = finalView.findViewById(android.R.id.hint); @@ -66,39 +60,35 @@ public View getView(View view, ViewGroup parent) { summary.setVisibility(valueAsSummary || getSummary() == null || getSummary().equals("") ? View.GONE : View.VISIBLE); valSummary.setVisibility(valueAsSummary ? View.VISIBLE : View.GONE); valSummary.setText(valueAsSummary ? sValue : ""); - if (valueAsSummary && Helpers.is11()) valSummary.setTextColor(Helpers.isNightMode(getContext()) ? secondary : primary); + if (valueAsSummary) valSummary.setTextColor(Helpers.isNightMode(getContext()) ? secondary : primary); title.setTextColor(isEnabled() ? primary : secondary); title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - if (paddings[0] == 0) paddings[0] = finalView.getPaddingLeft(); - if (paddings[1] == 0) paddings[1] = finalView.getPaddingTop(); - if (paddings[2] == 0) paddings[2] = finalView.getPaddingRight(); - if (paddings[3] == 0) paddings[3] = finalView.getPaddingBottom(); - finalView.setPadding(paddings[0] + (child ? childpadding : 0), paddings[1], paddings[2], paddings[3]); - - return finalView; + int hrzPadding = childpadding + (child ? childpadding : 0); + finalView.setPadding(hrzPadding, 0, childpadding, 0); } @Override - protected View onCreateView(ViewGroup parent) { - ViewGroup view = (ViewGroup)super.onCreateView(parent); - - TextView title = view.findViewById(android.R.id.title); + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + TextView title = (TextView) view.findViewById(android.R.id.title); title.setMaxLines(3); - title.setTextColor(primary); - TextView summary = view.findViewById(android.R.id.summary); + TextView summary = (TextView) view.findViewById(android.R.id.summary); summary.setTextColor(secondary); - TextView valSummary = new TextView(getContext()); - valSummary.setTextSize(TypedValue.COMPLEX_UNIT_PX, summary.getTextSize()); - valSummary.setTextColor(summary.getCurrentTextColor()); - valSummary.setPadding(summary.getPaddingLeft(), summary.getPaddingTop(), res.getDimensionPixelSize(R.dimen.preference_summary_padding_right), summary.getPaddingBottom()); - valSummary.setId(android.R.id.hint); - view.addView(valSummary, 2); - - return view; + TextView valSummary = view.itemView.findViewById(android.R.id.hint); + if (valSummary == null) { + valSummary = new TextView(getContext()); + valSummary.setTextSize(TypedValue.COMPLEX_UNIT_PX, summary.getTextSize()); + valSummary.setTextColor(summary.getCurrentTextColor()); + valSummary.setPadding(summary.getPaddingLeft(), summary.getPaddingTop(), res.getDimensionPixelSize(R.dimen.preference_summary_padding_right), summary.getPaddingBottom()); + valSummary.setId(android.R.id.hint); + ((ViewGroup) view.itemView).addView(valSummary, 2); + } + + getView(view.itemView); } @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListViewEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListViewEx.java index 081f5575..a19aeadc 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListViewEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListViewEx.java @@ -8,6 +8,8 @@ public class ListViewEx extends ListView { public ListViewEx(Context context, AttributeSet attrs) { super(context, attrs); + this.setDivider(null); + this.setDividerHeight(0); } public ListViewEx(Context context) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java index 4d5afbac..1946be78 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java @@ -1,23 +1,25 @@ package name.mikanoshi.customiuizer.prefs; -import android.annotation.SuppressLint; import android.content.Context; +import android.content.res.Resources; import android.content.res.TypedArray; -import android.preference.Preference; -import android.preference.PreferenceCategory; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.TextView; +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceViewHolder; + import name.mikanoshi.customiuizer.R; public class PreferenceCategoryEx extends PreferenceCategory { - private final boolean dynamic; private final boolean empty; private boolean hidden; private boolean unsupported = false; + private final Resources res = getContext().getResources(); + private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); public PreferenceCategoryEx(Context context, AttributeSet attrs) { super(context, attrs); @@ -36,21 +38,15 @@ public boolean onPrepareAddPreference(Preference preference) { } @Override - @SuppressLint("SetTextI18n") - public View getView(View view, ViewGroup parent) { - View finalView = super.getView(view, parent); - TextView title = finalView.findViewById(android.R.id.title); + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + TextView title = (TextView) view.findViewById(android.R.id.title); title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); title.setVisibility(hidden || empty ? View.GONE : View.VISIBLE); + View finalView = view.itemView; if (hidden) { - finalView.setPadding( - finalView.getPaddingLeft(), - 0, - finalView.getPaddingRight(), - 0 - ); + finalView.setPadding(childpadding, 0, childpadding, 0); } - return finalView; } public void setUnsupported(boolean value) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java index 3c15d401..87abb9b8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java @@ -1,10 +1,11 @@ package name.mikanoshi.customiuizer.prefs; -import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; -import android.preference.Preference; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; @@ -18,12 +19,10 @@ import name.mikanoshi.customiuizer.utils.Helpers; public class PreferenceEx extends Preference implements PreferenceState { - private final Resources res = getContext().getResources(); private final int primary = res.getColor(R.color.preference_primary_text, getContext().getTheme()); private final int secondary = res.getColor(R.color.preference_secondary_text, getContext().getTheme()); private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final int[] paddings = new int[] {0, 0, 0, 0}; private final boolean child; private final boolean dynamic; @@ -43,12 +42,10 @@ public PreferenceEx(Context context, AttributeSet attrs) { notice = xmlAttrs.getBoolean(R.styleable.PreferenceEx_notice, false); countAsSummary = xmlAttrs.getBoolean(R.styleable.PreferenceEx_countAsSummary, false); xmlAttrs.recycle(); + setIconSpaceReserved(false); } - @Override - @SuppressLint("SetTextI18n") - public View getView(View view, ViewGroup parent) { - View finalView = super.getView(view, parent); + public void getView(View finalView) { TextView title = finalView.findViewById(android.R.id.title); TextView summary = finalView.findViewById(android.R.id.summary); TextView valSummary = finalView.findViewById(android.R.id.hint); @@ -73,14 +70,8 @@ else if (countAsSummary) { ImageView arrow = finalView.findViewById(finalView.getResources().getIdentifier("arrow_right", "id", "miui")); if (arrow != null) arrow.setVisibility(View.GONE); } catch (Throwable ignore) {} - - if (paddings[0] == 0) paddings[0] = finalView.getPaddingLeft(); - if (paddings[1] == 0) paddings[1] = finalView.getPaddingTop(); - if (paddings[2] == 0) paddings[2] = finalView.getPaddingRight(); - if (paddings[3] == 0) paddings[3] = finalView.getPaddingBottom(); - finalView.setPadding(paddings[0] + (child ? childpadding : 0), paddings[1], paddings[2], paddings[3]); - - return finalView; + int hrzPadding = childpadding + (child ? childpadding : 0); + finalView.setPadding(hrzPadding, 0, childpadding, 0); } public void setCustomSummary(String text) { @@ -89,24 +80,26 @@ public void setCustomSummary(String text) { } @Override - protected View onCreateView(ViewGroup parent) { - ViewGroup view = (ViewGroup)super.onCreateView(parent); + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); - TextView title = view.findViewById(android.R.id.title); + TextView title = (TextView) view.findViewById(android.R.id.title); title.setMaxLines(3); title.setTextColor(primary); - TextView summary = view.findViewById(android.R.id.summary); + TextView summary = (TextView) view.findViewById(android.R.id.summary); summary.setTextColor(secondary); - TextView valSummary = new TextView(getContext()); - valSummary.setTextSize(TypedValue.COMPLEX_UNIT_PX, summary.getTextSize()); - valSummary.setTextColor(summary.getCurrentTextColor()); - valSummary.setPadding(summary.getPaddingLeft(), summary.getPaddingTop(), res.getDimensionPixelSize(R.dimen.preference_summary_padding_right), summary.getPaddingBottom()); - valSummary.setId(android.R.id.hint); - view.addView(valSummary, 2); - - return view; + TextView valSummary = view.itemView.findViewById(android.R.id.hint); + if (valSummary == null) { + valSummary = new TextView(getContext()); + valSummary.setTextSize(TypedValue.COMPLEX_UNIT_PX, summary.getTextSize()); + valSummary.setTextColor(secondary); + valSummary.setPadding(summary.getPaddingLeft(), summary.getPaddingTop(), res.getDimensionPixelSize(R.dimen.preference_summary_padding_right), summary.getPaddingBottom()); + valSummary.setId(android.R.id.hint); + ((ViewGroup) view.itemView).addView(valSummary, 2); + } + getView(view.itemView); } @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java index e9fe1d09..5ad2b847 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java @@ -1,13 +1,13 @@ package name.mikanoshi.customiuizer.prefs; -import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; -import android.preference.Preference; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.SeekBar; import android.widget.TextView; @@ -96,39 +96,34 @@ else if (mDefaultValue > mMaxValue) mSteppedMinValue = Math.round((float)mMinValue / mStepValue); mSteppedMaxValue = Math.round((float)mMaxValue / mStepValue); + setLayoutResource(R.layout.preference_seekbar12); } - @Override - @SuppressLint("SetTextI18n") - public View getView(View view, ViewGroup parent) { - View finalView = super.getView(view, parent); + public void getView(View finalView) { TextView mTitle = finalView.findViewById(android.R.id.title); mTitle.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (Helpers.is12()) mSeekBar.setAlpha(isEnabled() ? 1.0f : 0.75f); if (newmod) Helpers.applyNewMod(mTitle); - return finalView; } @Override - protected View onCreateView(ViewGroup parent) { - setLayoutResource(R.layout.preference_seekbar12); - - View view = super.onCreateView(parent); + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); - TextView mSummaryView = view.findViewById(android.R.id.summary); + TextView mSummaryView = (TextView) view.findViewById(android.R.id.summary); if (!TextUtils.isEmpty(getSummary())) mSummaryView.setText(getSummary()); else mSummaryView.setVisibility(View.GONE); - TextView mNoteView = view.findViewById(android.R.id.text1); + TextView mNoteView = (TextView) view.findViewById(android.R.id.text1); if (mNote == null || mNote.equals("")) mNoteView.setVisibility(View.GONE); else mNoteView.setText(mNote); - mValue = view.findViewById(R.id.seekbar_value); - mSeekBar = view.findViewById(R.id.seekbar); + mValue = (TextView) view.findViewById(R.id.seekbar_value); + mSeekBar = (SeekBar) view.findViewById(R.id.seekbar); mSeekBar.setMax(mSteppedMaxValue - mSteppedMinValue); setValue(Helpers.prefs.getInt(getKey(), mDefaultValue)); @@ -151,8 +146,8 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { updateDisplay(progress); } }); - - return view; + getView(view.itemView); + view.setDividerAllowedAbove(false); } public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java index 71e39918..dbe65e67 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java @@ -2,7 +2,6 @@ import android.annotation.SuppressLint; import android.app.Activity; -import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -12,6 +11,8 @@ import android.view.View; import android.widget.AdapterView; +import androidx.appcompat.app.AlertDialog; + import java.lang.reflect.Method; import java.util.LinkedHashSet; import java.util.Set; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java index 3b60a8d9..9a39e702 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java @@ -78,12 +78,6 @@ public void onActivityCreated(Bundle savedInstanceState) { listView1 = getView().findViewById(android.R.id.text1); listView2 = getView().findViewById(android.R.id.text2); - TextView cat1 = getView().findViewById(R.id.bt_category1); - TextView cat2 = getView().findViewById(R.id.bt_category2); - int resId = getResources().getIdentifier("preference_category_background", "drawable", "miui"); - cat1.setBackgroundResource(resId); - cat2.setBackgroundResource(resId); - @SuppressLint("CutPasteId") ViewStub locationStub = getView().findViewById(R.id.fetch_devices); locationStub.setLayoutResource(R.layout.pref_item); locationStub.inflate(); @@ -91,7 +85,6 @@ public void onActivityCreated(Bundle savedInstanceState) { @SuppressLint("CutPasteId") View location = getView().findViewById(R.id.fetch_devices); ((TextView)location.findViewById(android.R.id.title)).setText(R.string.bt_fetch_devices_title); ((TextView)location.findViewById(android.R.id.summary)).setText(R.string.bt_fetch_devices_summ); - Helpers.setMiuiPrefItem(location); location.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -224,7 +217,6 @@ public View getView(final int position, View convertView, ViewGroup parent) { row = convertView; } else { row = mInflater.inflate(R.layout.pref_item, parent, false); - Helpers.setMiuiPrefItem(row); } TextView itemTitle = row.findViewById(android.R.id.title); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java index edceef6d..bf41c502 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java @@ -1,8 +1,8 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.preference.Preference; -import android.preference.PreferenceScreen; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; import name.mikanoshi.customiuizer.MainFragment; import name.mikanoshi.customiuizer.R; @@ -21,14 +21,7 @@ public void onActivityCreated(Bundle savedInstanceState) { Bundle args = getArguments(); cat = args.getString("cat"); - if ("pref_key_system".equals(cat)) { - if (!Helpers.is12()) { - Preference pref = findPreference("pref_key_system_cat_floatingwindows"); - if (pref != null) ((PreferenceScreen)findPreference("pref_key_cat")).removePreference(pref); - } - } - - PreferenceScreen screen = (PreferenceScreen)findPreference("pref_key_cat"); + PreferenceScreen screen = findPreference("pref_key_cat"); int cnt = screen.getPreferenceCount(); for (int i = 0; i < cnt; i++) screen.getPreference(i).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Controls.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Controls.java index 75b25067..2d1fbf7c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Controls.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Controls.java @@ -1,7 +1,9 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.preference.Preference; + +import androidx.annotation.Nullable; +import androidx.preference.Preference; import android.widget.Toast; import java.util.Objects; @@ -13,15 +15,16 @@ public class Controls extends SubFragment { + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + selectSub(); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Bundle args = getArguments(); - String sub = args.getString("sub"); - if (sub == null) sub = ""; - - selectSub("pref_key_controls", sub); switch (sub) { case "pref_key_controls_cat_power": findPreference("pref_key_controls_powerdt").setOnPreferenceClickListener(openLaunchActions); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java index 8e88d23f..2c27b9ad 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java @@ -3,7 +3,9 @@ import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; -import android.preference.Preference; + +import androidx.annotation.Nullable; +import androidx.preference.Preference; import android.widget.SeekBar; import name.mikanoshi.customiuizer.R; @@ -14,19 +16,17 @@ public class Launcher extends SubFragment { - String sub = ""; + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + selectSub(); + } @Override @SuppressWarnings("ConstantConditions") public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Bundle args = getArguments(); - sub = args.getString("sub"); - if (sub == null) sub = ""; - - selectSub("pref_key_launcher", sub); - Preference.OnPreferenceClickListener openPrivacyAppEdit = new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java index 10fac10a..5ce3be10 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java @@ -25,7 +25,7 @@ public class SortableList extends SubFragment { String key; - int titleResId; + String titleResId; boolean activities; SortableListView listView; @@ -42,7 +42,7 @@ public void onActivityCreated(Bundle savedInstanceState) { Bundle args = getArguments(); key = args.getString("key"); - titleResId = args.getInt("titleResId"); + titleResId = args.getString("titleResId"); activities = args.getBoolean("activities", false); if (getView() == null) return; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 8f397717..a586dbf4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -9,13 +9,17 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; -import android.preference.Preference; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.Preference; import android.provider.Settings; import android.widget.SeekBar; +import androidx.appcompat.app.AlertDialog; + import java.util.Objects; -import android.app.AlertDialog; import name.mikanoshi.customiuizer.CredentialsLauncher; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SharedPrefsProvider; @@ -31,15 +35,16 @@ public class System extends SubFragment { + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + selectSub(); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Bundle args = getArguments(); - String sub = args.getString("sub"); - if (sub == null) sub = ""; - - selectSub("pref_key_system", sub); switch (sub) { case "pref_key_system_cat_screen": findPreference("pref_key_system_orientationlock").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -424,8 +429,8 @@ public boolean onPreferenceClick(Preference preference) { } }); - PreferenceEx airplaneModePref = (PreferenceEx)findPreference("pref_key_system_airplanemodeconfig"); - airplaneModePref.setUnsupported(!Helpers.checkSettingsPerm(getActivity())); + PreferenceEx airplaneModePref = findPreference("pref_key_system_airplanemodeconfig"); + airplaneModePref.setUnsupported(!Helpers.checkSettingsPerm((AppCompatActivity) getActivity())); airplaneModePref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AirplaneModeConfig.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AirplaneModeConfig.java index 1b534d22..c36c0713 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AirplaneModeConfig.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_AirplaneModeConfig.java @@ -2,8 +2,8 @@ import android.os.Bundle; import android.os.Handler; -import android.preference.Preference; -import android.preference.PreferenceScreen; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; import android.provider.Settings; import android.text.TextUtils; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_BatteryIndicator.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_BatteryIndicator.java index cb416363..034cdada 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_BatteryIndicator.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_BatteryIndicator.java @@ -2,7 +2,7 @@ import android.content.Intent; import android.os.Bundle; -import android.preference.Preference; +import androidx.preference.Preference; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.utils.Helpers; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java index 76a3cf1b..22fff164 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java @@ -1,7 +1,9 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.preference.Preference; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.Preference; import java.util.Objects; @@ -30,7 +32,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { findPreference("pref_key_system_noscreenlock_wifi").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - if (!Helpers.checkFinePerm(getActivity(), Helpers.REQUEST_PERMISSIONS_WIFI)) return false; + if (!Helpers.checkFinePerm((AppCompatActivity) getActivity(), Helpers.REQUEST_PERMISSIONS_WIFI)) return false; openWifiNetworks(); return true; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_ScreenshotConfig.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_ScreenshotConfig.java index 6bd9d454..5e99355e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_ScreenshotConfig.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_ScreenshotConfig.java @@ -3,7 +3,7 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.preference.Preference; +import androidx.preference.Preference; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.utils.GetPathUtils; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java index 500e3197..4b5c90a9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_VibrationAmp.java @@ -1,7 +1,7 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.preference.Preference; +import androidx.preference.Preference; import android.text.format.DateFormat; import java.util.Calendar; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_Visualizer.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_Visualizer.java index de634fb0..da504b83 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_Visualizer.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_Visualizer.java @@ -1,7 +1,7 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.preference.Preference; +import androidx.preference.Preference; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.utils.Helpers; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various.java index 03f08f18..de5a7635 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various.java @@ -4,7 +4,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Bundle; -import android.preference.Preference; +import androidx.preference.Preference; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java index ebf2e187..561a289c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java @@ -1,7 +1,6 @@ package name.mikanoshi.customiuizer.subs; import android.app.Activity; -import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -11,7 +10,7 @@ import android.os.Bundle; import android.os.VibrationEffect; import android.os.Vibrator; -import android.preference.Preference; +import androidx.preference.Preference; import android.text.InputType; import android.text.TextUtils; import android.text.method.DigitsKeyListener; @@ -21,6 +20,8 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.appcompat.app.AlertDialog; + import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java index 1f913ffd..9b55c9eb 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallUIBright.java @@ -1,7 +1,7 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.preference.Preference; +import androidx.preference.Preference; import android.text.format.DateFormat; import java.util.Calendar; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_HiddenFeatures.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_HiddenFeatures.java index 7c678935..97d4492c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_HiddenFeatures.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_HiddenFeatures.java @@ -4,7 +4,9 @@ import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.preference.Preference; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.Preference; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SubFragment; @@ -17,9 +19,9 @@ public class Various_HiddenFeatures extends SubFragment { public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - final Activity act = getActivity(); + final AppCompatActivity act = (AppCompatActivity) getActivity(); - PreferenceEx aosp = (PreferenceEx)findPreference("pref_key_various_memorystats"); + PreferenceEx aosp = findPreference("pref_key_various_memorystats"); aosp.setCustomSummary("AOSP"); aosp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override @@ -29,7 +31,7 @@ public boolean onPreferenceClick(Preference preference) { } }); - aosp = (PreferenceEx)findPreference("pref_key_various_runningservices"); + aosp = findPreference("pref_key_various_runningservices"); aosp.setCustomSummary("AOSP"); aosp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/WiFiList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/WiFiList.java index c13332cd..9eb42dc4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/WiFiList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/WiFiList.java @@ -99,12 +99,6 @@ public void onActivityCreated(Bundle savedInstanceState) { listView1 = getView().findViewById(android.R.id.text1); listView2 = getView().findViewById(android.R.id.text2); - TextView cat1 = getView().findViewById(R.id.wifi_category1); - TextView cat2 = getView().findViewById(R.id.wifi_category2); - int resId = getResources().getIdentifier("preference_category_background", "drawable", "miui"); - cat1.setBackgroundResource(resId); - cat2.setBackgroundResource(resId); - @SuppressLint("CutPasteId") ViewStub locationStub = getView().findViewById(R.id.location_settings); locationStub.setLayoutResource(R.layout.pref_item); locationStub.inflate(); @@ -112,7 +106,6 @@ public void onActivityCreated(Bundle savedInstanceState) { @SuppressLint("CutPasteId") View location = getView().findViewById(R.id.location_settings); ((TextView)location.findViewById(android.R.id.title)).setText(R.string.wifi_location_title); ((TextView)location.findViewById(android.R.id.summary)).setText(R.string.wifi_location_summ); - Helpers.setMiuiPrefItem(location); location.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -249,7 +242,6 @@ public View getView(final int position, View convertView, ViewGroup parent) { row = convertView; } else { row = mInflater.inflate(R.layout.pref_item, parent, false); - Helpers.setMiuiPrefItem(row); } TextView itemTitle = row.findViewById(android.R.id.title); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/tasker/UnlockSettings.java b/app/src/main/java/name/mikanoshi/customiuizer/tasker/UnlockSettings.java index 7ee96de1..01b9131f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/tasker/UnlockSettings.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/tasker/UnlockSettings.java @@ -7,9 +7,11 @@ import android.widget.Button; import android.widget.RadioGroup; +import androidx.appcompat.app.AppCompatActivity; + import name.mikanoshi.customiuizer.R; -public class UnlockSettings extends Activity { +public class UnlockSettings extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 54c73752..cf5c057d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -1,36 +1,8 @@ package name.mikanoshi.customiuizer.utils; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.TimeZone; - import android.Manifest; -import android.animation.Animator; import android.animation.ValueAnimator; import android.annotation.SuppressLint; -import android.app.Activity; import android.app.AlarmManager; import android.app.Application; import android.app.admin.DevicePolicyManager; @@ -51,13 +23,9 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; -import android.graphics.LinearGradient; -import android.graphics.Matrix; import android.graphics.Rect; -import android.graphics.Shader; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.net.Uri; @@ -70,8 +38,8 @@ import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; -import android.preference.PreferenceCategory; -import android.preference.PreferenceScreen; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceScreen; import android.provider.Settings; import android.text.InputType; import android.text.Spannable; @@ -94,15 +62,39 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; + import org.xmlpull.v1.XmlPullParser; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.TimeZone; + import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; - -import android.app.AlertDialog; import miui.util.HapticFeedbackUtil; - import name.mikanoshi.customiuizer.MainModule; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SharedPrefsProvider; @@ -139,7 +131,7 @@ public class Helpers { public static ArrayList allModsList = new ArrayList(); public static int xposedVersion = 0; public static final int markColor = Color.rgb(205, 73, 97); - public static final int markColorVibrant = Color.rgb(222, 45, 73); + public static final int markColorVibrant = Color.rgb(255, 0, 0); public static final int REQUEST_PERMISSIONS_BACKUP = 1; public static final int REQUEST_PERMISSIONS_RESTORE = 2; public static final int REQUEST_PERMISSIONS_WIFI = 3; @@ -345,10 +337,10 @@ public static boolean isSysAppUpdaterInstalled(Context context) { return res; } - public static void launchActivity(Activity act, String pkg, String cmp) { + public static void launchActivity(AppCompatActivity act, String pkg, String cmp) { launchActivity(act, pkg, cmp, false); } - public static boolean launchActivity(Activity act, String pkg, String cmp, boolean silent) { + public static boolean launchActivity(AppCompatActivity act, String pkg, String cmp, boolean silent) { PackageManager pm = act.getPackageManager(); try { pm.getPackageInfo(pkg, PackageManager.GET_ACTIVITIES); @@ -371,7 +363,7 @@ public static boolean launchActivity(Activity act, String pkg, String cmp, boole // return false; // } - public static void hideKeyboard(Activity act, View view) { + public static void hideKeyboard(AppCompatActivity act, View view) { try { Context context = act == null ? view.getContext() : act; InputMethodManager inputManager = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); @@ -433,32 +425,32 @@ public static boolean checkStorageReadable(Context context) { } } - public static boolean checkStoragePerm(Activity act, int action) { + public static boolean checkStoragePerm(AppCompatActivity act, int action) { if (act.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { act.requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE }, action); return false; } else return true; } - public static boolean checkSettingsPerm(Activity act) { + public static boolean checkSettingsPerm(AppCompatActivity act) { return act.checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED; } - public static boolean checkCoarsePerm(Activity act, int action) { + public static boolean checkCoarsePerm(AppCompatActivity act, int action) { if (act.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { act.requestPermissions(new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION }, action); return false; } else return true; } - public static boolean checkFinePerm(Activity act, int action) { + public static boolean checkFinePerm(AppCompatActivity act, int action) { if (act.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { act.requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, action); return false; } else return true; } - public static boolean preparePathForBackup(Activity act, String path) { + public static boolean preparePathForBackup(AppCompatActivity act, String path) { if (!checkStoragePerm(act, REQUEST_PERMISSIONS_BACKUP)) return false; String state = Environment.getExternalStorageState(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ModSearchAdapter.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ModSearchAdapter.java index 42479bdc..90676332 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ModSearchAdapter.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ModSearchAdapter.java @@ -60,7 +60,6 @@ public View getView(final int position, View convertView, ViewGroup parent) { row = convertView; } else { row = mInflater.inflate(R.layout.pref_item, parent, false); - Helpers.setMiuiPrefItem(row); } TextView itemTitle = row.findViewById(android.R.id.title); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java deleted file mode 100644 index c515ce5a..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/NestedHeaderLayout.java +++ /dev/null @@ -1,53 +0,0 @@ -package name.mikanoshi.customiuizer.utils; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; - -import name.mikanoshi.customiuizer.R; - -public class NestedHeaderLayout extends miui.widget.NestedScrollingLayout { - - private View mHeaderView; - private float mRangeOffset; - private View mScrollableSearchView; - - public NestedHeaderLayout(Context context) { - this(context, null); - } - - public NestedHeaderLayout(Context context, AttributeSet attributeSet) { - this(context, attributeSet, 0); - } - - public NestedHeaderLayout(Context context, AttributeSet attributeSet, int i) { - super(context, attributeSet, i); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mHeaderView = findViewById(R.id.searchView); - mScrollableView = findViewById(android.R.id.list); - mScrollableSearchView = findViewById(android.R.id.custom); - mRangeOffset = 0.0f; - } - - @Override - protected void onLayout(boolean z, int i, int i2, int i3, int i4) { - super.onLayout(z, i, i2, i3, i4); - if (mHeaderView != null) { - setScrollingRange((int)((float)(-mHeaderView.getMeasuredHeight()) + mRangeOffset), 0); - } - } - - @Override - protected void onScrollingProgressUpdated(int i) { - super.onScrollingProgressUpdated(i); - if (mHeaderView != null) { - mHeaderView.offsetTopAndBottom(i - mHeaderView.getTop()); - mScrollableView.offsetTopAndBottom(mHeaderView.getMeasuredHeight() + i - mScrollableView.getTop()); - mScrollableSearchView.setTop(mHeaderView.getMeasuredHeight()); - } - } -} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c1cc3534..5c501595 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -14,7 +14,7 @@ app:contentInsetLeft="0dp" app:contentInsetRight="0dp" app:titleMarginStart="0dp" - android:theme="@style/ToolbarStyle" + android:theme="@style/AppToolbarStyle" /> + app:srcCompat="@drawable/ic_xspace" /> + app:srcCompat="@drawable/am_card_item_disabled" /> + app:srcCompat="@drawable/ic_xspace" /> + app:srcCompat="@drawable/am_card_item_disabled" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_about_head.xml b/app/src/main/res/layout/fragment_about_head.xml new file mode 100644 index 00000000..bb0283e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_about_head.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_about_tail.xml b/app/src/main/res/layout/fragment_about_tail.xml new file mode 100644 index 00000000..673ee3bc --- /dev/null +++ b/app/src/main/res/layout/fragment_about_tail.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/pref_header.xml b/app/src/main/res/layout/pref_header.xml index 32eeedec..1896aa7a 100644 --- a/app/src/main/res/layout/pref_header.xml +++ b/app/src/main/res/layout/pref_header.xml @@ -4,8 +4,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingStart="?android:attr/listPreferredItemPaddingLeft" - android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?attr/listPreferredItemPaddingLeft" + android:paddingEnd="?attr/listPreferredItemPaddingRight" android:paddingTop="8.66dp" android:paddingBottom="8.66dp" tools:ignore="RtlSymmetry"> diff --git a/app/src/main/res/layout/pref_item.xml b/app/src/main/res/layout/pref_item.xml index 675ddacb..bd5fba89 100644 --- a/app/src/main/res/layout/pref_item.xml +++ b/app/src/main/res/layout/pref_item.xml @@ -1,14 +1,14 @@ + android:textSize="@dimen/normal_text_size" /> + android:textSize="@dimen/secondary_text_size" /> diff --git a/app/src/main/res/layout/pref_item_detailed.xml b/app/src/main/res/layout/pref_item_detailed.xml index 49302769..14dab4b7 100644 --- a/app/src/main/res/layout/pref_item_detailed.xml +++ b/app/src/main/res/layout/pref_item_detailed.xml @@ -4,9 +4,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:minHeight="?android:attr/listPreferredItemHeightLarge" - android:paddingStart="?android:attr/listPreferredItemPaddingLeft" - android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:minHeight="?attr/listPreferredItemHeightLarge" + android:paddingStart="?attr/listPreferredItemPaddingLeft" + android:paddingEnd="?attr/listPreferredItemPaddingRight" android:paddingTop="8.66dp" android:paddingBottom="8.66dp" tools:ignore="RtlSymmetry"> diff --git a/app/src/main/res/layout/preference_category.xml b/app/src/main/res/layout/preference_category.xml index bef5470d..df3284e8 100644 --- a/app/src/main/res/layout/preference_category.xml +++ b/app/src/main/res/layout/preference_category.xml @@ -2,13 +2,13 @@ + android:paddingStart="@dimen/preference_item_child_padding" + android:paddingTop="@dimen/preference_item_padding_top" + android:paddingBottom="@dimen/preference_item_padding_top"> + style="@style/AppPreferenceCategory"/> diff --git a/app/src/main/res/layout/preference_seekbar.xml b/app/src/main/res/layout/preference_seekbar.xml deleted file mode 100644 index 525a80f0..00000000 --- a/app/src/main/res/layout/preference_seekbar.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/preference_seekbar12.xml b/app/src/main/res/layout/preference_seekbar12.xml index 13dbcf96..975451c4 100644 --- a/app/src/main/res/layout/preference_seekbar12.xml +++ b/app/src/main/res/layout/preference_seekbar12.xml @@ -1,81 +1,83 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/prefs_bt_networks.xml b/app/src/main/res/layout/prefs_bt_networks.xml index 566616b4..f85cc628 100644 --- a/app/src/main/res/layout/prefs_bt_networks.xml +++ b/app/src/main/res/layout/prefs_bt_networks.xml @@ -55,7 +55,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/prefs_main.xml b/app/src/main/res/layout/prefs_main.xml deleted file mode 100644 index f9069613..00000000 --- a/app/src/main/res/layout/prefs_main.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/prefs_main12.xml b/app/src/main/res/layout/prefs_main12.xml index 78519984..9643646d 100644 --- a/app/src/main/res/layout/prefs_main12.xml +++ b/app/src/main/res/layout/prefs_main12.xml @@ -1,29 +1,13 @@ - - - - - - - \ No newline at end of file + android:cacheColorHint="@android:color/transparent" + android:clipToPadding="false" + android:drawSelectorOnTop="false" + android:scrollbarAlwaysDrawVerticalTrack="false" + /> \ No newline at end of file diff --git a/app/src/main/res/layout/prefs_system_audiosilencer.xml b/app/src/main/res/layout/prefs_system_audiosilencer.xml index c85b359b..1902ea57 100644 --- a/app/src/main/res/layout/prefs_system_audiosilencer.xml +++ b/app/src/main/res/layout/prefs_system_audiosilencer.xml @@ -55,7 +55,7 @@ + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 44b58698..b4fd9487 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -869,9 +869,7 @@ android - com.android.contacts com.android.incallui - com.android.mms com.android.packageinstaller com.android.server.telecom com.android.settings @@ -879,14 +877,11 @@ com.android.thememanager com.google.android.packageinstaller com.miui.cleanmaster - com.miui.contentcatcher - com.miui.notification com.miui.packageinstaller com.miui.powerkeeper com.miui.securitycenter com.miui.screenrecorder com.miui.home com.mi.android.globallauncher - com.xiaomi.misettings \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 0f2ff836..d70458d7 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,20 +2,21 @@ 20dp 15dp - 15.16dp - 15.19dp - 20dp - 15dp - 14sp - 12.36sp + 15.3dp + 15.3dp + 23.3dp + 10dp + 13sp + 13sp 13.3dp - 75dp + 8dp + 70dp 22.5dp 16.7sp - 12sp + 14sp 11dp diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7fbd0a25..859d4732 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,31 +1,41 @@ - - + + + - - - - - @@ -93,8 +103,8 @@ @@ -119,7 +129,7 @@ 16dp + - - - + + @@ -29,8 +35,12 @@ @anim/activity_close_exit + + @@ -39,6 +49,7 @@ - - @@ -103,7 +104,7 @@ diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 6b62fa6b..9aee8fa9 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -36,6 +36,7 @@ android:summary="@string/miuizer_show_settingsicon_summ" android:entries="@array/settingsicon" android:entryValues="@array/settingsicon_val" + miuizer:valueAsSummary="true" android:defaultValue="1" /> diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index cf487d1f..2f68e592 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -43,6 +43,7 @@ miuizer:minValue="0" miuizer:maxValue="48" miuizer:stepValue="1" + miuizer:child="true" miuizer:format="%d" /> Date: Sat, 26 Nov 2022 22:25:25 +0800 Subject: [PATCH 151/627] fix: disable screen lock with bt --- app/build.gradle | 2 +- .../mikanoshi/customiuizer/MainActivity.java | 22 ++++++++++++------- .../customiuizer/mods/PackagePermissions.java | 17 -------------- .../mikanoshi/customiuizer/subs/BTList.java | 8 ++++--- .../subs/System_NoScreenLock.java | 1 + .../mikanoshi/customiuizer/utils/Helpers.java | 7 +++--- 6 files changed, 25 insertions(+), 32 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b5180516..5e2178df 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,7 +27,7 @@ android { //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 versionCode 45 - versionName "22.11.24" + versionName "22.11.26" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java index 5e9c1d93..c6bb4978 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java @@ -165,14 +165,20 @@ else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); break; case Helpers.REQUEST_PERMISSIONS_WIFI: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { -// Fragment frag = getSupportFragmentManager().findFragmentById(R.id.fragment_container); -// if (frag instanceof name.mikanoshi.customiuizer.subs.System_NoScreenLock) -// ((name.mikanoshi.customiuizer.subs.System_NoScreenLock)frag).openWifiNetworks(); - } else if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) - Toast.makeText(this, R.string.permission_scan, Toast.LENGTH_LONG).show(); - else - Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { + if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) + Toast.makeText(this, R.string.permission_scan, Toast.LENGTH_LONG).show(); + else + Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); + } + break; + case Helpers.REQUEST_PERMISSIONS_BLUETOOTH: + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { + if (shouldShowRequestPermissionRationale(Manifest.permission.BLUETOOTH_CONNECT)) + Toast.makeText(this, R.string.permission_scan, Toast.LENGTH_LONG).show(); + else + Toast.makeText(this, R.string.permission_permanent, Toast.LENGTH_LONG).show(); + } break; case Helpers.REQUEST_PERMISSIONS_REPORT: Toast.makeText(this, ":(", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java index c9585a30..a5ef83d8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java @@ -151,23 +151,6 @@ protected void after(MethodHookParam param) throws Throwable { } }); - // Do not restrict background activity -// if (!Helpers.isNougat()) -// Helpers.hookAllMethods("com.android.server.am.ActivityManagerService", lpparam.classLoader, "appRestrictedInBackgroundLocked", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// if (Helpers.modulePkg.equals(param.args[1])) param.setResult(0); -// } -// }); -// -// if (!Helpers.isNougat()) -// Helpers.hookAllMethods("com.android.server.am.ActivityManagerService", lpparam.classLoader, "appServicesRestrictedInBackgroundLocked", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// if (Helpers.modulePkg.equals(param.args[1])) param.setResult(0); -// } -// }); - Helpers.hookAllMethodsSilently("com.android.server.wm.ActivityRecordInjector", lpparam.classLoader, "canShowWhenLocked", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java index a53cb57b..95830530 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/BTList.java @@ -47,9 +47,11 @@ public class BTList extends SubFragment { public void onReceive(Context context, Intent intent) { ArrayList deviceList = intent.getParcelableArrayListExtra("device_list"); btList.clear(); - if (deviceList != null) - for (BluetoothDevice device: deviceList) - btList.add(new Pair(device.getAddress(), device.getName())); + if (deviceList != null) { + for (BluetoothDevice device: deviceList) { + btList.add(new Pair(device.getAddress(), device.getName())); + } + } btAdapter1.notifyDataSetChanged(); btAdapter2.notifyDataSetChanged(); updateProgressBar(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java index 03c7da88..d55625a1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java @@ -41,6 +41,7 @@ public boolean onPreferenceClick(Preference preference) { findPreference("pref_key_system_noscreenlock_bt").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { + if (!Helpers.checkBluetoothPerm((AppCompatActivity) getActivity(), Helpers.REQUEST_PERMISSIONS_BLUETOOTH)) return false; openBtNetworks(); return true; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 1cc5abe1..0af27579 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -137,6 +137,7 @@ public class Helpers { public static final int REQUEST_PERMISSIONS_RESTORE = 2; public static final int REQUEST_PERMISSIONS_WIFI = 3; public static final int REQUEST_PERMISSIONS_REPORT = 4; + public static final int REQUEST_PERMISSIONS_BLUETOOTH = 5; public static LruCache memoryCache = new LruCache((int)(Runtime.getRuntime().maxMemory() / 1024) / 2) { @Override protected int sizeOf(String key, Bitmap icon) { @@ -420,9 +421,9 @@ public static boolean checkSettingsPerm(AppCompatActivity act) { return act.checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED; } - public static boolean checkCoarsePerm(AppCompatActivity act, int action) { - if (act.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - act.requestPermissions(new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION }, action); + public static boolean checkBluetoothPerm(AppCompatActivity act, int action) { + if (act.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + act.requestPermissions(new String[]{ Manifest.permission.BLUETOOTH_CONNECT }, action); return false; } else return true; } From 1695a1d6bb615c1caa8ab7eb0493618a43078235 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 26 Nov 2022 23:08:33 +0800 Subject: [PATCH 152/627] add scope tip --- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values/strings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9211178c..f757f38a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -600,7 +600,7 @@ 电源键 音量键 控制输入法光标 - 使用音量键移动文本输入法光标 + 使用音量键移动文本输入法光标(请将输入法App加入作用域) 改变方向 交换光标移动的方向 长按音量上键动作 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 71c9009e..37ba3add 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -178,7 +178,7 @@ Quality Save folder Hide overlays on screenshots - Temporarily hide overlays while taking a screenshot(Add apps that have overlays to LSPosed Scope first) + Temporarily hide overlays while taking a screenshot(Add apps that have overlays to LSPosed scope first) Floating screenshot display time Delay before a floating window with newly created screenshot disappears Charge animation screen timeout @@ -343,7 +343,7 @@ Disable signature verification Allow app updating even when APK signature differs from installed one Text magnifier - Display magnified text when moving an input cursor or making a selection + Display magnified text when moving an input cursor or making a selection(Add InputMethod apps to LSPosed scope first) Disable overscroll Prevent list views from overscrolling Disable secure content protection From 3b936ce7009133e19c85d40012b7324d7f391b07 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 26 Nov 2022 23:11:57 +0800 Subject: [PATCH 153/627] add tips --- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f757f38a..76f18ba9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -309,7 +309,7 @@ 附加功能 安全 其他元素 - 将应用程序的图标和文字添加到其toast + 将应用程序的图标和文字添加到其toast(请将发送Toast的App加入作用域) 阻止toast 阻止所选应用显示toast 5G开关 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 37ba3add..6e81e4b7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -322,7 +322,7 @@ Additional functionality Security Additional elements - Add application\'s icon and label to its toasts + Add application\'s icon and label to its toasts(Add apps that send toasts to LSPosed scope first) Block toasts Prevent selected apps from showing toasts Airplane mode configuration From 13c2dc8f98f069365f3c305da287eac8db241274 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 28 Nov 2022 13:14:00 +0800 Subject: [PATCH 154/627] fix: auto expand notification --- .../customiuizer/mods/GlobalActions.java | 21 ++++------ .../mikanoshi/customiuizer/mods/System.java | 39 +++++++------------ 2 files changed, 20 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 4ea3d1f5..731c086a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -1,5 +1,11 @@ package name.mikanoshi.customiuizer.mods; +import static java.lang.System.currentTimeMillis; +import static de.robv.android.xposed.XposedHelpers.findClass; +import static de.robv.android.xposed.XposedHelpers.findClassIfExists; +import static de.robv.android.xposed.XposedHelpers.findField; +import static de.robv.android.xposed.XposedHelpers.findMethodExact; + import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityManager; @@ -15,9 +21,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; -import android.graphics.LinearGradient; -import android.graphics.Shader; -import android.graphics.Typeface; import android.media.AudioManager; import android.net.wifi.WifiManager; import android.nfc.NfcAdapter; @@ -28,14 +31,12 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; -import android.preference.PreferenceActivity.Header; import android.provider.Settings; import android.telephony.TelephonyManager; import android.view.KeyEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; -import android.widget.TextView; import android.widget.Toast; import java.io.File; @@ -46,26 +47,18 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; -import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; - +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; import name.mikanoshi.customiuizer.GateWaySettings; import name.mikanoshi.customiuizer.MainModule; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.Helpers.MethodHook; -import static de.robv.android.xposed.XposedHelpers.findClass; -import static de.robv.android.xposed.XposedHelpers.findClassIfExists; -import static de.robv.android.xposed.XposedHelpers.findField; -import static de.robv.android.xposed.XposedHelpers.findMethodExact; -import static java.lang.System.currentTimeMillis; - @SuppressWarnings("WeakerAccess") public class GlobalActions { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d3fdb348..1c1467d9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -147,7 +147,6 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; @@ -175,19 +174,17 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; -import miui.telephony.TelephonyManager; - import de.robv.android.xposed.XC_MethodHook.MethodHookParam; import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; import de.robv.android.xposed.callbacks.XCallback; +import miui.telephony.TelephonyManager; import name.mikanoshi.customiuizer.MainModule; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.utils.AudioVisualizer; @@ -1208,26 +1205,17 @@ protected void before(MethodHookParam param) throws Throwable { } public static void ExpandNotificationsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationViewHierarchyManager", lpparam.classLoader, "updateRowStatesInternal", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mListContainer = XposedHelpers.getObjectField(param.thisObject, "mListContainer"); - int containerChildCount = (int)XposedHelpers.callMethod(mListContainer, "getContainerChildCount"); - int statusbarState = (int)XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mStatusBarStateController"), "getCurrentOrUpcomingState"); - if (statusbarState != 1) { - for (int i = containerChildCount - 1; i >= 0; i--) { - View enotificationrow = (View)XposedHelpers.callMethod(mListContainer, "getContainerChildAt", i); - if (enotificationrow != null && enotificationrow.getClass().getSimpleName().equalsIgnoreCase("MiuiExpandableNotificationRow")) try { - Object notification = XposedHelpers.getObjectField(XposedHelpers.callMethod(enotificationrow, "getEntry"), "mSbn"); - String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); - int opt = Integer.parseInt(MainModule.mPrefs.getString("system_expandnotifs", "1")); - boolean isSelected = MainModule.mPrefs.getStringSet("system_expandnotifs_apps").contains(pkgName); - if (opt == 2 && !isSelected || opt == 3 && isSelected) - XposedHelpers.callMethod(enotificationrow, "setSystemExpanded", true); - } catch (Throwable t) { - XposedBridge.log(t); - } - } + Helpers.hookAllMethods("com.android.systemui.statusbar.notification.row.ExpandableNotificationRow", lpparam.classLoader, "showFeedbackIcon", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean mOnKeyguard = (boolean) XposedHelpers.callMethod(param.thisObject, "isOnKeyguard"); + if (!mOnKeyguard) { + Object notification = XposedHelpers.getObjectField(XposedHelpers.callMethod(param.thisObject, "getEntry"), "mSbn"); + String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); + int opt = Integer.parseInt(MainModule.mPrefs.getString("system_expandnotifs", "1")); + boolean isSelected = MainModule.mPrefs.getStringSet("system_expandnotifs_apps").contains(pkgName); + if (opt == 2 && !isSelected || opt == 3 && isSelected) + XposedHelpers.callMethod(param.thisObject, "setSystemExpanded", true); } } }); @@ -2744,8 +2732,7 @@ protected void before(MethodHookParam param) throws Throwable { XposedHelpers.callMethod(mService, "reboot", false, "bootloader", false); custom = true; } else if ("softreboot".equals(cmd)) { - Helpers.proxySystemProperties("set", "ctl.restart", "surfaceflinger", null); - Helpers.proxySystemProperties("set", "ctl.restart", "zygote", null); + mContext.sendBroadcast(new Intent(ACTION_PREFIX + "FastReboot")); custom = true; } else if ("killsysui".equals(cmd)) { mContext.sendBroadcast(new Intent(ACTION_PREFIX + "RestartSystemUI")); From 037cf59fc5c1880361d24ca3b6ccb76b8905d18c Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 28 Nov 2022 20:11:57 +0800 Subject: [PATCH 155/627] change screenshots path in Gallery app when screenshots saved folder changes --- .../name/mikanoshi/customiuizer/MainModule.java | 7 +++++++ .../name/mikanoshi/customiuizer/mods/System.java | 15 +++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/arrays.xml | 2 +- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 8 ++++++++ 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 3f167aa7..c86c570e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -419,6 +419,13 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("system_screenshot_floattime", 0) > 0) System.ScreenshotFloatTimeHook(lpparam); } + if (pkg.equals("com.miui.gallery")) { + int folder = mPrefs.getStringAsInt("system_gallery_screenshots_path", 1); + if (folder > 1) { + System.GalleryScreenshotPathHook(lpparam); + } + } + final boolean isMIUILauncherPkg = pkg.equals("com.miui.home"); final boolean isLauncherPkg = isMIUILauncherPkg || pkg.equals("com.mi.android.globallauncher"); final boolean isLauncherPerf = mPrefs.getBoolean("launcher_compat"); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 1c1467d9..8a413c51 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6851,6 +6851,21 @@ protected void before(final MethodHookParam param) throws Throwable { Helpers.hookAllMethods("android.view.WindowManagerGlobal", lpparam.classLoader, "removeView", removeViewHook); } + public static void GalleryScreenshotPathHook(LoadPackageParam lpparam) { + Class MIUIStorageConstants = findClass("com.miui.gallery.storage.constants.MIUIStorageConstants", lpparam.classLoader); + int folder = MainModule.mPrefs.getStringAsInt("system_gallery_screenshots_path", 1); + String ssPath = ""; + if (folder == 2) { + ssPath = Environment.DIRECTORY_PICTURES + File.separator + "Screenshots"; + } + else if (folder == 3) { + ssPath = Environment.DIRECTORY_DCIM + File.separator + "Screenshots"; + } + if (folder > 1) { + XposedHelpers.setStaticObjectField(MIUIStorageConstants, "DIRECTORY_SCREENSHOT_PATH", ssPath); + } + } + public static void ScreenshotFloatTimeHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.miui.screenshot.GlobalScreenshot", lpparam.classLoader, "startGotoThumbnailAnimation", Runnable.class, new MethodHook() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 76f18ba9..b5a9a325 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -164,6 +164,7 @@ 格式 质量 存放目录 + 相册截图目录 截图时隐藏叠加层 当截图时临时隐藏叠加层(请将有叠加层的App加入作用域) 截图后的浮动窗口显示时间 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 79c3afce..95e3f82a 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -881,7 +881,7 @@ com.miui.screenrecorder com.miui.home com.miui.screenshot - miui.systemui.plugin com.mi.android.globallauncher + com.miui.gallery \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6e81e4b7..4a5bf10e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -177,6 +177,7 @@ Format Quality Save folder + Gallery screenshots folder Hide overlays on screenshots Temporarily hide overlays while taking a screenshot(Add apps that have overlays to LSPosed scope first) Floating screenshot display time diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 51ed792c..e55d45ca 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1318,6 +1318,14 @@ android:summary="@string/system_screenshot_overlay_summ" android:defaultValue="false" /> + + Date: Tue, 29 Nov 2022 19:53:31 +0800 Subject: [PATCH 156/627] optimize networkspeed hook --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 73 ++++++++++--------- .../mikanoshi/customiuizer/mods/Various.java | 12 ++- .../mikanoshi/customiuizer/utils/Helpers.java | 4 - .../customiuizer/utils/ResourceHooks.java | 1 + .../main/res/layout/statusbar_text_icon.xml | 10 +++ 6 files changed, 56 insertions(+), 45 deletions(-) create mode 100644 app/src/main/res/layout/statusbar_text_icon.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c86c570e..321e061f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -182,6 +182,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { } if (pkg.equals("com.android.systemui")) { + System.setupStatusBar(lpparam); GlobalActions.setupStatusBar(lpparam); if (mPrefs.getBoolean("system_screenshot_overlay")) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 8a413c51..063d1e1c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1390,11 +1390,13 @@ public static void TrafficSpeedSpacingHook(LoadPackageParam lpparam) { protected void after(MethodHookParam param) throws Throwable { TextView meter = (TextView)param.thisObject; if (meter == null) return; - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)meter.getLayoutParams(); - int margin = Math.round(meter.getResources().getDisplayMetrics().density * 4); - lp.rightMargin = margin; - lp.leftMargin = margin; - meter.setLayoutParams(lp); + if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)meter.getLayoutParams(); + int margin = Math.round(meter.getResources().getDisplayMetrics().density * 4); + lp.rightMargin = margin; + lp.leftMargin = margin; + meter.setLayoutParams(lp); + } } }); } @@ -1649,22 +1651,24 @@ public static void DetailedNetSpeedHook(LoadPackageParam lpparam) { @Override protected void after(final MethodHookParam param) throws Throwable { TextView meter = (TextView)param.thisObject; - float density = meter.getResources().getDisplayMetrics().density; - int font = Integer.parseInt(MainModule.mPrefs.getString("system_detailednetspeed_font", "3")); - float size = 8.0f; - float spacing = 0.9f; - int top = 0; - switch (font) { - case 1: size = 9f; spacing = 0.85f; top = Math.round(density);break; - case 2: size = 8.5f; break; - case 4: size = 7.5f; break; - } - meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size); - meter.setSingleLine(false); - meter.setLines(2); - meter.setMaxLines(2); - meter.setLineSpacing(0, spacing); - meter.setPadding(meter.getPaddingLeft(), meter.getPaddingTop() - top, meter.getPaddingRight(), meter.getPaddingBottom()); + if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { + float density = meter.getResources().getDisplayMetrics().density; + int font = Integer.parseInt(MainModule.mPrefs.getString("system_detailednetspeed_font", "3")); + float size = 8.0f; + float spacing = 0.9f; + int top = 0; + switch (font) { + case 1: size = 9f; spacing = 0.85f; top = Math.round(density);break; + case 2: size = 8.5f; break; + case 4: size = 7.5f; break; + } + meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size); + meter.setSingleLine(false); + meter.setLines(2); + meter.setMaxLines(2); + meter.setLineSpacing(0, spacing); + meter.setPadding(meter.getPaddingLeft(), meter.getPaddingTop() - top, meter.getPaddingRight(), meter.getPaddingBottom()); + } } }); boolean reduceVis = MainModule.mPrefs.getBoolean("system_detailednetspeed_zero"); @@ -5060,13 +5064,11 @@ protected void before(final MethodHookParam param) throws Throwable { } }); } - private static TextView createBatteryDetailView(Context mContext, Class NetworkSpeedViewClass, LinearLayout.LayoutParams lp) { - TextView batteryView = (TextView) XposedHelpers.newInstance(NetworkSpeedViewClass, mContext, null); - batteryView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); + private static TextView createBatteryDetailView(Context mContext, LinearLayout.LayoutParams lp) { + TextView batteryView = (TextView) LayoutInflater.from(mContext).inflate(statusbarTextIconLayoutResId, null); XposedHelpers.setObjectField(batteryView, "mVisibilityByDisableInfo", 0); XposedHelpers.setObjectField(batteryView, "mVisibleByController", true); XposedHelpers.setObjectField(batteryView, "mShown", true); - batteryView.setSingleLine(false); XposedHelpers.setAdditionalInstanceField(batteryView, "mCustomSlot", "battery_detail"); Resources res = mContext.getResources(); int styleId = res.getIdentifier("TextAppearance.StatusBar.Clock", "style", "com.android.systemui"); @@ -5075,12 +5077,11 @@ private static TextView createBatteryDetailView(Context mContext, Class Netw if (opt == 1) { batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 8.5f); batteryView.setLineSpacing(0, 0.9f); + batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); } else { batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13.45f); - batteryView.setLineSpacing(0, 1.0f); } - batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); int horizonMargin = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 2.5f, @@ -5137,8 +5138,11 @@ else if (opt == 2) { }; handler.post(refreshRunner); } + private static int statusbarTextIconLayoutResId = 0; + public static void setupStatusBar(LoadPackageParam lpparam) { + statusbarTextIconLayoutResId = MainModule.resHooks.addResource("statusbar_text_icon", R.layout.statusbar_text_icon); + } public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { - Class NetworkSpeedViewClass = XposedHelpers.findClass("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader); Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); Class StatusBarIconHolder = XposedHelpers.findClass("com.android.systemui.statusbar.phone.StatusBarIconHolder", lpparam.classLoader); @@ -5172,7 +5176,7 @@ protected void before(MethodHookParam param) throws Throwable { if (type == 91) { Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) XposedHelpers.callMethod(param.thisObject, "onCreateLayoutParams"); - TextView batteryView = createBatteryDetailView(mContext, NetworkSpeedViewClass, lp); + TextView batteryView = createBatteryDetailView(mContext, lp); int i = (int) param.args[0]; ViewGroup mGroup = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mGroup"); mGroup.addView(batteryView, i); @@ -5181,7 +5185,8 @@ protected void before(MethodHookParam param) throws Throwable { } } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, "getSlot", new MethodHook() { + Class NetworkSpeedViewClass = XposedHelpers.findClass("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader); + Helpers.findAndHookMethod(NetworkSpeedViewClass, "getSlot", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customSlot = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomSlot"); @@ -5200,7 +5205,7 @@ protected void after(MethodHookParam param) throws Throwable { ViewGroup batteryViewContainer = (ViewGroup) mPadClockView.getParent(); int bvIndex = batteryViewContainer.indexOfChild(mPadClockView) - 1; LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mPadClockView.getLayoutParams(); - TextView batteryView = createBatteryDetailView(mContext, NetworkSpeedViewClass, lp); + TextView batteryView = createBatteryDetailView(mContext, lp); batteryViewContainer.addView(batteryView, bvIndex); mBatteryDetailViews.add(batteryView); Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); @@ -6407,10 +6412,10 @@ protected void before(MethodHookParam param) throws Throwable { } public static void NoNetworkSpeedSeparatorHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.views.NetworkSpeedSplitter", lpparam.classLoader, "init", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.views.NetworkSpeedSplitter", lpparam.classLoader, "updateVisibility", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - ((TextView)param.thisObject).setText(""); + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "mNetworkSpeedVisibility", View.GONE); } }); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 33b00738..09e9711a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -322,18 +322,17 @@ protected void before(final MethodHookParam param) throws Throwable { param.args[0] = checkBundle((Context)param.thisObject, (Bundle)param.args[0]); // Bruteforce class on MIUI 12.5 - if (Helpers.is125()) { - String fragCls = null; - Class xfragCls = findClassIfExists("androidx.fragment.app.Fragment", lpparam.classLoader); - Field[] fields = param.thisObject.getClass().getDeclaredFields(); - for (Field field: fields) + String fragCls = null; + Class xfragCls = findClassIfExists("androidx.fragment.app.Fragment", lpparam.classLoader); + Field[] fields = param.thisObject.getClass().getDeclaredFields(); + for (Field field: fields) if (Fragment.class.isAssignableFrom(field.getType()) || (xfragCls != null && xfragCls.isAssignableFrom(field.getType()))) { fragCls = field.getType().getCanonicalName(); break; } - if (fragCls != null) + if (fragCls != null) Helpers.hookAllMethods(fragCls, lpparam.classLoader, "onActivityCreated", new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { @@ -344,7 +343,6 @@ protected void before(final MethodHookParam param) throws Throwable { } } }); - } } }); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 0af27579..583bc865 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -237,10 +237,6 @@ public static boolean is12() { return true; } - public static boolean is125() { - return true; - } - public static boolean isNightMode(Context context) { return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index e5d532cd..73b295ff 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -53,6 +53,7 @@ private void applyHooks() { if (hooksApplied) return; hooksApplied = true; Helpers.findAndHookMethod(Resources.class, "getInteger", int.class, mReplaceHook); + Helpers.findAndHookMethod(Resources.class, "getLayout", int.class, mReplaceHook); Helpers.findAndHookMethod(Resources.class, "getFraction", int.class, int.class, int.class, mReplaceHook); Helpers.findAndHookMethod(Resources.class, "getBoolean", int.class, mReplaceHook); Helpers.findAndHookMethod(Resources.class, "getDimension", int.class, mReplaceHook); diff --git a/app/src/main/res/layout/statusbar_text_icon.xml b/app/src/main/res/layout/statusbar_text_icon.xml new file mode 100644 index 00000000..54129ace --- /dev/null +++ b/app/src/main/res/layout/statusbar_text_icon.xml @@ -0,0 +1,10 @@ + + From ffd8c8ddfe3f5622cf13325a2134150d8a602898 Mon Sep 17 00:00:00 2001 From: uvzen <80232276+uvzen@users.noreply.github.com> Date: Tue, 29 Nov 2022 21:00:48 +0100 Subject: [PATCH 157/627] Add Polish translations Polish language --- app/src/main/res/values-pl-rPL/strings.xml | 1120 ++++++++++++++++++++ 1 file changed, 1120 insertions(+) create mode 100644 app/src/main/res/values-pl-rPL/strings.xml diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml new file mode 100644 index 00000000..9c066c24 --- /dev/null +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -0,0 +1,1120 @@ + + CustoMIUIzer13 + O aplikacji + Wersja %1$s + by Mikanoshi & MonwF + Ogólnie rzecz biorąc, modyfikacje wymagają ponownego uruchomienia urządzenia, aby były aktywowane lub dezaktywowane, ale te oznaczone ⟲ wymagają tylko jednego ponownego uruchomienia, a po zmianie ich wartości z domyślnej na niestandardową, kolejne zmiany są stosowane natychmiast. + Modyfikacje oznaczone ⨯ nie są obsługiwane na tym urządzeniu. + @string/app_name + + Odłożone powiadomienia + Aktualizacja + Odłóż to powiadomienie + Oznacz jako odrzucone + Oznacz jako oczekujące + Nie można pobrać listy odłożonych powiadomień + Brak odłożonych powiadomień + Wiadomości + Kanał + Utworzony + Zaktualizowany + Repost + + Modyfikacje + Działania + + Aktywuj mod + System + Ekran + Obrót + Podświetlenie + Audio + Wibracje + Toasts + Ukryj ikony + Zarządzaj widocznością ikon na pasku stanu + Pokaż standard Wi-Fi + Ikona baterii + Procent naładowania baterii + Wskaźnik ładowania + Może być nałożone na ikonę baterii w niektórych ROMach + Alarm + Ukryj się całkowicie + Selektywna widoczność ikony alarmu + Pokazuj ikonę alarmu tylko przez określoną liczbę godzin przed następnym alarmem + Sygnał sieci komórkowej + Brak karty SIM + VoLTE + VoWiFi + Roaming + VPN + NFC + Hotspot + Profil roboczy + Profile dźwiękowe + Tryb nie przeszkadzać + Tryb incognito + Zestaw słuchawkowy + Połączenie: wyciszony mikrofon + Połączenie: zestaw głośnomówiący + Połączenie: nagrywanie + Wskaźnik paska baterii + Wyświetl poziom naładowania baterii jako kolorowy pasek + Ograniczona widoczność + Pokaż tylko w szufladzie powiadomień i na ekranie blokady + Zaokrąglone końcówki + Wyśrodkowany + Bar height + Horizontal padding + Kolor pełnego naładowania + Kolor niskiego naładowania + Kolor oszczędzania baterii + Kolor ładowania + Niski poziom naładowania + Test + Animuj pasek od 100% do 0% w stanie rozładowania + Wysokość paska stanu + Kolor tła paska stanu + W miarę możliwości ustaw takie same kolory tła paska stanu i paska akcji aplikacji + Czarna lista + Skróty aplikacji + Otwórz wybraną aplikację na ikonie skrótu w nagłówku szuflady powiadomień + Aplikacja zegara + Otwórz wybraną aplikację po dotknięciu zegara w nagłówku szuflady powiadomień + Aplikacja kalendarza + Otwórz wybraną aplikację po dotknięciu daty w nagłówku szuflady powiadomień + Pokaż sekundy + Wyświetlaj sekundy w zegarze na pasku stanu + Limit ikon powiadomień + Liczba ikon powiadomień do wyświetlenia przed zamianą ich w kropki + Ukryj typ sieci komórkowej + Usuń ikonę typu sieci komórkowej z paska stanu + Wskaźniki ruchu sieciowego + Skonfiguruj dane mobilne i wskaźnik ruchu Wi-Fi + Pokaż ikonę LTE dla 4G + Brak wskaźnika ukrytych ikon + Nie pokazuj ikony z trzema kropkami, gdy ikony powiadomień są ukryte + Separator prędkości sieci + Nie pokazuj pionowej linii między czasem a szybkością sieci na urządzeniach z notchem w kształcie kropli wody + Częstotliwość aktualizacji prędkości sieci + Szczegółowy wskaźnik prędkości sieci + Pokaż osobno prędkości sieci przychodzącej i wychodzącej + Rozmiar czcionki + Ikony wskaźników + Ikony ruchu przychodzącego/wychodzącego wyświetlane obok wartości prędkości (nie wszystkie niestandardowe czcionki mają każdą ikonę) + Ukryj niską prędkość + Nie pokazuj wskaźnika, jeśli prędkość jest niska + Niski poziom prędkości + Wartości prędkości poniżej tego poziomu będą uważane za niskie i będą oznaczone inną ikoną wskazania + Zmniejsz widoczność, gdy nie jest aktywny + Ustaw wskaźnik na półprzezroczysty, gdy obie prędkości są równe zeru + Ukryj przyrostek bajtów na sekundę (B/s) + Sterowanie gestami + Wykonaj wybrane czynności, przesuwając i dwukrotnie stukając + Czułość regulacji + Jasność + Głośność + Poziome przesuwanie jednym palcem + Poziome przesuwanie dwoma palcami + Akcja podwójnego dotknięcia + Odstęp prędkości sieci + Zwiększ poziome marginesy dla wskaźnika prędkości sieci + Pokaż ważność powiadomienia + Kompaktowe powiadomienia + Zmniejsz pionowe odstępy powiadomień + Kolorowy tytuł powiadomienia + Zastosuj kolor ikony do tytułu (tylko styl powiadomień Androida) + Przywróć zwinięty minimalistyczny widok + Powiadomienia o minimalnym znaczeniu można ponownie zwinąć w jednym wierszu + Otwórz ustawienia kanału + Otwarcie ustawień z menu powiadomień prowadzi do ustawień kanału zamiast typowych ustawień powiadomień aplikacji + Maksymalna liczba linii w stylu przesyłania wiadomości + Ogranicz liczbę wyświetlanych linii w powiadomieniach w stylu wiadomości + Ukryj przycisk czyszczenia + Usuń przycisk, który usuwa wszystkie powiadomienia + Pokaż poziom oświetlenia + Wyświetl wartość natężenia oświetlenia otoczenia w luksach wewnątrz suwaka jasności + Styl alternatywny + Duży, półprzezroczysty tekst + Pokaż procent jasności + Wyświetl poziom jasności w procentach podczas przeciągania suwaka jasności + Górny margines panelu procentowego + Spójny styl suwaka jasności + Usuń cień i dodatkowe tło z suwaka podczas zmiany jasności + Dezaktywuj suwak jasności + Rozszerzone menu powiadomień + Otwórz informacje o aplikacji i wymuś zamknięcie aplikacji z menu powiadomień (przesuń powiadomienie w lewo, aby je otworzyć) + Informacje o aplikacji + Wymuś zamknięcie + Wyłącz wszelkie powiadomienia + Pozwól też wyłączyć powiadomienia systemowe + Rozwiń powiadomienia + Pokaż powiadomienia w pełni rozwinięte + Czarna & biała lista + Modyfikacja czasu wyświetlania + Zmienia zarówno krótkie, jak i długie czasy trwania + Wynikający z tego czas trwania nie spadnie poniżej 1 sekundy + Automatyczne powiadomienia grupowe + Liczba powiadomień z jednej aplikacji, która uruchamia automatyczne grupowanie + Menedżer odłożonych powiadomień + Zwiększ liczbę interwałów drzemki i dodaj ikonę do launchera, który otwiera listę aktualnie odłożonych powiadomień + Wycisz, jeśli jest widoczny + Nie odtwarzaj dźwięku powiadomienia, jeśli ekran jest włączony + Suwak pozycji mediów + Dodaj suwak powiadomień multimedialnych, który wskazuje aktualną pozycję i pozwala ją zmienić + Użyj stylu systemowego + Nie stosuj niestandardowego cienkiego stylu do suwaka + Automatycznie otwierana szuflada powiadomień + Automatycznie otwieraj szufladę powiadomień w przypadku powiadomień z wybranych aplikacji + Uwzględnij pełny ekran + Nie otwieraj szuflady powiadomień, gdy aplikacja pełnoekranowa jest aktywna (nie dotyczy aplikacji immersyjnych z ukrytymi paskami stanu i nawigacji) + Wybrane aplikacje + Zwiń tytuły MIUI + Skonfiguruj stan tytułu paska akcji we wszystkich aplikacjach MIUI 12 + Zrzuty ekranu + Konfiguracja zrzutów ekranu + Dostosuj format, jakość i zapisz ścieżkę folderu dla zrzutów ekranu + Format + Jakość + Zapisz folder + Ukryj nakładki na zrzutach ekranu + Tymczasowo ukryj nakładki podczas robienia zrzutu ekranu (najpierw dodaj aplikacje z nakładkami do LSPosed Scope) + Pływający czas wyświetlania zrzutu ekranu + Opóźnienie przed zniknięciem pływającego okna z nowo utworzonym zrzutem ekranu + Limit czasu ładowania ekranu animacji + Jak długo ekran powinien być włączony po rozpoczęciu animacji ładowania + Brak podświetlenia ekranu podczas ładowania + Nie włączaj ekranu podczas podłączania lub odłączania ładowarki + Nie podświetlaj ekranu po podłączeniu zestawu słuchawkowego + Nie włączaj ekranu po podłączeniu zestawu słuchawkowego + Limit czasu wyłączenia ekranu na ekranie blokady + Czas trwania DIM + Jak długo ekran powinien pozostać przyciemniony przed automatycznym wyłączeniem (w procentach całkowitego czasu wyłączenia ekranu) + Automatyczny zakres jasności + Zdefiniuj minimalne i maksymalne wartości automatycznej jasności + Minimalna automatyczna jasność + Maksymalna automatyczna jasność + Tłumik dźwięku + Wycisz wszystkie dźwięki, które można jednoznacznie zidentyfikować + Odśwież listę + Pobierz listę ostatnio odtwarzanych dźwięków + Wyciszone dźwięki + Odtworzone dźwięki + Wyłącz ostrzeżenie o wysokim poziomie głośności + Nie pokazuj okna dialogowego, gdy głośność osiągnie niebezpieczny poziom + Wyłącz ducking + Nie zmniejszaj głośności aktualnie odtwarzanej muzyki, aby odtworzyć dźwięk powiadomienia + Natychmiastowa regulacja głośności + Dostosuj głośność strumienia multimediów przy pierwszym naciśnięciu klawisza + Oddzielne regulatory głośności + Pozwól skonfigurować osobną głośność dla dzwonków/powiadomień/dźwięków systemowych w ustawieniach + Suwak głośności powiadomień + Dodaj suwak powiadomień do rozszerzonego okna dialogowego głośności + Brak wyciszenia multimediów + Nie ustawiaj głośności multimediów na zero w trybie nie przeszkadzać + Przełącznik trybu DND + Ustaw przycisk w zwiniętym oknie dialogowym głośności, aby przełączać tryb nie przeszkadzać zamiast trybu cichego + Wydłużone timery + Dodaj więcej interwałów do timerów dla trybu cichego i trybu nie przeszkadzać + Opóźnienie automatycznego ukrywania okna dialogowego głośności + Zwinięty + Rozwinięty + Mnożnik poziomów głośności + Zmień liczbę poziomów głośności dla każdego typu strumienia + Wizualizator muzyki + Wyświetl widma gęstości dla pasm częstotliwości audio + Wizualizator jest wyświetlany w górnej części tapety ekranu blokady + Pokaż na niestandardowym ekranie blokady + Narysuj wizualizator w górnej części niestandardowego ekranu blokady + Pokaż w szufladzie powiadomień + Dodatkowo wyświetl wizualizator w rozszerzonej szufladzie powiadomień + Pokaż tylko, jeśli istnieje kontroler multimediów + Odtwarzacze audio zwykle tworzą je dla powiadomień za pomocą elementów sterujących multimediami + Czas trwania animacji + Przezroczystość + Metoda renderowania + Styl + Blask + Kolor + Wybierz niestandardowy kolor + Dynamiczny interwał zmiany koloru + Ignoruj połączenia + Zapobiegaj kradzieży fokusu audio przez połączenia przychodzące, gdy jest w wybranych aplikacjach, i przestań powiadamiać ich o zmianach stanu połączenia + Brak wibracji testowych + Nie wibruj podczas przełączania trybu dzwonka na cichy lub włączania wibracji w tym trybie + Stłumione wibracje + Zmniejsz intensywność wibracji w wybranych godzinach + Intensywność wibracji + Zmienia czas trwania lub siłę wibracji w zależności od kontroli amplitudy obsługiwanej przez urządzenie + Połączenia + Powiadomienia + Wszystko inne + Okres czasu + Zablokuj wibracje + Zapobiegaj korzystania z wibracji przez wybrane aplikacje + Dźwięki systemowe + Wymieszaj PIN + Losowo zmieniaj kolejność przycisków dla kodu PIN + Zaawansowana blokada ekranu + Wyłącz menu zasilania, gdy blokada ekranu jest aktywna + Bezpieczne centrum sterowania + Wyłącz centrum sterowania, gdy blokada ekranu jest aktywna + Bezpieczne szybkie ustawienia + Wyłącz kafelki, które są ważne dla bezpieczeństwa, gdy blokada ekranu jest aktywna + Wszystkie kafelki od stron trzecich + Edycja kafelek + Nie dotyczy centrum sterowania + Trzymaj otwarte + Nie zwijaj panelu po odblokowaniu + Kafelki bezpieczeństwa + Tryb samolotowy + Lokalizacja + Synchronizacja + Brak hasła po uruchomieniu + Nie wymagaj hasła zamiast odcisku palca po pierwszym uruchomieniu. Mało prawdopodobne, aby zadziało na zaszyfrowanych urządzeniach. + Okładka albumu jako tapeta + Wyświetl okładkę albumu aktualnie odtwarzanego utworu jako tapetę ekranu blokady + Skala szarości + Konwertuj okładkę albumu na czarno-biały obraz + Rozmycie okładki albumu + Skala okładki albumu + Unlock dane uwierzytelniające + Uwierzytelnianie w niektórych aplikacjach wymaga dostępu do danych uwierzytelniających, ale pozostają one zablokowane, jeśli kod PIN/hasło/wzór zostanie pominięty po uruchomieniu. Bieżąca opcja dodaje ikonę launchera, która umożliwia odblokowanie danych uwierzytelniających. + Niestandardowe akcje + Konfigurowalne akcje dla skrótów i przeciągnięć + Wyłącz gest przeciągnięcia w lewo + Akcja po przesunięciu palcem w lewo + Zmień prawą ikonę + Zastąp ikonę aparatu ikoną CustoMIUIzer + Przeciągnij ikonę, aby wykonać niestandardową akcję + Wyłącz gest przeciągnięcia palcem w prawo + Skróty w lewej części ekranu + Zarządzaj listą skrótów + Wyrównanie w pionie + Wyśrodkuj poziomo + Nie wymagaj odblokowania + Dostęp do uruchomionych aplikacji można uzyskać, gdy urządzenie jest nadal zablokowane + Wyłącz blokadę ekranu + Niektóre urządzenia mogą nie działać bez odblokowania raz po uruchomieniu + Selektywnie wyłącz blokadę ekranu (nie zmienia zabezpieczeń dla żadnych aplikacji i nie usuwa danych odcisków palców) + Pomiń ekran blokady + Nie pokazuj ekranu blokady, gdy blokada ekranu jest wyłączona + Pomiń rozpoznawanie twarzy + Nie uruchamiaj rozpoznawania twarzy, gdy blokada ekranu jest wyłączona + Zaufane sieci Wi-Fi + Tymczasowo wyłącz blokadę ekranu podczas połączenia z tymi sieciami + Zaufane urządzenia Bluetooth + Tymczasowo wyłącz blokadę ekranu, gdy te urządzenia są połączone + Wymuszone zablokowanie + Wymuszone odblokowanie + Nie wymuszaj + Wyłączanie animacji + Skonfiguruj długość animacji + Bardzo niskie wartości wyłączają animację + Rozmycie tła + Intensywność rozmycia tła w ostatnich aplikacjach + Intensywność rozmycia tła w szufladzie powiadomień + Tymczasowo ukryj tematyczne tło + Ukryj tło podczas zmiany jasności + Przezroczystość tematycznego tła + Przezroczystość tematycznego tła w szufladzie powiadomień + Ekran blokady + Dodatkowa funkcjonalność + Bezpieczeństwo + Dodatkowe elementy + Dodaj ikonę i etykietę aplikacji do jej toastów + Zablokuj toasty + Zapobiegaj wyświetlaniu toastów przez wybrane aplikacje + Konfiguracja trybu samolotowego + Zdefiniuj dozwolone połączenia w trybie samolotowym. Nie wymaga ponownego uruchomienia. + Modyfikacja zmienia tylko istniejące ustawienia systemowe, niektóre opcje mogą nie działać + Kafelek 5G + Dodaj kafelek 5G do panelu szybkich ustawień + Zobacz hasło zapisanej sieci Wi-Fi + Podgląd + Hasło + Szczegóły Wi-Fi + Wyłącz wymuszony tryb ciemny + Nie odwracaj niektórych kolorów w trybie ciemnym + Zaawansowane menu zasilania + Dodaj nowe opcje restartu do menu zasilania (tryb fastboot, tryb odzyskiwania, restart) + Zezwalaj na obniżenie wersji + Spraw, aby instalacja starszej wersji aplikacji była możliwa na nowszej + Wyłącz weryfikację podpisu + Zezwalaj na aktualizowanie aplikacji, nawet jeśli podpis pliku APK różni się od podpisu zainstalowanego + Lupa tekstowa + Wyświetlaj powiększony tekst podczas przesuwania kursora wejściowego lub dokonywania wyboru + Wyłącz nadmierne przewijanie + Zapobiegaj nadmiernemu przewijaniu widoków listy + Wyłącz ochronę bezpiecznej zawartości + Zezwalaj na zrzut ekranu i nagrywanie wideo dowolnej aplikacji + Ukryj ostrzeżenie o niskim poziomie baterii + Nie wyświetlaj okna dialogowego ostrzeżenia z prośbą o włączenie Oszczędzania baterii + Ukryj ostrzeżenie o wyłączonych dotknięciach + Nie wyświetlaj ostrzeżenia, że obszar słuchawek jest zasłonięty + Dowolna zmiana rozmiaru widżetu + Usuń wszelkie ograniczenia rozmiaru widżetu + Odblokuj launcher + Usuń ograniczenia launcherów innych firm na chińskich ROMach + Wyczyść menu udostępniania + Usuń wybrane aplikacje z menu udostępniania + Menu testowe + Wyczyść menu Otwórz za pomocą + Usuń wybrane aplikacje z menu Otwórz za pomocą + Wybierz testowy typ danych + Wybierz typ danych do ukrycia + Domyślna konfiguracja USB + Zastosuj wybraną konfigurację po podłączeniu innego urządzenia + Ignoruj blokadę + Zastosuj, nawet jeśli urządzenie jest nadal zablokowane + RNDIS (USB Tethering) + MIDI + MTP (Przesyłanie plików) + PTP (Przesyłanie obrazów) + Zapobiegaj wymuszaniu zamknięcia aplikacji + Nie zezwalaj MIUI na zamykanie wybranych aplikacji + Animacja rotacji + Wszystkie rotacje + Zezwalaj na wszystkie obroty ekranu, w tym odwrócenie portretu + Blokada orientacji + Dodaj kafelek szybkich ustawień, który może blokować orientację w trybie pionowym lub poziomym + Zachowaj powiadomienia + Pokazuj powiadomienia na ekranie blokady nawet po jego odrzuceniu i ponownym otwarciu + Więcej powiadomień + Zwiększ limit aktywnych powiadomień dla pojedynczej aplikacji z 10 do 24 + Bezpośrednia odpowiedź bez odblokowania + Nie wymagaj odblokowania urządzenia, aby użyć bezpośredniej odpowiedzi na ekranie blokady + Zezwól na ekranie blokady + Wymuś wyświetlanie wszystkich powiadomień z aplikacji MIUI na ekranie blokady + Zezwalaj jako pływające powiadomienia + Wymuś wyświetlanie wszystkich powiadomień z aplikacji MIUI jako pływające powiadomienia + Ukryj pasek stanu + Usuń pasek stanu z ekranu blokady + Ukryj blok górny + Usuń górny blok zawierający zegar, datę i inne dane + Ukryj wskazówkę dotyczącą odblokowania + Usuń wskazówkę "Przesuń w górę, aby odblokować". + Brak połączeń alarmowych + Wyłącz przycisk połączenia alarmowego na ekranie blokady + Zastosuj tapetę za pomocą dowolnej aplikacji + Spraw, aby aplikacje innych firm mogły ustawiać tapetę ekranu blokady. Aplikacja Motywy musi być zainstalowana i mieć uprawnienia dostępu do pamięci masowej. + Wyczyść widok trybu rozszerzonego + Ukryj szybkie ustawienia i suwak jasności w rozszerzonym trybie powiadomień na ekranie blokady + Wyłącz kolorowe tło + Zmień tło z automatycznie generowanym kolorem z tapety na przezroczysty na ekranie blokady + Dotknij, aby odblokować + Rozpocznij odblokowywanie urządzenia, dotykając dolnego obszaru ekranu blokady + Dotknij dwukrotnie, aby uśpić + Wyłącz ekran, dotykając dwukrotnie pustego miejsca na ekranie blokady + Wyświetlanie danych dotyczących ładowania + Wyświetlaj dodatkowe informacje o ładowaniu w dolnej części ekranu blokady + Sposób wyświetlania + Prąd ładowania + Napięcie baterii + Pobór energii + Temperatura baterii + Wyświetl następny alarm + Pokaż najbliższą godzinę alarmu obok daty + Format wyswietlania + Pokaż wszystkie alarmy + Uzyskaj czas następnego alarmu, korzystając z domyślnego interfejsu API systemu Android, gdy alarm MIUI nie jest ustawiony. Może przynieść nieoczekiwane rezultaty. + Pasek stanu i szuflada powiadomień + Pasek stanu + Szuflada powiadomień + Powiadomienia + Lista ostatnich aplikacji + Użyj natywnej implementacji + Nie używaj listy ostatnich aplikacji z Launchera MIUI. Źle działa z gestami pełnoekranowymi. + Usuń przycisk czyszczenia + Ukryj przycisk, który usuwa ostatnie aplikacje i czyści pamięć + Wyczyść wszystko + Spraw, aby przycisk czyszczenia zabił wszystkie uruchomione zadania + Ukryj przed ostatnimi + Ukryj wybrane aplikacje z listy ostatnich zadań + Pierwsze działanie skrótu + Działanie dla skrótu pierwszej sugestii + Drugie działanie skrótu + Działanie dla drugiego skrótu sugestii + Trzecie działanie skrótu + Działanie dla trzeciego skrótu sugestii + Czwarte działanie skrótu + Działanie dla skrótu czwartej sugestii + Wyskakujące powiadomienia + Opóźnienie automatycznego chowania + Brak automatycznego chowania + Nie odrzucaj automatycznie wyskakujących okienek + Zezwalaj na pływające okno + Otwórz aplikację w pływającym oknie gestem przeciągnięcia w dół, jeśli powiadomienie ma zdefiniowaną odpowiednią akcję kliknięcia + Włącz przesuwanie w dół + Otwórz szufladę powiadomień gestem przeciągnięcia w dół + Pokaż wyśrodkowane + Wyświetlaj wyskakujące okienka na środku ekranu + Pływające okna i podzielony ekran + Wyłącz umieszczanie na czarnej liście + Zezwalaj na otwieranie dowolnej aplikacji w pływającym oknie + Zapamiętaj stan + Otwieraj aplikacje w ruchomych oknach, dopóki nie zostaną przełączone z powrotem do trybu pełnoekranowego + Multiwindow+ + Zezwalaj na jednoczesne używanie podzielonego ekranu i pływających okien, wyłącz backlistę dla podzielonego ekranu + Blokada aplikacji + Mniej rygorystyczna blokada aplikacji + Nie blokuj aplikacji, gdy urządzenie jest zablokowane, jeśli wybrana jest opcja z blokadą aplikacji po wyjściu + Limit czasu blokady aplikacji + Przedział czasu, w którym aplikacja pozostaje odblokowana po zamknięciu + Lista aplikacji do zablokowania + Zaawansowana wersja opcji blokady aplikacji, która pozwala zablokować dowolną zainstalowaną aplikację. Nie jest wymagane ponowne uruchomienie. + Pomiń blokadę aplikacji + Zezwalaj wybranym czynnościom na omijanie blokady aplikacji + Wybrane czynności + Szybkie ustawienia + Centrum sterowania + Liczba rzędów + Etykiety będą ukryte przez 5 wierszy w orientacji pionowej. Liczba wierszy jest ograniczona do 3 z ukrytymi etykietami w orientacji poziomej. + Liczba kolumn + Orientacja pozioma będzie miała jedną dodatkową kolumnę. Jeśli twój ROM ma kompaktową opcję układu szybkich ustawień, doda kolejną kolumnę w obu orientacjach. + Liczba kolumn w zwiniętym panelu + Orientacja pozioma będzie miała jedną dodatkową kolumnę. + Całkowicie usuń etykiety + Reakcje haptyczne w panelu szybkich ustawień + Wibruj po dotknięciu kafelka szybkie ustawień + Inne + Rozmycie tła okna dialogowego głośności + Zwinięte okno dialogowe + Rozwinięte okno dialogowe + Skala animacji + Okna + Przejścia + Wartości animatorów + + POCO Launcher + MIUI Launcher + Gesty + Czynność + Ustawienie do przełączania + Aplikacja do uruchomienia + Skrót do uruchomienia + Działanie do uruchomienia + Launcher + Wyświetl modyfikacje dla wybranego launchera. Tylko dla pomocy wizualnej, nie ma żadnego wpływu na modyfikacje. + Tryb wydajności + Alternatywna metoda zastosowania wszystkich modyfikacji launchera + Nieskończone przewijanie + Przeskakuj z ostatniej strony na pierwszą i odwrotnie + Nie ukrywaj zegara + Nie ukrywaj zegara paska stanu na stronach z widżetami zegara + Włącz -1 przełącznik ekranu + Wyświetlaj przełączanie między App Vault i Google Discover w ustawieniach ekranu głównego + Wymaga globalnej (międzynarodowej) pamięci ROM + Wymuś Google Discover + Zamień App Vault na Google Discover (wymaga zainstalowania aplikacji Google) + Wyłącz ekran tylko z widżetami + Spraw, aby wszystkie ekrany obsługiwały zarówno widżety, jak i aplikacje na tabletach + Usuń animację odblokowania + Nie animuj ikon, gdy urządzenie jest odblokowane + Usuń animację uruchamiania + Nie powiększaj/pomniejszaj ikon, gdy aplikacja jest zamknięta/otwarta + Użyj starej animacji uruchamiania + Przywróć animację przejścia otwierania aplikacji do poprzedniego + Wsparcie dla odwróconego portretu + Obróć orientację pionową launchera + Dynamiczny wskaźnik strony + Wyświetlaj wskaźnik strony tylko podczas przewijania + Pokaż tylko w trybie edycji + Odblokuj rozmiary siatki + Udostępnij wszystkie rozmiary siatki od 3x4 do 10x10 w ustawieniach układu ekranu głównego + Więcej ikon w docku + Nieograniczona liczba ikon doków + Automatyczne zamykanie szuflady aplikacji + Zamknij szufladę aplikacji po uruchomieniu + Skalowanie ikon + Poziome marginesy siatki + Górny margines siatki + Dolny margines dokowania + Poziomy margines widżetu + Działa tylko z najnowszymi wersjami launchera z dynamicznym pozycjonowaniem widżetów + Wysokość wskaźnika strony + Foldery + Liczba kolumn w folderach + Użyj całej szerokości folderu + Zmniejsz boczną wyściółkę + Napraw tryb paska stanu + Dostosuj kolor zawartości paska stanu dla jasnych/ciemnych tapet w wersji dla programistów + Napraw animację + Zastosuj skalowanie czasu trwania animatorów wartości do niektórych animacji launchera + Napraw informacje o aplikacji + Zawsze otwieraj informacje o aplikacji w stylu MIUI z długiego menu + Kolorowa nakładka + Przyciemnij lub rozjaśnij tło + Intensywność koloru + Rozmycie + Opcje rozmycia tła i tapety. Launcher musi obsługiwać rozmycie w folderach. + Rozmycie tła + Rozmycie tapety + Widoczność + Promień + Wpływa również na rozmycie tapety w trybie edycji + Automatyczne zamykanie folderów + Po uruchomieniu zamknij folder aplikacji + Tytuły aplikacji + Ukryj tytuły + Pokaż tytuły w docku + Rozmiar czcionki + Dodatkowy górny margines + Ciemniejszy odcień + Zmniejsza przezroczystość cienia tytułu + Niestandardowe tytuły aplikacji + Zmodyfikowane tytuły + Zmodyfikowany tytuł + Ukryte aplikacje + Wymagane uprawnienia nie zostały udzielone + Brak ukrytego folderu + Wyłącz gest z dwoma palcami, który otwiera ukryty folder aplikacji + Lista aplikacji do ukrycia + Zaawansowana wersja opcji ukrywania aplikacji, która pozwala ukryć dowolną zainstalowaną aplikację. Nie wymaga restartu urządzenia. + Przeciągnij w dół (1 palec) + Czynność polegająca na przesunięciu w dół jednym palcem na dowolnym ekranie głównym + Przeciągnij w dół (2 palce) + Czynność polegająca na przesunięciu w dół dwoma palcami na dowolnym ekranie głównym + Przesuń w górę (1 palec) + Czynność polegająca na przesunięciu palcem w górę na dowolnym ekranie głównym + Przesuń w górę (2 palce) + Czynność polegająca na przesunięciu w górę dwoma palcami na dowolnym ekranie głównym + Przesuń w prawo + Czynność gestu przesunięcia w prawo w docku launchera + Przesuń w lewo + Czynność gestu przesunięcia w lewo w docku launchera + Wstrząsanie + Czynność polegająca na potrząśnięciu urządzeniem na dowolnym ekranie głównym + Podwójne dotknięcie + Czynność dwukrotnego dotknięcia pustego miejsca na dowolnym ekranie głównym + Uszczypnięcie + Czynność polegająca na zbliżeniu 2 palców do siebie na dowolnym ekranie głównym + Rozszerzanie dwoma palcami + Czynność polegająca na odsunięciu od siebie 2 palców na dowolnym ekranie głównym + Poprawki błędów + + Sterowanie + Podwójnego naciśnięcie + Zastąp uruchamianie aparatu po dwukrotnym naciśnięciu klawisza zasilania. Wymaga włączenia skrótu przycisku akcji. + Wyłącz kombinację zrzutów ekranu + Nie rób zrzutu ekranu, gdy klawisz zasilania jest wciśnięty razem z klawiszem zmniejszania głośności + Latarka + Długie naciśnięcie przycisku zasilania, gdy ekran jest wyłączony, aby włączyć latarkę + Longer quick flashlight delay + Zwiększ opóźnienie długiego naciśnięcia przycisku zasilania + Skaner linii papilarnych + Pojedyncze dotknięcie + Czynność dla pojedynczego dotknięcia, gdy ekran jest włączony + Podwójnego dotknięcie + Czynność dla dwukrotnego dotknięcia, gdy jest włączony + Opóźnienie dla podwójnego dotknięcia + Pojedyncze kliknięcie zostanie opóźnione o tę wartość + Długie naciśnięcie + Czynność dla długiego naciśnięcia, gdy ekran jest włączony + Opóźnienie dla długiego naciśnięcia + Brak działań w aparacie + Włącz tę opcję, jeśli używasz odcisku palca + Brak działań podczas połączeń + Nie wykonuj czynności, gdy połączenie jest aktywne + Odbierz połączenie przychodzące + Odrzuć połączenie przychodzące + Zakończ bieżące połączenie + Akceptacja i odrzucenia nie mogą mieć tej samej kombinacji. + Czynność akceptacji została wyłączona. + Czynność odrzucania została wyłączona. + Włącz ekran po awarii + Podświetl ekran w przypadku nieudanego uwierzytelnienia + Wymagaj odcisku palca + Nie włączaj ekranu, jeśli nie zarejestrowano żadnych odcisków palców + Wibruj, gdy skan odcisku palca przejdzie pomyślnie + Zwrotna reakcja haptyczna po pomyślnym uwierzytelnieniu + Ignoruj ustawienia systemowe + Nie wyłączaj reakcji haptycznych, gdy wibracje przy dotknięciu są wyłączone + Brak wibracji w przypadku awarii + Usuń zwrotną reakcję haptyczną w przypadku niepowodzenia uwierzytelniania + Przycisk zasilania + Przyciski głośności + Kontroluj kursor wejściowy + Przesuń kursor wprowadzania tekstu za pomocą klawiszy głośności + Zmień kierunki + Zamiana kierunków ruchu kursora + Długie naciśnięcie przycisku zwiększania głośności + Ta czynność zwiększania głośność podczas długiego naciśnięcia, gdy ekran jest wyłączony + Długie naciśnięcie przycisku zmniejszania głośności + Ta czynność zmniejszania głośność podczas długiego naciśnięcie, gdy ekran jest wyłączony + Wibracje przy długim naciśnięciu + Wibruj, gdy zostanie wykonane długie naciśnięcie + Pasek nawigacyjny + Ukryj pasek nawigacyjny + Reaktywny przycisk cofania + Przełącz z powrotem ikonę przycisku na alternatywną w trybie wprowadzania + Wysokość paska nawigacyjnego + Długie naciśnięcie przycisku wstecz + Długie naciśnięcie przycisku home + Długie naciśnięcie przycisku menu + Działanie po naciśnięciu lewego dodatkowego przycisku nawigacyjnego + Działanie lewego przycisku + Akcja po długim naciśnięciu lewego dodatkowego przycisku nawigacji + Długie naciśnięcie lewego przycisku + Działanie po naciśnięciu prawego dodatkowego przycisku nawigacyjnego + Działanie prawego przycisku + Czynność na prawym dodatkowym przycisku nawigacji po długim naciśnięciu + Długie naciśnięcie prawego przycisku + Dodatkowy margines + Zwiększ odległość od krawędzi ekranu, aby uzyskać dodatkowe przyciski + Nie zdefiniowano działania + Gesty nawigacyjne na pełnym ekranie + Wysokość obszaru gestów wstecz + Szerokość obszaru gestów wstecz + Gesty poziome + Włącz gesty poziome i pasek nawigacyjny + Akcja przesuwania rogu + Wykonaj wybraną czynność zamiast otwierać Asystenta Google + + Różne + Ukryte funkcje + Działania, które nie zawsze są łatwo dostępne + Niedostępne na tym urządzeniu + Uruchomione usługi + Statystyki pamięci + Użycie pamięci przez aplikację + Statystyki użytkownika + Szukaj + Aplikacje & powiadomienia + Dziennik powiadomień + Wyczyść głośnik + Odblokuj liczbę kl./s + Zwiększ do 90 klatek na sekundę w aplikacji Screen Recorder. To, czy wyższa liczba klatek na sekundę rzeczywiście zadziała, zależy od urządzenia i sterownika wideo. + Użyj instalatora pakietów MIUI + zezwól na aktualizację aplikacji systemowych + Wymagana aplikacja nie jest zainstalowana lub jest wyłączona + Informacje o aplikacji w instalatorze + Wyświetl informacje o aplikacji, która jest instalowana + Pakiet + Nazwa wersji + Kod wersji + Obsługiwane SDK + aktualnie + Kompatybilność z budzikiem + Spraw, by wybrane aplikacje wyświetlały poprawny czas następnego alarmu ustawiony przez aplikację Zegar MIUI + Dolna wyściółka w pozycji pionowej + Dolna wyściółka w pozycji poziomej + Pokaż interfejs połączenia + Zdefiniuj, kiedy interfejs połączenia przychodzącego powinien być wyświetlany zamiast wyskakującego powiadomienia + Jasność ekranu podczas rozmowy + Typy połączeń + Wartość jasności + Tryb nocny + Nie zmieniaj jasności w nocy + Start + Koniec + Przypomnienie o nieodebranym połączeniu + Zdefiniuj dźwięk, wibrację i interwał dla przypomnienia + Interwał + Dźwięk + Brak dźwięku + Własny wzór + Format: opóźnienie,wibracja,opóźnienie,wibracja,… + Pełne ograniczenia + Umożliwia skonfigurowanie oszczędzania baterii i dostępu do Wi-Fi dla aplikacji systemowych + Kontrola stanu aplikacji + Pozwala wyłączyć prawie każdą aplikację ze strony informacji o aplikacji + Pokaż dodatkowe szczegóły aplikacji + Dodaj nowe pola do strony informacji o aplikacji:\n- kod wersji\n- pełna ścieżka do apk\n- ścieżka do danych\n- ID użytkownika\n- docelowa wersja SDK\n- link do Sklepu Play\n- uruchom aplikację + Kolejność sortowania zainstalowanych aplikacji + Wyłączyć aplikację? + Jeśli jest to niezbędna aplikacja systemowa, wyłączenie jej może spowodować uszkodzenie + To zły pomysł! + Nie udało się zmienić stanu aplikacji + + Otwórz w Sklepie Play + Uruchom + Aplikacja nie ma domyślnej aktywności, którą można uruchomić + Nazwa pliku APK + Kod wersji APK + Ścieżka do danych + ID użytkownika + Docelowa wersja SDK + Status (domyślny) + Nazwa aplikacji + Częstotliwość użytkowania + Użycie pamięci + Czas instalacji + + Klawiatura Google + Połączenia + Ustawienia + + Domyślny + System + Brak działania + Rozwiń szufladę powiadomień + Rozwiń panel szybkich ustawień + Zablokuj urządzenie + Uśpij + Zrób zrzut ekranu + Otwórz menu + Open ostatnie + Otwórz okno głośności + Zwiększ głośność + Zmniejsz głośność + Uruchom aplikację + Uruchom skrót + Uruchom działanie + Funkcja przełączania + Przełącz do poprzedniej aplikacji + Wymuś zamknięcie bieżącej aplikacji + Otwórz menu zasilania + Menu zasilania + Wyczyść pamięć + Odwróć kolory + Zmień klawiaturę + Wróć + Tryb jednoręczny (lewa strona) + Tryb jednoręczny (prawa strona) + Wi-Fi + Bluetooth + GPS + NFC + Profil dźwięku + Automatyczna jasność + Auromatyczne obracanie + Latarka + Dane mobilne + WiMAX + Ikona + Etykieta + Ikona i etykieta + None + Fade + Brak zmian + Odtwórz/wstrzymaj + Następny utwór + Poprzedni utwór + AWszystkie zdarzenia związane z ładowaniem + Tylko wydarzenia bez animacji + Domyślne ustawienie systemowe + Wyłącz całkowicie + Wymagaj uwierzytelnienia po uruchomieniu + Wyłącz w zaufanych sieciach/urządzeniach + Nie wymagaj + Słaby (odcisk palca) + Silny (PIN/hasło/wzór) + Brak rozmycia + Brak ikon + △▲▽▼ + ☖ ☗ ⛉ ⛊ + Całe tło + Tylko pośrodku + Dla wszystkich aplikacji z wyjątkiem wymienionych + Tylko dla wymienionych aplikacji + Ukryj tylko wtedy, gdy nie jest podłączony + Ukryj całkowicie + Nie grupuj + Lekkie wibracje + Silne wibracje + Włącz + Wyłącz + Bliżej szczytu + Pośrodku + Bliżej dna + Maksymalny + Wielki + Normalny + Mały + Niski + Średni + Wysoki + Dopasuj okładkę albumu lub tapetęs + Niestandardowy kolor + Kolory tęczy (w poziomie) + Kolory tęczy (w pionie) + Tęcza + Dynamiczny kolor + Oddzielny + Stopniowy + Solidne paski + Solidne zaokrąglone paski + Przerywane paski + Kółka + Linia + Nigdy + Przez 1 dzień po aktualizacji + Przez 3 dni po aktualizacji + Przez tydzień po aktualizacji + Zawsze + Obraz + Audio + Wideo + Dokument + Archiwum + Link + Dowolny + Inne + Gdy nie jest w trybie pełnoekranowym + Przychodzące + Wychodzące + Obydwa + Brak wibracji + Pojedyncza (krótka) + Pojedyncza (długa) + TiK Tak + Bicie serca + Walc + Zig-zig-zig + Własny wzór + Dopasuj do ekranu + Zakryj cały ekran + Na górze + Na dole + Dostosuj jasność + Dostosuj głośność + Regularny czas + Względny czas + Regularny i względny czas + Pojedyncze dotknięcie + Podwójne dotknięcie + Długie naciśnięcie + Nowy Rok + Chiński Nowy Rok + Koronawirus anty-wakacje + Wyświetl tylko + Ukryj + Wykryj automatycznie + drawLines + drawPath + Dodaj + Dodaj przed + Wstaw jako nowy wiersz + Wybierz ścieżkę + Początkowo + Na stałe + Początek sekundy + Koniec sekundy + Sieć komórkowa i dane mobilne + Zostaw tak jak jest + Wyłącz + Wyłącz i dezaktywuj + Tylko temperatura + Tylko bieżące + Bez limitu + + Wi-Fi włączone + Wi-Fi wyłączone + Bluetooth włączone + Bluetooth wyłączone + GPS włączone + GPS wyłączone + Hotspot włączone + Hotspot wyłączone + NFC włączone + NFC wyłączone + Profil dźwięku: Normaly + Profil dźwięku: Cichy + Profil dźwięku: Wibracje + Automatyczna jasność włączona + Automatyczna jasność wyłączona + Automatyczne obracanie włączone + Automatyczne obracanie wyłączone + Latarka: wł + Latarkat: wył + Dane mobilne włączone + Dane mobilne wyłączone + Blokada rotacji + Nieograniczony + Portret + Krajobraz + Sieć 5G + CustoMIUIzer nie ma uprawnień do zmiany trybu ciemnego + + Ustawienia CustoMIUIzera + Zaznacz nowe modyfikacje + Wyświetl \"Nowy!\" etykietę w tytule dla modyfikacji dodanych w bieżącej wersji + Nowy! + Ikona launchera + Pokaż ikonę w launcherach + Tryb LSPosed + Załóżmy, że LSPosed Framework jest zainstalowany, aby poprawnie współpracował z jego menedżerem + Ikona szybkiego dostępu + Pokaż ikonę w Ustawieniach + Język interfejsu + Zawsze wyświetlaj interfejs modułu w wybranym języku + Wakacyjny design + Udekoruj interfejs modułu zgodnie z okazją + + Rozwiązywanie problemów + Wyślij szczegółowy raport + Zbierz informacje o urządzeniu i środowisku, logcat i Xposed log, a następnie wyślij je do programisty. \nWymagane jest połączenie z Internetem + Wprowadź swoje dane kontaktowe, a zostaną one uwzględnione w szczegółowych raportach i raportach o awariach + Dane kontaktowe + Wypełnienie tego pola jest absolutnie konieczne, jeśli oczekujesz odpowiedzi na swoje raporty o awariach. Użyj pseudonimu e-mail, ICQ, XDA lub 4PDA. + + Wsparcie + Kod i problemy + Skontaktuj się ze mną + Wydania + Wydania na Github + Repozytorium Mikanoshi CustoMIUIzer + Repozytorium Git ze źródłami modułów i dystrybucjami + Wątek XDA + Wątek modułu na forach XDA + Wątek 4PDA + Wątek modułu na forach 4PDA + + Zgłoś błąd + Wyślij nam raport o błędzie lub prośbę o dodanie funkcji za pośrednictwem oficjalnego narzędzia do śledzenia problemów + Donate $%1$d + Donate via PayPal + Donate Mikanoshi + Najlepszy sposób, aby wyrazić swoją wdzięczność za ten niesamowity moduł + W aplikacji + Pozwól Google zająć się wszystkim + Przestarzałe waluty + Paypal, Webmoney, QIWI + + Dziękujemy za darowiznę! + Dziękujemy za hojną darowiznę! + Dziękujemy za niesamowicie hojną darowiznę! 😮 + Pobranie informacji rozliczeniowych nie powiodło się. Sprawdź połączenie internetowe + Zmieniłeś zdanie? + + CustoMIUIzer właśnie uległ awarii! + Wszystkie niezbędne dane zostały zebrane + Wygenerowano rozmiar zgłoszenia + Opisz swój problem (w miarę możliwości po angielsku): + Opisz działania, które doprowadziły do tej awarii\n(w miarę możliwości w języku angielskim): + Nie podano danych kontaktowych, nie otrzymasz odpowiedzi na to zgłoszenie! + Połączenie z Internetem jest wymagane + Opis nie może być pusty + Ignoruj + Wyślij zgłoszenie + Wysyłanie wyniku + Zgłoszenie zostało pomyślnie wysłane! + Nie udało się wysłać zgłoszenia + Potwierdzenie + Budowanie zgłoszenia… + Wysyłanie zgłoszenia… + + Automatyczny + Ciemny + Jasny + + Nie wybrano + Ostrzeżenie! + Opcja czarnej/białej listy jest aktywna w Xposed Framework, może uniemożliwić prawidłowe działanie modyfikacji. + Dodatkowo, zainstalowana wersja modułu pochodzi z Google Play i posiada więcej ograniczeń. Rozważ ponowną instalację z innego źródła. + Zakres aktywacji jest aktywny dla tego modułu, może uniemożliwić prawidłowe działanie niektórych modyfikacji. + Android %1$s nie jest obsługiwany, modyfikacje mogą nie działać poprawnie. + Zarządzaj modułami Xposed + Miękki restart + Wykonać teraz miękki restart? + Restart launcher + Otwórz w przeglądarce + Restart systemUI + Zarządzanie ustawieniami + Wybierz żądaną rutynę + Kopia zapasowa + Przywróć + Twoja pamięć zewnętrzna jest tylko do odczytu + Nie można uzyskać dostępu do odpowiedniej pamięci + Nie udało się utworzyć katalogu kopii zapasowej + Nie udało się utworzyć pliku kopii zapasowej + Nie znaleziono kopii zapasowej ustawień + Kopia zapasowa ustawień została pomyślnie utworzona! + Ustawienia zostały pomyślnie przywrócone! + Twoje ustawienia zostały przywrócone przez Google Cloud Backup. Wykonaj miękki restart po włączeniu modułu Xposed. + Ustawienia modułu zostały pomyślnie przeniesione do działania z nową wersją LSposed/EdXposed. Uruchom ponownie, aby zastosować zmiany. + Nie udało się przenieść ustawień do działa z nową wersją LSPosed/EdXposed. Będziesz musiał użyć funkcji przywracania lub skonfigurować od nowa. + Dostępna jest aktualizacja ⚠ + Wybierz aplikację + Wybierz aplikacje + Wybierz działanie + Nie znaleziono żadnych działań + Wybierz skrót + Wyszukaj modyfikacje + Sieci Wi-Fi + Ustawienia lokalizacji + Dostęp do lokalizacji jest wymagany, aby aplikacje mogły uzyskać listę sieci Wi-Fi w Androidzie 9 (Pie) + Zaufane sieci + Dostępne sieci + Pobierz listę urządzeń + Pobierz listę urządzeń Bluetooth z systemu + Zaufane urządzenia + Dostępne urządzenia + Urządzenia Bluetooth + Bluetooth nie jest obsługiwane na tym urządzeniu + Najpierw włącz Bluetooth + Najpierw włącz Wi-Fi + Nie można skanować bez dostępu do lokalizacji + Wymuszone zamknięcie %s + Dane uwierzytelniające są już odblokowane + Odblokuj dane uwierzytelniające + Odblokowano dane uwierzytelniające! + + Nie znaleziono aplikacji Xposed + Wygląda na to, że nie masz zainstalowanego Xposed Framework.\n\nPamiętaj, że modyfikacje działają tylko z Xposed! + Moduł CustoMIUIzer nie jest aktywny!\nOtwórz aplikację LSposed, aktywuj moduł i uruchom ponownie. + Do otwierania adresów URL wymagana jest przeglądarka + Ok + Anuluj + Dodaj + Usuń + Przytrymaj, aby usunąć + Zmień ikonę + + Szukaj modyfikacji według nazwy.\nPrzytrzymaj, aby wyświetlić listę nowych modów. + Nie, że aby zastosować modyfikacje musisz zrobić miękki restart.\nDynamiczne ⟲ modyfikacje wymagają tego tylko raz.\nWięcej informacji znajduje się na stronie "Informacje". + Nowe modyfikacje od poprzedniej aktualizacji \ncan be marked for better visibility + + Czy chcesz utworzyć kopię zapasową, czy nie? + Czy chcesz przywrócić kopię zapasową, czy nie? + Czy chcesz otrzymać listę sieci/urządzeń, czy nie? + Będziesz musiał teraz ręcznie włączyć uprawnienia dla tej opcji. Dobra robota! + + %d ms + %d s + %d m + %d KB/s + 1 KB/s + B/s + KMGTPE + %s lux + + Wył + 30 minut + 1 godzina + 2 godziny + 3 godziny + 4 godziny + 5 godzin + 6 godzin + 8 godzin + 10 godzin + 12 godzin + + + Biały + Czarny + Kolor paska stanu + + plik + zasób + + + Wyświetl temperaturę i prąd baterii + Wyświetl informacje + Wyświetlacz po prawej stronie + Kliknij dwukrotnie, aby spać + Paski sygnałowe Dual SIM w dwóch rzędach + prawy margines + Umieść typ sieci komórkowej po prawej stronie ikony sygnału + lewy margines + Przesuń niektóre ikony w prawo + Głównie do urządzeń z wycięciem na środku górnej krawędzi + Wskaźnik ruchu sieciowego + Zegar + Zezwalaj na niezaufany dotyk + Pomiń licznik czasu przechwycenia uprawnień + Dotknij lewego skrótu, aby przełączyć latarkę + Zaokrąglony prostokątny kafelek + From 3bd2dadba1ec956083ed0c978da0b239324aef8a Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 30 Nov 2022 09:28:01 +0800 Subject: [PATCH 158/627] hook after systemui create --- .../mikanoshi/customiuizer/mods/System.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 063d1e1c..6d74134c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2675,12 +2675,12 @@ protected void after(MethodHookParam param) throws Throwable { public static void ExtendedPowerMenuHook(LoadPackageParam lpparam) { final boolean[] isListened = {false}; - Helpers.findAndHookMethod("com.android.systemui.SystemUIFactory", lpparam.classLoader, "createFromConfig", Context.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { if (!isListened[0]) { isListened[0] = true; - Context mContext = (Context)param.args[0]; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); File powermenu = new File(mContext.getCacheDir(), "extended_power_menu"); if (powermenu == null) { Helpers.log("ExtendedPowerMenuHook", "No writable path found!"); @@ -5256,12 +5256,12 @@ protected void before(MethodHookParam param) throws Throwable { }); final boolean[] isListened = {false}; - Helpers.findAndHookMethod("com.android.systemui.SystemUIFactory", lpparam.classLoader, "createFromConfig", Context.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { + protected void after(MethodHookParam param) throws Throwable { if (!isListened[0]) { isListened[0] = true; - Context mContext = (Context) param.args[0]; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); Class MiuiEndIconManager = findClass("com.android.systemui.statusbar.phone.MiuiEndIconManager", lpparam.classLoader); Object blockList = Helpers.getStaticObjectFieldSilently(MiuiEndIconManager, "RIGHT_BLOCK_LIST"); ArrayList rightBlockList; @@ -8399,12 +8399,12 @@ protected void after(final MethodHookParam param) throws Throwable { public static void AddFiveGTileHook(LoadPackageParam lpparam) { final boolean[] isListened = {false}; - Helpers.findAndHookMethod("com.android.systemui.SystemUIFactory", lpparam.classLoader, "createFromConfig", Context.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { + protected void after(MethodHookParam param) throws Throwable { if (!isListened[0]) { isListened[0] = true; - Context mContext = (Context) param.args[0]; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); int stockTilesResId = mContext.getResources().getIdentifier("miui_quick_settings_tiles_stock", "string", lpparam.packageName); String stockTiles = mContext.getString(stockTilesResId) + ",custom_5G"; MainModule.resHooks.setObjectReplacement(lpparam.packageName, "string", "miui_quick_settings_tiles_stock", stockTiles); @@ -8555,12 +8555,12 @@ public static void SystemCCGridHook(LoadPackageParam lpparam) { } final boolean[] isListened = {false}; - Helpers.findAndHookMethod("com.android.systemui.SystemUIFactory", lpparam.classLoader, "createFromConfig", Context.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { + protected void after(MethodHookParam param) throws Throwable { if (!isListened[0]) { isListened[0] = true; - Context mContext = (Context) param.args[0]; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); Resources res = mContext.getResources(); float density = res.getDisplayMetrics().density; int tileWidthResId = res.getIdentifier("qs_control_center_tile_width", "dimen", "com.android.systemui"); From 9f2ca87e9ca05cb2585e4cdfd17a4d682ee84ff0 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 30 Nov 2022 20:08:19 +0800 Subject: [PATCH 159/627] fix(lockscreen): tap to unlock --- .../name/mikanoshi/customiuizer/mods/System.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 6d74134c..0e0b3c37 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6708,7 +6708,7 @@ private static void processLSEvent(MethodHookParam param) { int action = event.getActionMasked(); if (action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_UP) return; - ViewGroup mKeyguardBottomArea = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mKeyguardBottomArea"); + ViewGroup mKeyguardBottomArea = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mBottomAreaView"); if (mKeyguardBottomArea == null) return; ViewGroup mIndicationArea = (ViewGroup)XposedHelpers.getObjectField(mKeyguardBottomArea, "mIndicationArea"); if (!Helpers.isReallyVisible(mIndicationArea)) return; @@ -6725,22 +6725,24 @@ private static void processLSEvent(MethodHookParam param) { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); int slop = ViewConfiguration.get(mContext).getScaledTouchSlop(); if (Math.abs(event.getX() - startPos[0]) > slop || Math.abs(event.getY() - startPos[1]) > slop) return; - Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); - XposedHelpers.callMethod(mStatusBar, "showBouncer"); + Object mPanelViewController = XposedHelpers.getObjectField(param.thisObject, "mPanelViewController"); + Object statusBarKeyguardViewManager = XposedHelpers.getObjectField(mPanelViewController, "statusBarKeyguardViewManager"); + + XposedHelpers.callMethod(statusBarKeyguardViewManager, "showGenericBouncer", true); } catch (Throwable t) { XposedBridge.log(t); } } public static void TapToUnlockHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "onTouchEvent", new MethodHook() { + Helpers.hookAllMethods("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader, "onTouchEvent", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { processLSEvent(param); } }); - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "onInterceptTouchEvent", new MethodHook() { + Helpers.hookAllMethods("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader, "onInterceptTouchEvent", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { processLSEvent(param); From 8eeaf73a18ead95acea7b03db90b16dd6830f41a Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 30 Nov 2022 20:50:06 +0800 Subject: [PATCH 160/627] feat: add leading zero to hours in statusbar --- .../mikanoshi/customiuizer/MainModule.java | 5 +- .../mikanoshi/customiuizer/mods/System.java | 86 +++++++++++++------ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 5 ++ 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 321e061f..e4dab9e0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -223,7 +223,10 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { mPrefs.getInt("system_recommended_fourth_action", 1) > 1) System.CustomRecommendedHook(lpparam, false); if (mPrefs.getBoolean("system_scramblepin")) System.ScramblePINHook(lpparam); if (mPrefs.getBoolean("system_dttosleep")) System.DoubleTapToSleepHook(lpparam); - if (mPrefs.getBoolean("system_clockseconds") || mPrefs.getBoolean("system_drawer_clockseconds")) System.ClockSecondsHook(lpparam); + if (mPrefs.getBoolean("system_clockseconds") + || mPrefs.getBoolean("system_drawer_clockseconds") + || mPrefs.getBoolean("system_clockleadingzero") + ) System.ClockSecondsHook(lpparam); if (mPrefs.getBoolean("system_fixmeter")) System.TrafficSpeedSpacingHook(lpparam); if (mPrefs.getBoolean("system_noscreenlock_act")) System.NoScreenLockHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed")) System.DetailedNetSpeedHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 0e0b3c37..d9547025 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1079,6 +1079,7 @@ protected void after(MethodHookParam param) throws Throwable { } public static void ClockSecondsHook(LoadPackageParam lpparam) { + boolean showSeconds = MainModule.mPrefs.getBoolean("system_clockseconds") || MainModule.mPrefs.getBoolean("system_drawer_clockseconds"); MethodHook ScheduleHook = new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -1113,28 +1114,30 @@ public void run() { XposedHelpers.setAdditionalInstanceField(param.thisObject, "scheduleTimer", timer); } }; - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "onReceive", Context.class, Intent.class, ScheduleHook); - Helpers.hookAllConstructors("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, ScheduleHook); - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "fireTimeChange", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - ArrayList mClockListeners = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "mClockListeners"); - Iterator it = mClockListeners.iterator(); - while (it.hasNext()) { - Object clock = it.next(); - if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "updateFromTimer") != null - && XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null) { - XposedHelpers.callMethod(clock, "onTimeChange"); - } - else if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "updateFromTimer") == null - && XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") == null) { - XposedHelpers.callMethod(clock, "onTimeChange"); + if (showSeconds) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "onReceive", Context.class, Intent.class, ScheduleHook); + Helpers.hookAllConstructors("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, ScheduleHook); + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "fireTimeChange", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + ArrayList mClockListeners = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "mClockListeners"); + Iterator it = mClockListeners.iterator(); + while (it.hasNext()) { + Object clock = it.next(); + if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "updateFromTimer") != null + && XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null) { + XposedHelpers.callMethod(clock, "onTimeChange"); + } + else if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "updateFromTimer") == null + && XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") == null) { + XposedHelpers.callMethod(clock, "onTimeChange"); + } } + XposedHelpers.removeAdditionalInstanceField(param.thisObject, "updateFromTimer"); + param.setResult(null); } - XposedHelpers.removeAdditionalInstanceField(param.thisObject, "updateFromTimer"); - param.setResult(null); - } - }); + }); + } Helpers.hookAllConstructors("com.android.systemui.statusbar.views.MiuiClock", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) { @@ -1149,32 +1152,61 @@ protected void after(MethodHookParam param) { XposedHelpers.setAdditionalInstanceField(clock, "mFixedWidth", true); } } + if (clock.getId() == clockId && MainModule.mPrefs.getBoolean("system_clockleadingzero")) { + XposedHelpers.setAdditionalInstanceField(clock, "showLeadingZero", true); + } } }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.views.MiuiClock", lpparam.classLoader, "updateTime", new MethodHook(XCallback.PRIORITY_HIGHEST) { @Override protected void before(MethodHookParam param) throws Throwable { TextView clock = (TextView)param.thisObject; - if (XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null) { + boolean clockShowSeconds = XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null; + boolean clockShowLeadingZero = XposedHelpers.getAdditionalInstanceField(clock, "showLeadingZero") != null; + if (clockShowSeconds || clockShowLeadingZero) { Context mContext = clock.getContext(); Object mMiuiStatusBarClockController = XposedHelpers.getObjectField(clock, "mMiuiStatusBarClockController"); int mAmPmStyle = (int) XposedHelpers.getObjectField(clock, "mAmPmStyle"); boolean is24 = (boolean) XposedHelpers.callMethod(mMiuiStatusBarClockController, "getIs24"); Object mCalendar = XposedHelpers.callMethod(mMiuiStatusBarClockController, "getCalendar"); String fmt; - if (is24) { - fmt = "fmt_time_24hour_minute_second"; + if (clockShowSeconds) { + if (is24) { + fmt = "fmt_time_24hour_minute_second"; + } + else { + if (mAmPmStyle == 0) { + fmt = "fmt_time_12hour_minute_second_pm"; + } + else { + fmt = "fmt_time_12hour_minute_second"; + } + } } else { - if (mAmPmStyle == 0) { - fmt = "fmt_time_12hour_minute_second_pm"; + if (is24) { + fmt = "fmt_time_24hour_minute"; } else { - fmt = "fmt_time_12hour_minute_second"; + if (mAmPmStyle == 0) { + fmt = "fmt_time_12hour_minute_pm"; + } + else { + fmt = "fmt_time_12hour_minute"; + } } } int fmtResId = mContext.getResources().getIdentifier(fmt, "string", "com.android.systemui"); - StringBuilder formatSb = new StringBuilder(mContext.getString(fmtResId).replace("mm:ms", "mm:ss").replaceFirst("mm:s$", "mm:ss")); + String timeFmt = mContext.getString(fmtResId); + if (clockShowSeconds) { + timeFmt = timeFmt.replaceFirst("mm:ms", "mm:ss").replaceFirst("mm:s$", "mm:ss"); + } + if (clockShowLeadingZero) { + timeFmt = timeFmt.replaceFirst("^H:mm", "HH:mm").replaceFirst("^h:mm", "hh:mm") + .replaceFirst("ah:mm", "ahh:mm").replaceFirst(" h:mm", " hh:mm"); + } + StringBuilder formatSb = new StringBuilder(timeFmt); StringBuilder textSb = new StringBuilder(); XposedHelpers.callMethod(mCalendar, "format", mContext, textSb, formatSb); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b5a9a325..0abd356e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -77,6 +77,7 @@ 日历应用 点击通知抽屉上方的日期时打开所选应用 显示秒 + 时钟补0(小时) 状态栏显示秒钟 通知图标限制 变成点前显示的通知图标的数目 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4a5bf10e..17ba484e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -84,6 +84,7 @@ Calendar app Open selected app when date in notification drawer\'s header is tapped Show seconds + Show leading zero to hours Display seconds in the status bar clock Notification icons limit Number of notification icons to display before turning them into dots diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index e55d45ca..64c4436f 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -447,6 +447,11 @@ android:title="@string/system_clockseconds_title" android:defaultValue="false" /> + + Date: Thu, 1 Dec 2022 13:15:16 +0800 Subject: [PATCH 161/627] feat: adjust single mobile type position --- .../mikanoshi/customiuizer/mods/System.java | 18 ++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 5 ++-- app/src/main/res/xml/prefs_system.xml | 29 +++++++++++++++++-- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d9547025..3cca7414 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8203,6 +8203,24 @@ protected void after(final MethodHookParam param) throws Throwable { res.getDisplayMetrics() ); mlp.leftMargin = (int) marginLeft; + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_rightmargin", 0); + if (rightMargin > 0) { + float marginRight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin * 0.5f, + res.getDisplayMetrics() + ); + mlp.rightMargin = (int) marginRight; + } + int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_verticaloffset", 8); + if (verticalOffset != 8) { + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + res.getDisplayMetrics() + ); + mlp.topMargin = (int) marginTop; + } mMobileTypeSingle.setLayoutParams(mlp); int fontSize = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_fontsize", 27); mMobileTypeSingle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0abd356e..87282500 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1062,6 +1062,7 @@ 右侧间距 移动网络类型单独显示 左侧间距 + 上下偏移量 应用信息 强制关闭 重启系统界面 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 17ba484e..8d7f5aae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1108,9 +1108,10 @@ Display on the right Double tap to sleep Dual SIM signal bars in dual rows - right margin + Right margin Put mobile network type at the right of signal icon - left margin + Left margin + Vertical offset Move some icons to the right Mainly for devices with cutout at the center of the top edge Network speed indicator diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 64c4436f..04478dd5 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -347,11 +347,36 @@ android:defaultValue="7" miuizer:child="true" miuizer:minValue="2" - miuizer:maxValue="12" + miuizer:maxValue="10" + miuizer:stepValue="1" + miuizer:displayDividerValue="2" + miuizer:format="%s dip" /> + + + + From 5fa8cb4c753584e2a959ff5a7afd457be1774754 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 1 Dec 2022 13:49:04 +0800 Subject: [PATCH 162/627] feat: hide gps icon --- .../mikanoshi/customiuizer/MainModule.java | 3 +- .../mikanoshi/customiuizer/mods/System.java | 34 ++----------------- app/src/main/res/values/strings.xml | 1 + .../main/res/xml/prefs_system_hideicons.xml | 5 +++ 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index e4dab9e0..83314f54 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -299,7 +299,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_statusbaricons_battery1")) System.HideIconsBattery1Hook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery3") || mPrefs.getBoolean("system_statusbaricons_battery2")) System.HideIconsBattery2Hook(lpparam); if (mPrefs.getStringAsInt("system_statusbaricons_wifistandard", 1) > 1) System.DisplayWifiStandardHook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_nosims")) System.HideIconsNoSIMsHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_signal") || mPrefs.getBoolean("system_statusbaricons_sim1") || mPrefs.getBoolean("system_statusbaricons_sim2") @@ -331,6 +330,8 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { mPrefs.getBoolean("system_statusbaricons_nfc") || mPrefs.getBoolean("system_statusbaricons_vpn") || mPrefs.getBoolean("system_statusbaricons_hotspot") || + mPrefs.getBoolean("system_statusbaricons_nosims") || + mPrefs.getBoolean("system_statusbaricons_gps") || mPrefs.getBoolean("system_statusbaricons_volte"); if (hideIconsActive) System.HideIconsHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 3cca7414..a80f50a8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2673,23 +2673,6 @@ protected void after(MethodHookParam param) throws Throwable { applyHeight(param.thisObject); } }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.SignalClusterView", lpparam.classLoader, "onFinishInflate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - try { - ViewGroup mSignalDualNotchGroup = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mSignalDualNotchGroup"); - applyHeight(mSignalDualNotchGroup.findViewById(mSignalDualNotchGroup.getResources().getIdentifier("notch_mobile", "id", lpparam.packageName))); - } catch (Throwable t) { - XposedBridge.log(t); - } - - try { - ViewGroup mSignalSimpleDualMobileContainer = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mSignalSimpleDualMobileContainer"); - applyHeight(mSignalSimpleDualMobileContainer); - } catch (Throwable ignore) {} - } - }); } @SuppressWarnings("ConstantConditions") @@ -3961,21 +3944,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void HideIconsNoSIMsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.SignalClusterView", lpparam.classLoader, "apply", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - try { - View mNoSimsCombo = (View)XposedHelpers.getObjectField(param.thisObject, "mNoSimsCombo"); - if (mNoSimsCombo != null) mNoSimsCombo.setVisibility(View.GONE); - } catch (Throwable t) { - View mNoSims = (View)XposedHelpers.getObjectField(param.thisObject, "mNoSims"); - if (mNoSims != null) mNoSims.setVisibility(View.GONE); - } - } - }); - } - public static void HideIconsPrivacyHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("android.app.StatusBarManager", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, new MethodHook() { @Override @@ -4032,8 +4000,10 @@ private static boolean checkSlot(String slotName) { "managed_profile".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_profile") || "vpn".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_vpn") || "nfc".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nfc") || + "location".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_gps") || "wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_wifi") || "hotspot".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_hotspot") || + "no_sim".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nosims") || "hd".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_volte"); } catch (Throwable t) { XposedBridge.log(t); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d7f5aae..4cd2138f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -47,6 +47,7 @@ VoLTE VoWiFi Roaming + GPS VPN NFC Hotspot diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index 2f68e592..7671a774 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -106,6 +106,11 @@ android:title="@string/system_statusbaricons_nfc_title" android:defaultValue="false" /> + + Date: Thu, 1 Dec 2022 18:27:51 +0800 Subject: [PATCH 163/627] feat: hide operator name in control center --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 30 +++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 3 +- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 5 ++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 83314f54..3ccbaced 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -311,6 +311,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || !mPrefs.getString("system_calendar_app", "").equals("") || !mPrefs.getString("system_clock_app", "").equals("")) System.ReplaceShortcutAppHook(lpparam); if (mPrefs.getStringAsInt("system_qshaptics", 1) > 1) System.QSHapticHook(lpparam); + if (mPrefs.getBoolean("system_qs_hideoperator")) System.HideCCOperatorHook(lpparam); if (mPrefs.getStringAsInt("system_expandnotifs", 1) > 1) System.ExpandNotificationsHook(lpparam); if (mPrefs.getStringAsInt("system_inactivebrightness", 1) > 1) System.InactiveBrightnessSliderHook(lpparam); if (mPrefs.getStringAsInt("system_mobiletypeicon", 1) > 1) System.HideNetworkTypeHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index a80f50a8..57865d43 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2263,6 +2263,36 @@ else if (opt == 3) }); } + public static void HideCCOperatorHook(LoadPackageParam lpparam) { + MethodHook hideOperatorHook = new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object carrierView; + TextView mCarrierText; + try { + carrierView = XposedHelpers.getObjectField(param.thisObject, "carrierText"); + } + catch (Throwable e) { + carrierView = XposedHelpers.getObjectField(param.thisObject, "mCarrierText"); + } + mCarrierText = (TextView) carrierView; + mCarrierText.setVisibility(View.GONE); + } + }; + + boolean hookedFlaresInfo = Helpers.hookAllMethodsSilently("com.android.systemui.controlcenter.phone.widget.ControlCenterStatusBar", lpparam.classLoader, "updateFlaresInfo", hideOperatorHook); + if (!hookedFlaresInfo) { + Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.widget.ControlCenterStatusBar", lpparam.classLoader, "onFinishInflate", hideOperatorHook); + } + + Helpers.findAndHookMethod("com.android.systemui.qs.MiuiNotificationHeaderView", lpparam.classLoader, "updateCarrierTextVisibility", hideOperatorHook); + + hookedFlaresInfo = Helpers.hookAllMethodsSilently("com.android.systemui.qs.MiuiQSHeaderView", lpparam.classLoader, "updateFlaresInfo", hideOperatorHook); + if (!hookedFlaresInfo) { + Helpers.findAndHookMethod("com.android.systemui.qs.MiuiQSHeaderView", lpparam.classLoader, "onFinishInflate", hideOperatorHook); + } + } + public static void AutoGroupNotificationsHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.notification.GroupHelper", lpparam.classLoader, "adjustAutogroupingSummary", int.class, String.class, String.class, boolean.class, new MethodHook() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 87282500..a799ef8f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -77,7 +77,7 @@ 日历应用 点击通知抽屉上方的日期时打开所选应用 显示秒 - 时钟补0(小时) + 小时补0 状态栏显示秒钟 通知图标限制 变成点前显示的通知图标的数目 @@ -454,6 +454,7 @@ 折叠面板中的列数 横屏时将会额外增加一列。 彻底移除标签 + 隐藏运营商名称 快速设置触觉反馈 点击快速设置磁贴时振动 其他 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4cd2138f..176db9ba 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -478,6 +478,7 @@ Number of columns in collapsed panel Landscape orientation will have one additional column. Remove labels completely + Hide carrier name Quick settings haptic feedback Vibrate on Quick settings tile tap Other diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 04478dd5..c8a88f1b 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -824,6 +824,11 @@ android:title="@string/system_qsnolabels_title" android:defaultValue="false" /> + + Date: Thu, 1 Dec 2022 20:58:29 +0800 Subject: [PATCH 164/627] double tap to scroll top --- .../customiuizer/mods/GlobalActions.java | 40 ++++++++++++++++++- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/arrays.xml | 2 + app/src/main/res/values/strings.xml | 1 + 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 731c086a..53006827 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -21,6 +21,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; +import android.hardware.input.InputManager; import android.media.AudioManager; import android.net.wifi.WifiManager; import android.nfc.NfcAdapter; @@ -33,6 +34,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.TelephonyManager; +import android.view.InputEvent; import android.view.KeyEvent; import android.view.View; import android.view.ViewConfiguration; @@ -88,7 +90,6 @@ public static boolean handleAction(Context context, String key, boolean skipLock case 7: return openRecents(context); case 8: return launchAppIntent(context, key, skipLock); case 9: return launchShortcutIntent(context, key, skipLock); - case 20: return launchActivityIntent(context, key, skipLock); case 10: return toggleThis(context, Helpers.getSharedIntPref(context, key + "_toggle", 0)); case 11: return switchToPrevApp(context); case 12: return openPowerMenu(context); @@ -99,10 +100,12 @@ public static boolean handleAction(Context context, String key, boolean skipLock case 17: return openVolumeDialog(context); case 18: return volumeUp(context); case 19: return volumeDown(context); + case 20: return launchActivityIntent(context, key, skipLock); case 21: return switchKeyboard(context); case 22: return switchOneHandedLeft(context); case 23: return switchOneHandedRight(context); case 24: return forceClose(context); + case 25: return scrollToTop(context); default: return false; } } @@ -130,6 +133,7 @@ public static int getActionResId(int action) { case 22: return R.string.array_global_actions_onehanded_left; case 23: return R.string.array_global_actions_onehanded_right; case 24: return R.string.array_global_actions_forceclose; + case 25: return R.string.array_global_actions_scrolltotop; default: return 0; } } @@ -402,6 +406,28 @@ public void run() { }).start(); } + if (action.equals(ACTION_PREFIX + "ScrollToTop")) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + try { + Helpers.log("scrollToTop action"); + Method injectInputEventMethod = InputManager.class.getDeclaredMethod("injectInputEvent", InputEvent.class, int.class); + Method instanceMethod = InputManager.class.getDeclaredMethod("getInstance"); + InputManager im = (InputManager) instanceMethod.invoke(InputManager.class); + long uptimeMillis = SystemClock.uptimeMillis(); + KeyEvent downEvent = new KeyEvent(uptimeMillis, uptimeMillis, 0, 122, 0, 4096); + KeyEvent upEvent = new KeyEvent(uptimeMillis, uptimeMillis, 1, 122, 0, 4096); + injectInputEventMethod.invoke(im, downEvent, 0); + injectInputEventMethod.invoke(im, upEvent, 0); + } + catch (Throwable e) { + Helpers.log("err: " + e); + } + } + }, 150L); + } + if (action.equals(ACTION_PREFIX + "SwitchToPrevApp")) { PackageManager pm = context.getPackageManager(); Intent intent_home = new Intent(Intent.ACTION_MAIN); @@ -867,6 +893,7 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "SwitchToPrevApp"); intentfilter.addAction(ACTION_PREFIX + "GoBack"); intentfilter.addAction(ACTION_PREFIX + "OpenPowerMenu"); + intentfilter.addAction(ACTION_PREFIX + "ScrollToTop"); intentfilter.addAction(ACTION_PREFIX + "SwitchKeyboard"); intentfilter.addAction(ACTION_PREFIX + "SwitchOneHandedLeft"); intentfilter.addAction(ACTION_PREFIX + "SwitchOneHandedRight"); @@ -1189,6 +1216,17 @@ public static boolean switchToPrevApp(Context context) { } } + public static boolean scrollToTop(Context context) { + try { + Helpers.log("scrollToTop func"); + context.sendBroadcast(new Intent(ACTION_PREFIX + "ScrollToTop")); + return true; + } catch (Throwable t) { + XposedBridge.log(t); + return false; + } + } + public static boolean openPowerMenu(Context context) { try { context.sendBroadcast(new Intent(ACTION_PREFIX + "OpenPowerMenu")); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a799ef8f..2bd85504 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -715,6 +715,7 @@ 强制关闭当前应用 打开电源菜单 电源菜单 + 回到顶部 清理内存 颜色反转 切换键盘 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 95e3f82a..ed886a70 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -187,6 +187,7 @@ @string/array_global_actions_back @string/array_global_actions_forceclose @string/array_global_actions_powermenu + @string/array_global_actions_scrolltotop @string/array_global_actions_clearmemory @string/array_global_actions_invertcolors @string/array_global_actions_switchkeyboard @@ -214,6 +215,7 @@ 11 24 12 + 25 13 14 21 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 176db9ba..ca4114a4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -770,6 +770,7 @@ Force close current app Open power menu Power menu + Scroll to top Clear memory Invert colors Switch keyboard From 31b68792f46e83eb13e50fd656bfe7e81425aba3 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 1 Dec 2022 22:25:18 +0800 Subject: [PATCH 165/627] fix: search crash --- app/src/main/res/xml/prefs_system.xml | 55 +++++++++++++-------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index c8a88f1b..61539baf 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -847,35 +847,32 @@ miuizer:child="true" /> - - - - - - - - + android:title="@string/system_mods_cc" /> + + + + + + From 55682672a942d0d48607dc645b44b25ca470effd Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 2 Dec 2022 19:22:07 +0800 Subject: [PATCH 166/627] dt2scroll in statusbar scope --- .../customiuizer/mods/GlobalActions.java | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 53006827..4246871b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -201,6 +201,26 @@ else if (action.equals(ACTION_PREFIX + "RestartLauncher")) { ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); XposedHelpers.callMethod(am, "forceStopPackage", "com.miui.home"); } + else if (action.equals(ACTION_PREFIX + "ScrollToTop")) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + try { + Method injectInputEventMethod = InputManager.class.getDeclaredMethod("injectInputEvent", InputEvent.class, int.class); + Method instanceMethod = InputManager.class.getDeclaredMethod("getInstance"); + InputManager im = (InputManager) instanceMethod.invoke(InputManager.class); + long uptimeMillis = SystemClock.uptimeMillis(); + KeyEvent downEvent = new KeyEvent(uptimeMillis, uptimeMillis, 0, 122, 0, 4096); + KeyEvent upEvent = new KeyEvent(uptimeMillis, uptimeMillis, 1, 122, 0, 4096); + injectInputEventMethod.invoke(im, downEvent, 0); + injectInputEventMethod.invoke(im, upEvent, 0); + } + catch (Throwable e) { + Helpers.log("err: " + e); + } + } + }, 150L); + } if (mStatusBar != null) { if (action.equals(ACTION_PREFIX + "ExpandNotifications")) try { @@ -226,16 +246,14 @@ else if (action.equals(ACTION_PREFIX + "RestartLauncher")) { if (action.equals(ACTION_PREFIX + "ExpandSettings")) try { boolean forceExpand = intent.getBooleanExtra("forceExpand", false); - if (Helpers.is12()) { - Object controller = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", context.getClassLoader()), "get", findClassIfExists("com.android.systemui.miui.statusbar.policy.ControlPanelController", context.getClassLoader())); - boolean isUseControlCenter = (boolean)XposedHelpers.callMethod(controller, "isUseControlCenter"); - if (isUseControlCenter) { - if (forceExpand || (boolean)XposedHelpers.callMethod(controller, "isQSFullyCollapsed")) - XposedHelpers.callMethod(controller, "openPanel"); - else - XposedHelpers.callMethod(controller, "collapsePanel", true); - return; - } + Object controller = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", context.getClassLoader()), "get", findClassIfExists("com.android.systemui.miui.statusbar.policy.ControlPanelController", context.getClassLoader())); + boolean isUseControlCenter = (boolean)XposedHelpers.callMethod(controller, "isUseControlCenter"); + if (isUseControlCenter) { + if (forceExpand || (boolean)XposedHelpers.callMethod(controller, "isQSFullyCollapsed")) + XposedHelpers.callMethod(controller, "openPanel"); + else + XposedHelpers.callMethod(controller, "collapsePanel", true); + return; } Object mNotificationPanel = XposedHelpers.getObjectField(mStatusBar, "mNotificationPanel"); @@ -406,28 +424,6 @@ public void run() { }).start(); } - if (action.equals(ACTION_PREFIX + "ScrollToTop")) { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - try { - Helpers.log("scrollToTop action"); - Method injectInputEventMethod = InputManager.class.getDeclaredMethod("injectInputEvent", InputEvent.class, int.class); - Method instanceMethod = InputManager.class.getDeclaredMethod("getInstance"); - InputManager im = (InputManager) instanceMethod.invoke(InputManager.class); - long uptimeMillis = SystemClock.uptimeMillis(); - KeyEvent downEvent = new KeyEvent(uptimeMillis, uptimeMillis, 0, 122, 0, 4096); - KeyEvent upEvent = new KeyEvent(uptimeMillis, uptimeMillis, 1, 122, 0, 4096); - injectInputEventMethod.invoke(im, downEvent, 0); - injectInputEventMethod.invoke(im, upEvent, 0); - } - catch (Throwable e) { - Helpers.log("err: " + e); - } - } - }, 150L); - } - if (action.equals(ACTION_PREFIX + "SwitchToPrevApp")) { PackageManager pm = context.getPackageManager(); Intent intent_home = new Intent(Intent.ACTION_MAIN); @@ -508,8 +504,6 @@ public void run() { if (action.equals(ACTION_PREFIX + "SwitchKeyboard")) { context.sendBroadcast( - Helpers.isNougat() ? - new Intent("android.settings.SHOW_INPUT_METHOD_PICKER") : new Intent("com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER").setPackage("android") ); } @@ -828,7 +822,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void setupForegroundMonitor(LoadPackageParam lpparam) { - String windowClass = Helpers.isQPlus() ? "com.android.server.wm.DisplayPolicy" : "com.android.server.policy.PhoneWindowManager"; + String windowClass = "com.android.server.wm.DisplayPolicy"; Helpers.hookAllMethods(windowClass, lpparam.classLoader, "focusChangedLw", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { @@ -893,7 +887,6 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "SwitchToPrevApp"); intentfilter.addAction(ACTION_PREFIX + "GoBack"); intentfilter.addAction(ACTION_PREFIX + "OpenPowerMenu"); - intentfilter.addAction(ACTION_PREFIX + "ScrollToTop"); intentfilter.addAction(ACTION_PREFIX + "SwitchKeyboard"); intentfilter.addAction(ACTION_PREFIX + "SwitchOneHandedLeft"); intentfilter.addAction(ACTION_PREFIX + "SwitchOneHandedRight"); @@ -996,6 +989,8 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "RestartLauncher"); intentfilter.addAction(ACTION_PREFIX + "CopyToExternal"); + intentfilter.addAction(ACTION_PREFIX + "ScrollToTop"); + mStatusBarContext.registerReceiver(mSBReceiver, intentfilter); } }); @@ -1218,7 +1213,6 @@ public static boolean switchToPrevApp(Context context) { public static boolean scrollToTop(Context context) { try { - Helpers.log("scrollToTop func"); context.sendBroadcast(new Intent(ACTION_PREFIX + "ScrollToTop")); return true; } catch (Throwable t) { From dc0d8091b87711e029e06c3797880ada8f0c4e96 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 3 Dec 2022 21:27:27 +0800 Subject: [PATCH 167/627] fix: hide clear all button in notification drawer --- .../mikanoshi/customiuizer/mods/System.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 57865d43..baac5b83 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2817,25 +2817,24 @@ protected void before(MethodHookParam param) throws Throwable { } public static void HideDismissViewHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "inflateDismissView", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateDismissView", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { + protected void before(MethodHookParam param) throws Throwable { View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); - if (mDismissView != null) mDismissView.setVisibility(View.GONE); + if (mDismissView != null) { + Object mKeyguardShowing = XposedHelpers.getObjectField(param.thisObject, "mKeyguardShowing"); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "currentKeyguard", mKeyguardShowing); + XposedHelpers.setObjectField(param.thisObject, "mKeyguardShowing", true); + } } - }); - if (!Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "updateDismissView", boolean.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); - if (mDismissView != null) mDismissView.setVisibility(View.GONE); - } - })) Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "updateDismissView", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); - if (mDismissView != null) mDismissView.setVisibility(View.GONE); + if (mDismissView != null) { + Object mKeyguardShowing = XposedHelpers.getAdditionalInstanceField(param.thisObject, "currentKeyguard"); + XposedHelpers.setObjectField(param.thisObject, "mKeyguardShowing", mKeyguardShowing); + } } }); } From c782e9f886af74c69c6fff1fad83a09a50944d4d Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 5 Dec 2022 11:21:05 +0800 Subject: [PATCH 168/627] double tap statusbar to scroll to the top --- .../customiuizer/mods/GlobalActions.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 4246871b..6b289a90 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -34,8 +34,10 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.TelephonyManager; +import android.view.InputDevice; import android.view.InputEvent; import android.view.KeyEvent; +import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; @@ -210,16 +212,24 @@ public void run() { Method instanceMethod = InputManager.class.getDeclaredMethod("getInstance"); InputManager im = (InputManager) instanceMethod.invoke(InputManager.class); long uptimeMillis = SystemClock.uptimeMillis(); - KeyEvent downEvent = new KeyEvent(uptimeMillis, uptimeMillis, 0, 122, 0, 4096); - KeyEvent upEvent = new KeyEvent(uptimeMillis, uptimeMillis, 1, 122, 0, 4096); - injectInputEventMethod.invoke(im, downEvent, 0); - injectInputEventMethod.invoke(im, upEvent, 0); + MotionEvent swipeDownEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis, MotionEvent.ACTION_DOWN, 500, 500, 0); + swipeDownEvt.setSource(InputDevice.SOURCE_TOUCHSCREEN); + injectInputEventMethod.invoke(im, swipeDownEvt, 1); + MotionEvent swipeMoveEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis + 25, MotionEvent.ACTION_MOVE, 500, 36000, 0); + swipeMoveEvt.setSource(InputDevice.SOURCE_TOUCHSCREEN); + injectInputEventMethod.invoke(im, swipeMoveEvt, 2); + MotionEvent swipeUpEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis + 25, MotionEvent.ACTION_UP, 500, 36000, 0); + swipeUpEvt.setSource(InputDevice.SOURCE_TOUCHSCREEN); + injectInputEventMethod.invoke(im, swipeUpEvt, 2); + swipeDownEvt.recycle(); + swipeMoveEvt.recycle(); + swipeUpEvt.recycle(); } catch (Throwable e) { Helpers.log("err: " + e); } } - }, 150L); + }, 100L); } if (mStatusBar != null) { From eac83c2bb17ddf0281c8488e23581e7ac98d6403 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 5 Dec 2022 13:38:15 +0800 Subject: [PATCH 169/627] feat: collapse qs after touch --- .../name/mikanoshi/customiuizer/MainModule.java | 1 + .../customiuizer/mods/GlobalActions.java | 4 ++-- .../mikanoshi/customiuizer/mods/System.java | 17 +++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 5 +++++ 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 3ccbaced..0fbd68d6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -312,6 +312,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || !mPrefs.getString("system_clock_app", "").equals("")) System.ReplaceShortcutAppHook(lpparam); if (mPrefs.getStringAsInt("system_qshaptics", 1) > 1) System.QSHapticHook(lpparam); if (mPrefs.getBoolean("system_qs_hideoperator")) System.HideCCOperatorHook(lpparam); + if (mPrefs.getBoolean("system_cc_collapse_after_clicked")) System.CollapseCCAfterClickHook(lpparam); if (mPrefs.getStringAsInt("system_expandnotifs", 1) > 1) System.ExpandNotificationsHook(lpparam); if (mPrefs.getStringAsInt("system_inactivebrightness", 1) > 1) System.InactiveBrightnessSliderHook(lpparam); if (mPrefs.getStringAsInt("system_mobiletypeicon", 1) > 1) System.HideNetworkTypeHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 6b289a90..0572789c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -215,10 +215,10 @@ public void run() { MotionEvent swipeDownEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis, MotionEvent.ACTION_DOWN, 500, 500, 0); swipeDownEvt.setSource(InputDevice.SOURCE_TOUCHSCREEN); injectInputEventMethod.invoke(im, swipeDownEvt, 1); - MotionEvent swipeMoveEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis + 25, MotionEvent.ACTION_MOVE, 500, 36000, 0); + MotionEvent swipeMoveEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis + 25, MotionEvent.ACTION_MOVE, 500, 240000, 0); swipeMoveEvt.setSource(InputDevice.SOURCE_TOUCHSCREEN); injectInputEventMethod.invoke(im, swipeMoveEvt, 2); - MotionEvent swipeUpEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis + 25, MotionEvent.ACTION_UP, 500, 36000, 0); + MotionEvent swipeUpEvt = MotionEvent.obtain(uptimeMillis, uptimeMillis + 25, MotionEvent.ACTION_UP, 500, 240000, 0); swipeUpEvt.setSource(InputDevice.SOURCE_TOUCHSCREEN); injectInputEventMethod.invoke(im, swipeUpEvt, 2); swipeDownEvt.recycle(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index baac5b83..254466e1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2293,6 +2293,23 @@ protected void after(MethodHookParam param) throws Throwable { } } + public static void CollapseCCAfterClickHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.qs.tileimpl.QSTileImpl", lpparam.classLoader, "click", View.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mState = XposedHelpers.callMethod(param.thisObject, "getState"); + int state = XposedHelpers.getIntField(mState, "state"); + if (state != 0) { + String tileSpec = (String) XposedHelpers.callMethod(param.thisObject, "getTileSpec"); + if (!"edit".equals(tileSpec)) { + Object mHost = XposedHelpers.getObjectField(param.thisObject, "mHost"); + XposedHelpers.callMethod(mHost, "collapsePanels"); + } + } + } + }); + } + public static void AutoGroupNotificationsHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.notification.GroupHelper", lpparam.classLoader, "adjustAutogroupingSummary", int.class, String.class, String.class, boolean.class, new MethodHook() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2bd85504..04f244c0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1074,4 +1074,5 @@ 跳过开启特殊权限的倒计时 点击左侧图标时切换手电筒 圆角矩形磁贴 + 单击开关后自动收起 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca4114a4..2033e89a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1123,4 +1123,5 @@ Skip permission intercept timer Tap left shortcut to toggle flashlight Rounded rectangle tile + Collapse after touch \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 61539baf..56025b8e 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -829,6 +829,11 @@ android:title="@string/system_qs_hideoperator_title" android:defaultValue="false" /> + + Date: Mon, 5 Dec 2022 14:23:06 +0800 Subject: [PATCH 170/627] feat: remove open app confirm --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 5 +++++ 5 files changed, 12 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 0fbd68d6..9a745737 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -137,6 +137,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (!mPrefs.getString("system_defaultusb", "none").equals("none")) System.USBConfigHook(lpparam); if (mPrefs.getBoolean("system_nolightuponheadset")) System.NoLightUpOnHeadsetHook(lpparam); if (mPrefs.getBoolean("system_removesecure")) System.RemoveSecureHook(lpparam); + if (mPrefs.getBoolean("system_remove_startactconfirm")) System.RemoveActStartConfirmHook(lpparam); if (mPrefs.getBoolean("system_securelock")) System.EnhancedSecurityHook(lpparam); if (mPrefs.getBoolean("system_separatevolume")) System.NotificationVolumeServiceHook(lpparam); if (mPrefs.getBoolean("system_downgrade")) System.NoVersionCheckHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 254466e1..b5815760 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5941,6 +5941,10 @@ public static void RemoveSecureHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.wm.WindowState", lpparam.classLoader, "isSecureLocked", XC_MethodReplacement.returnConstant(false)); } + public static void RemoveActStartConfirmHook(LoadPackageParam lpparam) { + Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkAllowStartActivity", XC_MethodReplacement.returnConstant(true)); + } + public static void AllowAllKeyguardHook(LoadPackageParam lpparam) { //noinspection ResultOfMethodCallIgnored Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.notification.MiuiNotificationCompat", lpparam.classLoader, "isEnableKeyguard", Notification.class, XC_MethodReplacement.returnConstant(true)); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 04f244c0..fef71536 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -333,6 +333,7 @@ 禁用弹性滚动 阻止列表视图越界回弹 禁用安全内容保护 + 移除启动应用确认 允许对任意应用进行截图和录屏 隐藏低电量警告 不显示打开省电模式的警告对话框 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2033e89a..29b35800 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -350,6 +350,7 @@ Disable overscroll Prevent list views from overscrolling Disable secure content protection + Remove open app confirm Allow to screenshot and record video of any app Hide warning about low battery level Do not display a warning dialog that asks to turn on Battery saver diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 56025b8e..5e7f0a83 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1242,6 +1242,11 @@ android:summary="@string/system_removesecure_summ" android:defaultValue="false" /> + + Date: Tue, 6 Dec 2022 14:13:29 +0800 Subject: [PATCH 171/627] add polish translation and bump version --- app/build.gradle | 6 ++--- .../mikanoshi/customiuizer/MainFragment.java | 23 ++++++++++-------- .../customiuizer/subs/CommonActivity.java | 13 ++++++++++ .../mikanoshi/customiuizer/utils/Helpers.java | 1 + app/src/main/res/drawable/donatewx.jpeg | Bin 0 -> 73437 bytes app/src/main/res/layout/fragment_donate.xml | 14 +++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/xml/prefs_main.xml | 1 - 8 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java create mode 100644 app/src/main/res/drawable/donatewx.jpeg create mode 100644 app/src/main/res/layout/fragment_donate.xml diff --git a/app/build.gradle b/app/build.gradle index 5e2178df..324099cb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,9 +26,9 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 - versionCode 45 - versionName "22.11.26" - resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW' + versionCode 46 + versionName "22.12.06" + resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } buildTypes { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java index 694ff8f5..41375a7e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java @@ -46,6 +46,7 @@ import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; import name.mikanoshi.customiuizer.prefs.PreferenceEx; import name.mikanoshi.customiuizer.subs.CategorySelector; +import name.mikanoshi.customiuizer.subs.CommonActivity; import name.mikanoshi.customiuizer.subs.Controls; import name.mikanoshi.customiuizer.subs.Launcher; import name.mikanoshi.customiuizer.subs.System; @@ -280,7 +281,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } }); - String[] locales = new String[] { "ru-RU", "zh-CN", "zh-TW" }; + String[] locales = new String[] { "ru-RU", "zh-CN", "zh-TW", "pl-PL" }; ArrayList localesArr = new ArrayList(Arrays.asList(locales)); ArrayList localeNames = new ArrayList(); @@ -370,17 +371,19 @@ public boolean onPreferenceClick(Preference pref) { } }); } - else { - PreferenceEx donateEntry = findPreference("pref_key_donate"); - donateEntry.setVisible(true); - donateEntry.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference pref) { + PreferenceEx donateEntry = findPreference("pref_key_donate"); + donateEntry.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference pref) { + if (!config.getLocales().get(0).getCountry().equals("CN")) { Helpers.openURL(act, "https://www.paypal.com/paypalme/tpsxj"); - return true; } - }); - } + else { + openSubFragment(new CommonActivity(), null, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitle().toString(), R.layout.fragment_donate); + } + return true; + } + }); } void findMod(String filter) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java new file mode 100644 index 00000000..f3e1602b --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java @@ -0,0 +1,13 @@ +package name.mikanoshi.customiuizer.subs; + +import android.os.Bundle; + +import name.mikanoshi.customiuizer.SubFragment; + +public class CommonActivity extends SubFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + this.padded = false; + super.onCreate(savedInstanceState); + } +} \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 583bc865..4656de68 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -159,6 +159,7 @@ protected int sizeOf(String key, Bitmap icon) { put("ru-RU", "100"); put("zh-CN", "99"); put("zh-TW", "99"); + put("pl-PL", "99"); }}; public static final ArrayList shortcutIcons = new ArrayList(); diff --git a/app/src/main/res/drawable/donatewx.jpeg b/app/src/main/res/drawable/donatewx.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..d245ecf0ffc7981e09de5a388fb02149ac20c5c4 GIT binary patch literal 73437 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 MHvj%U&)(4g1>4-d^8f$< literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/fragment_donate.xml b/app/src/main/res/layout/fragment_donate.xml new file mode 100644 index 00000000..46a03ebf --- /dev/null +++ b/app/src/main/res/layout/fragment_donate.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index fef71536..05c79e71 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -891,7 +891,7 @@ 报告错误 通过官方问题跟踪器向我们发送错误报告或者功能请求 捐出$%1$d - 赞赏 + 微信赞赏 捐赠 Mikanoshi 表达您对这个高大上模块感激之情的最好方式 :) 应用内 diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 9aee8fa9..49a2494a 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -69,7 +69,6 @@ android:key="pref_key_github" /> From 90b668006d084a5bbb6d4eaf1ffefb8c585c5ee4 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 7 Dec 2022 12:58:34 +0800 Subject: [PATCH 172/627] feat: hide bt battery in statusbar --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 1 + app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../main/res/xml/prefs_system_hideicons.xml | 321 +++++++++--------- 5 files changed, 167 insertions(+), 158 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 9a745737..c642c5ce 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -335,6 +335,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { mPrefs.getBoolean("system_statusbaricons_hotspot") || mPrefs.getBoolean("system_statusbaricons_nosims") || mPrefs.getBoolean("system_statusbaricons_gps") || + mPrefs.getBoolean("system_statusbaricons_btbattery") || mPrefs.getBoolean("system_statusbaricons_volte"); if (hideIconsActive) System.HideIconsHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index b5815760..696d7d84 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -4050,6 +4050,7 @@ private static boolean checkSlot(String slotName) { "wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_wifi") || "hotspot".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_hotspot") || "no_sim".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nosims") || + "bluetooth_handsfree_battery".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_btbattery") || "hd".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_volte"); } catch (Throwable t) { XposedBridge.log(t); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 05c79e71..bff6b745 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -38,6 +38,7 @@ 完全隐藏 选择闹钟图标的可见性 仅在闹钟响铃前显示闹钟图标 + 蓝牙电量 移动网络信号 无SIM卡 热点 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 29b35800..459ed35a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,6 +42,7 @@ Hide completely Selective alarm icon visibility Show alarm icon only during the defined number of hours before next alarm + Bluetooth battery Mobile network signal No SIM card VoLTE diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index 7671a774..a2001736 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -1,159 +1,164 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 1191155aac88362b0999e70cb8cb7af5b138229f Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 7 Dec 2022 14:26:31 +0800 Subject: [PATCH 173/627] feat: show bt battery with center cutout --- .../name/mikanoshi/customiuizer/MainFragment.java | 3 +-- .../name/mikanoshi/customiuizer/MainModule.java | 1 + .../name/mikanoshi/customiuizer/mods/System.java | 3 +++ .../mikanoshi/customiuizer/subs/CommonActivity.java | 13 ------------- .../res/xml/prefs_system_statusbar_righticons.xml | 6 ++++++ 5 files changed, 11 insertions(+), 15 deletions(-) delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java index 41375a7e..66ce88e9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java @@ -46,7 +46,6 @@ import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; import name.mikanoshi.customiuizer.prefs.PreferenceEx; import name.mikanoshi.customiuizer.subs.CategorySelector; -import name.mikanoshi.customiuizer.subs.CommonActivity; import name.mikanoshi.customiuizer.subs.Controls; import name.mikanoshi.customiuizer.subs.Launcher; import name.mikanoshi.customiuizer.subs.System; @@ -379,7 +378,7 @@ public boolean onPreferenceClick(Preference pref) { Helpers.openURL(act, "https://www.paypal.com/paypalme/tpsxj"); } else { - openSubFragment(new CommonActivity(), null, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitle().toString(), R.layout.fragment_donate); + openSubFragment(new SubFragment(), null, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, pref.getTitle().toString(), R.layout.fragment_donate); } return true; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c642c5ce..9dbda64a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -265,6 +265,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_statusbar_sound_atright") || mPrefs.getBoolean("system_statusbar_dnd_atright") || mPrefs.getBoolean("system_statusbar_nfc_atright") + || mPrefs.getBoolean("system_statusbar_btbattery_atright") ) { System.StatusBarIconsAtRightHook(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 696d7d84..ff715968 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5334,6 +5334,9 @@ protected void after(MethodHookParam param) throws Throwable { if (MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) { rightBlockList.remove("zen"); } + if (MainModule.mPrefs.getBoolean("system_statusbar_btbattery_atright")) { + rightBlockList.remove("bluetooth_handsfree_battery"); + } if (MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) { rightBlockList.remove("nfc"); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java deleted file mode 100644 index f3e1602b..00000000 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/CommonActivity.java +++ /dev/null @@ -1,13 +0,0 @@ -package name.mikanoshi.customiuizer.subs; - -import android.os.Bundle; - -import name.mikanoshi.customiuizer.SubFragment; - -public class CommonActivity extends SubFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - this.padded = false; - super.onCreate(savedInstanceState); - } -} \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system_statusbar_righticons.xml b/app/src/main/res/xml/prefs_system_statusbar_righticons.xml index c2e5047f..ee16b747 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_righticons.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_righticons.xml @@ -41,6 +41,12 @@ android:title="@string/system_statusbaricons_dnd_title" android:defaultValue="false" /> + + + Date: Wed, 7 Dec 2022 15:22:19 +0800 Subject: [PATCH 174/627] adjust batteryandcurrent style in statusbar --- .../mikanoshi/customiuizer/mods/System.java | 27 +++++++------- app/src/main/res/xml/prefs_system.xml | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index ff715968..cc13d2ae 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1423,11 +1423,8 @@ protected void after(MethodHookParam param) throws Throwable { TextView meter = (TextView)param.thisObject; if (meter == null) return; if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)meter.getLayoutParams(); int margin = Math.round(meter.getResources().getDisplayMetrics().density * 4); - lp.rightMargin = margin; - lp.leftMargin = margin; - meter.setLayoutParams(lp); + meter.setPaddingRelative(margin, 0, margin, 0); } } }); @@ -5122,22 +5119,26 @@ private static TextView createBatteryDetailView(Context mContext, LinearLayout.L Resources res = mContext.getResources(); int styleId = res.getIdentifier("TextAppearance.StatusBar.Clock", "style", "com.android.systemui"); batteryView.setTextAppearance(styleId); + float fontSize = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_fontsize", 16) * 0.5f; int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); if (opt == 1) { - batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 8.5f); - batteryView.setLineSpacing(0, 0.9f); + batteryView.setLineSpacing(0, fontSize > 8.5f ? 0.85f : 0.9f); batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); } - else { - batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13.45f); - } - int horizonMargin = (int) TypedValue.applyDimension( + batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize); + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_leftmargin", 8); + leftMargin = (int)TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin * 0.5f, + res.getDisplayMetrics() + ); + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_rightmargin", 8); + rightMargin = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, - 2.5f, + rightMargin * 0.5f, res.getDisplayMetrics() ); - lp.leftMargin = horizonMargin; - lp.rightMargin = horizonMargin; + batteryView.setPaddingRelative(leftMargin, 0, rightMargin, 0); batteryView.setLayoutParams(lp); return batteryView; } diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 5e7f0a83..854000a9 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -438,6 +438,42 @@ miuizer:child="true" android:defaultValue="false" /> + + + + + + Date: Wed, 7 Dec 2022 23:08:55 +0800 Subject: [PATCH 175/627] feat: statusbar horiz padding --- .../mikanoshi/customiuizer/MainModule.java | 2 +- .../mikanoshi/customiuizer/mods/System.java | 220 +++--------------- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 41 ++-- 5 files changed, 56 insertions(+), 209 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 9dbda64a..fc55adbe 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -273,7 +273,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.StatusBarClockAtRightHook(lpparam); } if (mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) System.DisplayBatteryDetailHook(lpparam); - if (mPrefs.getBoolean("system_showlux")) System.BrightnessLuxHook(lpparam); + if (mPrefs.getBoolean("system_statusbar_horizmargin")) System.HorizMarginHook(lpparam); if (mPrefs.getBoolean("system_showpct")) System.BrightnessPctHook(lpparam); if (mPrefs.getBoolean("system_cleanmirror")) System.ClearBrightnessMirrorHook(lpparam); if (mPrefs.getBoolean("system_hidelsstatusbar")) System.HideLockScreenStatusBarHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index cc13d2ae..027b7e62 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5407,200 +5407,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - private static final TextView[] lux = { null, null, null }; - private static class LuxListener implements SensorEventListener { - @Override - public void onSensorChanged(SensorEvent event) { - long cTime = currentTimeMillis(); - String caption = null; - - if (lux[0] != null && lux[0].isAttachedToWindow()) try { - Long last = (Long)lux[0].getTag(); - if (last != null && cTime - last < 750) return; - caption = Helpers.getModuleRes(lux[0].getContext()).getString(R.string.lux, String.valueOf(Math.round(event.values[0]))); - lux[0].setText(caption); - lux[0].setTag(cTime); - } catch (Throwable t) { - XposedBridge.log(t); - } - - if (lux[1] != null && lux[1].isAttachedToWindow()) try { - Long last = (Long)lux[1].getTag(); - if (last != null && cTime - last < 750) return; - if (caption == null) - caption = Helpers.getModuleRes(lux[1].getContext()).getString(R.string.lux, String.valueOf(Math.round(event.values[0]))); - lux[1].setText(caption); - lux[1].setTag(cTime); - } catch (Throwable t) { - XposedBridge.log(t); - } - - if (lux[2] != null && lux[2].isAttachedToWindow()) try { - Long last = (Long)lux[2].getTag(); - if (last != null && cTime - last < 750) return; - if (caption == null) - caption = Helpers.getModuleRes(lux[2].getContext()).getString(R.string.lux, String.valueOf(Math.round(event.values[0]))); - lux[2].setText(caption); - lux[2].setTag(cTime); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) {} - } - - private static void registerLuxListener(Object statusBar) { - try { - Context mContext = (Context)XposedHelpers.getObjectField(statusBar, "mContext"); - PowerManager powerMgr = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); - if (!powerMgr.isInteractive()) return; - boolean sBootCompleted = XposedHelpers.getBooleanField(statusBar, "sBootCompleted"); - if (!sBootCompleted) return; - SensorManager sensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE); - LuxListener mLuxListener = (LuxListener)XposedHelpers.getAdditionalInstanceField(statusBar, "mLuxListener"); - sensorMgr.registerListener(mLuxListener, sensorMgr.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_NORMAL); - XposedHelpers.setAdditionalInstanceField(statusBar, "mListenerEnabled", true); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - - private static void unregisterLuxListener(Object statusBar) { - try { - Context mContext = (Context)XposedHelpers.getObjectField(statusBar, "mContext"); - SensorManager sensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE); - LuxListener mLuxListener = (LuxListener)XposedHelpers.getAdditionalInstanceField(statusBar, "mLuxListener"); - sensorMgr.unregisterListener(mLuxListener); - XposedHelpers.setAdditionalInstanceField(statusBar, "mListenerEnabled", false); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - - public static void setTextColors(Context context, TextView textView) { - textView.setTextColor(Helpers.isNightMode(context) ? 0xFFDDDDDD : 0xFF606060); - if (Helpers.isNightMode(context)) - textView.setShadowLayer(context.getResources().getDisplayMetrics().density, 1f, 1f, 0xEE222224); - else - textView.setShadowLayer(0, 0, 0, Color.WHITE); - } - - public static void BrightnessLuxHook(LoadPackageParam lpparam) { - MethodHook hook = new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context context = (Context)param.args[0]; - ViewGroup container = (ViewGroup)param.thisObject; - int port = context.getResources().getIdentifier("qs_brightness", "id", lpparam.packageName); - int land = context.getResources().getIdentifier("qs_brightness_land", "id", lpparam.packageName); - if (container.getId() != port && container.getId() != land) return; - - TextView clux = new TextView(context); - RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); - lp.alignWithParent = true; - lp.addRule(RelativeLayout.CENTER_IN_PARENT); - clux.setLayoutParams(lp); - clux.setGravity(Gravity.CENTER); - - boolean isAlt = MainModule.mPrefs.getBoolean("system_showlux_style"); - setTextColors(context, clux); - if (isAlt) { - clux.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); - clux.setAlpha(0.33f); - } - - container.addView(clux); - - if ("QCToggleSliderView".equals(param.thisObject.getClass().getSimpleName())) { - if (container.getId() == land) - lux[2] = clux; - else - lux[1] = clux; - } else { - lux[0] = clux; - } - } - }; - - Helpers.findAndHookConstructor("com.android.systemui.settings.ToggleSliderView", lpparam.classLoader, Context.class, AttributeSet.class, int.class, hook); - Helpers.findAndHookConstructor("com.android.systemui.miui.controlcenter.QCToggleSliderView", lpparam.classLoader, Context.class, AttributeSet.class, int.class, hook); - - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - LuxListener mLuxListener = new LuxListener(); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mLuxListener", mLuxListener); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mListenerEnabled", false); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "setPanelExpanded", boolean.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean isExpanded = (boolean)param.args[0]; - boolean mListenerEnabled = (boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mListenerEnabled"); - - if (isExpanded && !mListenerEnabled) - registerLuxListener(param.thisObject); - else if (!isExpanded && mListenerEnabled) - unregisterLuxListener(param.thisObject); - } - }); - - if (Helpers.is12()) { - Helpers.findAndHookMethod("com.android.systemui.miui.controlcenter.QSControlCenterPanel", lpparam.classLoader, "setListening", boolean.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean isExpanded = (boolean)param.args[0]; - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Object mApplication = XposedHelpers.callMethod(mContext.getApplicationContext(), "getSystemUIApplication"); - Object mStatusBar = XposedHelpers.callMethod(mApplication, "getComponent", findClassIfExists("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader)); - boolean mListenerEnabled = (boolean)XposedHelpers.getAdditionalInstanceField(mStatusBar, "mListenerEnabled"); - if (isExpanded && !mListenerEnabled) - registerLuxListener(mStatusBar); - else if (!isExpanded && mListenerEnabled) - unregisterLuxListener(mStatusBar); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.miui.controlcenter.QSControlCenterPanel", lpparam.classLoader, "updateResources", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (lux[1] != null) setTextColors(mContext, lux[1]); - if (lux[2] != null) setTextColors(mContext, lux[2]); - } - }); - } - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "onScreenTurnedOff", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - unregisterLuxListener(param.thisObject); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "onScreenTurnedOn", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean mPanelExpanded = XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); - boolean mListenerEnabled = (boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mListenerEnabled"); - if (mPanelExpanded && !mListenerEnabled) registerLuxListener(param.thisObject); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "onBootCompleted", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean mPanelExpanded = XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); - boolean mListenerEnabled = (boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mListenerEnabled"); - if (mPanelExpanded && !mListenerEnabled) registerLuxListener(param.thisObject); - } - }); - } - @SuppressLint("StaticFieldLeak") private static TextView mPct = null; private static void initPct(ViewGroup container, int source, Context context) { @@ -8191,6 +7997,32 @@ protected void after(final MethodHookParam param) throws Throwable { }); } + public static void HorizMarginHook(LoadPackageParam lpparam) { + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarWindowView", lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Context context = Helpers.findContext(); + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_left", 16); + float marginLeft = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin, + context.getResources().getDisplayMetrics() + ); + leftMargin = (int) marginLeft; + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_right", 16); + float marginRight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin, + context.getResources().getDisplayMetrics() + ); + rightMargin = (int) marginRight; + param.setResult(new Pair(Integer.valueOf(leftMargin), Integer.valueOf(rightMargin))); + } + }); + } + public static void MobileTypeSingleHook(LoadPackageParam lpparam) { MethodHook showSingleMobileType = new MethodHook(MethodHook.PRIORITY_HIGHEST) { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index bff6b745..6e980da2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1067,6 +1067,7 @@ 移动网络类型单独显示 左侧间距 上下偏移量 + 状态栏水平边距 应用信息 强制关闭 重启系统界面 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 459ed35a..bc1d26cc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1117,6 +1117,7 @@ Put mobile network type at the right of signal icon Left margin Vertical offset + Statusbar horizontal padding Move some icons to the right Mainly for devices with cutout at the center of the top edge Network speed indicator diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 854000a9..1b5f22bd 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -483,12 +483,39 @@ android:key="pref_key_system_statusbarheight" android:title="@string/system_statusbarheight_title" android:defaultValue="19" + app:isPreferenceVisible="false" miuizer:offtext="@string/array_default" miuizer:minValue="19" miuizer:maxValue="100" miuizer:stepValue="1" miuizer:format="%d dip" /> + + + + + + - - - - Date: Fri, 9 Dec 2022 14:57:56 +0800 Subject: [PATCH 176/627] increase left padding limit in statusbar --- .../mikanoshi/customiuizer/MainModule.java | 3 +-- .../mikanoshi/customiuizer/mods/System.java | 24 +------------------ app/src/main/res/values-pl-rPL/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - app/src/main/res/xml/prefs_system.xml | 7 +----- 7 files changed, 3 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index fc55adbe..74edf9f2 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -259,7 +259,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationHook(lpparam); if (mPrefs.getBoolean("system_lockscreenshortcuts")) System.LockScreenShortcutHook(lpparam); if (mPrefs.getBoolean("system_4gtolte")) System.Network4GtoLTEHook(lpparam); - if (mPrefs.getBoolean("system_statusbar_dttosleep")) System.StatusBarDoubleTapToSleepHook(lpparam); if (mPrefs.getBoolean("system_statusbar_netspeed_atright") || mPrefs.getBoolean("system_statusbar_alarm_atright") || mPrefs.getBoolean("system_statusbar_sound_atright") @@ -388,7 +387,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("various_restrictapp")) Various.AppsRestrictPowerHook(lpparam); } - if (pkg.equals("com.android.settings")) { + if (pkg.equals("com.android.settings") && lpparam.processName.equals("com.android.settings")) { GlobalActions.miuizerSettingsRes(); GlobalActions.miuizerSettings12Hook(lpparam); if (mPrefs.getBoolean("system_separatevolume")) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 027b7e62..ee61ad14 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5087,29 +5087,7 @@ protected void after(MethodHookParam param) throws Throwable { } }); } - public static void StatusBarDoubleTapToSleepHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Object mDoubleTapControllerEx = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mDoubleTapControllerEx"); - if (mDoubleTapControllerEx != null) return; - mDoubleTapControllerEx = new Launcher.DoubleTapController((Context)param.args[0], ""); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mDoubleTapControllerEx", mDoubleTapControllerEx); - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "handleEvent", MotionEvent.class, new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Launcher.DoubleTapController mDoubleTapControllerEx = (Launcher.DoubleTapController)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mDoubleTapControllerEx"); - if (mDoubleTapControllerEx == null) return; - boolean isPanelVisible = (boolean)XposedHelpers.callMethod(param.thisObject, "shouldPanelBeVisible"); - if (isPanelVisible) return; - if (!mDoubleTapControllerEx.isDoubleTapEvent((MotionEvent)param.args[0])) return; - GlobalActions.goToSleep(mDoubleTapControllerEx.mContext); - } - }); - } private static TextView createBatteryDetailView(Context mContext, LinearLayout.LayoutParams lp) { TextView batteryView = (TextView) LayoutInflater.from(mContext).inflate(statusbarTextIconLayoutResId, null); XposedHelpers.setObjectField(batteryView, "mVisibilityByDisableInfo", 0); @@ -6147,9 +6125,9 @@ protected void before(final MethodHookParam param) throws Throwable { currentTouchTime = currentTimeMillis(); currentTouchX = event.getX(); if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100F) { - GlobalActions.handleAction(mContext, "pref_key_system_statusbarcontrols_dt"); currentTouchTime = 0L; currentTouchX = 0F; + GlobalActions.handleAction(mContext, "pref_key_system_statusbarcontrols_dt"); } case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 9c066c24..b8c8266b 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -1104,7 +1104,6 @@ Wyświetl temperaturę i prąd baterii Wyświetl informacje Wyświetlacz po prawej stronie - Kliknij dwukrotnie, aby spać Paski sygnałowe Dual SIM w dwóch rzędach prawy margines Umieść typ sieci komórkowej po prawej stronie ikony sygnału diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6e980da2..52606ec5 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1052,7 +1052,6 @@ LSPosed模式 假定已安装LSPosed框架以使用其管理器 正在运行的服务 - 双击锁屏 系统图标移至右侧显示 部分针对中置挖孔屏 网速 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 0ac41ec5..e2101271 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -858,7 +858,6 @@ 百分比面板的上邊距 增大延遲間隔的數字並添加開啟目前延遲通知列表的圖示到啟動器 延遲通知管理器 - 雙擊鎖屏 黑名單 盡量將狀態欄和應用操作欄的背景顏色保持一致 狀態欄背景顏色 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bc1d26cc..37183733 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1111,7 +1111,6 @@ Display battery temp and current Display info Display on the right - Double tap to sleep Dual SIM signal bars in dual rows Right margin Put mobile network type at the right of signal icon diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 1b5f22bd..f9d8f7c8 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -501,7 +501,7 @@ android:defaultValue="16" miuizer:child="true" miuizer:minValue="0" - miuizer:maxValue="60" + miuizer:maxValue="80" miuizer:stepValue="1" miuizer:format="%s dip" /> @@ -579,11 +579,6 @@ android:summary="@string/system_statusbarcontrols_summ" android:title="@string/system_statusbarcontrols_title" /> - - Date: Mon, 12 Dec 2022 20:58:54 +0800 Subject: [PATCH 177/627] start --- .../customiuizer/mods/GlobalActions.java | 10 ++- .../mikanoshi/customiuizer/mods/System.java | 89 ++++++++++++------- .../subs/Various_CallReminder.java | 1 - .../mikanoshi/customiuizer/utils/Helpers.java | 16 ++-- 4 files changed, 72 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 0572789c..815be465 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -975,7 +975,15 @@ public void onReceive(final Context context, Intent intent) { } public static void setupStatusBar(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "start", new MethodHook() { + Class StatusBarClass; + if (Helpers.isTPlus()) { + StatusBarClass = findClassIfExists("com.android.systemui.statusbar.phone.CentralSurfacesImpl", lpparam.classLoader); + } + else { + StatusBarClass = findClassIfExists("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader); + } + if (StatusBarClass == null) return; + Helpers.findAndHookMethod(StatusBarClass, "start", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { mStatusBar = param.thisObject; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index ee61ad14..a88480a9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -909,15 +909,20 @@ protected void after(MethodHookParam param) throws Throwable { private static ClassLoader pluginLoader = null; public static void MIUIVolumeDialogHook(LoadPackageParam lpparam) { - final boolean[] isHooked = {false}; - Helpers.findAndHookMethod("com.android.systemui.shared.plugins.PluginManagerImpl", lpparam.classLoader, "getClassLoader", ApplicationInfo.class, new MethodHook() { + Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + if (PluginContextWrapper == null) { + PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + } + if (PluginContextWrapper == null) return; + Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked[0]) { - isHooked[0] = true; + Context pluginContext = (Context) param.args[0]; + if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); + pluginLoader = (ClassLoader) param.args[1]; } Class MiuiVolumeDialogImpl = XposedHelpers.findClassIfExists("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", pluginLoader); if (MainModule.mPrefs.getBoolean("system_separatevolume") && MainModule.mPrefs.getBoolean("system_separatevolume_slider")) { @@ -2607,16 +2612,20 @@ protected void after(MethodHookParam param) throws Throwable { } }); - - final boolean[] isHooked = {false}; - Helpers.findAndHookMethod("com.android.systemui.shared.plugins.PluginManagerImpl", lpparam.classLoader, "getClassLoader", ApplicationInfo.class, new MethodHook() { + Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + if (PluginContextWrapper == null) { + PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + } + if (PluginContextWrapper == null) return; + Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked[0]) { - isHooked[0] = true; + Context pluginContext = (Context) param.args[0]; + if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); + pluginLoader = (ClassLoader) param.args[1]; } MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85.0f); Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); @@ -3458,15 +3467,20 @@ protected void after(MethodHookParam param) throws Throwable { public static void VolumeTimerValuesRes(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("miui.systemui.plugin", "array", "miui_volume_timer_segments", R.array.miui_volume_timer_segments); - final boolean[] isHooked = {false}; - Helpers.findAndHookMethod("com.android.systemui.shared.plugins.PluginManagerImpl", lpparam.classLoader, "getClassLoader", ApplicationInfo.class, new MethodHook() { + Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + if (PluginContextWrapper == null) { + PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + } + if (PluginContextWrapper == null) return; + Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked[0]) { - isHooked[0] = true; + Context pluginContext = (Context) param.args[0]; + if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); + pluginLoader = (ClassLoader) param.args[1]; } Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeTimerDrawableHelper", pluginLoader, "initTimerString", new MethodHook() { @Override @@ -3815,7 +3829,7 @@ public void onReceive(Context context, Intent intent) { } }); - if (!Helpers.isNougat() && MainModule.mPrefs.getBoolean("system_defaultusb_unsecure")) { + if (MainModule.mPrefs.getBoolean("system_defaultusb_unsecure")) { if (!Helpers.findAndHookMethodSilently("com.android.server.usb.UsbDeviceManager$UsbHandler", lpparam.classLoader, "isUsbDataTransferActive", long.class, XC_MethodReplacement.returnConstant(true))) Helpers.findAndHookMethod("com.android.server.usb.UsbDeviceManager$UsbHandler", lpparam.classLoader, "isUsbDataTransferActive", XC_MethodReplacement.returnConstant(true)); Helpers.findAndHookMethod("com.android.server.usb.UsbDeviceManager$UsbHandler", lpparam.classLoader, "handleMessage", Message.class, new MethodHook() { @@ -8295,6 +8309,7 @@ protected void after(MethodHookParam param) throws Throwable { int stockTilesResId = mContext.getResources().getIdentifier("miui_quick_settings_tiles_stock", "string", lpparam.packageName); String stockTiles = mContext.getString(stockTilesResId) + ",custom_5G"; MainModule.resHooks.setObjectReplacement(lpparam.packageName, "string", "miui_quick_settings_tiles_stock", stockTiles); + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "string", "miui_quick_settings_tiles_stock", stockTiles); MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "string", "quick_settings_tiles_stock", stockTiles); } } @@ -8465,15 +8480,20 @@ protected void after(MethodHookParam param) throws Throwable { } }); - final boolean[] isHooked = {false}; - Helpers.findAndHookMethod("com.android.systemui.shared.plugins.PluginManagerImpl", lpparam.classLoader, "getClassLoader", ApplicationInfo.class, new MethodHook() { + Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + if (PluginContextWrapper == null) { + PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + } + if (PluginContextWrapper == null) return; + Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked[0]) { - isHooked[0] = true; + Context pluginContext = (Context) param.args[0]; + if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); + pluginLoader = (ClassLoader) param.args[1]; } if (cols > 4) { Helpers.findAndHookConstructor("miui.systemui.controlcenter.qs.QSPager", pluginLoader, Context.class, AttributeSet.class, new MethodHook() { @@ -8565,15 +8585,20 @@ public static void CCTileCornerHook(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_disabled", R.drawable.ic_qs_tile_bg_disabled); MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_warning", R.drawable.ic_qs_tile_bg_warning); - final boolean[] isHooked = {false}; - Helpers.findAndHookMethod("com.android.systemui.shared.plugins.PluginManagerImpl", lpparam.classLoader, "getClassLoader", ApplicationInfo.class, new MethodHook() { + Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + if (PluginContextWrapper == null) { + PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); + } + if (PluginContextWrapper == null) return; + Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked[0]) { - isHooked[0] = true; + Context pluginContext = (Context) param.args[0]; + if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); + pluginLoader = (ClassLoader) param.args[1]; } Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.tileview.ExpandableIconView", pluginLoader, "setCornerRadius", float.class, new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java index 5ad620b5..05aaf892 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Various_CallReminder.java @@ -122,7 +122,6 @@ public void onClick(View v) { dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (Helpers.isNougat()) return; EditText edit = dialog.findViewById(android.R.id.edit); Vibrator vibrator = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE); try { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 4656de68..896a1913 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -73,6 +73,7 @@ import java.io.InputStream; import java.io.OutputStreamWriter; import java.lang.reflect.Field; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Paths; @@ -242,16 +243,12 @@ public static boolean isNightMode(Context context) { return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } - public static boolean isNougat() { - return false; - } - public static boolean isQPlus() { return true; } - public static boolean isRPlus() { - return Build.VERSION.SDK_INT >= 31; + public static boolean isTPlus() { + return Build.VERSION.SDK_INT >= 33; } public static boolean isDeviceEncrypted(Context context) { @@ -1155,13 +1152,12 @@ public static void performCustomVibration(Context context, int vibration, String pattern = getVibrationPattern(ownPattern); break; } - if (!isNougat()) try { + try { vibrator.vibrate(VibrationEffect.createWaveform(pattern, -1)); } catch (Throwable t) { //noinspection deprecation vibrator.vibrate(200); - } else - vibrator.vibrate(200); + } } public static long[] getVibrationPattern(String patternStr) { @@ -1628,7 +1624,7 @@ public final void afterHookedMethod(MethodHookParam param) throws Throwable { } } - public static void hookMethod(Method method, MethodHook callback) { + public static void hookMethod(Member method, MethodHook callback) { try { XposedBridge.hookMethod(method, callback); } catch (Throwable t) { From 677b0f80bc18e7c1e715082cdf86c52ef6c0635c Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 12 Dec 2022 22:55:09 +0800 Subject: [PATCH 178/627] fix(miui14): statusbar horizmargin --- .../mikanoshi/customiuizer/mods/System.java | 80 +++++++------------ .../mikanoshi/customiuizer/utils/Helpers.java | 4 - 2 files changed, 28 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index a88480a9..9b5d6b01 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -314,7 +314,7 @@ protected void after(MethodHookParam param) throws Throwable { } public static void NoPasswordHook() { - String isAllowed = Helpers.isQPlus() ? "isBiometricAllowedForUser" : "isFingerprintAllowedForUser"; + String isAllowed = "isBiometricAllowedForUser"; Helpers.findAndHookMethod("com.android.internal.widget.LockPatternUtils$StrongAuthTracker", null, isAllowed, boolean.class, int.class, XC_MethodReplacement.returnConstant(true)); Helpers.findAndHookMethod("com.android.internal.widget.LockPatternUtils", null, isAllowed, int.class, XC_MethodReplacement.returnConstant(true)); } @@ -2673,8 +2673,8 @@ public void onChange(String name, int defValue) { } }); - String windowClass = Helpers.isQPlus() ? "com.android.server.wm.DisplayRotation" : "com.android.server.policy.PhoneWindowManager"; - String rotMethod = Helpers.isQPlus() ? "rotationForOrientation" : "rotationForOrientationLw"; + String windowClass = "com.android.server.wm.DisplayRotation"; + String rotMethod = "rotationForOrientation"; Helpers.hookAllMethods(windowClass, lpparam.classLoader, rotMethod, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -3780,20 +3780,12 @@ public static void AllRotationsRes() { } public static void AllRotationsHook(LoadPackageParam lpparam) { - if (Helpers.isQPlus()) - Helpers.hookAllConstructors("com.android.server.wm.DisplayRotation", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setIntField(param.thisObject, "mAllowAllRotations", MainModule.mPrefs.getStringAsInt("system_allrotations2", 1) == 2 ? 1 : 0); - } - }); - else - Helpers.hookAllMethods("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "init", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setIntField(param.thisObject, "mAllowAllRotations", MainModule.mPrefs.getStringAsInt("system_allrotations2", 1) == 2 ? 1 : 0); - } - }); + Helpers.hookAllConstructors("com.android.server.wm.DisplayRotation", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.setIntField(param.thisObject, "mAllowAllRotations", MainModule.mPrefs.getStringAsInt("system_allrotations2", 1) == 2 ? 1 : 0); + } + }); } private static boolean mUSBConnected = false; @@ -4243,21 +4235,16 @@ public static void TextMagnifierHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Point mClampedCenterZoomCoords = (Point)XposedHelpers.getObjectField(param.thisObject, "mClampedCenterZoomCoords"); - if (Helpers.isQPlus()) { - Object mView = XposedHelpers.getObjectField(param.thisObject, "mView"); - float f = (float)param.args[0]; - int x; - if (mView instanceof SurfaceView) { - x = Math.round(f); - } else { - int[] mViewCoordinatesInSurface = (int[])XposedHelpers.getObjectField(param.thisObject, "mViewCoordinatesInSurface"); - x = Math.round(f + (float)mViewCoordinatesInSurface[0]); - } - mClampedCenterZoomCoords.x = x; + Object mView = XposedHelpers.getObjectField(param.thisObject, "mView"); + float f = (float)param.args[0]; + int x; + if (mView instanceof SurfaceView) { + x = Math.round(f); } else { - Point mCenterZoomCoords = (Point)XposedHelpers.getObjectField(param.thisObject, "mCenterZoomCoords"); - mClampedCenterZoomCoords.x = mCenterZoomCoords.x; + int[] mViewCoordinatesInSurface = (int[])XposedHelpers.getObjectField(param.thisObject, "mViewCoordinatesInSurface"); + x = Math.round(f + (float)mViewCoordinatesInSurface[0]); } + mClampedCenterZoomCoords.x = x; } }); @@ -5049,11 +5036,7 @@ public void run() { } }; - if (Helpers.isQPlus()) - Helpers.findAndHookConstructor("android.media.session.MediaSession", null, Context.class, String.class, Bundle.class, hook); - else - Helpers.findAndHookConstructor("android.media.session.MediaSession", null, Context.class, String.class, int.class, hook); - + Helpers.findAndHookConstructor("android.media.session.MediaSession", null, Context.class, String.class, Bundle.class, hook); Helpers.findAndHookMethod("android.media.session.MediaSession", null, "setActive", boolean.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { @@ -5620,20 +5603,12 @@ protected void after(MethodHookParam param) throws Throwable { } public static void NoOverscrollHook() { - if (Helpers.isQPlus()) - Helpers.findAndHookMethod("android.widget.AbsListView", null, "initAbsListView", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - ((AbsListView)param.thisObject).setOverScrollMode(View.OVER_SCROLL_NEVER); - } - }); - else - Helpers.findAndHookMethod("android.widget.AbsListView", null, "setOverScrollMode", int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = View.OVER_SCROLL_NEVER; - } - }); + Helpers.findAndHookMethod("android.widget.AbsListView", null, "initAbsListView", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + ((AbsListView)param.thisObject).setOverScrollMode(View.OVER_SCROLL_NEVER); + } + }); } public static void NoOverscrollAppHook(LoadPackageParam lpparam) { @@ -6310,7 +6285,7 @@ public void onChange(String name, int defValue) { } }); - String windowClass = Helpers.isQPlus() ? "com.android.server.wm.DisplayPolicy" : "com.android.server.policy.PhoneWindowManager"; + String windowClass = "com.android.server.wm.DisplayPolicy"; Helpers.hookAllMethods(windowClass, lpparam.classLoader, "adjustWindowParamsLw", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { @@ -6334,7 +6309,7 @@ protected void after(MethodHookParam param) throws Throwable { } public static void ClearAllTasksHook(LoadPackageParam lpparam) { - String wpuClass = Helpers.isQPlus() ? "com.android.server.wm.WindowProcessUtils" : "com.android.server.am.ProcessUtils"; + String wpuClass = "com.android.server.wm.WindowProcessUtils"; Helpers.hookAllMethods(wpuClass, lpparam.classLoader, "getPerceptibleRecentAppList", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -7992,7 +7967,8 @@ protected void after(final MethodHookParam param) throws Throwable { public static void HorizMarginHook(LoadPackageParam lpparam) { MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarWindowView", lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", new MethodHook() { + String StatusBarWindowViewCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.window.StatusBarWindowView" : "com.android.systemui.statusbar.phone.StatusBarWindowView"; + Helpers.hookAllMethods(StatusBarWindowViewCls, lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { Context context = Helpers.findContext(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 896a1913..ff7c4708 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -243,10 +243,6 @@ public static boolean isNightMode(Context context) { return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } - public static boolean isQPlus() { - return true; - } - public static boolean isTPlus() { return Build.VERSION.SDK_INT >= 33; } From 6275a0bf1c5b3db884bf012a078240ded22b4b22 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 12 Dec 2022 22:59:38 +0800 Subject: [PATCH 179/627] fix(miui14): max notify icons --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 9b5d6b01..bf523bb7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6955,7 +6955,8 @@ protected void before(MethodHookParam param) throws Throwable { opt = opt == -1 ? 999 : opt; XposedHelpers.setObjectField(param.thisObject, "MAX_DOTS", 3); XposedHelpers.setObjectField(param.thisObject, "MAX_STATIC_ICONS", opt); - XposedHelpers.setObjectField(param.thisObject, "MAX_VISIBLE_ICONS_ON_LOCK", opt); + String fieldLockVisible = Helpers.isTPlus() ? "MAX_ICONS_ON_LOCKSCREEN" : "MAX_VISIBLE_ICONS_ON_LOCK"; + XposedHelpers.setObjectField(param.thisObject, fieldLockVisible, opt); XposedHelpers.callMethod(param.thisObject, "updateState"); param.setResult(null); } From 384a87f4546d3838dd7387d8f402da8971f6d4d2 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 12 Dec 2022 23:45:15 +0800 Subject: [PATCH 180/627] fix(miui14): 5G tile --- .../mikanoshi/customiuizer/mods/System.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bf523bb7..de668b86 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8291,20 +8291,23 @@ protected void after(MethodHookParam param) throws Throwable { } } }); + String QSFactoryCls = Helpers.isTPlus() ? "com.android.systemui.qs.tileimpl.MiuiQSFactory" : "com.android.systemui.qs.tileimpl.QSFactoryImpl"; Class ResourceIconClass = findClass("com.android.systemui.qs.tileimpl.QSTileImpl$ResourceIcon", lpparam.classLoader); - Helpers.findAndHookMethod("com.android.systemui.qs.tileimpl.QSFactoryImpl", lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { + Helpers.findAndHookMethod(QSFactoryCls, lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { String tileName = (String) param.args[0]; if (tileName.startsWith("custom_")) { - Object provider = XposedHelpers.getObjectField(param.thisObject, "mNfcTileProvider"); + String nfcField = Helpers.isTPlus() ? "nfcTileProvider" : "mNfcTileProvider"; + Object provider = XposedHelpers.getObjectField(param.thisObject, nfcField); Object tile = XposedHelpers.callMethod(provider, "get"); XposedHelpers.setAdditionalInstanceField(tile, "customName", tileName); param.setResult(tile); } } }); - Helpers.findAndHookMethod("com.android.systemui.qs.tiles.NfcTile", lpparam.classLoader, "isAvailable", new MethodHook() { + String NfcTileCls = Helpers.isTPlus() ? "com.android.systemui.qs.tiles.MiuiNfcTile" : "com.android.systemui.qs.tiles.NfcTile"; + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "isAvailable", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); @@ -8319,7 +8322,7 @@ protected void before(MethodHookParam param) throws Throwable { } } }); - Helpers.findAndHookMethod("com.android.systemui.qs.tiles.NfcTile", lpparam.classLoader, "getTileLabel", new MethodHook() { + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "getTileLabel", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); @@ -8333,7 +8336,7 @@ protected void before(MethodHookParam param) throws Throwable { } } }); - Helpers.findAndHookMethod("com.android.systemui.qs.tiles.NfcTile", lpparam.classLoader, "handleSetListening", boolean.class, new MethodHook() { + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "handleSetListening", boolean.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); @@ -8362,7 +8365,7 @@ public void onChange(boolean z) { } } }); - Helpers.findAndHookMethod("com.android.systemui.qs.tiles.NfcTile", lpparam.classLoader, "getLongClickIntent", new MethodHook() { + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "getLongClickIntent", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); @@ -8380,7 +8383,7 @@ protected void before(MethodHookParam param) throws Throwable { } } }); - Helpers.findAndHookMethod("com.android.systemui.qs.tiles.NfcTile", lpparam.classLoader, "handleClick", View.class, new MethodHook() { + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "handleClick", View.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); @@ -8397,7 +8400,7 @@ protected void before(MethodHookParam param) throws Throwable { int fiveGIconResId = MainModule.resHooks.addResource("ic_qs_5g_on", R.drawable.ic_qs_5g_on); int fiveGIconOffResId = MainModule.resHooks.addResource("ic_qs_5g_off", R.drawable.ic_qs_5g_off); - Helpers.hookAllMethods("com.android.systemui.qs.tiles.NfcTile", lpparam.classLoader, "handleUpdateState", new MethodHook() { + Helpers.hookAllMethods(NfcTileCls, lpparam.classLoader, "handleUpdateState", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); From 52d1fbc31d2a13cc82561235594ed6bbd72a3f5d Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 13 Dec 2022 13:02:20 +0800 Subject: [PATCH 181/627] fix(miui14): auto expand notify --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index de668b86..9076f214 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1242,7 +1242,8 @@ protected void before(MethodHookParam param) throws Throwable { } public static void ExpandNotificationsHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.notification.row.ExpandableNotificationRow", lpparam.classLoader, "showFeedbackIcon", new MethodHook() { + String feedbackMethod = Helpers.isTPlus() ? "setFeedbackIcon" : "showFeedbackIcon"; + Helpers.hookAllMethods("com.android.systemui.statusbar.notification.row.ExpandableNotificationRow", lpparam.classLoader, feedbackMethod, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { boolean mOnKeyguard = (boolean) XposedHelpers.callMethod(param.thisObject, "isOnKeyguard"); From 300db4b36a9986cfc5ca9ae32ba95b1f4f75faa6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 13 Dec 2022 20:06:55 +0800 Subject: [PATCH 182/627] update hook cc --- .../mikanoshi/customiuizer/mods/System.java | 121 ++++++++---------- 1 file changed, 51 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 9076f214..b7c58d7a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -195,6 +195,7 @@ import name.mikanoshi.customiuizer.utils.SoundData; public class System { + private static String StatusBarCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfacesImpl" : "com.android.systemui.statusbar.phone.StatusBar"; public static void ScreenAnimHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.display.DisplayPowerController", lpparam.classLoader, "initialize", new MethodHook() { @@ -909,20 +910,16 @@ protected void after(MethodHookParam param) throws Throwable { private static ClassLoader pluginLoader = null; public static void MIUIVolumeDialogHook(LoadPackageParam lpparam) { - Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - if (PluginContextWrapper == null) { - PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - } - if (PluginContextWrapper == null) return; - Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - Context pluginContext = (Context) param.args[0]; - if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.args[1]; + pluginLoader = (ClassLoader) param.getResult(); } Class MiuiVolumeDialogImpl = XposedHelpers.findClassIfExists("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", pluginLoader); if (MainModule.mPrefs.getBoolean("system_separatevolume") && MainModule.mPrefs.getBoolean("system_separatevolume_slider")) { @@ -1260,7 +1257,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void PopupNotificationsHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "addNotification", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "addNotification", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { if (param.args[0] == null) return; @@ -2613,20 +2610,16 @@ protected void after(MethodHookParam param) throws Throwable { } }); - Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - if (PluginContextWrapper == null) { - PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - } - if (PluginContextWrapper == null) return; - Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - Context pluginContext = (Context) param.args[0]; - if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.args[1]; + pluginLoader = (ClassLoader) param.getResult(); } MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85.0f); Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); @@ -2867,7 +2860,7 @@ public static void ReplaceShortcutAppHook(LoadPackageParam lpparam) { MethodHook openAppHook = new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context) AndroidAppHelper.currentApplication(); + Context mContext = AndroidAppHelper.currentApplication(); int user = 0; String pkgAppName = ""; if (param.method.getName().equals("startCalendarApp")) { @@ -3468,20 +3461,16 @@ protected void after(MethodHookParam param) throws Throwable { public static void VolumeTimerValuesRes(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("miui.systemui.plugin", "array", "miui_volume_timer_segments", R.array.miui_volume_timer_segments); - Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - if (PluginContextWrapper == null) { - PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - } - if (PluginContextWrapper == null) return; - Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - Context pluginContext = (Context) param.args[0]; - if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.args[1]; + pluginLoader = (ClassLoader) param.getResult(); } Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeTimerDrawableHelper", pluginLoader, "initTimerString", new MethodHook() { @Override @@ -3626,7 +3615,7 @@ private static void updateAudioVisualizerState(Context context) { audioViz.updateViewState(isPlaying, isKeyguardShowing, isNotificationPanelExpanded); } public static void AudioVisualizerHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Object viewController = XposedHelpers.getObjectField(param.thisObject, "mNotificationPanelViewController"); @@ -3683,14 +3672,14 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "setPanelExpanded", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "setPanelExpanded", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { - boolean isNotificationPanelExpandedNew = XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); - if (isNotificationPanelExpanded != isNotificationPanelExpandedNew) { - isNotificationPanelExpanded = isNotificationPanelExpandedNew; - updateAudioVisualizerState((Context)XposedHelpers.getObjectField(param.thisObject, "mContext")); - } + boolean isNotificationPanelExpandedNew = XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); + if (isNotificationPanelExpanded != isNotificationPanelExpandedNew) { + isNotificationPanelExpanded = isNotificationPanelExpandedNew; + updateAudioVisualizerState((Context)XposedHelpers.getObjectField(param.thisObject, "mContext")); + } } }); @@ -4077,7 +4066,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void BatteryIndicatorHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); @@ -4098,7 +4087,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "setPanelExpanded", boolean.class, new MethodHook() { + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "setPanelExpanded", boolean.class, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); @@ -4107,7 +4096,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "setQsExpanded", boolean.class, new MethodHook() { + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "setQsExpanded", boolean.class, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); @@ -4117,7 +4106,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateKeyguardState", new MethodHook() { + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "updateKeyguardState", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); @@ -5764,7 +5753,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void HideQSHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "onStateChanged", int.class, new MethodHook() { + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "onStateChanged", int.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object mNotificationPanel = XposedHelpers.getObjectField(param.thisObject, "mQSContainer"); @@ -6033,7 +6022,7 @@ protected void after(MethodHookParam param) throws Throwable { public static void StatusBarGesturesHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); @@ -7799,7 +7788,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void HideLockScreenStatusBarHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { View mKeyguardStatusBar = (View) XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mNotificationPanelViewController"), "mKeyguardStatusBar"); @@ -8063,7 +8052,6 @@ public static void DualRowSignalHook(LoadPackageParam lpparam) { MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_type_middle_to_strength_start", -0.4f); } - final boolean[] isListened = {false}; SparseIntArray signalResToLevelMap = new SparseIntArray(); int signalRes1_0 = MainModule.resHooks.addResource("signalRes1_0", R.drawable.statusbar_signal_1_0); int signalRes1_1 = MainModule.resHooks.addResource("signalRes1_1", R.drawable.statusbar_signal_1_1); @@ -8153,10 +8141,11 @@ public static void DualRowSignalHook(LoadPackageParam lpparam) { signalDarkLevelToRes2Map.put(6, signalDarkRes2_0); Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarIconControllerImpl", lpparam.classLoader, "setMobileIcons", new MethodHook() { + private boolean isHooked = false; @Override protected void before(MethodHookParam param) throws Throwable { - if (!isListened[0]) { - isListened[0] = true; + if (!isHooked) { + isHooked = true; Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); Resources res = mContext.getResources(); signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_0", "drawable", lpparam.packageName), 0); @@ -8437,12 +8426,12 @@ public static void SystemCCGridHook(LoadPackageParam lpparam) { MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_min_rows", rows); } - final boolean[] isListened = {false}; Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - if (!isListened[0]) { - isListened[0] = true; + if (!isHooked) { + isHooked = true; Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); Resources res = mContext.getResources(); float density = res.getDisplayMetrics().density; @@ -8461,20 +8450,16 @@ protected void after(MethodHookParam param) throws Throwable { } }); - Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - if (PluginContextWrapper == null) { - PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - } - if (PluginContextWrapper == null) return; - Helpers.hookMethod(PluginContextWrapper, new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - Context pluginContext = (Context) param.args[0]; - if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.args[1]; + pluginLoader = (ClassLoader) param.getResult(); } if (cols > 4) { Helpers.findAndHookConstructor("miui.systemui.controlcenter.qs.QSPager", pluginLoader, Context.class, AttributeSet.class, new MethodHook() { @@ -8566,20 +8551,16 @@ public static void CCTileCornerHook(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_disabled", R.drawable.ic_qs_tile_bg_disabled); MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_warning", R.drawable.ic_qs_tile_bg_warning); - Constructor PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginActionManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - if (PluginContextWrapper == null) { - PluginContextWrapper = XposedHelpers.findConstructorExactIfExists("com.android.systemui.shared.plugins.PluginInstanceManager$PluginContextWrapper", lpparam.classLoader, Context.class, ClassLoader.class); - } - if (PluginContextWrapper == null) return; - Helpers.hookMethod(PluginContextWrapper, new MethodHook() { + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { - Context pluginContext = (Context) param.args[0]; - if ("miui.systemui.plugin".equals(pluginContext.getPackageName()) && !isHooked) { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { isHooked = true; if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.args[1]; + pluginLoader = (ClassLoader) param.getResult(); } Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.tileview.ExpandableIconView", pluginLoader, "setCornerRadius", float.class, new MethodHook() { @Override From de8844a879aa36f6e8a4130e975901b854c857d6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 14 Dec 2022 13:12:56 +0800 Subject: [PATCH 183/627] feat(miui14): Disable disconnect bluetooth until tomorrow --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++++ .../main/java/name/mikanoshi/customiuizer/subs/System.java | 4 ++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 6 ++++++ 6 files changed, 17 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 74edf9f2..7dbd02dd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -313,6 +313,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || !mPrefs.getString("system_clock_app", "").equals("")) System.ReplaceShortcutAppHook(lpparam); if (mPrefs.getStringAsInt("system_qshaptics", 1) > 1) System.QSHapticHook(lpparam); if (mPrefs.getBoolean("system_qs_hideoperator")) System.HideCCOperatorHook(lpparam); + if (mPrefs.getBoolean("system_cc_disable_bluetooth_restrict")) System.DisableBluetoothRestrictHook(lpparam); if (mPrefs.getBoolean("system_cc_collapse_after_clicked")) System.CollapseCCAfterClickHook(lpparam); if (mPrefs.getStringAsInt("system_expandnotifs", 1) > 1) System.ExpandNotificationsHook(lpparam); if (mPrefs.getStringAsInt("system_inactivebrightness", 1) > 1) System.InactiveBrightnessSliderHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index b7c58d7a..4e409cfc 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2310,6 +2310,10 @@ protected void after(MethodHookParam param) throws Throwable { }); } + public static void DisableBluetoothRestrictHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.settingslib.bluetooth.LocalBluetoothAdapter", lpparam.classLoader, "isSupportBluetoothRestrict", Context.class, XC_MethodReplacement.returnConstant(false)); + } + public static void AutoGroupNotificationsHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.notification.GroupHelper", lpparam.classLoader, "adjustAutogroupingSummary", int.class, String.class, String.class, boolean.class, new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index a8cc856a..7f66d518 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -244,6 +244,10 @@ public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); + + if (Helpers.isTPlus()) { + findPreference("pref_key_system_cc_disable_bluetooth_restrict").setVisible(true); + } break; case "pref_key_system_cat_recents": findPreference("pref_key_system_hidefromrecents_apps").setOnPreferenceClickListener(openAppsEdit); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 52606ec5..d42632d4 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1076,5 +1076,6 @@ 跳过开启特殊权限的倒计时 点击左侧图标时切换手电筒 圆角矩形磁贴 + 禁用蓝牙临时关闭态 单击开关后自动收起 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 37183733..a9c98455 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1125,5 +1125,6 @@ Skip permission intercept timer Tap left shortcut to toggle flashlight Rounded rectangle tile + Disable disconnect bluetooth until tomorrow Collapse after touch \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index f9d8f7c8..732e95b4 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -903,6 +903,12 @@ android:title="@string/system_cc_tile_roundedrect_title" android:defaultValue="false" /> + + Date: Thu, 15 Dec 2022 10:33:37 +0800 Subject: [PATCH 184/627] adjust battery temp-current position --- .../mikanoshi/customiuizer/MainModule.java | 2 -- .../mikanoshi/customiuizer/mods/Launcher.java | 15 --------- .../mikanoshi/customiuizer/mods/System.java | 33 +++---------------- app/src/main/res/xml/prefs_system.xml | 3 +- 4 files changed, 5 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 7dbd02dd..0eb7f64c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -202,7 +202,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); if (mPrefs.getStringAsInt("system_networkindicator", 1) == 3) System.NetworkIndicatorRes(lpparam); - if (mPrefs.getInt("system_statusbarheight", 19) > 19) System.StatusBarHeightHook(lpparam); if (mPrefs.getInt("system_recents_blur", 100) < 100) System.RecentsBlurRatioHook(lpparam); if (mPrefs.getInt("system_drawer_blur", 100) < 100) System.DrawerBlurRatioHook(lpparam); if (mPrefs.getInt("system_drawer_opacity", 100) < 100) System.DrawerThemeBackgroundHook(lpparam); @@ -484,7 +483,6 @@ private void handleLoadLauncher(final LoadPackageParam lpparam) { if (mPrefs.getInt("launcher_iconscale", 45) > 45) Launcher.IconScaleHook(lpparam); if (mPrefs.getInt("launcher_titlefontsize", 5) > 5) Launcher.TitleFontSizeHook(lpparam); if (mPrefs.getInt("launcher_titletopmargin", 0) > 0) Launcher.TitleTopMarginHook(lpparam); - if (mPrefs.getInt("system_statusbarheight", 19) > 19) Launcher.StatusBarHeightHook(lpparam); if (mPrefs.getBoolean("launcher_noclockhide")) Launcher.NoClockHideHook(lpparam); if (mPrefs.getBoolean("launcher_renameapps")) Launcher.RenameShortcutsHook(lpparam); if (mPrefs.getBoolean("launcher_darkershadow")) Launcher.TitleShadowHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index de31c736..30ea5524 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1268,21 +1268,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void StatusBarHeightHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.miui.home.launcher.Workspace", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - ViewGroup workspace = (ViewGroup)param.thisObject; - workspace.setPadding( - workspace.getPaddingLeft(), - workspace.getResources().getDimensionPixelSize(workspace.getResources().getIdentifier("status_bar_height", "dimen", "android")), - workspace.getPaddingRight(), - workspace.getPaddingBottom() - ); - } - }); - } - private static float scaleStiffness(float val, float scale) { return (scale < 1.0f ? 2f / scale : 1.0f / scale) * val; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 4e409cfc..0a33013e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2701,31 +2701,6 @@ public static void StatusBarHeightRes() { MainModule.resHooks.setDensityReplacement("*", "dimen", "status_bar_height_landscape", heightDpi); } - private static void applyHeight(Object thisObject) { - if (thisObject == null) return; - ViewGroup view = (ViewGroup)thisObject; - ViewGroup.LayoutParams lp = view.getLayoutParams(); - Resources res = view.getResources(); - lp.height = res.getDimensionPixelSize(res.getIdentifier("status_bar_height", "dimen", "android")); - view.setLayoutParams(lp); - } - - public static void StatusBarHeightHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - applyHeight(param.thisObject); - } - }); - - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.PhoneStatusBarView", lpparam.classLoader, "setBar", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - applyHeight(param.thisObject); - } - }); - } - @SuppressWarnings("ConstantConditions") public static void HideMemoryCleanHook(LoadPackageParam lpparam, boolean isInLauncher) { String raClass = isInLauncher ? "com.miui.home.recents.views.RecentsContainer" : "com.android.systemui.recents.RecentsActivity"; @@ -5220,10 +5195,10 @@ protected void before(MethodHookParam param) throws Throwable { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getContext"); - TextView mPadClockView = (TextView) XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedSplitter"); - ViewGroup batteryViewContainer = (ViewGroup) mPadClockView.getParent(); - int bvIndex = batteryViewContainer.indexOfChild(mPadClockView) - 1; - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mPadClockView.getLayoutParams(); + TextView mSplitter = (TextView) XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedSplitter"); + ViewGroup batteryViewContainer = (ViewGroup) mSplitter.getParent(); + int bvIndex = batteryViewContainer.indexOfChild(mSplitter); + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSplitter.getLayoutParams(); TextView batteryView = createBatteryDetailView(mContext, lp); batteryViewContainer.addView(batteryView, bvIndex); mBatteryDetailViews.add(batteryView); diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 732e95b4..749338f6 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -483,10 +483,9 @@ android:key="pref_key_system_statusbarheight" android:title="@string/system_statusbarheight_title" android:defaultValue="19" - app:isPreferenceVisible="false" miuizer:offtext="@string/array_default" miuizer:minValue="19" - miuizer:maxValue="100" + miuizer:maxValue="80" miuizer:stepValue="1" miuizer:format="%d dip" /> From fc2590e872b1b714101913d013e2ac909bc7a390 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 15 Dec 2022 13:43:55 +0800 Subject: [PATCH 185/627] fix(miui14): Music visualizer and album art on lock screen --- .../customiuizer/PreferenceFragmentBase.java | 3 +- .../mikanoshi/customiuizer/SubFragment.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 33 +++++++++---------- .../mikanoshi/customiuizer/subs/Launcher.java | 15 ++------- .../mikanoshi/customiuizer/subs/System.java | 12 ------- .../subs/System_NoScreenLock.java | 7 ++-- .../customiuizer/utils/AudioVisualizer.java | 10 ++---- .../mikanoshi/customiuizer/utils/Helpers.java | 26 ++++----------- app/src/main/res/values-zh-rCN/strings.xml | 8 ++--- app/src/main/res/values/strings.xml | 2 +- app/src/main/res/xml/prefs_system.xml | 2 +- 11 files changed, 40 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java index 77d98e51..29c8feca 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java @@ -1,5 +1,6 @@ package name.mikanoshi.customiuizer; +import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; @@ -385,7 +386,7 @@ public void onActivityResult(int requestCode, int resultCode, } public void restoreSettings(final AppCompatActivity act) { - if (!Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_RESTORE)) return; + if (!Helpers.checkPermAndRequest(act, Manifest.permission.WRITE_EXTERNAL_STORAGE, Helpers.REQUEST_PERMISSIONS_RESTORE)) return; if (!Helpers.checkStorageReadable(act)) return; Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java index 1afd6ef6..f7bc8f21 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java @@ -245,6 +245,7 @@ public boolean onPreferenceClick(Preference preference) { public Preference.OnPreferenceClickListener openActivitiesList = new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { + if (!Helpers.checkPermAndRequest((AppCompatActivity) getActivity(), Helpers.ACCESS_SECURITY_CENTER, Helpers.REQUEST_PERMISSIONS_SECURITY_CENTER)) return false; openActivitiesItemList(preference); return true; } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 0a33013e..c18e3182 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1838,10 +1838,8 @@ private static Bitmap processAlbumArt(Context context, Bitmap bitmap) { } public static void LockScreenAlbumArtHook(LoadPackageParam lpparam) { - Class WallpaperUtilClass = XposedHelpers.findClassIfExists("com.android.keyguard.wallpaper.KeyguardWallpaperUtils", lpparam.classLoader); - Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.miui.systemui.util.MiuiThemeUtils", lpparam.classLoader); + Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader); - final boolean[] isListened = {false}; Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -1856,6 +1854,7 @@ protected void after(MethodHookParam param) throws Throwable { } }); Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackground", new MethodHook() { + private boolean isListened = false; @Override protected void after(MethodHookParam param) throws Throwable { boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); @@ -1863,8 +1862,8 @@ protected void after(MethodHookParam param) throws Throwable { return ; } View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); - if (!isListened[0]) { - isListened[0] = true; + if (!isListened) { + isListened = true; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); view.getContext().registerReceiver(new BroadcastReceiver() { @@ -1883,7 +1882,7 @@ public void onReceive(Context context, Intent intent) { view.setVisibility(View.GONE); } else { - Object mAlbumArt = XposedHelpers.getAdditionalStaticField(WallpaperUtilClass, "mAlbumArt"); + Object mAlbumArt = XposedHelpers.getAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt"); if (mAlbumArt != null) { view.setBackground(new BitmapDrawable(view.getContext().getResources(), (Bitmap) mAlbumArt)); } @@ -1898,8 +1897,8 @@ protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); if (!isDefaultLockScreenTheme) { - XposedHelpers.setAdditionalStaticField(WallpaperUtilClass, "mAlbumArtSource", null); - XposedHelpers.setAdditionalStaticField(WallpaperUtilClass, "mAlbumArt", null); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); return; } MediaMetadata mMediaMetadata = (MediaMetadata)XposedHelpers.getObjectField(param.thisObject, "mMediaMetadata"); @@ -1909,16 +1908,16 @@ protected void after(MethodHookParam param) throws Throwable { if (art == null) art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); if (art == null) art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON); } - Bitmap mAlbumArt = (Bitmap)XposedHelpers.getAdditionalStaticField(WallpaperUtilClass, "mAlbumArtSource"); + Bitmap mAlbumArt = (Bitmap)XposedHelpers.getAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource"); try { if (art == null && mAlbumArt == null) return; if (art != null && art.sameAs(mAlbumArt)) return; } catch (Throwable ignore) {} - XposedHelpers.setAdditionalStaticField(WallpaperUtilClass, "mAlbumArtSource", art); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", art); int blur = Helpers.getSharedIntPref(mContext, "pref_key_system_albumartonlock_blur", 0); Bitmap blurArt = processAlbumArt(mContext, art != null && blur > 0 ? Helpers.fastBlur(art, blur + 1) : art); - XposedHelpers.setAdditionalStaticField(WallpaperUtilClass, "mAlbumArt", blurArt); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", blurArt); Intent updateAlbumWallpaper = new Intent(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); updateAlbumWallpaper.setPackage("com.android.systemui"); @@ -1939,8 +1938,8 @@ protected void after(MethodHookParam param) throws Throwable { protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); - XposedHelpers.setAdditionalStaticField(WallpaperUtilClass, "mAlbumArtSource", null); - XposedHelpers.setAdditionalStaticField(WallpaperUtilClass, "mAlbumArt", null); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); if (isDefaultLockScreenTheme) { Intent updateAlbumWallpaper = new Intent(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); updateAlbumWallpaper.setPackage("com.android.systemui"); @@ -3637,12 +3636,10 @@ protected void after(final MethodHookParam param) throws Throwable { if (audioViz != null) audioViz.updateScreenOn(true); } }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateKeyguardState", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.KeyguardStateControllerImpl", lpparam.classLoader, "notifyKeyguardState", boolean.class, boolean.class, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { - Object mStatusBarKeyguardViewManager = XposedHelpers.getObjectField(param.thisObject, "mStatusBarKeyguardViewManager"); - boolean isKeyguardShowingNew = (boolean)XposedHelpers.callMethod(mStatusBarKeyguardViewManager, "isShowing"); + boolean isKeyguardShowingNew = (boolean) param.args[0]; if (isKeyguardShowing != isKeyguardShowingNew) { isKeyguardShowing = isKeyguardShowingNew; isNotificationPanelExpanded = false; @@ -5200,7 +5197,7 @@ protected void after(MethodHookParam param) throws Throwable { int bvIndex = batteryViewContainer.indexOfChild(mSplitter); LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSplitter.getLayoutParams(); TextView batteryView = createBatteryDetailView(mContext, lp); - batteryViewContainer.addView(batteryView, bvIndex); + batteryViewContainer.addView(batteryView, bvIndex + 1); mBatteryDetailViews.add(batteryView); Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java index 2c27b9ad..a855e46d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java @@ -5,6 +5,7 @@ import android.os.Bundle; import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; import androidx.preference.Preference; import android.widget.SeekBar; @@ -30,6 +31,7 @@ public void onActivityCreated(Bundle savedInstanceState) { Preference.OnPreferenceClickListener openPrivacyAppEdit = new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { + if (!Helpers.checkPermAndRequest((AppCompatActivity) getActivity(), Helpers.ACCESS_SECURITY_CENTER, Helpers.REQUEST_PERMISSIONS_SECURITY_CENTER)) return false; openPrivacyAppEdit(Launcher.this, 0); return true; } @@ -47,7 +49,7 @@ public boolean onPreferenceClick(Preference preference) { switch (sub) { case "pref_key_launcher_cat_folders": - SeekBarPreference folderCols = (SeekBarPreference)findPreference("pref_key_launcher_folder_cols"); + SeekBarPreference folderCols = findPreference("pref_key_launcher_folder_cols"); findPreference("pref_key_launcher_folderwidth").setEnabled(Helpers.prefs.getInt("pref_key_launcher_folder_cols", 1) > 1); findPreference("pref_key_launcher_folderspace").setEnabled(Helpers.prefs.getInt("pref_key_launcher_folder_cols", 1) > 3); folderCols.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @@ -96,11 +98,6 @@ public boolean onPreferenceClick(Preference preference) { case "pref_key_launcher_cat_privacyapps": findPreference("pref_key_launcher_cat_privacyapps").setEnabled(opt == 1); findPreference("pref_key_launcher_privacyapps_list").setOnPreferenceClickListener(openPrivacyAppEdit); - if (!checkPermissions()) { - Preference pref = findPreference("pref_key_launcher_privacyapps_list"); - pref.setSummary(R.string.launcher_privacyapps_fail); - pref.setEnabled(false); - } break; case "pref_key_launcher_cat_titles": findPreference("pref_key_launcher_renameapps_list").setOnPreferenceClickListener(openLaunchableList); @@ -127,10 +124,4 @@ public boolean onPreferenceClick(Preference preference) { break; } } - - private boolean checkPermissions() { - PackageManager pm = getActivity().getPackageManager(); - return pm.checkPermission(Helpers.ACCESS_SECURITY_CENTER, Helpers.modulePkg) == PackageManager.PERMISSION_GRANTED; - } - } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 7f66d518..03eb7c52 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -270,13 +270,6 @@ public boolean onPreferenceClick(Preference preference) { }); findPreference("pref_key_system_applock_skip_activities").setOnPreferenceClickListener(openActivitiesList); - - if (!checkSecurityPermission()) { - Preference pref = findPreference("pref_key_system_applock_list"); - pref.setEnabled(false); - pref.setSummary(R.string.launcher_privacyapps_fail); - } - break; case "pref_key_system_cat_lockscreen": findPreference("pref_key_system_noscreenlock_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @@ -503,11 +496,6 @@ public void onActivityResult(int requestCode, int resultCode, final Intent data) super.onActivityResult(requestCode, resultCode, data); } - private boolean checkSecurityPermission() { - PackageManager pm = getActivity().getPackageManager(); - return pm.checkPermission(Helpers.ACCESS_SECURITY_CENTER, Helpers.modulePkg) == PackageManager.PERMISSION_GRANTED; - } - private boolean checkUSBPermission() { PackageManager pm = getActivity().getPackageManager(); return pm.checkPermission("android.permission.MANAGE_USB", Helpers.modulePkg) == PackageManager.PERMISSION_GRANTED; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java index d55625a1..27c1fec8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_NoScreenLock.java @@ -1,5 +1,6 @@ package name.mikanoshi.customiuizer.subs; +import android.Manifest; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; @@ -32,7 +33,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { findPreference("pref_key_system_noscreenlock_wifi").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - if (!Helpers.checkFinePerm((AppCompatActivity) getActivity(), Helpers.REQUEST_PERMISSIONS_WIFI)) return false; + if (!Helpers.checkPermAndRequest((AppCompatActivity) getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, Helpers.REQUEST_PERMISSIONS_WIFI)) return false; openWifiNetworks(); return true; } @@ -41,14 +42,14 @@ public boolean onPreferenceClick(Preference preference) { findPreference("pref_key_system_noscreenlock_bt").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - if (!Helpers.checkBluetoothPerm((AppCompatActivity) getActivity(), Helpers.REQUEST_PERMISSIONS_BLUETOOTH)) return false; + if (!Helpers.checkPermAndRequest((AppCompatActivity) getActivity(), Manifest.permission.BLUETOOTH_CONNECT, Helpers.REQUEST_PERMISSIONS_BLUETOOTH)) return false; openBtNetworks(); return true; } }); if (Helpers.isDeviceEncrypted(getContext())) { - ListPreferenceEx req = (ListPreferenceEx)findPreference("pref_key_system_noscreenlock_req"); + ListPreferenceEx req = findPreference("pref_key_system_noscreenlock_req"); req.setValue("3"); req.setEnabled(false); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/AudioVisualizer.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/AudioVisualizer.java index 8bfd88ae..5b9c0347 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/AudioVisualizer.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/AudioVisualizer.java @@ -316,12 +316,6 @@ public AudioVisualizer(Context context) { this(context, null, 0); } - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - } - - @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); @@ -377,7 +371,7 @@ protected void onDraw(Canvas canvas) { else if (renderType == RenderType.PATH) drawAsLines = false; else - drawAsLines = glowLevel == 0 && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P || (barStyle != BarStyle.DASHED && barStyle != BarStyle.CIRCLES)); + drawAsLines = glowLevel == 0; if (drawAsLines) { if (glowLevel > 0) @@ -498,7 +492,7 @@ else if (colorMode == ColorMode.STATIC) private void updateRainbowColors() { float jump = 300f / (float)mBandsNum; for (int i = 0; i < mRainbow.length; i++) - mRainbow[i] = Color.HSVToColor(transparency, new float[]{jump * i, 1.0f, 1.0f}); + mRainbow[i] = Color.HSVToColor(transparency, new float[]{jump * i, 1.0f, 1.0f}); for (int i = 0; i < mRainbowVertical.length; i++) { float h = 140 + jump * i; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index ff7c4708..0bb66cff 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -139,6 +139,7 @@ public class Helpers { public static final int REQUEST_PERMISSIONS_WIFI = 3; public static final int REQUEST_PERMISSIONS_REPORT = 4; public static final int REQUEST_PERMISSIONS_BLUETOOTH = 5; + public static final int REQUEST_PERMISSIONS_SECURITY_CENTER = 6; public static LruCache memoryCache = new LruCache((int)(Runtime.getRuntime().maxMemory() / 1024) / 2) { @Override protected int sizeOf(String key, Bitmap icon) { @@ -400,33 +401,20 @@ public static boolean checkStorageReadable(Context context) { } } - public static boolean checkStoragePerm(AppCompatActivity act, int action) { - if (act.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - act.requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE }, action); - return false; - } else return true; - } - public static boolean checkSettingsPerm(AppCompatActivity act) { return act.checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED; } - public static boolean checkBluetoothPerm(AppCompatActivity act, int action) { - if (act.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - act.requestPermissions(new String[]{ Manifest.permission.BLUETOOTH_CONNECT }, action); - return false; - } else return true; - } - - public static boolean checkFinePerm(AppCompatActivity act, int action) { - if (act.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - act.requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION }, action); + public static boolean checkPermAndRequest(AppCompatActivity act, String perm, int action) { + if (act.checkSelfPermission(perm) != PackageManager.PERMISSION_GRANTED) { + act.requestPermissions(new String[]{ perm }, action); return false; - } else return true; + } + return true; } public static boolean preparePathForBackup(AppCompatActivity act, String path) { - if (!checkStoragePerm(act, REQUEST_PERMISSIONS_BACKUP)) return false; + if (!checkPermAndRequest(act, Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_PERMISSIONS_BACKUP)) return false; String state = Environment.getExternalStorageState(); switch (state) { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d42632d4..e41888d8 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -542,8 +542,8 @@ 修改标题 隐藏应用 未授予所需权限 - 没有隐藏的文件夹 - 打开隐藏应用文件夹禁用双指手势 + 禁止手势进入隐藏应用列表 + 禁用双指手势打开隐藏应用文件夹 隐藏应用列表 隐藏应用选项的增强版,可以隐藏任何已安装的应用。无需重启。 下滑动作(单指) @@ -931,8 +931,8 @@ 现在执行软重启吗? 重启桌面 在浏览器中打开 - 设置管理 - 请选择所需操作 + 备份与恢复 + 备份位于 /sdcard/Documents/CustoMIUIzer/ 备份 恢复 您的外部存储是只读的 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a9c98455..448d43e5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1019,7 +1019,7 @@ Open in browser Restart systemui Settings management - Choose the desired routine + Backups are stored in /sdcard/Documents/CustoMIUIzer/ Backup Restore Your external storage is read-only diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 749338f6..b88abef9 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -444,7 +444,7 @@ android:dependency="pref_key_system_statusbar_batterytempandcurrent" android:defaultValue="16" miuizer:child="true" - miuizer:minValue="15" + miuizer:minValue="14" miuizer:maxValue="30" miuizer:stepValue="1" miuizer:displayDividerValue="2" From 14f1e8e2d1371dcc495d4e92bcf29d311bafc9f5 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 15 Dec 2022 19:21:29 +0800 Subject: [PATCH 186/627] fix(miui14): set customiuizer as system app --- .../java/name/mikanoshi/customiuizer/MainModule.java | 4 ++-- .../name/mikanoshi/customiuizer/mods/Launcher.java | 5 ++++- .../customiuizer/mods/PackagePermissions.java | 11 +++++++---- .../java/name/mikanoshi/customiuizer/mods/System.java | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 0eb7f64c..f9691638 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -61,13 +61,13 @@ public void initZygote(StartupParam startParam) { if (mPrefs.getStringAsInt("system_rotateanim", 1) > 1) System.RotationAnimationRes(); if (mPrefs.getInt("system_betterpopups_delay", 0) > 0 && !mPrefs.getBoolean("system_betterpopups_nohide")) System.BetterPopupsHideDelaySysHook(); - if (mPrefs.getInt("system_messagingstylelines", 0) > 0 && Helpers.is12()) System.MessagingStyleLinesSysHook(); + if (mPrefs.getInt("system_messagingstylelines", 0) > 0) System.MessagingStyleLinesSysHook(); if (mPrefs.getBoolean("system_colorizenotiftitle")) System.ColorizedNotificationTitlesHook(); if (mPrefs.getBoolean("system_nopassword")) System.NoPasswordHook(); if (mPrefs.getBoolean("system_statusbarcolor")) System.StatusBarBackgroundHook(); if (mPrefs.getBoolean("system_magnifier")) System.TextMagnifierHook(); if (mPrefs.getBoolean("system_lockscreenshortcuts") || mPrefs.getInt("controls_powerdt_action", 1) > 1) System.LockScreenSecureLaunchHook(); - if (mPrefs.getBoolean("system_notifmediaseekbar") && !Helpers.is12()) System.MediaNotificationSeekBarHook(); + if (mPrefs.getBoolean("system_notifmediaseekbar")) System.MediaNotificationSeekBarHook(); if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationBlockHook(); if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyHook(); if (mPrefs.getBoolean("system_nooverscroll")) System.NoOverscrollHook(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 30ea5524..0c28af1b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -394,7 +394,10 @@ protected void after(final MethodHookParam param) throws Throwable { } public static void NoClockHideHook(final LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.miui.home.launcher.Workspace", lpparam.classLoader, "isScreenHasClockGadget", long.class, XC_MethodReplacement.returnConstant(false)); + boolean latestHome = Helpers.findAndHookMethodSilently("com.miui.home.launcher.Workspace", lpparam.classLoader, "isScreenHasClockWidget", long.class, XC_MethodReplacement.returnConstant(false)); + if (!latestHome) { + Helpers.findAndHookMethodSilently("com.miui.home.launcher.Workspace", lpparam.classLoader, "isScreenHasClockGadget", long.class, XC_MethodReplacement.returnConstant(false)); + } } private static void modifyTitle(Object thisObject) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java index a5ef83d8..b550d789 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/PackagePermissions.java @@ -49,11 +49,12 @@ public static void hook(LoadPackageParam lpparam) { //systemPackages.add("com.miui.packageinstaller"); // Allow signature level permissions for module - Helpers.hookAllMethods("com.android.server.pm.permission.PermissionManagerService", lpparam.classLoader, "shouldGrantPermissionBySignature", + String PMSCls = Helpers.isTPlus() ? "com.android.server.pm.permission.PermissionManagerServiceImpl" : "com.android.server.pm.permission.PermissionManagerService"; + Helpers.hookAllMethods(PMSCls, lpparam.classLoader, "shouldGrantPermissionBySignature", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - String pkgName = (String)XposedHelpers.getObjectField(param.args[0], "packageName"); + String pkgName = (String)XposedHelpers.callMethod(param.args[0], "getPackageName"); if (systemPackages.contains(pkgName)) param.setResult(true); } } @@ -63,7 +64,7 @@ protected void before(MethodHookParam param) throws Throwable { new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - String pkgName = (String)XposedHelpers.getObjectField(param.args[0], "name"); + String pkgName = (String)XposedHelpers.callMethod(param.args[0], "getName"); if (systemPackages.contains(pkgName)) param.setResult(true); } } @@ -109,10 +110,12 @@ protected void before(MethodHookParam param) throws Throwable { // ); // Make module appear as system app - Helpers.hookAllMethods("com.android.server.pm.PackageManagerService", lpparam.classLoader, "queryIntentActivitiesInternal", new MethodHook() { + String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService"; + Helpers.hookAllMethods(ActQueryService, lpparam.classLoader, "queryIntentActivitiesInternal", new MethodHook() { @Override @SuppressWarnings("unchecked") protected void after(MethodHookParam param) throws Throwable { + if (param.args.length < 6) return; List infos = (List)param.getResult(); if (infos != null) { for (ResolveInfo info: infos) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index c18e3182..fe2960b9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2121,7 +2121,8 @@ protected void after(MethodHookParam param) throws Throwable { } public static void NoVersionCheckHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.pm.PackageManagerService", lpparam.classLoader, "checkDowngrade", XC_MethodReplacement.DO_NOTHING); + String PMSCls = Helpers.isTPlus() ? "com.android.server.pm.PackageManagerServiceUtils" : "com.android.server.pm.PackageManagerService"; + Helpers.hookAllMethods(PMSCls, lpparam.classLoader, "checkDowngrade", XC_MethodReplacement.DO_NOTHING); } public static void ColorizedNotificationTitlesHook() { @@ -2138,7 +2139,6 @@ protected void after(MethodHookParam param) throws Throwable { RemoteViews rv = (RemoteViews)param.args[0]; Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); if (rv != null && mContext != null) { - Helpers.log("Colorize Notify Header"); int contrastColor = (int)XposedHelpers.callMethod(param.thisObject, "getPrimaryAccentColor", param.args[1]); rv.setTextColor(mContext.getResources().getIdentifier("app_name_text", "id", "android"), contrastColor); } From c1cfc14812f736ba41379cd01b97e4922f12e314 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 15 Dec 2022 19:42:05 +0800 Subject: [PATCH 187/627] fix(miui14): keep notify on lockscreen --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index fe2960b9..bc6b7e0e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2353,8 +2353,8 @@ protected void before(final MethodHookParam param) throws Throwable { } public static void ShowNotificationsAfterUnlockHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.miui.statusbar.notification.ExpandedNotification", lpparam.classLoader, "hasShownAfterUnlock", XC_MethodReplacement.returnConstant(false)); - Helpers.findAndHookMethod("com.android.systemui.miui.statusbar.notification.ExpandedNotification", lpparam.classLoader, "setHasShownAfterUnlock", boolean.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.ExpandedNotification", lpparam.classLoader, "hasShownAfterUnlock", XC_MethodReplacement.returnConstant(false)); + Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.ExpandedNotification", lpparam.classLoader, "setHasShownAfterUnlock", boolean.class, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { XposedHelpers.setBooleanField(param.thisObject, "mHasShownAfterUnlock", false); From 2332b3bb8093cdc4096ea054fffda5bba8722621 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 15 Dec 2022 19:56:25 +0800 Subject: [PATCH 188/627] fix(miui14): hide unlock indicator --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bc6b7e0e..de168b9e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7760,7 +7760,12 @@ protected void before(MethodHookParam param) throws Throwable { XposedHelpers.setObjectField(param.thisObject, "mUpArrowIndication", null); } }; - Helpers.findAndHookMethod("com.android.systemui.statusbar.KeyguardIndicationController", lpparam.classLoader, "updateIndication", boolean.class, boolean.class, hook); + if (Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController", lpparam.classLoader, "hasIndicationsExceptResting", XC_MethodReplacement.returnConstant(true)); + } + else { + Helpers.findAndHookMethod("com.android.systemui.statusbar.KeyguardIndicationController", lpparam.classLoader, "updateIndication", boolean.class, boolean.class, hook); + } } public static void HideLockScreenStatusBarHook(LoadPackageParam lpparam) { From c380d80f1e733bc9441eaea97d1f7cf5740c17b6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 15 Dec 2022 20:53:50 +0800 Subject: [PATCH 189/627] fix(miui14): statusbar gesture and fingerprint vibrate --- .../mikanoshi/customiuizer/mods/Controls.java | 18 +++++++- .../mikanoshi/customiuizer/mods/System.java | 41 ++++++++++++++++--- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java index b0998d05..c8322dce 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java @@ -866,7 +866,14 @@ public static void FingerprintHapticSuccessHook(LoadPackageParam lpparam) { Helpers.hookAllMethods(authClient, lpparam.classLoader, "onAuthenticated", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - if (!((boolean)param.getResult())) return; + boolean mAuthSuccess; + if (Helpers.isTPlus()) { + mAuthSuccess = XposedHelpers.getBooleanField(param.thisObject, "mAuthSuccess"); + } + else { + mAuthSuccess = (boolean)param.getResult(); + } + if (!mAuthSuccess) return; Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); boolean ignoreSystem = MainModule.mPrefs.getBoolean("controls_fingerprintsuccess_ignore"); @@ -900,7 +907,14 @@ public static void FingerprintScreenOnHook(LoadPackageParam lpparam) { Helpers.hookAllMethods(authClient, lpparam.classLoader, "onAuthenticated", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - if ((boolean)param.getResult()) return; + boolean mAuthSuccess; + if (Helpers.isTPlus()) { + mAuthSuccess = XposedHelpers.getBooleanField(param.thisObject, "mAuthSuccess"); + } + else { + mAuthSuccess = (boolean)param.getResult(); + } + if (mAuthSuccess) return; Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); PowerManager mPowerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); if (mPowerManager.isInteractive()) return; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index de168b9e..49640b6b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6034,13 +6034,17 @@ protected void before(final MethodHookParam param) throws Throwable { MethodHook hook = new MethodHook() { Object mBrightnessController = null; + private int sbHeight = 0; @Override @SuppressLint("SetTextI18n") protected void before(final MethodHookParam param) throws Throwable { - boolean isInControlCenter = "ControlPanelWindowView".equals(param.thisObject.getClass().getSimpleName()); + String clsName = param.thisObject.getClass().getSimpleName(); + boolean isInControlCenter = "ControlPanelWindowView".equals(clsName) || "ControlCenterWindowViewImpl".equals(clsName); Context mContext = isInControlCenter ? ((View)param.thisObject).getContext() : (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); Resources res = mContext.getResources(); - int sbHeight = res.getDimensionPixelSize(res.getIdentifier("status_bar_height", "dimen", "android")); + if (sbHeight == 0) { + sbHeight = res.getDimensionPixelSize(res.getIdentifier("status_bar_height", "dimen", "android")); + } MotionEvent event = (MotionEvent)param.args[0]; switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: @@ -6049,7 +6053,13 @@ protected void before(final MethodHookParam param) throws Throwable { isSlidingStart = isInControlCenter ? tapStartY <= sbHeight : !XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); tapStartPointers = 1; if (mBrightnessController == null) { - Object mControlCenterController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); + Object mControlCenterController; + if (Helpers.isTPlus() && isInControlCenter) { + mControlCenterController = XposedHelpers.getObjectField(param.thisObject, "controlCenterController"); + } + else { + mControlCenterController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); + } mBrightnessController = XposedHelpers.callMethod(XposedHelpers.getObjectField(mControlCenterController, "brightnessController"), "get"); } Object mDisplayManager = XposedHelpers.getObjectField(mBrightnessController, "mDisplayManager"); @@ -6135,9 +6145,28 @@ protected void before(final MethodHookParam param) throws Throwable { } } }; - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "interceptTouchEvent", MotionEvent.class, hook); - Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.ControlPanelWindowView", lpparam.classLoader, "onTouchEvent", MotionEvent.class, hook); + String eventMethod = Helpers.isTPlus() ? "onTouchEvent" : "interceptTouchEvent"; + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, eventMethod, MotionEvent.class, hook); + if (Helpers.isTPlus()) { + String pluginLoaderClass = "com.android.systemui.shared.plugins.PluginInstance$Factory"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { + isHooked = true; + if (pluginLoader == null) { + pluginLoader = (ClassLoader) param.getResult(); + } + Helpers.findAndHookMethod("miui.systemui.controlcenter.windowview.ControlCenterWindowViewImpl", pluginLoader, "handleMotionEvent", MotionEvent.class, boolean.class, hook); + } + } + }); + } + else { + Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.ControlPanelWindowView", lpparam.classLoader, "onTouchEvent", MotionEvent.class, hook); + } } public static void ScreenshotConfigHook(LoadPackageParam lpparam) { From ce3e7002b317ee6a773d2dfeacb4adb82df6aebd Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 15 Dec 2022 21:09:11 +0800 Subject: [PATCH 190/627] feat: show am|pm when seconds is shown in statusbar --- .../java/name/mikanoshi/customiuizer/mods/System.java | 9 ++++++++- .../java/name/mikanoshi/customiuizer/subs/System.java | 6 ++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 8 ++++++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 49640b6b..5511c09c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1157,6 +1157,9 @@ protected void after(MethodHookParam param) { if (clock.getId() == clockId && MainModule.mPrefs.getBoolean("system_clockleadingzero")) { XposedHelpers.setAdditionalInstanceField(clock, "showLeadingZero", true); } + if (clock.getId() == clockId && MainModule.mPrefs.getBoolean("system_clock_show_ampm")) { + XposedHelpers.setAdditionalInstanceField(clock, "showAmPm", true); + } } }); @@ -1166,6 +1169,7 @@ protected void before(MethodHookParam param) throws Throwable { TextView clock = (TextView)param.thisObject; boolean clockShowSeconds = XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null; boolean clockShowLeadingZero = XposedHelpers.getAdditionalInstanceField(clock, "showLeadingZero") != null; + boolean clockShowAmPm = XposedHelpers.getAdditionalInstanceField(clock, "showAmPm") != null; if (clockShowSeconds || clockShowLeadingZero) { Context mContext = clock.getContext(); Object mMiuiStatusBarClockController = XposedHelpers.getObjectField(clock, "mMiuiStatusBarClockController"); @@ -1208,6 +1212,9 @@ protected void before(MethodHookParam param) throws Throwable { timeFmt = timeFmt.replaceFirst("^H:mm", "HH:mm").replaceFirst("^h:mm", "hh:mm") .replaceFirst("ah:mm", "ahh:mm").replaceFirst(" h:mm", " hh:mm"); } + if (clockShowAmPm) { + timeFmt = "aa" + timeFmt; + } StringBuilder formatSb = new StringBuilder(timeFmt); StringBuilder textSb = new StringBuilder(); XposedHelpers.callMethod(mCalendar, "format", mContext, textSb, formatSb); @@ -1219,7 +1226,7 @@ protected void before(MethodHookParam param) throws Throwable { String hour = textSb.toString().replaceFirst(".*?(\\d+):\\d+:\\d+.*", "$1"); if ( mTextLength == null || (int) mTextLength != len - || mHourText == null || !hour.equals((String)mHourText) + || mHourText == null || !hour.equals(mHourText) ) { XposedHelpers.setAdditionalInstanceField(clock, "mTextLength", len); XposedHelpers.setAdditionalInstanceField(clock, "mHourText", hour); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 03eb7c52..7f395ef1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -5,6 +5,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; @@ -158,6 +159,11 @@ public boolean onPreferenceClick(Preference preference) { } }); + Configuration config = getResources().getConfiguration(); + if (config.getLocales().get(0).getCountry().equals("CN")) { + findPreference("pref_key_system_clock_show_ampm").setVisible(true); + } + break; case "pref_key_system_cat_drawer": findPreference("pref_key_system_popupnotif_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e41888d8..a5855b34 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -78,6 +78,7 @@ 日历应用 点击通知抽屉上方的日期时打开所选应用 显示秒 + 显示时段 小时补0 状态栏显示秒钟 通知图标限制 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 448d43e5..b2ab2d76 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -86,6 +86,7 @@ Calendar app Open selected app when date in notification drawer\'s header is tapped Show seconds + Show AM|PM Show leading zero to hours Display seconds in the status bar clock Notification icons limit diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index b88abef9..8c077521 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -534,6 +534,14 @@ android:title="@string/system_clockseconds_title" android:defaultValue="false" /> + + Date: Thu, 15 Dec 2022 21:56:53 +0800 Subject: [PATCH 191/627] bump version --- app/build.gradle | 2 +- .../main/java/name/mikanoshi/customiuizer/mods/Launcher.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 324099cb..9ecc001f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,7 +27,7 @@ android { //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 versionCode 46 - versionName "22.12.06" + versionName "22.12.15" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 0c28af1b..8fb8b93b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1101,6 +1101,8 @@ protected void after(final MethodHookParam param) throws Throwable { public static void HorizontalSpacingRes() { int opt = MainModule.mPrefs.getInt("launcher_horizmargin", 0) - 21; MainModule.resHooks.setDensityReplacement("com.miui.home", "dimen", "workspace_cell_padding_side", opt); + MainModule.resHooks.setDensityReplacement("com.miui.home", "dimen", "workspace_cell_padding_side_no_word", opt); + MainModule.resHooks.setDensityReplacement("com.miui.home", "dimen", "workspace_cell_padding_side_rotatable", opt); MainModule.resHooks.setDensityReplacement("com.mi.android.globallauncher", "dimen", "workspace_cell_padding_side", opt); } From 22c5d7f5d86e6c7904690ad76771eb488f076a91 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 16 Dec 2022 17:34:50 +0800 Subject: [PATCH 192/627] feat: headsup notification auto expand --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 28 ++++++++++++++++++- .../mikanoshi/customiuizer/subs/System.java | 11 ++++++-- app/src/main/res/values-zh-rCN/strings.xml | 4 +-- app/src/main/res/xml/prefs_system.xml | 14 ++++++++++ 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index f9691638..9cf002ab 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -232,6 +232,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_detailednetspeed")) System.DetailedNetSpeedHook(lpparam); if (mPrefs.getBoolean("system_albumartonlock")) System.LockScreenAlbumArtHook(lpparam); if (mPrefs.getBoolean("system_popupnotif")) System.PopupNotificationsHook(lpparam); + if (mPrefs.getStringAsInt("system_expandheadups", 1) > 1) System.ExpandHeadsUpHook(lpparam); if (mPrefs.getBoolean("system_betterpopups_nohide")) System.BetterPopupsNoHideHook(lpparam); if (mPrefs.getBoolean("system_betterpopups_swipedown")) System.BetterPopupsSwipeDownHook(lpparam); if (mPrefs.getBoolean("system_betterpopups_center")) System.BetterPopupsCenteredHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 5511c09c..23ce276e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1263,6 +1263,32 @@ protected void before(MethodHookParam param) throws Throwable { }); } + public static void ExpandHeadsUpHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.systemui.statusbar.notification.row.ExpandableNotificationRow", lpparam.classLoader, "setHeadsUp", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + boolean mOnKeyguard = (boolean) XposedHelpers.callMethod(param.thisObject, "isOnKeyguard"); + boolean showHeadsUp = (boolean) param.args[0]; + if (!mOnKeyguard && showHeadsUp) { + View notifyRow = (View) param.thisObject; + Object notification = XposedHelpers.getObjectField(XposedHelpers.callMethod(param.thisObject, "getEntry"), "mSbn"); + String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); + int opt = Integer.parseInt(MainModule.mPrefs.getString("system_expandheadups", "1")); + boolean isSelected = MainModule.mPrefs.getStringSet("system_expandheadups_apps").contains(pkgName); + if (opt == 2 && !isSelected || opt == 3 && isSelected) { + Runnable expandNotify = new Runnable() { + @Override + public void run() { + XposedHelpers.callMethod(param.thisObject, "expandNotification"); + } + }; + notifyRow.postDelayed(expandNotify, 60); + } + } + } + }); + } + public static void PopupNotificationsHook(LoadPackageParam lpparam) { Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "addNotification", new MethodHook() { @Override @@ -2021,7 +2047,7 @@ protected void after(final MethodHookParam param) throws Throwable { MotionEvent me = (MotionEvent)param.args[0]; if (me.getActionMasked() == MotionEvent.ACTION_DOWN) { boolean mAllowSwipingDown = true; - if (Helpers.is12()) try { + try { Object mPickedChild = XposedHelpers.getObjectField(param.thisObject, "mPickedChild"); if (mPickedChild != null) { View mMiniBar = (View)XposedHelpers.callMethod(mPickedChild, "getMiniWindowBar"); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 7f395ef1..6edaa50b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -220,7 +220,6 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { return true; } }); - break; case "pref_key_system_cat_qs": findPreference("pref_key_system_qshaptics_ignore").setEnabled(!Objects.equals(Helpers.prefs.getString("pref_key_system_qshaptics", "1"), "1")); @@ -264,7 +263,15 @@ public void onStopTrackingTouch(SeekBar seekBar) {} break; case "pref_key_system_cat_betterpopups": findPreference("pref_key_system_betterpopups_allowfloat_apps").setOnPreferenceClickListener(openAppsBWEdit); - + findPreference("pref_key_system_expandheadups_apps").setOnPreferenceClickListener(openAppsEdit); + findPreference("pref_key_system_expandheadups_apps").setEnabled(!Objects.equals(Helpers.prefs.getString("pref_key_system_expandheadups", "1"), "1")); + findPreference("pref_key_system_expandheadups").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + findPreference("pref_key_system_expandheadups_apps").setEnabled(!newValue.equals("1")); + return true; + } + }); break; case "pref_key_system_cat_applock": findPreference("pref_key_system_applock_list").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a5855b34..a8d3cf15 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -423,11 +423,11 @@ 第三个快捷方式方案的动作 第四个快捷方式动作 第四个快捷方式方案的动作 - 弹窗通知 + 浮动通知 自动隐藏延迟 不自动隐藏 不自动关闭弹窗 - 允许浮窗 + 允许浮窗中打开 如果通知定义了适当的点击动作,向下滑动手势时在浮动窗口中打开应用 启用下滑手势 向下滑动手势时打开通知抽屉 diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 8c077521..151e9eab 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1023,6 +1023,20 @@ android:title="@string/system_betterpopups_center_title" android:defaultValue="false" /> + + + + Date: Sun, 18 Dec 2022 16:31:09 +0800 Subject: [PATCH 193/627] add extra width for clock that displays an ellipsis in status bar --- .../name/mikanoshi/customiuizer/mods/System.java | 3 ++- app/src/main/res/values-zh-rCN/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/prefs_system.xml | 13 +++++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 23ce276e..4ff69d59 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1234,7 +1234,8 @@ protected void before(MethodHookParam param) throws Throwable { clock.setText(maxLenText); clock.measure(0, 0); ViewGroup.LayoutParams lp = clock.getLayoutParams(); - lp.width = clock.getMeasuredWidth() + (int)Math.ceil(mContext.getResources().getDisplayMetrics().density); + float extraWidth = MainModule.mPrefs.getInt("system_clock_extra_width", 2) * 0.5f; + lp.width = clock.getMeasuredWidth() + (int)(mContext.getResources().getDisplayMetrics().density * extraWidth); clock.setLayoutParams(lp); } } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a8d3cf15..4cf124b9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -79,6 +79,8 @@ 点击通知抽屉上方的日期时打开所选应用 显示秒 显示时段 + 额外宽度 + 增加时钟宽度以完整显示秒数 小时补0 状态栏显示秒钟 通知图标限制 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b2ab2d76..b2b6f0cb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,6 +88,8 @@ Show seconds Show AM|PM Show leading zero to hours + Extra width + Avoid to display an ellipsis Display seconds in the status bar clock Notification icons limit Number of notification icons to display before turning them into dots diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 151e9eab..c2c54603 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -542,6 +542,19 @@ android:dependency="pref_key_system_clockseconds" android:defaultValue="false" /> + + Date: Sun, 18 Dec 2022 17:31:01 +0800 Subject: [PATCH 194/627] feat: show battery tempandcurrent in status bar when charging only --- .../mikanoshi/customiuizer/mods/System.java | 78 ++++++++++++------- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 7 ++ 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 4ff69d59..679a81a5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5119,7 +5119,7 @@ private static TextView createBatteryDetailView(Context mContext, LinearLayout.L } static final ArrayList mBatteryDetailViews = new ArrayList(); - private static void updateTempAndCurrent() { + private static void updateTempAndCurrent(Class ChargeUtilsClass) { Handler handler = new Handler(Looper.getMainLooper()); Runnable refreshRunner = new Runnable() { @Override @@ -5127,38 +5127,56 @@ public void run() { String batteryInfo = ""; FileInputStream fis = null; Properties props = null; - try { - fis = new FileInputStream("/sys/class/power_supply/battery/uevent"); - props = new Properties(); - props.load(fis); + boolean showInfo = true; + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_incharge") && ChargeUtilsClass != null) { + Object batteryStatus = Helpers.getStaticObjectFieldSilently(ChargeUtilsClass, "sBatteryStatus"); + if (batteryStatus == null) { + showInfo = false; + } + else { + showInfo = (boolean) XposedHelpers.callMethod(batteryStatus, "isCharging"); + } } - catch (Throwable ign) {} - finally { + if (showInfo) { try { - fis.close(); + fis = new FileInputStream("/sys/class/power_supply/battery/uevent"); + props = new Properties(); + props.load(fis); } catch (Throwable ign) {} - } - if (props != null) { - int tempVal = Integer.parseInt(props.getProperty("POWER_SUPPLY_TEMP")); - int currVal = Math.round(Integer.parseInt(props.getProperty("POWER_SUPPLY_CURRENT_NOW")) / 1000); - int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); - if (opt == 1) { - batteryInfo = tempVal / 10f + "℃" + "\n" + currVal + "mA"; - } - else if (opt == 2) { - batteryInfo = tempVal / 10f + "℃"; + finally { + try { + fis.close(); + } + catch (Throwable ign) {} + } + if (props != null) { + int tempVal = Integer.parseInt(props.getProperty("POWER_SUPPLY_TEMP")); + int currVal = Math.abs(Math.round(Integer.parseInt(props.getProperty("POWER_SUPPLY_CURRENT_NOW")) / 1000)); + int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); + if (opt == 1) { + batteryInfo = tempVal / 10f + "℃" + "\n" + currVal + "mA"; + } + else if (opt == 2) { + batteryInfo = tempVal / 10f + "℃"; + } + else { + batteryInfo = currVal + "mA"; + } } - else { - batteryInfo = currVal + "mA"; + } + if (!showInfo || batteryInfo.isEmpty()) { + for (TextView tv:mBatteryDetailViews) { + tv.setVisibility(View.GONE); } } - if (!batteryInfo.isEmpty()) { + else { for (TextView tv:mBatteryDetailViews) { + tv.setVisibility(View.VISIBLE); XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); } - handler.postDelayed(this, 2000); } + handler.postDelayed(this, 1500); } }; handler.post(refreshRunner); @@ -5168,13 +5186,14 @@ public static void setupStatusBar(LoadPackageParam lpparam) { statusbarTextIconLayoutResId = MainModule.resHooks.addResource("statusbar_text_icon", R.layout.statusbar_text_icon); } public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { + Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); Class StatusBarIconHolder = XposedHelpers.findClass("com.android.systemui.statusbar.phone.StatusBarIconHolder", lpparam.classLoader); boolean atRight = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright"); - final boolean[] isListened = {false}; if (atRight) { Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { Object iconController = XposedHelpers.getObjectField(param.thisObject, "mStatusBarIconController"); @@ -5185,9 +5204,9 @@ protected void after(MethodHookParam param) throws Throwable { XposedHelpers.setObjectField(iconHolder, "mType", 91); XposedHelpers.callMethod(iconController, "setIcon", slotIndex, iconHolder); } - if (isListened[0] == false) { - isListened[0] = true; - updateTempAndCurrent(); + if (!isHooked) { + isHooked = true; + updateTempAndCurrent(ChargeUtilsClass); } } }); @@ -5223,6 +5242,7 @@ protected void before(MethodHookParam param) throws Throwable { } else { Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { + private boolean isHooked = false; @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getContext"); @@ -5236,9 +5256,9 @@ protected void after(MethodHookParam param) throws Throwable { Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); XposedHelpers.setAdditionalInstanceField(param.thisObject, "mBatteryView", batteryView); - if (isListened[0] == false) { - isListened[0] = true; - updateTempAndCurrent(); + if (!isHooked) { + isHooked = true; + updateTempAndCurrent(ChargeUtilsClass); } } }); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4cf124b9..3fcf1674 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1061,6 +1061,7 @@ 时钟 显示电池温度和电流 显示内容 + 仅在充电时显示 仅温度 仅电流 右侧显示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b2b6f0cb..8d595943 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1114,6 +1114,7 @@ Display battery temp and current Display info Display on the right + Show when charging only Dual SIM signal bars in dual rows Right margin Put mobile network type at the right of signal icon diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index c2c54603..da63b314 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -438,6 +438,13 @@ miuizer:child="true" android:defaultValue="false" /> + + Date: Sun, 18 Dec 2022 19:50:34 +0800 Subject: [PATCH 195/627] feat: add thick style for dual row signal --- .../mikanoshi/customiuizer/mods/System.java | 200 +++++-------- .../mikanoshi/customiuizer/mods/Various.java | 282 ++++++------------ .../mikanoshi/customiuizer/utils/Helpers.java | 36 +-- .../statusbar_signal_1_0_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_1_0_thick.xml | 18 ++ .../statusbar_signal_1_0_tint_thick.xml | 18 ++ .../statusbar_signal_1_1_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_1_1_thick.xml | 18 ++ .../statusbar_signal_1_1_tint_thick.xml | 18 ++ .../statusbar_signal_1_2_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_1_2_thick.xml | 18 ++ .../statusbar_signal_1_2_tint_thick.xml | 18 ++ .../statusbar_signal_1_3_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_1_3_thick.xml | 18 ++ .../statusbar_signal_1_3_tint_thick.xml | 18 ++ .../statusbar_signal_1_4_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_1_4_thick.xml | 18 ++ .../statusbar_signal_1_4_tint_thick.xml | 18 ++ .../statusbar_signal_1_5_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_1_5_thick.xml | 18 ++ .../statusbar_signal_1_5_tint_thick.xml | 18 ++ .../statusbar_signal_2_0_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_2_0_thick.xml | 18 ++ .../statusbar_signal_2_0_tint_thick.xml | 18 ++ .../statusbar_signal_2_1_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_2_1_thick.xml | 18 ++ .../statusbar_signal_2_1_tint_thick.xml | 18 ++ .../statusbar_signal_2_2_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_2_2_thick.xml | 18 ++ .../statusbar_signal_2_2_tint_thick.xml | 18 ++ .../statusbar_signal_2_3_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_2_3_thick.xml | 18 ++ .../statusbar_signal_2_3_tint_thick.xml | 18 ++ .../statusbar_signal_2_4_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_2_4_thick.xml | 18 ++ .../statusbar_signal_2_4_tint_thick.xml | 18 ++ .../statusbar_signal_2_5_dark_thick.xml | 18 ++ .../drawable/statusbar_signal_2_5_thick.xml | 18 ++ .../statusbar_signal_2_5_tint_thick.xml | 18 ++ app/src/main/res/values-zh-rCN/strings.xml | 2 + app/src/main/res/values/arrays.xml | 9 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/prefs_system.xml | 10 + 43 files changed, 850 insertions(+), 339 deletions(-) create mode 100644 app/src/main/res/drawable/statusbar_signal_1_0_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_0_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_0_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_1_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_1_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_1_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_2_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_2_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_2_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_3_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_3_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_3_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_4_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_4_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_4_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_5_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_5_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_1_5_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_0_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_0_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_0_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_1_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_1_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_1_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_2_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_2_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_2_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_3_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_3_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_3_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_4_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_4_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_4_tint_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_5_dark_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_5_thick.xml create mode 100644 app/src/main/res/drawable/statusbar_signal_2_5_tint_thick.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 679a81a5..bc06c350 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -161,6 +161,7 @@ import java.util.Collections; import java.util.Date; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; @@ -608,7 +609,7 @@ protected void after(MethodHookParam param) throws Throwable { protected void before(MethodHookParam param) throws Throwable { boolean skip = MainModule.mPrefs.getBoolean("system_noscreenlock_nofaceunlock"); if (!skip) return; - if (Helpers.is12() && param.args.length == 0) return; + if (param.args.length == 0) return; Boolean isScreenLockDisabled = (Boolean)XposedHelpers.getAdditionalStaticField(findClass("com.android.systemui.keyguard.KeyguardViewMediator", lpparam.classLoader), "isScreenLockDisabled"); isScreenLockDisabled = isScreenLockDisabled != null && isScreenLockDisabled; if (isScreenLockDisabled) param.setResult(null); @@ -852,10 +853,8 @@ public static void NotificationVolumeDialogRes() { notifVolumeOffResId = MainModule.resHooks.addResource("ic_miui_volume_notification_mute", R.drawable.ic_miui_volume_notification_mute); } - private static int settingsSystemResId; private static int callsResId; public static void NotificationVolumeSettingsRes() { - settingsSystemResId = MainModule.resHooks.addResource("ic_audio_system", R.drawable.ic_audio_system); callsResId = MainModule.resHooks.addResource("ring_volume_option_newtitle", R.string.calls); } @@ -999,7 +998,7 @@ protected void after(MethodHookParam param) throws Throwable { XposedHelpers.callMethod(pref, "setTitle", modRes.getString(R.string.system_volume)); XposedHelpers.callMethod(pref, "setPersistent", true); XposedHelpers.callMethod(prefScreen, addPreference, pref); - initSeekBar[0].invoke(fragment, "system_volume", 1, Helpers.is12() ? context.getResources().getIdentifier("ic_audio_vol", "drawable", context.getPackageName()) : settingsSystemResId); + initSeekBar[0].invoke(fragment, "system_volume", 1, context.getResources().getIdentifier("ic_audio_vol", "drawable", context.getPackageName())); XposedHelpers.callMethod(pref, "setOrder", order); Object mRingVolume = XposedHelpers.callMethod(param.thisObject, "findPreference", "ring_volume"); @@ -1352,10 +1351,8 @@ protected void after(MethodHookParam param) throws Throwable { public void onChange(String name, int defValue) { int opt = Helpers.getSharedIntPref(mContext, name, defValue); XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomBlurModifier", opt); - if (Helpers.is12()) { - Object mControlPanelWindowManager = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.miui.statusbar.phone.ControlPanelWindowManager", lpparam.classLoader)); - XposedHelpers.setAdditionalInstanceField(mControlPanelWindowManager, "mCustomBlurModifier", opt); - } + Object mControlPanelWindowManager = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.miui.statusbar.phone.ControlPanelWindowManager", lpparam.classLoader)); + XposedHelpers.setAdditionalInstanceField(mControlPanelWindowManager, "mCustomBlurModifier", opt); } }; } @@ -6404,31 +6401,30 @@ protected void after(MethodHookParam param) throws Throwable { } }); - if (Helpers.is12()) - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationSnooze", lpparam.classLoader, "createOptionViews", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - LinearLayout mSnoozeOptionContainer = (LinearLayout)XposedHelpers.getObjectField(param.thisObject, "mSnoozeOptionContainer"); - ViewGroup parent = ((ViewGroup)mSnoozeOptionContainer.getParent()); - if (parent.getClass() == ScrollView.class) return; - parent.removeView(mSnoozeOptionContainer); - HorizontalScrollView scrollView = new HorizontalScrollView(mSnoozeOptionContainer.getContext()); - scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); - scrollView.setVerticalScrollBarEnabled(false); - scrollView.setHorizontalScrollBarEnabled(false); - scrollView.addView(mSnoozeOptionContainer); - parent.addView(scrollView); - ViewGroup.LayoutParams lp1 = scrollView.getLayoutParams(); - lp1.width = ViewGroup.LayoutParams.MATCH_PARENT; - lp1.height = ViewGroup.LayoutParams.WRAP_CONTENT; - scrollView.setLayoutParams(lp1); - ViewGroup.MarginLayoutParams lp2 = (ViewGroup.MarginLayoutParams)mSnoozeOptionContainer.getLayoutParams(); - lp2.setMarginStart(0); - lp2.width = ViewGroup.LayoutParams.MATCH_PARENT; - lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT; - mSnoozeOptionContainer.setLayoutParams(lp2); - } - }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationSnooze", lpparam.classLoader, "createOptionViews", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + LinearLayout mSnoozeOptionContainer = (LinearLayout)XposedHelpers.getObjectField(param.thisObject, "mSnoozeOptionContainer"); + ViewGroup parent = ((ViewGroup)mSnoozeOptionContainer.getParent()); + if (parent.getClass() == ScrollView.class) return; + parent.removeView(mSnoozeOptionContainer); + HorizontalScrollView scrollView = new HorizontalScrollView(mSnoozeOptionContainer.getContext()); + scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); + scrollView.setVerticalScrollBarEnabled(false); + scrollView.setHorizontalScrollBarEnabled(false); + scrollView.addView(mSnoozeOptionContainer); + parent.addView(scrollView); + ViewGroup.LayoutParams lp1 = scrollView.getLayoutParams(); + lp1.width = ViewGroup.LayoutParams.MATCH_PARENT; + lp1.height = ViewGroup.LayoutParams.WRAP_CONTENT; + scrollView.setLayoutParams(lp1); + ViewGroup.MarginLayoutParams lp2 = (ViewGroup.MarginLayoutParams)mSnoozeOptionContainer.getLayoutParams(); + lp2.setMarginStart(0); + lp2.width = ViewGroup.LayoutParams.MATCH_PARENT; + lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT; + mSnoozeOptionContainer.setLayoutParams(lp2); + } + }); } public static void MoreSnoozeOptionsServiceHook(LoadPackageParam lpparam) { @@ -8116,94 +8112,36 @@ public static void DualRowSignalHook(LoadPackageParam lpparam) { MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_type_middle_to_strength_start", -0.4f); } - SparseIntArray signalResToLevelMap = new SparseIntArray(); - int signalRes1_0 = MainModule.resHooks.addResource("signalRes1_0", R.drawable.statusbar_signal_1_0); - int signalRes1_1 = MainModule.resHooks.addResource("signalRes1_1", R.drawable.statusbar_signal_1_1); - int signalRes1_2 = MainModule.resHooks.addResource("signalRes1_2", R.drawable.statusbar_signal_1_2); - int signalRes1_3 = MainModule.resHooks.addResource("signalRes1_3", R.drawable.statusbar_signal_1_3); - int signalRes1_4 = MainModule.resHooks.addResource("signalRes1_4", R.drawable.statusbar_signal_1_4); - int signalRes1_5 = MainModule.resHooks.addResource("signalRes1_5", R.drawable.statusbar_signal_1_5); - int signalRes2_0 = MainModule.resHooks.addResource("signalRes2_0", R.drawable.statusbar_signal_2_0); - int signalRes2_1 = MainModule.resHooks.addResource("signalRes2_1", R.drawable.statusbar_signal_2_1); - int signalRes2_2 = MainModule.resHooks.addResource("signalRes2_2", R.drawable.statusbar_signal_2_2); - int signalRes2_3 = MainModule.resHooks.addResource("signalRes2_3", R.drawable.statusbar_signal_2_3); - int signalRes2_4 = MainModule.resHooks.addResource("signalRes2_4", R.drawable.statusbar_signal_2_4); - int signalRes2_5 = MainModule.resHooks.addResource("signalRes2_5", R.drawable.statusbar_signal_2_5); - SparseIntArray signalLevelToRes1Map = new SparseIntArray(); - SparseIntArray signalLevelToRes2Map = new SparseIntArray(); - signalLevelToRes1Map.put(0, signalRes1_0); - signalLevelToRes1Map.put(1, signalRes1_1); - signalLevelToRes1Map.put(2, signalRes1_2); - signalLevelToRes1Map.put(3, signalRes1_3); - signalLevelToRes1Map.put(4, signalRes1_4); - signalLevelToRes1Map.put(5, signalRes1_5); - signalLevelToRes1Map.put(6, signalRes1_0); - signalLevelToRes2Map.put(0, signalRes2_0); - signalLevelToRes2Map.put(1, signalRes2_1); - signalLevelToRes2Map.put(2, signalRes2_2); - signalLevelToRes2Map.put(3, signalRes2_3); - signalLevelToRes2Map.put(4, signalRes2_4); - signalLevelToRes2Map.put(5, signalRes2_5); - signalLevelToRes2Map.put(6, signalRes2_0); - - int signalTintRes1_0 = MainModule.resHooks.addResource("signalTintRes1_0", R.drawable.statusbar_signal_1_0_tint); - int signalTintRes1_1 = MainModule.resHooks.addResource("signalTintRes1_1", R.drawable.statusbar_signal_1_1_tint); - int signalTintRes1_2 = MainModule.resHooks.addResource("signalTintRes1_2", R.drawable.statusbar_signal_1_2_tint); - int signalTintRes1_3 = MainModule.resHooks.addResource("signalTintRes1_3", R.drawable.statusbar_signal_1_3_tint); - int signalTintRes1_4 = MainModule.resHooks.addResource("signalTintRes1_4", R.drawable.statusbar_signal_1_4_tint); - int signalTintRes1_5 = MainModule.resHooks.addResource("signalTintRes1_5", R.drawable.statusbar_signal_1_5_tint); - int signalTintRes2_0 = MainModule.resHooks.addResource("signalTintRes2_0", R.drawable.statusbar_signal_2_0_tint); - int signalTintRes2_1 = MainModule.resHooks.addResource("signalTintRes2_1", R.drawable.statusbar_signal_2_1_tint); - int signalTintRes2_2 = MainModule.resHooks.addResource("signalTintRes2_2", R.drawable.statusbar_signal_2_2_tint); - int signalTintRes2_3 = MainModule.resHooks.addResource("signalTintRes2_3", R.drawable.statusbar_signal_2_3_tint); - int signalTintRes2_4 = MainModule.resHooks.addResource("signalTintRes2_4", R.drawable.statusbar_signal_2_4_tint); - int signalTintRes2_5 = MainModule.resHooks.addResource("signalTintRes2_5", R.drawable.statusbar_signal_2_5_tint); - SparseIntArray signalTintLevelToRes1Map = new SparseIntArray(); - SparseIntArray signalTintLevelToRes2Map = new SparseIntArray(); - signalTintLevelToRes1Map.put(0, signalTintRes1_0); - signalTintLevelToRes1Map.put(1, signalTintRes1_1); - signalTintLevelToRes1Map.put(2, signalTintRes1_2); - signalTintLevelToRes1Map.put(3, signalTintRes1_3); - signalTintLevelToRes1Map.put(4, signalTintRes1_4); - signalTintLevelToRes1Map.put(5, signalTintRes1_5); - signalTintLevelToRes1Map.put(6, signalTintRes1_0); - signalTintLevelToRes2Map.put(0, signalTintRes2_0); - signalTintLevelToRes2Map.put(1, signalTintRes2_1); - signalTintLevelToRes2Map.put(2, signalTintRes2_2); - signalTintLevelToRes2Map.put(3, signalTintRes2_3); - signalTintLevelToRes2Map.put(4, signalTintRes2_4); - signalTintLevelToRes2Map.put(5, signalTintRes2_5); - signalTintLevelToRes2Map.put(6, signalTintRes2_0); - - int signalDarkRes1_0 = MainModule.resHooks.addResource("signalDarkRes1_0", R.drawable.statusbar_signal_1_0_dark); - int signalDarkRes1_1 = MainModule.resHooks.addResource("signalDarkRes1_1", R.drawable.statusbar_signal_1_1_dark); - int signalDarkRes1_2 = MainModule.resHooks.addResource("signalDarkRes1_2", R.drawable.statusbar_signal_1_2_dark); - int signalDarkRes1_3 = MainModule.resHooks.addResource("signalDarkRes1_3", R.drawable.statusbar_signal_1_3_dark); - int signalDarkRes1_4 = MainModule.resHooks.addResource("signalDarkRes1_4", R.drawable.statusbar_signal_1_4_dark); - int signalDarkRes1_5 = MainModule.resHooks.addResource("signalDarkRes1_5", R.drawable.statusbar_signal_1_5_dark); - int signalDarkRes2_0 = MainModule.resHooks.addResource("signalDarkRes2_0", R.drawable.statusbar_signal_2_0_dark); - int signalDarkRes2_1 = MainModule.resHooks.addResource("signalDarkRes2_1", R.drawable.statusbar_signal_2_1_dark); - int signalDarkRes2_2 = MainModule.resHooks.addResource("signalDarkRes2_2", R.drawable.statusbar_signal_2_2_dark); - int signalDarkRes2_3 = MainModule.resHooks.addResource("signalDarkRes2_3", R.drawable.statusbar_signal_2_3_dark); - int signalDarkRes2_4 = MainModule.resHooks.addResource("signalDarkRes2_4", R.drawable.statusbar_signal_2_4_dark); - int signalDarkRes2_5 = MainModule.resHooks.addResource("signalDarkRes2_5", R.drawable.statusbar_signal_2_5_dark); - SparseIntArray signalDarkLevelToRes1Map = new SparseIntArray(); - SparseIntArray signalDarkLevelToRes2Map = new SparseIntArray(); - signalDarkLevelToRes1Map.put(0, signalDarkRes1_0); - signalDarkLevelToRes1Map.put(1, signalDarkRes1_1); - signalDarkLevelToRes1Map.put(2, signalDarkRes1_2); - signalDarkLevelToRes1Map.put(3, signalDarkRes1_3); - signalDarkLevelToRes1Map.put(4, signalDarkRes1_4); - signalDarkLevelToRes1Map.put(5, signalDarkRes1_5); - signalDarkLevelToRes1Map.put(6, signalDarkRes1_0); - signalDarkLevelToRes2Map.put(0, signalDarkRes2_0); - signalDarkLevelToRes2Map.put(1, signalDarkRes2_1); - signalDarkLevelToRes2Map.put(2, signalDarkRes2_2); - signalDarkLevelToRes2Map.put(3, signalDarkRes2_3); - signalDarkLevelToRes2Map.put(4, signalDarkRes2_4); - signalDarkLevelToRes2Map.put(5, signalDarkRes2_5); - signalDarkLevelToRes2Map.put(6, signalDarkRes2_0); + HashMap dualSignalResMap = new HashMap(); + String[] colorModeList = {"", "dark", "tint"}; + String[] iconStyles = {"", "thick"}; + String selectedIconStyle = MainModule.mPrefs.getString("system_statusbar_dualsimin2rows_style", ""); + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isHooked) { + isHooked = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + Resources modRes = Helpers.getModuleRes(mContext); + for (int slot = 1;slot <= 2;slot++) { + for (int lvl = 0;lvl <= 5;lvl++) { + for (String colorMode : colorModeList) { + for (String iconStyle : iconStyles) { + String dualIconId = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!iconStyle.equals("") ? ("_" + iconStyle) : ""); + int iconResId = modRes.getIdentifier(dualIconId, "drawable", Helpers.modulePkg); + String statusbarFakeId = "cust_" + dualIconId; + dualSignalResMap.put(statusbarFakeId, MainModule.resHooks.addResource(statusbarFakeId, iconResId)); + } + } + } + } + } + } + }); + + SparseIntArray signalResToLevelMap = new SparseIntArray(); Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarIconControllerImpl", lpparam.classLoader, "setMobileIcons", new MethodHook() { private boolean isHooked = false; @Override @@ -8285,25 +8223,25 @@ protected void before(final MethodHookParam param) throws Throwable { Object mobileIconState = XposedHelpers.getObjectField(param.thisObject, "mState"); int level1 = (int) XposedHelpers.getObjectField(mobileIconState, "strengthId"); level1 = level1 / 10; - int level2 = subStrengthId; boolean mLight = (boolean) XposedHelpers.getObjectField(param.thisObject, "mLight"); boolean mUseTint = (boolean) XposedHelpers.getObjectField(param.thisObject, "mUseTint"); Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); Object mMobile = XposedHelpers.getObjectField(param.thisObject, "mMobile"); - int sim1ResId; - int sim2ResId; + String colorMode = ""; if (mUseTint) { - sim1ResId = signalTintLevelToRes1Map.get(level1); - sim2ResId = signalTintLevelToRes2Map.get(level2); + colorMode = "_tint"; } - else if (mLight) { - sim1ResId = signalLevelToRes1Map.get(level1); - sim2ResId = signalLevelToRes2Map.get(level2); + else if (!mLight) { + colorMode = "_dark"; } - else { - sim1ResId = signalDarkLevelToRes1Map.get(level1); - sim2ResId = signalDarkLevelToRes2Map.get(level2); + String iconStyle = ""; + if (!selectedIconStyle.equals("")) { + iconStyle = "_" + selectedIconStyle; } + String sim1IconId = "cust_statusbar_signal_1_" + level1 + colorMode + iconStyle; + String sim2IconId = "cust_statusbar_signal_2_" + subStrengthId + colorMode + iconStyle; + int sim1ResId = dualSignalResMap.get(sim1IconId); + int sim2ResId = dualSignalResMap.get(sim2IconId); XposedHelpers.callMethod(mMobile, "setImageResource", sim1ResId); XposedHelpers.callMethod(mSmallRoaming, "setImageResource", sim2ResId); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 09e9711a..5a4adf58 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -91,10 +91,6 @@ public static void AppInfoHook(LoadPackageParam lpparam) { return; } - boolean oldMethodFound = false; - for (Member method: amaCls.getDeclaredMethods()) - if (method.getName().equals("onLoadFinished")) oldMethodFound = true; - if (findClassIfExists("androidx.fragment.app.Fragment", lpparam.classLoader) != null) Helpers.findAndHookConstructor("androidx.fragment.app.Fragment", lpparam.classLoader, new MethodHook() { @Override @@ -106,201 +102,113 @@ protected void before(final MethodHookParam param) throws Throwable { } }); - if (Helpers.is12() || !oldMethodFound) - Helpers.findAndHookMethod(amaCls, "onCreate", Bundle.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Handler handler = new Handler(Looper.getMainLooper()); - handler.post(new Runnable() { - @Override - public void run() { - final Activity act = (Activity)param.thisObject; - Object contentFrag = act.getFragmentManager().findFragmentById(android.R.id.content); - Object frag = contentFrag != null ? contentFrag : mSupportFragment; - if (frag == null) { - Helpers.log("AppInfoHook", "Unable to find fragment"); - return; - } + Helpers.findAndHookMethod(amaCls, "onCreate", Bundle.class, new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + final Activity act = (Activity)param.thisObject; + Object contentFrag = act.getFragmentManager().findFragmentById(android.R.id.content); + Object frag = contentFrag != null ? contentFrag : mSupportFragment; + if (frag == null) { + Helpers.log("AppInfoHook", "Unable to find fragment"); + return; + } - final Resources modRes; - try { - modRes = Helpers.getModuleRes(act); - Field piField = XposedHelpers.findFirstFieldByExactType(frag.getClass(), PackageInfo.class); - mLastPackageInfo = (PackageInfo)piField.get(frag); - Method[] addPref = XposedHelpers.findMethodsByExactParameters(frag.getClass(), void.class, String.class, String.class, String.class); - if (mLastPackageInfo == null || addPref.length == 0) { - Helpers.log("AppInfoHook", "Unable to find field/class/method in SecurityCenter to hook"); - return; - } else { - addPref[0].setAccessible(true); - } - addPref[0].invoke(frag, "apk_versioncode", modRes.getString(R.string.appdetails_apk_version_code), String.valueOf(mLastPackageInfo.versionCode)); - addPref[0].invoke(frag, "apk_filename", modRes.getString(R.string.appdetails_apk_file), mLastPackageInfo.applicationInfo.sourceDir); - addPref[0].invoke(frag, "data_path", modRes.getString(R.string.appdetails_data_path), mLastPackageInfo.applicationInfo.dataDir); - addPref[0].invoke(frag, "app_uid", modRes.getString(R.string.appdetails_app_uid), String.valueOf(mLastPackageInfo.applicationInfo.uid)); - addPref[0].invoke(frag, "target_sdk", modRes.getString(R.string.appdetails_sdk), String.valueOf(mLastPackageInfo.applicationInfo.targetSdkVersion)); - handler.post(new Runnable() { - @Override - public void run() { - try { - addPref[0].invoke(frag, "open_in_store", modRes.getString(R.string.appdetails_playstore), ""); - addPref[0].invoke(frag, "launch_app", modRes.getString(R.string.appdetails_launch), ""); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }); - } catch (Throwable t) { - XposedBridge.log(t); + final Resources modRes; + try { + modRes = Helpers.getModuleRes(act); + Field piField = XposedHelpers.findFirstFieldByExactType(frag.getClass(), PackageInfo.class); + mLastPackageInfo = (PackageInfo)piField.get(frag); + Method[] addPref = XposedHelpers.findMethodsByExactParameters(frag.getClass(), void.class, String.class, String.class, String.class); + if (mLastPackageInfo == null || addPref.length == 0) { + Helpers.log("AppInfoHook", "Unable to find field/class/method in SecurityCenter to hook"); return; + } else { + addPref[0].setAccessible(true); } - - XposedBridge.hookAllMethods(frag.getClass(), "onPreferenceTreeClick", new MethodHook() { + addPref[0].invoke(frag, "apk_versioncode", modRes.getString(R.string.appdetails_apk_version_code), String.valueOf(mLastPackageInfo.versionCode)); + addPref[0].invoke(frag, "apk_filename", modRes.getString(R.string.appdetails_apk_file), mLastPackageInfo.applicationInfo.sourceDir); + addPref[0].invoke(frag, "data_path", modRes.getString(R.string.appdetails_data_path), mLastPackageInfo.applicationInfo.dataDir); + addPref[0].invoke(frag, "app_uid", modRes.getString(R.string.appdetails_app_uid), String.valueOf(mLastPackageInfo.applicationInfo.uid)); + addPref[0].invoke(frag, "target_sdk", modRes.getString(R.string.appdetails_sdk), String.valueOf(mLastPackageInfo.applicationInfo.targetSdkVersion)); + handler.post(new Runnable() { @Override - protected void before(final MethodHookParam param) throws Throwable { - String key = (String)XposedHelpers.callMethod(param.args[0], "getKey"); - String title = (String)XposedHelpers.callMethod(param.args[0], "getTitle"); - switch (key) { - case "apk_filename": - ((ClipboardManager)act.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(title, mLastPackageInfo.applicationInfo.sourceDir)); - Toast.makeText(act, act.getResources().getIdentifier("app_manager_copy_pkg_to_clip", "string", act.getPackageName()), Toast.LENGTH_SHORT).show(); - param.setResult(true); - break; - case "data_path": - ((ClipboardManager)act.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(title, mLastPackageInfo.applicationInfo.dataDir)); - Toast.makeText(act, act.getResources().getIdentifier("app_manager_copy_pkg_to_clip", "string", act.getPackageName()), Toast.LENGTH_SHORT).show(); - param.setResult(true); - break; - case "open_in_store": - try { - Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + mLastPackageInfo.packageName)); - launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - act.startActivity(launchIntent); - } catch (android.content.ActivityNotFoundException anfe) { - Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + mLastPackageInfo.packageName)); - launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - act.startActivity(launchIntent); - } - param.setResult(true); - break; - case "launch_app": - Intent launchIntent = act.getPackageManager().getLaunchIntentForPackage(mLastPackageInfo.packageName); - if (launchIntent == null) { - Toast.makeText(act, modRes.getString(R.string.appdetails_nolaunch), Toast.LENGTH_SHORT).show(); - } else { - int user = 0; - try { - int uid = act.getIntent().getIntExtra("am_app_uid", -1); - user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); - } catch (Throwable t) { - XposedBridge.log(t); - } - - launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - if (user != 0) try { - XposedHelpers.callMethod(act, "startActivityAsUser", launchIntent, XposedHelpers.newInstance(UserHandle.class, user)); - } catch (Throwable t) { - XposedBridge.log(t); - } else { - act.startActivity(launchIntent); - } - } - param.setResult(true); - break; + public void run() { + try { + addPref[0].invoke(frag, "open_in_store", modRes.getString(R.string.appdetails_playstore), ""); + addPref[0].invoke(frag, "launch_app", modRes.getString(R.string.appdetails_launch), ""); + } catch (Throwable t) { + XposedBridge.log(t); } } }); + } catch (Throwable t) { + XposedBridge.log(t); + return; } - }); - } - }); - else - Helpers.hookAllMethods(amaCls, "onLoadFinished", new MethodHook() { - @Override - @SuppressWarnings("deprecation") - protected void after(final MethodHookParam param) throws Throwable { - final PreferenceActivity act = (PreferenceActivity)param.thisObject; - Field piField = XposedHelpers.findFirstFieldByExactType(act.getClass(), PackageInfo.class); - final PackageInfo mPackageInfo = (PackageInfo)piField.get(act); - final Resources modRes = Helpers.getModuleRes(act); - Method[] addPref = XposedHelpers.findMethodsByExactParameters(act.getClass(), void.class, String.class, String.class, String.class); - if (mPackageInfo == null || addPref.length == 0) { - Helpers.log("AppInfoHook", "Unable to find field/class/method in SecurityCenter to hook"); - return; - } else { - addPref[0].setAccessible(true); - } - addPref[0].invoke(act, "apk_versioncode", modRes.getString(R.string.appdetails_apk_version_code), String.valueOf(mPackageInfo.versionCode)); - addPref[0].invoke(act, "apk_filename", modRes.getString(R.string.appdetails_apk_file), mPackageInfo.applicationInfo.sourceDir); - addPref[0].invoke(act, "data_path", modRes.getString(R.string.appdetails_data_path), mPackageInfo.applicationInfo.dataDir); - addPref[0].invoke(act, "app_uid", modRes.getString(R.string.appdetails_app_uid), String.valueOf(mPackageInfo.applicationInfo.uid)); - addPref[0].invoke(act, "target_sdk", modRes.getString(R.string.appdetails_sdk), String.valueOf(mPackageInfo.applicationInfo.targetSdkVersion)); - addPref[0].invoke(act, "open_in_store", modRes.getString(R.string.appdetails_playstore), ""); - addPref[0].invoke(act, "launch_app", modRes.getString(R.string.appdetails_launch), ""); - - act.findPreference("apk_filename").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - ((ClipboardManager)act.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(preference.getTitle(), mPackageInfo.applicationInfo.sourceDir)); - Toast.makeText(act, act.getResources().getIdentifier("app_manager_copy_pkg_to_clip", "string", act.getPackageName()), Toast.LENGTH_SHORT).show(); - return true; - } - }); - act.findPreference("data_path").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - ((ClipboardManager)act.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(preference.getTitle(), mPackageInfo.applicationInfo.dataDir)); - Toast.makeText(act, act.getResources().getIdentifier("app_manager_copy_pkg_to_clip", "string", act.getPackageName()), Toast.LENGTH_SHORT).show(); - return true; - } - }); - - act.findPreference("open_in_store").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - try { - Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + mPackageInfo.packageName)); - launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - act.startActivity(launchIntent); - } catch (android.content.ActivityNotFoundException anfe) { - Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + mPackageInfo.packageName)); - launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - act.startActivity(launchIntent); - } - return true; - } - }); - - act.findPreference("launch_app").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent launchIntent = act.getPackageManager().getLaunchIntentForPackage(mPackageInfo.packageName); - if (launchIntent == null) { - Toast.makeText(act, modRes.getString(R.string.appdetails_nolaunch), Toast.LENGTH_SHORT).show(); - } else { - int user = 0; - try { - int uid = act.getIntent().getIntExtra("am_app_uid", -1); - user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); - } catch (Throwable t) { - XposedBridge.log(t); - } + XposedBridge.hookAllMethods(frag.getClass(), "onPreferenceTreeClick", new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + String key = (String)XposedHelpers.callMethod(param.args[0], "getKey"); + String title = (String)XposedHelpers.callMethod(param.args[0], "getTitle"); + switch (key) { + case "apk_filename": + ((ClipboardManager)act.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(title, mLastPackageInfo.applicationInfo.sourceDir)); + Toast.makeText(act, act.getResources().getIdentifier("app_manager_copy_pkg_to_clip", "string", act.getPackageName()), Toast.LENGTH_SHORT).show(); + param.setResult(true); + break; + case "data_path": + ((ClipboardManager)act.getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText(title, mLastPackageInfo.applicationInfo.dataDir)); + Toast.makeText(act, act.getResources().getIdentifier("app_manager_copy_pkg_to_clip", "string", act.getPackageName()), Toast.LENGTH_SHORT).show(); + param.setResult(true); + break; + case "open_in_store": + try { + Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + mLastPackageInfo.packageName)); + launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + act.startActivity(launchIntent); + } catch (android.content.ActivityNotFoundException anfe) { + Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + mLastPackageInfo.packageName)); + launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + act.startActivity(launchIntent); + } + param.setResult(true); + break; + case "launch_app": + Intent launchIntent = act.getPackageManager().getLaunchIntentForPackage(mLastPackageInfo.packageName); + if (launchIntent == null) { + Toast.makeText(act, modRes.getString(R.string.appdetails_nolaunch), Toast.LENGTH_SHORT).show(); + } else { + int user = 0; + try { + int uid = act.getIntent().getIntExtra("am_app_uid", -1); + user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); + } catch (Throwable t) { + XposedBridge.log(t); + } - launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - if (user != 0) try { - XposedHelpers.callMethod(act, "startActivityAsUser", launchIntent, XposedHelpers.newInstance(UserHandle.class, user)); - } catch (Throwable t) { - XposedBridge.log(t); - } else { - act.startActivity(launchIntent); + launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + if (user != 0) try { + XposedHelpers.callMethod(act, "startActivityAsUser", launchIntent, XposedHelpers.newInstance(UserHandle.class, user)); + } catch (Throwable t) { + XposedBridge.log(t); + } else { + act.startActivity(launchIntent); + } + } + param.setResult(true); + break; } } - return true; - } - }); - } - }); + }); + } + }); + } + }); } public static Bundle checkBundle(Context context, Bundle bundle) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 0bb66cff..622e9c1f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -202,23 +202,21 @@ public static void setMiuiCheckbox(CheckBox checkbox) { public static void setMiuiPrefItem(View item) { item.setBackgroundResource(R.drawable.list_item_bg); TextView title = item.findViewById(android.R.id.title); - if (is12()) { - int resId = item.getResources().getIdentifier("preference_item_bg", "drawable", "miui"); - if (resId != 0) item.setBackgroundResource(resId); - resId = item.getResources().getIdentifier("normal_text_size", "dimen", "miui"); - if (resId != 0 && title != null) { - title.setTextSize(TypedValue.COMPLEX_UNIT_PX, item.getResources().getDimensionPixelSize(resId)); - } - resId = item.getResources().getIdentifier("secondary_text_size", "dimen", "miui"); - if (resId != 0) { - TextView summary = item.findViewById(android.R.id.summary); - TextView text1 = item.findViewById(android.R.id.text1); - TextView text2 = item.findViewById(android.R.id.text2); - int size = item.getResources().getDimensionPixelSize(resId); - if (summary != null) summary.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); - if (text1 != null) text1.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); - if (text2 != null) text2.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); - } + int resId = item.getResources().getIdentifier("preference_item_bg", "drawable", "miui"); + if (resId != 0) item.setBackgroundResource(resId); + resId = item.getResources().getIdentifier("normal_text_size", "dimen", "miui"); + if (resId != 0 && title != null) { + title.setTextSize(TypedValue.COMPLEX_UNIT_PX, item.getResources().getDimensionPixelSize(resId)); + } + resId = item.getResources().getIdentifier("secondary_text_size", "dimen", "miui"); + if (resId != 0) { + TextView summary = item.findViewById(android.R.id.summary); + TextView text1 = item.findViewById(android.R.id.text1); + TextView text2 = item.findViewById(android.R.id.text2); + int size = item.getResources().getDimensionPixelSize(resId); + if (summary != null) summary.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + if (text1 != null) text1.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + if (text2 != null) text2.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); } if (title != null && "header".equals(title.getTag())) { int resIdSize = item.getResources().getIdentifier("preference_category_text_size", "dimen", "miui"); @@ -236,10 +234,6 @@ public static void setMiuiPrefItem(View item) { item.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); } - public static boolean is12() { - return true; - } - public static boolean isNightMode(Context context) { return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } diff --git a/app/src/main/res/drawable/statusbar_signal_1_0_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_0_dark_thick.xml new file mode 100644 index 00000000..9d669944 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_0_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_0_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_0_thick.xml new file mode 100644 index 00000000..0729f31c --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_0_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_0_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_0_tint_thick.xml new file mode 100644 index 00000000..a6a9fcd3 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_0_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_1_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_1_dark_thick.xml new file mode 100644 index 00000000..f14bc6b6 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_1_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_1_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_1_thick.xml new file mode 100644 index 00000000..fd8a6ca1 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_1_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_1_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_1_tint_thick.xml new file mode 100644 index 00000000..bd66cffa --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_1_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_2_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_2_dark_thick.xml new file mode 100644 index 00000000..b306f0b1 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_2_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_2_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_2_thick.xml new file mode 100644 index 00000000..d0eaeb3b --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_2_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_2_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_2_tint_thick.xml new file mode 100644 index 00000000..49565cc7 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_2_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_3_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_3_dark_thick.xml new file mode 100644 index 00000000..83f854a6 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_3_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_3_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_3_thick.xml new file mode 100644 index 00000000..a7889dd0 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_3_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_3_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_3_tint_thick.xml new file mode 100644 index 00000000..95e39aa0 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_3_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_4_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_4_dark_thick.xml new file mode 100644 index 00000000..aff7db04 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_4_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_4_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_4_thick.xml new file mode 100644 index 00000000..0e10dfff --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_4_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_4_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_4_tint_thick.xml new file mode 100644 index 00000000..004c90ee --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_4_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_5_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_5_dark_thick.xml new file mode 100644 index 00000000..aff7db04 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_5_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_5_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_5_thick.xml new file mode 100644 index 00000000..0e10dfff --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_5_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_1_5_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_1_5_tint_thick.xml new file mode 100644 index 00000000..004c90ee --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_1_5_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_0_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_0_dark_thick.xml new file mode 100644 index 00000000..f226a482 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_0_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_0_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_0_thick.xml new file mode 100644 index 00000000..eac16128 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_0_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_0_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_0_tint_thick.xml new file mode 100644 index 00000000..14e06391 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_0_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_1_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_1_dark_thick.xml new file mode 100644 index 00000000..20771198 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_1_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_1_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_1_thick.xml new file mode 100644 index 00000000..2fa081ed --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_1_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_1_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_1_tint_thick.xml new file mode 100644 index 00000000..3987c268 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_1_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_2_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_2_dark_thick.xml new file mode 100644 index 00000000..5c65559e --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_2_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_2_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_2_thick.xml new file mode 100644 index 00000000..52e95c19 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_2_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_2_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_2_tint_thick.xml new file mode 100644 index 00000000..1996d31d --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_2_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_3_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_3_dark_thick.xml new file mode 100644 index 00000000..04f8b7b7 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_3_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_3_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_3_thick.xml new file mode 100644 index 00000000..2d7a0556 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_3_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_3_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_3_tint_thick.xml new file mode 100644 index 00000000..dc4169dc --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_3_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_4_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_4_dark_thick.xml new file mode 100644 index 00000000..fa620b39 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_4_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_4_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_4_thick.xml new file mode 100644 index 00000000..f85a821e --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_4_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_4_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_4_tint_thick.xml new file mode 100644 index 00000000..d6c90f64 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_4_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_5_dark_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_5_dark_thick.xml new file mode 100644 index 00000000..fa620b39 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_5_dark_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_5_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_5_thick.xml new file mode 100644 index 00000000..f85a821e --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_5_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/statusbar_signal_2_5_tint_thick.xml b/app/src/main/res/drawable/statusbar_signal_2_5_tint_thick.xml new file mode 100644 index 00000000..d6c90f64 --- /dev/null +++ b/app/src/main/res/drawable/statusbar_signal_2_5_tint_thick.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 3fcf1674..f64de56f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -836,6 +836,7 @@ 所选路径 原本 永久 + 加粗 无限制 Wi-Fi已启用 Wi-Fi已禁用 @@ -1066,6 +1067,7 @@ 仅电流 右侧显示 双排信号栏 + 图标样式 右侧间距 移动网络类型单独显示 左侧间距 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index ed886a70..3e8f41eb 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -467,6 +467,15 @@ 3 + + @string/array_default + @string/array_dualsimin2rows_style_thick + + + + thick + + @string/array_system_default @string/array_autogroupnotif_no diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d595943..78eee507 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -907,6 +907,7 @@ Turn off and disable Temperature Only Current Only + Thick Unlimited Wi-Fi enabled @@ -1116,6 +1117,7 @@ Display on the right Show when charging only Dual SIM signal bars in dual rows + Icon style Right margin Put mobile network type at the right of signal icon Left margin diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index da63b314..d7c1462e 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -404,6 +404,16 @@ android:title="@string/system_statusbar_dualsimin2rows_title" android:defaultValue="false" /> + + Date: Sun, 18 Dec 2022 21:10:30 +0800 Subject: [PATCH 196/627] fix(miui14): Scramble PIN --- .../java/name/mikanoshi/customiuizer/mods/System.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bc06c350..aab00773 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -275,10 +275,11 @@ public static void ScramblePINHook(LoadPackageParam lpparam) { protected void after(MethodHookParam param) throws Throwable { View[][] mViews = (View[][])XposedHelpers.getObjectField(param.thisObject, "mViews"); ArrayList mRandomViews = new ArrayList(); - for (int row = 1; row <= 4; row++) + for (int row = 1; row <= 3; row++) for (int col = 0; col <= 2; col++) if (mViews[row][col] != null) mRandomViews.add(mViews[row][col]); + mRandomViews.add(mViews[4][1]); Collections.shuffle(mRandomViews); View pinview = (View)param.thisObject; @@ -290,7 +291,7 @@ protected void after(MethodHookParam param) throws Throwable { row1.removeAllViews(); row2.removeAllViews(); row3.removeAllViews(); - row4.removeAllViews(); + row4.removeViewAt(1); mViews[1] = new View[]{ mRandomViews.get(0), mRandomViews.get(1), mRandomViews.get(2)}; row1.addView(mRandomViews.get(0)); @@ -307,8 +308,8 @@ protected void after(MethodHookParam param) throws Throwable { row3.addView(mRandomViews.get(7)); row3.addView(mRandomViews.get(8)); - mViews[4] = new View[]{ null, mRandomViews.get(9), null}; - row4.addView(mRandomViews.get(9)); + mViews[4] = new View[]{ null, mRandomViews.get(9), mViews[4][2]}; + row4.addView(mRandomViews.get(9), 1); XposedHelpers.setObjectField(param.thisObject, "mViews", mViews); } From 30b8a027d76f3dec1fc1a9aa71eadabb0f85257a Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 21 Dec 2022 20:18:27 +0800 Subject: [PATCH 197/627] dual row system icons in status bar --- .../mikanoshi/customiuizer/MainModule.java | 3 + .../mikanoshi/customiuizer/mods/System.java | 193 +++++++++++++++++- .../mikanoshi/customiuizer/utils/Helpers.java | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/prefs_system.xml | 18 ++ 6 files changed, 217 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 9cf002ab..a4cf29cd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -352,6 +352,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_statusbar_dualsimin2rows")) { System.DualRowSignalHook(lpparam); } + if (mPrefs.getBoolean("system_statusbar_dualrows")) { + System.DualRowStatusbarHook(lpparam); + } if (mPrefs.getInt("system_ccgridcolumns", 4) > 4 || mPrefs.getInt("system_ccgridrows", 4) > 4) System.SystemCCGridHook(lpparam); if (mPrefs.getBoolean("system_cc_tile_roundedrect")) { System.CCTileCornerHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index aab00773..f9d0cd9f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5112,6 +5112,16 @@ private static TextView createBatteryDetailView(Context mContext, LinearLayout.L res.getDisplayMetrics() ); batteryView.setPaddingRelative(leftMargin, 0, rightMargin, 0); + + int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_verticaloffset", 8); + if (verticalOffset != 8) { + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + res.getDisplayMetrics() + ); + lp.topMargin = (int) (marginTop); + } batteryView.setLayoutParams(lp); return batteryView; } @@ -5189,7 +5199,7 @@ public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); Class StatusBarIconHolder = XposedHelpers.findClass("com.android.systemui.statusbar.phone.StatusBarIconHolder", lpparam.classLoader); boolean atRight = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright"); - if (atRight) { + if (atRight && !MainModule.mPrefs.getBoolean("system_statusbar_dualsimin2rows")) { Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { private boolean isHooked = false; @Override @@ -5238,7 +5248,7 @@ protected void before(MethodHookParam param) throws Throwable { } }); } - else { + else if (!atRight) { Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { private boolean isHooked = false; @Override @@ -8601,4 +8611,183 @@ protected void before(MethodHookParam param) throws Throwable { } }); } + + public static void DualRowStatusbarHook(LoadPackageParam lpparam) { + final int[] statusBarPaddingTop = new int[1]; + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + int dimenResId = mContext.getResources().getIdentifier("status_bar_padding_top", "dimen", lpparam.packageName); + statusBarPaddingTop[0] = mContext.getResources().getDimensionPixelSize(dimenResId); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", 2); + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + FrameLayout sbView = (FrameLayout) param.thisObject; + Context mContext = sbView.getContext(); + LinearLayout leftLayout = new LinearLayout(mContext); + LinearLayout rightLayout = new LinearLayout(mContext); + LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); + ViewGroup rightContainer = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mSystemIconArea"); + LinearLayout statusBarcontents = (LinearLayout) rightContainer.getParent(); + statusBarcontents.removeView(leftContainer); + statusBarcontents.removeView(rightContainer); + statusBarcontents.addView(leftLayout, 0); + statusBarcontents.addView(rightLayout); + XposedHelpers.setObjectField(param.thisObject, "mSystemIconArea", rightLayout); + leftLayout.addView(leftContainer); + LinearLayout secondLeft = new LinearLayout(mContext); + leftLayout.addView(secondLeft); + LinearLayout firstRight = new LinearLayout(mContext); + rightLayout.addView(firstRight); + firstRight.setGravity(Gravity.END); + LinearLayout secondRight = new LinearLayout(mContext); + rightLayout.addView(secondRight); + secondRight.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); + View mBattery = (View) XposedHelpers.getObjectField(param.thisObject, "mBattery"); + ((ViewGroup) mBattery.getParent()).removeView(mBattery); + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright") && MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) { + TextView batteryView = createBatteryDetailView(mContext, new LinearLayout.LayoutParams(-2, -2)); + secondRight.addView(batteryView); + mBatteryDetailViews.add(batteryView); + Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); + Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); + Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); + Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); + XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); + updateTempAndCurrent(ChargeUtilsClass); + } + secondRight.addView(mBattery); + + XposedHelpers.setAdditionalInstanceField(param.thisObject, "leftLayout", leftLayout); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "rightLayout", rightLayout); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "firstRight", firstRight); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "secondLeft", secondLeft); + + View mFullscreenStatusBarNotificationIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mFullscreenStatusBarNotificationIconArea"); + ((ViewGroup) mFullscreenStatusBarNotificationIconArea.getParent()).removeView(mFullscreenStatusBarNotificationIconArea); + secondLeft.addView(mFullscreenStatusBarNotificationIconArea); + View mDripStatusBarNotificationIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarNotificationIconArea"); + ((ViewGroup) mDripStatusBarNotificationIconArea.getParent()).removeView(mDripStatusBarNotificationIconArea); + secondLeft.addView(mDripStatusBarNotificationIconArea); + View mStatusBarStatusIcons = (View) XposedHelpers.getObjectField(param.thisObject, "mStatusBarStatusIcons"); + ((ViewGroup) mStatusBarStatusIcons.getParent()).removeView(mStatusBarStatusIcons); + firstRight.addView(mStatusBarStatusIcons); + int resSystemIconsId = sbView.getResources().getIdentifier("system_icons", "id", lpparam.packageName); + firstRight.setId(resSystemIconsId); + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); + LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); + LinearLayout leftLayout = (LinearLayout) leftContainer.getParent(); + LinearLayout rightLayout = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "rightLayout"); + LinearLayout rightContainer = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "firstRight"); + LinearLayout secondLeft = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "secondLeft"); + LinearLayout secondRight = (LinearLayout) rightLayout.getChildAt(1); + LinearLayout statusBarcontents = (LinearLayout) leftLayout.getParent(); + + statusBarcontents.setOrientation(mCurrentStatusBarType == 0 ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); + if (mCurrentStatusBarType == 0) { + if (leftLayout.getChildAt(1) != rightContainer) { + leftLayout.removeViewAt(1); + rightLayout.removeViewAt(0); + leftLayout.addView(rightContainer); + rightLayout.addView(secondLeft, 0); + } + leftLayout.setOrientation(LinearLayout.HORIZONTAL); + rightLayout.setOrientation(LinearLayout.HORIZONTAL); + LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(-1, 0, 1); + leftLayout.setLayoutParams(leftLayoutLp); + LinearLayout.LayoutParams rightLayoutLp = new LinearLayout.LayoutParams(-1, 0, 1); + rightLayout.setLayoutParams(rightLayoutLp); + + LinearLayout.LayoutParams firstRowlp = new LinearLayout.LayoutParams(-2, -1, 0); + leftContainer.setLayoutParams(firstRowlp); + firstRowlp = new LinearLayout.LayoutParams(0, -1, 1); + rightContainer.setLayoutParams(firstRowlp); + + LinearLayout.LayoutParams secondRowLp = new LinearLayout.LayoutParams(0, -1, 1); + secondLeft.setLayoutParams(secondRowLp); + secondRight.setLayoutParams(secondRowLp); + } + else { + if (leftLayout.getChildAt(1) != secondLeft) { + Helpers.log("horiz two cols"); + leftLayout.removeViewAt(1); + rightLayout.removeViewAt(0); + leftLayout.addView(secondLeft); + rightLayout.addView(rightContainer, 0); + } + Object mMiuiEndIconManager = XposedHelpers.getObjectField(param.thisObject, "mMiuiEndIconManager"); + XposedHelpers.callMethod(mMiuiEndIconManager, "setDripEnd", false); + Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); + XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); + View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); + mDripStatusBarLeftStatusIconArea.setVisibility(View.GONE); + leftLayout.setOrientation(LinearLayout.VERTICAL); + rightLayout.setOrientation(LinearLayout.VERTICAL); + LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); + leftLayout.setLayoutParams(leftLayoutLp); + LinearLayout.LayoutParams rightLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); + rightLayout.setLayoutParams(rightLayoutLp); + + LinearLayout.LayoutParams leftLp = new LinearLayout.LayoutParams(-1, 0, 1); + leftContainer.setLayoutParams(leftLp); + secondLeft.setLayoutParams(leftLp); + + LinearLayout.LayoutParams rightLp = new LinearLayout.LayoutParams(-1, 0, 1); + rightContainer.setLayoutParams(rightLp); + secondRight.setLayoutParams(rightLp); + } + secondLeft.setGravity(Gravity.CENTER_VERTICAL | Gravity.START); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showSystemIconArea", boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); + View rightLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "rightLayout"); + View leftLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "leftLayout"); + leftLayout.setVisibility(LinearLayout.VISIBLE); + rightLayout.setVisibility(LinearLayout.VISIBLE); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "hideSystemIconArea", boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); + View rightLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "rightLayout"); + View leftLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "leftLayout"); + leftLayout.setVisibility(LinearLayout.GONE); + rightLayout.setVisibility(LinearLayout.GONE); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View view = (View) param.args[0]; + if (view != null) { + view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); + param.setResult(null); + } + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); + } + }); + } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 622e9c1f..9db64a39 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -158,14 +158,12 @@ protected int sizeOf(String key, Bitmap icon) { "pref_key_launcher_horizwidgetmargin" )); public static final HashMap l10nProgress = new HashMap() {{ - put("ru-RU", "100"); + put("ru-RU", "99"); put("zh-CN", "99"); put("zh-TW", "99"); put("pl-PL", "99"); }}; - public static final ArrayList shortcutIcons = new ArrayList(); - public enum SettingsType { Preference, Edit } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f64de56f..33f30dca 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1067,6 +1067,8 @@ 仅电流 右侧显示 双排信号栏 + 双排状态栏 + 如有必要请适当增加状态栏高度 图标样式 右侧间距 移动网络类型单独显示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78eee507..a0e53af0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1117,6 +1117,8 @@ Display on the right Show when charging only Dual SIM signal bars in dual rows + Dual rows in status bar + Need increase statusbar height on some devices Icon style Right margin Put mobile network type at the right of signal icon diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index d7c1462e..5c40e8b4 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -491,11 +491,29 @@ miuizer:displayDividerValue="2" miuizer:format="%s dip" /> + + + + Date: Wed, 21 Dec 2022 21:30:15 +0800 Subject: [PATCH 198/627] fix: Hide warning about low battery level --- .../java/name/mikanoshi/customiuizer/MainModule.java | 5 ++++- .../java/name/mikanoshi/customiuizer/mods/System.java | 10 ++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index a4cf29cd..261b25c1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -76,7 +76,6 @@ public void initZygote(StartupParam startParam) { if (mPrefs.getBoolean("system_allownotifonkeyguard")) System.AllowAllKeyguardSysHook(); if (mPrefs.getBoolean("system_allownotiffloat")) System.AllowAllFloatSysHook(); if (mPrefs.getBoolean("system_resizablewidgets")) System.ResizableWidgetsHook(); - if (mPrefs.getBoolean("system_hidelowbatwarn")) System.NoLowBatteryWarningHook(); if (mPrefs.getBoolean("system_nomediamute")) System.NoMediaMuteInDNDHook(); if (mPrefs.getBoolean("system_audiosilencer")) System.AudioSilencerHook(); if (mPrefs.getBoolean("controls_volumecursor")) Controls.VolumeCursorHook(); @@ -194,6 +193,10 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.AddFiveGTileHook(lpparam); } + if (mPrefs.getBoolean("system_hidelowbatwarn")) { + System.NoLowBatteryWarningHook(lpparam); + } + if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); if (mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || mPrefs.getInt("system_volumeblur_expanded", 0) > 0) System.BlurVolumeDialogBackgroundRes(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index f9d0cd9f..f9decbb5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6641,14 +6641,8 @@ public static void NoSafeVolumeWarningRes() { MainModule.resHooks.setObjectReplacement("android", "bool", "config_safe_media_disable_on_volume_up", false); } - public static void NoLowBatteryWarningHook() { - Helpers.hookAllMethods(Settings.System.class, "getIntForUser", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String key = (String)param.args[1]; - if ("low_battery_dialog_disabled".equals(key)) param.setResult(1); - } - }); + public static void NoLowBatteryWarningHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.power.PowerNotificationWarnings", lpparam.classLoader, "showLowBatteryWarning", boolean.class, XC_MethodReplacement.DO_NOTHING); } public static void TempHideOverlaySystemUIHook(LoadPackageParam lpparam) { From 93a68718373d0877898d2cc7e440d172231390bb Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 24 Dec 2022 16:44:24 +0800 Subject: [PATCH 199/627] fix(miui14): 4g to lte --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index f9decbb5..9c3b0e2c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5073,7 +5073,8 @@ protected void after(MethodHookParam param) throws Throwable { } public static void Network4GtoLTEHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MobileSignalController", lpparam.classLoader, "getMobileTypeName", int.class, new MethodHook() { + String MobileController = Helpers.isTPlus() ? "com.android.systemui.statusbar.connectivity.MobileSignalController" : "com.android.systemui.statusbar.policy.MobileSignalController"; + Helpers.findAndHookMethod(MobileController, lpparam.classLoader, "getMobileTypeName", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { String net = (String)param.getResult(); From 387400128d876e5f7f45a7aa24ac1200765c1fce Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 24 Dec 2022 17:10:45 +0800 Subject: [PATCH 200/627] feat: statusbar padding top adjust --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 62 ++++++++++--------- app/src/main/res/values-zh-rCN/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/prefs_system.xml | 21 +++++++ 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 261b25c1..965bce33 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -276,6 +276,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { } if (mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) System.DisplayBatteryDetailHook(lpparam); if (mPrefs.getBoolean("system_statusbar_horizmargin")) System.HorizMarginHook(lpparam); + if (mPrefs.getBoolean("system_statusbar_topmargin")) System.TopMarginHook(lpparam); if (mPrefs.getBoolean("system_showpct")) System.BrightnessPctHook(lpparam); if (mPrefs.getBoolean("system_cleanmirror")) System.ClearBrightnessMirrorHook(lpparam); if (mPrefs.getBoolean("system_hidelsstatusbar")) System.HideLockScreenStatusBarHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 9c3b0e2c..bf05e794 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8048,6 +8048,40 @@ protected void before(final MethodHookParam param) throws Throwable { }); } + public static void TopMarginHook(LoadPackageParam lpparam) { + int topMargin = MainModule.mPrefs.getInt("system_statusbar_topmargin_val", 1); + boolean unsetLS = MainModule.mPrefs.getBoolean("system_statusbar_topmargin_unset_lockscreen"); + final int[] statusBarPaddingTop = new int[1]; + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + int dimenResId = mContext.getResources().getIdentifier("status_bar_padding_top", "dimen", lpparam.packageName); + statusBarPaddingTop[0] = mContext.getResources().getDimensionPixelSize(dimenResId); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", topMargin); + } + }); + if (unsetLS) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View view = (View) param.args[0]; + if (view != null) { + view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); + param.setResult(null); + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); + } + }); + } + } + + public static void MobileTypeSingleHook(LoadPackageParam lpparam) { MethodHook showSingleMobileType = new MethodHook(MethodHook.PRIORITY_HIGHEST) { @Override @@ -8608,16 +8642,6 @@ protected void before(MethodHookParam param) throws Throwable { } public static void DualRowStatusbarHook(LoadPackageParam lpparam) { - final int[] statusBarPaddingTop = new int[1]; - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - int dimenResId = mContext.getResources().getIdentifier("status_bar_padding_top", "dimen", lpparam.packageName); - statusBarPaddingTop[0] = mContext.getResources().getDimensionPixelSize(dimenResId); - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", 2); - } - }); Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -8766,23 +8790,5 @@ protected void after(MethodHookParam param) throws Throwable { rightLayout.setVisibility(LinearLayout.GONE); } }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - View view = (View) param.args[0]; - if (view != null) { - view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); - param.setResult(null); - } - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); - } - }); } } \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 33f30dca..c5186c90 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1075,6 +1075,9 @@ 左侧间距 上下偏移量 状态栏水平边距 + 状态栏上边距 + 上边距大小 + 不修改锁屏状态栏 应用信息 强制关闭 重启系统界面 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a0e53af0..accc8ce5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1125,6 +1125,9 @@ Left margin Vertical offset Statusbar horizontal padding + Statusbar top padding + Top padding + Unset statusbar in Keyguard Move some icons to the right Mainly for devices with cutout at the center of the top edge Network speed indicator diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 5c40e8b4..73389f4c 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -524,6 +524,27 @@ miuizer:stepValue="1" miuizer:format="%d dip" /> + + + + + + From 3e18d7331b53068e009e3e5217a6f751a549f2b0 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 26 Dec 2022 23:15:35 +0800 Subject: [PATCH 201/627] style: notification slider in miui volume dialog --- .../java/name/mikanoshi/customiuizer/mods/System.java | 1 - app/src/main/res/values-440dpi/dimens.xml | 3 --- app/src/main/res/values-land/dimens.xml | 4 ++-- app/src/main/res/values-xxhdpi/dimens.xml | 3 --- app/src/main/res/values/dimens.xml | 8 ++++---- 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bf05e794..1de15270 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8738,7 +8738,6 @@ protected void after(MethodHookParam param) throws Throwable { } else { if (leftLayout.getChildAt(1) != secondLeft) { - Helpers.log("horiz two cols"); leftLayout.removeViewAt(1); rightLayout.removeViewAt(0); leftLayout.addView(secondLeft); diff --git a/app/src/main/res/values-440dpi/dimens.xml b/app/src/main/res/values-440dpi/dimens.xml index 2b3d37b0..b3276684 100644 --- a/app/src/main/res/values-440dpi/dimens.xml +++ b/app/src/main/res/values-440dpi/dimens.xml @@ -1,8 +1,5 @@ - 368.4792dp - 368.4792dp - 19.64dp diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml index 1f152bf1..6e38c0b4 100644 --- a/app/src/main/res/values-land/dimens.xml +++ b/app/src/main/res/values-land/dimens.xml @@ -1,5 +1,5 @@ - + 302dp -2px - + 60dp diff --git a/app/src/main/res/values-xxhdpi/dimens.xml b/app/src/main/res/values-xxhdpi/dimens.xml index 763a6e10..e7d6efc0 100644 --- a/app/src/main/res/values-xxhdpi/dimens.xml +++ b/app/src/main/res/values-xxhdpi/dimens.xml @@ -1,8 +1,5 @@ - 337.77dp - 337.77dp - 18dp diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 16859ddc..0f8619b4 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -19,10 +19,10 @@ 11dp - 337.77dp - 337.77dp - 60dp - 30dp + 283.625dp + @dimen/miui_volume_content_width_expanded + 56dp + 19.5dp 30dp 40.0dp From 3cf2ae1b02308e571c94520e981c8279c2f9a46b Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 27 Dec 2022 11:45:20 +0800 Subject: [PATCH 202/627] fix: show battery tempandcurrent at right --- .../name/mikanoshi/customiuizer/mods/System.java | 5 ++--- .../customiuizer/utils/ResourceHooks.java | 14 +------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 1de15270..e4f97886 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5200,7 +5200,7 @@ public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); Class StatusBarIconHolder = XposedHelpers.findClass("com.android.systemui.statusbar.phone.StatusBarIconHolder", lpparam.classLoader); boolean atRight = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright"); - if (atRight && !MainModule.mPrefs.getBoolean("system_statusbar_dualsimin2rows")) { + if (atRight && !MainModule.mPrefs.getBoolean("system_statusbar_dualrows")) { Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { private boolean isHooked = false; @Override @@ -7592,8 +7592,7 @@ protected void before(MethodHookParam param) throws Throwable { } public static void SecureControlCenterHook(LoadPackageParam lpparam) { - XposedHelpers.findAndHookMethod("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader, "supportExpandableStatusbarUnderKeyguard", XC_MethodReplacement.returnConstant(false)); - + Helpers.findAndHookMethodSilently("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader, "supportExpandableStatusbarUnderKeyguard", XC_MethodReplacement.returnConstant(false)); Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader, "onContentChanged", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index 73b295ff..112c9032 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -110,15 +110,6 @@ public void setResReplacement(String pkg, String type, String name, int replacem } } - public void setDensityReplacement(String pkg, String type, String name, Integer replacementResValue) { - try { - applyHooks(); - replacements.put(pkg + ":" + type + "/" + name, new Pair<>(ReplacementType.DENSITY, replacementResValue)); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - public void setDensityReplacement(String pkg, String type, String name, float replacementResValue) { try { applyHooks(); @@ -165,10 +156,7 @@ else if (replacements.containsKey(resAnyPkgName)) if (replacement != null) if (replacement.first == ReplacementType.OBJECT) return replacement.second; else if (replacement.first == ReplacementType.DENSITY) { - if (replacement.second instanceof Float) { - return (Float) replacement.second * res.getDisplayMetrics().density; - } - return (Integer)replacement.second * res.getDisplayMetrics().density; + return (Float)replacement.second * res.getDisplayMetrics().density; } else if (replacement.first == ReplacementType.ID) modResId = (Integer)replacement.second; if (modResId == null) return null; From 878f1cd36086b773fd2132fcbd92167aa7d1e82f Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 27 Dec 2022 22:16:07 +0800 Subject: [PATCH 203/627] hide clock on lockscreen --- .../mikanoshi/customiuizer/mods/System.java | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index e4f97886..18807392 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5502,21 +5502,29 @@ public static void HideProximityWarningHook(LoadPackageParam lpparam) { } public static void HideLockScreenClockHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "setKeyguardStatusViewVisibility", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - View mKeyguardClockView = (View)XposedHelpers.getObjectField(param.thisObject, "mKeyguardClockView"); - if (mKeyguardClockView == null) { - Helpers.log("HideLockScreenClockHook", "mKeyguardClockView is null"); - return; + if (!Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.keyguard.clock.KeyguardClockContainer", lpparam.classLoader, "updateClock", float.class, int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = 0.0f; } - ((ViewGroup)mKeyguardClockView).getChildAt(0).setVisibility(View.INVISIBLE); - mKeyguardClockView.animate().cancel(); - XposedHelpers.setBooleanField(param.thisObject, "mKeyguardStatusViewAnimating", false); - mKeyguardClockView.setAlpha(0.0f); - mKeyguardClockView.setVisibility(View.INVISIBLE); - } - }); + }); + Helpers.hookAllMethods("com.android.keyguard.KeyguardVisibilityHelper", lpparam.classLoader, "setViewVisibility", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object KeyguardClockInjector = XposedHelpers.callStaticMethod(findClassIfExists("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.keyguard.injector.KeyguardClockInjector", lpparam.classLoader)); + View mKeyguardClockView = (View)XposedHelpers.callMethod(KeyguardClockInjector, "getView"); + if (mKeyguardClockView == null) { + Helpers.log("HideLockScreenClockHook", "mKeyguardClockView is null"); + return; + } + mKeyguardClockView.animate().cancel(); + XposedHelpers.setBooleanField(param.thisObject, "mKeyguardViewVisibilityAnimating", false); + mKeyguardClockView.setAlpha(0.0f); + mKeyguardClockView.setVisibility(View.INVISIBLE); + } + }); + } } public static void FirstVolumePressHook(LoadPackageParam lpparam) { From 48175f80e46374354ccbc904556420327a604f1d Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 28 Dec 2022 19:38:24 +0800 Subject: [PATCH 204/627] fix(miui14): battery indicator --- .../mikanoshi/customiuizer/mods/System.java | 27 +++++++++---------- app/src/main/res/values-night-v31/colors.xml | 5 ---- app/src/main/res/values-night/colors.xml | 4 +-- app/src/main/res/values-v31/colors.xml | 5 ---- app/src/main/res/values/colors.xml | 4 +-- 5 files changed, 17 insertions(+), 28 deletions(-) delete mode 100644 app/src/main/res/values-night-v31/colors.xml delete mode 100644 app/src/main/res/values-v31/colors.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bf05e794..7594b66b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -196,7 +196,7 @@ import name.mikanoshi.customiuizer.utils.SoundData; public class System { - private static String StatusBarCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfacesImpl" : "com.android.systemui.statusbar.phone.StatusBar"; + private final static String StatusBarCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfacesImpl" : "com.android.systemui.statusbar.phone.StatusBar"; public static void ScreenAnimHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.display.DisplayPowerController", lpparam.classLoader, "initialize", new MethodHook() { @@ -4074,11 +4074,19 @@ protected void before(MethodHookParam param) throws Throwable { } public static void BatteryIndicatorHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "createAndAddWindows", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - FrameLayout mStatusBarWindow = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mPhoneStatusBarWindow"); + ViewGroup mStatusBarWindow; + if (Helpers.isTPlus()) { + Object sbWindowController = XposedHelpers.getObjectField(param.thisObject, "mStatusBarWindowController"); + mStatusBarWindow = (ViewGroup) XposedHelpers.getObjectField(sbWindowController, "mStatusBarWindowView"); + } + else { + mStatusBarWindow = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mPhoneStatusBarWindow"); + } + BatteryIndicator indicator = new BatteryIndicator(mContext); View panel = mStatusBarWindow.findViewById(mContext.getResources().getIdentifier("notification_panel", "id", lpparam.packageName)); mStatusBarWindow.addView(indicator, panel != null ? mStatusBarWindow.indexOfChild(panel) + 1 : Math.max(mStatusBarWindow.getChildCount() - 1, 2)); @@ -4091,7 +4099,6 @@ protected void after(final MethodHookParam param) throws Throwable { XposedHelpers.setAdditionalInstanceField(mBatteryController, "mBatteryIndicator", indicator); XposedHelpers.callMethod(mBatteryController, "fireBatteryLevelChanged"); XposedHelpers.callMethod(mBatteryController, "firePowerSaveChanged"); -// XposedHelpers.callMethod(mBatteryController, "fireExtremePowerSaveChanged"); } }); @@ -4114,7 +4121,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "updateKeyguardState", new MethodHook() { + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "updateIsKeyguard", boolean.class, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); @@ -4123,7 +4130,7 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.NotificationIconAreaController", lpparam.classLoader, "onDarkChanged", Rect.class, float.class, int.class, new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationIconAreaController", lpparam.classLoader, "onDarkChanged", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); @@ -4149,14 +4156,6 @@ protected void after(final MethodHookParam param) throws Throwable { if (indicator != null) indicator.onPowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mPowerSave")); } }); - -// Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BatteryControllerImpl", lpparam.classLoader, "fireExtremePowerSaveChanged", new MethodHook() { -// @Override -// protected void after(final MethodHookParam param) throws Throwable { -// BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); -// if (indicator != null) indicator.onExtremePowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mIsExtremePowerSaveMode")); -// } -// }); } private static boolean obtainMagnifierShowCoordinates(Object mEditor, int type, final MotionEvent event, final PointF showPosInView) { diff --git a/app/src/main/res/values-night-v31/colors.xml b/app/src/main/res/values-night-v31/colors.xml deleted file mode 100644 index be8d7198..00000000 --- a/app/src/main/res/values-night-v31/colors.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - @android:color/system_neutral1_900 - @android:color/system_accent1_200 - \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index b680b0a0..6b2323a2 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -1,12 +1,12 @@ - @color/background_material_dark + @android:color/system_neutral1_900 @android:color/system_neutral2_700 @android:color/system_neutral1_100 @android:color/system_neutral1_200 #99ffffff #337f7f7f - #ff0073dd + @android:color/system_accent1_200 @android:color/system_neutral1_100 #e6ffffff diff --git a/app/src/main/res/values-v31/colors.xml b/app/src/main/res/values-v31/colors.xml deleted file mode 100644 index 10645f4d..00000000 --- a/app/src/main/res/values-v31/colors.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - @android:color/system_neutral1_10 - @android:color/system_accent1_600 - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 883e2a7c..15c5b000 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,13 +1,13 @@ #ff424a60 - @color/background_material_light + @android:color/system_neutral1_10 @android:color/system_neutral2_100 @android:color/system_neutral1_900 @android:color/system_neutral1_700 #99000000 #33808080 - #ff0d84ff + @android:color/system_accent1_600 @color/highlight_normal_light @android:color/system_neutral1_900 From 9f015ef722e32e2915aa7f48e5b9c35defd4c542 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 28 Dec 2022 19:39:18 +0800 Subject: [PATCH 205/627] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9ecc001f..d909f227 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 - versionCode 46 - versionName "22.12.15" + versionCode 47 + versionName "22.12.28" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } From 416db5f63d2ad97dc61eec04ead5e26f898dc8cd Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 29 Dec 2022 10:54:19 +0800 Subject: [PATCH 206/627] fix(miui14): dual row system icons in status bar --- .../name/mikanoshi/customiuizer/mods/System.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 67c3222c..453f2d46 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8657,6 +8657,12 @@ protected void after(MethodHookParam param) throws Throwable { LinearLayout rightLayout = new LinearLayout(mContext); LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); ViewGroup rightContainer = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mSystemIconArea"); + View switchUserView = null; + if (Helpers.isTPlus()) { + int userViewId = sbView.getResources().getIdentifier("user_switcher_container", "id", lpparam.packageName); + switchUserView = sbView.findViewById(userViewId); + ((ViewGroup) switchUserView.getParent()).removeView(switchUserView); + } LinearLayout statusBarcontents = (LinearLayout) rightContainer.getParent(); statusBarcontents.removeView(leftContainer); statusBarcontents.removeView(rightContainer); @@ -8687,6 +8693,12 @@ protected void after(MethodHookParam param) throws Throwable { } secondRight.addView(mBattery); + if (Helpers.isTPlus()) { + if (switchUserView != null) { + secondRight.addView(switchUserView); + } + } + XposedHelpers.setAdditionalInstanceField(param.thisObject, "leftLayout", leftLayout); XposedHelpers.setAdditionalInstanceField(param.thisObject, "rightLayout", rightLayout); XposedHelpers.setAdditionalInstanceField(param.thisObject, "firstRight", firstRight); From ef472bbd4bc71a3bf2c3cd6d8d9458d87ba84568 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 29 Dec 2022 11:25:22 +0800 Subject: [PATCH 207/627] fix(miui14): unlock with bluetooth --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 453f2d46..7328a4a1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -462,15 +462,15 @@ protected void after(MethodHookParam param) throws Throwable { } }); - Helpers.findAndHookMethod("com.android.keyguard.KeyguardSecurityContainer", lpparam.classLoader, "onFinishInflate", new MethodHook() { + Helpers.hookAllConstructors("com.android.keyguard.KeyguardSecurityContainerController", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context)XposedHelpers.callMethod(param.thisObject, "getContext"); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { try { - Object mCallback = XposedHelpers.getObjectField(param.thisObject, "mCallback"); + Object mCallback = XposedHelpers.getObjectField(param.thisObject, "mKeyguardSecurityCallback"); XposedHelpers.callMethod(mCallback, "reportUnlockAttempt", 0, true, 0, 0); } catch (Throwable t) { XposedBridge.log(t); From 775aac19d811c60993a005735ae56243752042bd Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 29 Dec 2022 11:50:41 +0800 Subject: [PATCH 208/627] fix(miui14): clean share apps --- .../name/mikanoshi/customiuizer/mods/System.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 7328a4a1..c68d8aa2 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -3273,6 +3273,7 @@ public void onChange(String name) { protected void after(MethodHookParam param) throws Throwable { try { if (param.args[0] == null) return; + if (param.args.length < 6) return; Intent origIntent = (Intent)param.args[0]; String action = origIntent.getAction(); if (action == null) return; @@ -3303,8 +3304,8 @@ protected void after(MethodHookParam param) throws Throwable { } }; - if (!Helpers.findAndHookMethodSilently("com.android.server.pm.PackageManagerService", lpparam.classLoader, "queryIntentActivitiesInternal", Intent.class, String.class, int.class, int.class, int.class, boolean.class, boolean.class, hook)) - Helpers.findAndHookMethod("com.android.server.pm.PackageManagerService", lpparam.classLoader, "queryIntentActivitiesInternal", Intent.class, String.class, int.class, int.class, hook); + String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService"; + Helpers.hookAllMethods(ActQueryService, lpparam.classLoader, "queryIntentActivitiesInternal", hook); } private static boolean hideMimeType(int mimeFlags, String mimeType) { @@ -3427,6 +3428,7 @@ public void onChange(Uri uri) { protected void after(MethodHookParam param) throws Throwable { try { if (param.args[0] == null) return; + if (param.args.length < 6) return; Intent origIntent = (Intent)param.args[0]; Intent intent = (Intent)origIntent.clone(); String action = intent.getAction(); @@ -3464,8 +3466,8 @@ protected void after(MethodHookParam param) throws Throwable { } }; - if (!Helpers.findAndHookMethodSilently("com.android.server.pm.PackageManagerService", lpparam.classLoader, "queryIntentActivitiesInternal", Intent.class, String.class, int.class, int.class, int.class, boolean.class, boolean.class, hook)) - Helpers.findAndHookMethod("com.android.server.pm.PackageManagerService", lpparam.classLoader, "queryIntentActivitiesInternal", Intent.class, String.class, int.class, int.class, hook); + String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService"; + Helpers.hookAllMethods(ActQueryService, lpparam.classLoader, "queryIntentActivitiesInternal", hook); } public static void VolumeTimerValuesRes(LoadPackageParam lpparam) { @@ -8266,9 +8268,11 @@ protected void after(final MethodHookParam param) throws Throwable { protected void before(final MethodHookParam param) throws Throwable { int subStrengthId = (int) XposedHelpers.getAdditionalInstanceField(param.thisObject, "subStrengthId"); if (subStrengthId < 0) return; + if (subStrengthId == 6) subStrengthId = 0; Object mobileIconState = XposedHelpers.getObjectField(param.thisObject, "mState"); int level1 = (int) XposedHelpers.getObjectField(mobileIconState, "strengthId"); level1 = level1 / 10; + if (level1 == 6) level1 = 0; boolean mLight = (boolean) XposedHelpers.getObjectField(param.thisObject, "mLight"); boolean mUseTint = (boolean) XposedHelpers.getObjectField(param.thisObject, "mUseTint"); Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); From fab59d4c8b7540c1d8b94d10769488323a341ab3 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 29 Dec 2022 14:00:36 +0800 Subject: [PATCH 209/627] fix(miui14): double tap action in statusbar --- .../name/mikanoshi/customiuizer/mods/System.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index c68d8aa2..e91079e5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -659,15 +659,15 @@ public void onReceive(final Context context, Intent intent) { Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BluetoothControllerImpl", lpparam.classLoader, "updateConnected", new MethodHook() { @Override protected void after(MethodHookParam param) { - checkBTConnections((Context)XposedHelpers.getObjectField(param.thisObject, "mContext")); + checkBTConnections((Context)XposedHelpers.getObjectField(param.thisObject, "mContext")); } }); Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BluetoothControllerImpl", lpparam.classLoader, "onBluetoothStateChanged", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) { - int state = (int)param.args[0]; - if (state != 10) checkBTConnections((Context)XposedHelpers.getObjectField(param.thisObject, "mContext")); + int state = (int)param.args[0]; + if (state != 10) checkBTConnections((Context)XposedHelpers.getObjectField(param.thisObject, "mContext")); } }); } @@ -6112,6 +6112,16 @@ protected void before(final MethodHookParam param) throws Throwable { protected void before(final MethodHookParam param) throws Throwable { String clsName = param.thisObject.getClass().getSimpleName(); boolean isInControlCenter = "ControlPanelWindowView".equals(clsName) || "ControlCenterWindowViewImpl".equals(clsName); + if (Helpers.isTPlus() && isInControlCenter) { + if (param.args.length == 2 && (boolean) param.args[1]) { + return ; + } + Object statusBarStateController = XposedHelpers.getObjectField(param.thisObject, "statusBarStateController"); + int state = (int) XposedHelpers.callMethod(statusBarStateController, "getState"); + if (state == 1 || state == 2) { + return; + } + } Context mContext = isInControlCenter ? ((View)param.thisObject).getContext() : (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); Resources res = mContext.getResources(); if (sbHeight == 0) { From 76c568dbbfe69fa6dd39b740b658490bc5acf36a Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 29 Dec 2022 15:15:13 +0800 Subject: [PATCH 210/627] fix: adjust status height --- app/build.gradle | 4 ++-- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d909f227..1ee367b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 - versionCode 47 - versionName "22.12.28" + versionCode 48 + versionName "22.12.29" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index e91079e5..40d21257 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2727,6 +2727,7 @@ protected void after(MethodHookParam param) throws Throwable { public static void StatusBarHeightRes() { int opt = MainModule.mPrefs.getInt("system_statusbarheight", 19); int heightDpi = opt == 19 ? 27 : opt; + MainModule.resHooks.setDensityReplacement("*", "dimen", "status_bar_height_default", heightDpi); MainModule.resHooks.setDensityReplacement("*", "dimen", "status_bar_height", heightDpi); MainModule.resHooks.setDensityReplacement("*", "dimen", "status_bar_height_portrait", heightDpi); MainModule.resHooks.setDensityReplacement("*", "dimen", "status_bar_height_landscape", heightDpi); From d9ce8130188d1d31b533b7e068c1d39356435acc Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 29 Dec 2022 20:53:52 +0800 Subject: [PATCH 211/627] fix: hide battery tempandcurrent on lockscreen --- .../java/name/mikanoshi/customiuizer/mods/System.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index e91079e5..70b81b56 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5182,8 +5182,10 @@ else if (opt == 2) { } else { for (TextView tv:mBatteryDetailViews) { - tv.setVisibility(View.VISIBLE); - XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); + if (!"HiddeninLS".equals(tv.getTag())) { + tv.setVisibility(View.VISIBLE); + XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); + } } } handler.postDelayed(this, 1500); @@ -5279,6 +5281,7 @@ protected void after(MethodHookParam param) throws Throwable { if (bv != null) { TextView batteryView = (TextView) bv; batteryView.setVisibility(View.VISIBLE); + batteryView.setTag(null); } } }); @@ -5288,7 +5291,8 @@ protected void after(MethodHookParam param) throws Throwable { Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); if (bv != null) { TextView batteryView = (TextView) bv; - batteryView.setVisibility((Integer) param.args[0]); + batteryView.setVisibility((int)param.args[0]); + batteryView.setTag("HiddeninLS"); } } }); From 230028ec312bd0ad86ec3af2db7227c0aec65bfd Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 30 Dec 2022 11:08:49 +0800 Subject: [PATCH 212/627] fix: dont turn on screen when headset is connected --- app/src/main/java/name/mikanoshi/customiuizer/MainModule.java | 4 +++- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++-- .../main/java/name/mikanoshi/customiuizer/subs/System.java | 4 ++++ app/src/main/res/xml/prefs_system.xml | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 965bce33..5a4ad750 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -134,7 +134,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("system_dimtime", 0) > 0) System.ScreenDimTimeHook(lpparam); if (mPrefs.getInt("system_toasttime", 0) > 0) System.ToastTimeHook(lpparam); if (!mPrefs.getString("system_defaultusb", "none").equals("none")) System.USBConfigHook(lpparam); - if (mPrefs.getBoolean("system_nolightuponheadset")) System.NoLightUpOnHeadsetHook(lpparam); + if (!Helpers.isTPlus()) { + if (mPrefs.getBoolean("system_nolightuponheadset")) System.NoLightUpOnHeadsetHook(lpparam); + } if (mPrefs.getBoolean("system_removesecure")) System.RemoveSecureHook(lpparam); if (mPrefs.getBoolean("system_remove_startactconfirm")) System.RemoveActStartConfirmHook(lpparam); if (mPrefs.getBoolean("system_securelock")) System.EnhancedSecurityHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 40d21257..f350038e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -260,10 +260,10 @@ protected void before(final MethodHookParam param) throws Throwable { } public static void NoLightUpOnHeadsetHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "wakeUpNoUpdateLocked", new MethodHook() { + Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "wakeDisplayGroupNoUpdateLocked", new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { - String reason = param.args[1] instanceof String ? (String)param.args[1] : (String)param.args[2]; + String reason = (String)param.args[3]; if ("com.android.systemui:HEADSET".equals(reason)) param.setResult(false); } }); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 6edaa50b..c1ac53af 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -65,6 +65,10 @@ public boolean onPreferenceClick(Preference preference) { } }); + if (!Helpers.isTPlus()) { + findPreference("pref_key_system_nolightuponheadset").setVisible(true); + } + break; case "pref_key_system_cat_audio": findPreference("pref_key_system_ignorecalls_apps").setOnPreferenceClickListener(openAppsEdit); diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 73389f4c..a5564e27 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -48,6 +48,7 @@ android:key="pref_key_system_nolightuponheadset" android:summary="@string/system_nolightuponheadset_summ" android:title="@string/system_nolightuponheadset_title" + app:isPreferenceVisible="false" android:defaultValue="false" /> Date: Fri, 30 Dec 2022 11:25:14 +0800 Subject: [PATCH 213/627] fix: HideProximityWarningHook --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index b3fbd351..2e6e3c24 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5505,6 +5505,7 @@ protected void after(final MethodHookParam param) throws Throwable { public static void HideProximityWarningHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.policy.MiuiScreenOnProximityLock", lpparam.classLoader, "showHint", XC_MethodReplacement.DO_NOTHING); + Helpers.findAndHookMethod("com.android.server.policy.MiuiScreenOnProximityLock", lpparam.classLoader, "prepareHintWindow", XC_MethodReplacement.DO_NOTHING); } public static void HideLockScreenClockHook(LoadPackageParam lpparam) { From aa1d5cd03ecc5246be77d713a36e2713755ec767 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 30 Dec 2022 16:42:20 +0800 Subject: [PATCH 214/627] feat: Show temperature in battery --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/Various.java | 62 +++- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_various.xml | 271 +++++++++--------- 5 files changed, 200 insertions(+), 136 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 5a4ad750..d7056e03 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -390,6 +390,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getStringAsInt("various_appsort", 0) > 0) Various.AppsDefaultSortHook(lpparam); if (mPrefs.getStringAsInt("various_skip", 0) > 0) Various.AppsDefaultSortHook(lpparam); if (mPrefs.getBoolean("various_skip_interceptperm")) Various.InterceptPermHook(lpparam); + if (mPrefs.getBoolean("various_show_battery_temperature")) Various.ShowTempInBatteryHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_privacy")) System.HideIconsPrivacyHook(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 5a4adf58..e64c62f1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -11,6 +11,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -26,6 +27,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.Message; import android.os.UserHandle; import android.preference.Preference; import android.preference.PreferenceActivity; @@ -49,6 +51,7 @@ import android.widget.TextView; import android.widget.Toast; +import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; @@ -410,9 +413,9 @@ public static void InterceptPermHook(LoadPackageParam lpparam) { Class InterceptBaseFragmentClass = XposedHelpers.findClass("com.miui.permcenter.privacymanager.InterceptBaseFragment", lpparam.classLoader); Class[] innerClasses = InterceptBaseFragmentClass.getDeclaredClasses(); Class HandlerClass = null; - for (int i = 0; i < innerClasses.length; i++) { - if (android.os.Handler.class.isAssignableFrom(innerClasses[i])) { - HandlerClass = innerClasses[i]; + for (Class innerClass : innerClasses) { + if (Handler.class.isAssignableFrom(innerClass)) { + HandlerClass = innerClass; break; } } @@ -436,6 +439,59 @@ protected void before(final MethodHookParam param) throws Throwable { } } } + public static void ShowTempInBatteryHook(LoadPackageParam lpparam) { + Class InterceptBaseFragmentClass = XposedHelpers.findClass("com.miui.powercenter.BatteryFragment", lpparam.classLoader); + Class[] innerClasses = InterceptBaseFragmentClass.getDeclaredClasses(); + Class HandlerClass = null; + for (Class innerClass : innerClasses) { + if (Handler.class.isAssignableFrom(innerClass)) { + HandlerClass = innerClass; + break; + } + } + if (HandlerClass != null) { + Field[] fields = HandlerClass.getDeclaredFields(); + String fieldName = null; + for (Field field: fields) { + if (WeakReference.class.isAssignableFrom(field.getType())) { + fieldName = field.getName(); + break; + } + } + if (fieldName == null) { + return; + } + String finalFieldName = fieldName; + XposedHelpers.findAndHookMethod(HandlerClass, "handleMessage", Message.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Message msg = (Message) param.args[0]; + int i = msg.what; + if (i == 1) { + Object wk = XposedHelpers.getObjectField(param.thisObject, finalFieldName); + Object frag = XposedHelpers.callMethod(wk, "get"); + Activity batteryView = (Activity) XposedHelpers.callMethod(frag, "getActivity"); + int temp = batteryView.registerReceiver(null, new IntentFilter("android.intent.action.BATTERY_CHANGED")).getIntExtra("temperature", 0) / 10; + int symbolResId = batteryView.getResources().getIdentifier("temp_symbol", "id", lpparam.packageName); + int stateResId = batteryView.getResources().getIdentifier("current_temperature_state", "id", lpparam.packageName); + TextView stateTv = batteryView.findViewById(stateResId); + if (symbolResId > 0) { + stateTv.setVisibility(View.GONE); + TextView symbolTv = batteryView.findViewById(symbolResId); + symbolTv.setVisibility(View.VISIBLE); + int digitResId = batteryView.getResources().getIdentifier("current_temperature_value", "id", lpparam.packageName); + TextView digitTv = batteryView.findViewById(digitResId); + digitTv.setText(temp + ""); + digitTv.setVisibility(View.VISIBLE); + } + else { + stateTv.setText(temp + "℃"); + } + } + } + }); + } + } public static void AlarmCompatHook() { Helpers.findAndHookMethod(Settings.System.class, "getStringForUser", ContentResolver.class, String.class, int.class, new MethodHook() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c5186c90..e52e0788 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1085,6 +1085,7 @@ 去除启动动画 app启动、关闭时不缩放图标 跳过开启特殊权限的倒计时 + 电池页面显示温度值 点击左侧图标时切换手电筒 圆角矩形磁贴 禁用蓝牙临时关闭态 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index accc8ce5..52de5e36 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1134,6 +1134,7 @@ Clock Allow untrusted touch Skip permission intercept timer + Show temperature in battery Tap left shortcut to toggle flashlight Rounded rectangle tile Disable disconnect bluetooth until tomorrow diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index 9ed5daf9..96a5bbf7 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -1,134 +1,139 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 97b2384457da88f8312a98438f296a04e5f235cb Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 31 Dec 2022 23:43:09 +0800 Subject: [PATCH 215/627] disable system integrity verification and app sign verification --- .../mikanoshi/customiuizer/MainModule.java | 2 +- .../mikanoshi/customiuizer/mods/System.java | 18 +++++++++++++++--- .../mikanoshi/customiuizer/subs/System.java | 4 ++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 6 ++++++ 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index d7056e03..5f98f0da 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -69,7 +69,6 @@ public void initZygote(StartupParam startParam) { if (mPrefs.getBoolean("system_lockscreenshortcuts") || mPrefs.getInt("controls_powerdt_action", 1) > 1) System.LockScreenSecureLaunchHook(); if (mPrefs.getBoolean("system_notifmediaseekbar")) System.MediaNotificationSeekBarHook(); if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationBlockHook(); - if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyHook(); if (mPrefs.getBoolean("system_nooverscroll")) System.NoOverscrollHook(); if (mPrefs.getBoolean("system_cleanshare")) System.CleanShareMenuHook(); if (mPrefs.getBoolean("system_cleanopenwith")) System.CleanOpenWithMenuHook(); @@ -156,6 +155,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_hideproxywarn")) System.HideProximityWarningHook(lpparam); if (mPrefs.getBoolean("system_firstpress")) System.FirstVolumePressHook(lpparam); if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyServiceHook(lpparam); + if (mPrefs.getBoolean("system_apksign") || mPrefs.getBoolean("system_disableintegrity")) System.DisableSystemIntegrityHook(lpparam); if (mPrefs.getBoolean("system_vibration_amp")) System.MuffledVibrationHook(lpparam); if (mPrefs.getBoolean("system_clearalltasks")) System.ClearAllTasksHook(lpparam); if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsServiceHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 2e6e3c24..0c14e214 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5571,18 +5571,30 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void NoSignatureVerifyHook() { - Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", null, "checkCapability", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", null, "checkCapabilityRecover", XC_MethodReplacement.returnConstant(true)); + public static void DisableSystemIntegrityHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("android.util.apk.ApkSignatureVerifier", lpparam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class, XC_MethodReplacement.returnConstant(1)); } public static void NoSignatureVerifyServiceHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapability", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapabilityRecover", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkSysAppCrack", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(0)); Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "matchSignaturesCompat", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "matchSignaturesRecover", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("miui.util.CertificateUtils", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(true)); + if (Helpers.isTPlus()) { + Helpers.hookAllMethods("android.content.pm.SigningDetails", lpparam.classLoader, "checkCapability", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllConstructors("android.util.jar.StrictJarVerifier", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "signatureSchemeRollbackProtectionsEnforced", false); + } + }); + Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verifyMessageDigest", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verify", XC_MethodReplacement.returnConstant(true)); + } } @SuppressWarnings("ResultOfMethodCallIgnored") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index c1ac53af..3fe2e77a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -426,6 +426,10 @@ public boolean onPreferenceClick(Preference preference) { } }); + if (Helpers.isTPlus()) { + findPreference("pref_key_system_disableintegrity").setVisible(true); + } + Helpers.prefs.edit().putInt("pref_key_system_animationscale_window", Math.round(Helpers.getAnimationScale(0) * 10)).apply(); ((SeekBarPreference)findPreference("pref_key_system_animationscale_window")).setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e52e0788..6e47b841 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -331,6 +331,7 @@ 允许降级 可以在新版本应用上安装旧版本应用 禁用签名认证 + 禁用系统完整性检查 APK签名与已安装应用不同时允许对其进行更新 文本放大镜 移动光标或进行选择时显示文本放大镜 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 52de5e36..804bed46 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -348,6 +348,7 @@ Allow downgrade Make installing older app version on top of a newer one possible Disable signature verification + Disable system integrity verification Allow app updating even when APK signature differs from installed one Text magnifier Display magnified text when moving an input cursor or making a selection(Add InputMethod apps to LSPosed scope first) diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index a5564e27..b2069117 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1371,6 +1371,12 @@ android:summary="@string/system_apksign_summ" android:defaultValue="false" /> + + Date: Sat, 31 Dec 2022 23:49:18 +0800 Subject: [PATCH 216/627] set minimum rows in cc to 3 --- app/src/main/java/name/mikanoshi/customiuizer/MainModule.java | 2 +- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++-- app/src/main/res/xml/prefs_system.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 5f98f0da..9e9825ec 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -361,7 +361,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_statusbar_dualrows")) { System.DualRowStatusbarHook(lpparam); } - if (mPrefs.getInt("system_ccgridcolumns", 4) > 4 || mPrefs.getInt("system_ccgridrows", 4) > 4) System.SystemCCGridHook(lpparam); + if (mPrefs.getInt("system_ccgridcolumns", 4) > 4 || mPrefs.getInt("system_ccgridrows", 4) != 4) System.SystemCCGridHook(lpparam); if (mPrefs.getBoolean("system_cc_tile_roundedrect")) { System.CCTileCornerHook(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 0c14e214..2ea96d5b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8502,7 +8502,7 @@ public static void SystemCCGridHook(LoadPackageParam lpparam) { if (cols > 4) { MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_columns", cols); } - if (rows > 2) { + if (rows != 4) { MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_min_rows", rows); } @@ -8564,7 +8564,7 @@ protected void after(MethodHookParam param) throws Throwable { }); } } - if (rows > 2) { + if (rows != 4) { Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.QSPager", pluginLoader, "distributeTiles", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index b2069117..18d166a3 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -991,7 +991,7 @@ android:title="@string/system_qsgridrows_title" android:defaultValue="4" miuizer:offtext="@string/array_default" - miuizer:minValue="4" + miuizer:minValue="3" miuizer:maxValue="6" miuizer:stepValue="1" miuizer:format="%d" /> From 1ee99aff5a45484a0b9aa52e6c0912c8e4d0eb6c Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 1 Jan 2023 00:26:43 +0800 Subject: [PATCH 217/627] feat: battery current value is always positive --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 5 ++++- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 7 +++++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 2ea96d5b..fa2c0843 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5163,7 +5163,10 @@ public void run() { } if (props != null) { int tempVal = Integer.parseInt(props.getProperty("POWER_SUPPLY_TEMP")); - int currVal = Math.abs(Math.round(Integer.parseInt(props.getProperty("POWER_SUPPLY_CURRENT_NOW")) / 1000)); + int currVal = -1 * Math.round(Integer.parseInt(props.getProperty("POWER_SUPPLY_CURRENT_NOW")) / 1000); + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_positive")) { + currVal = Math.abs(currVal); + } int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); if (opt == 1) { batteryInfo = tempVal / 10f + "℃" + "\n" + currVal + "mA"; diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6e47b841..9ba655ca 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1067,6 +1067,7 @@ 仅温度 仅电流 右侧显示 + 电流总显示正值 双排信号栏 双排状态栏 如有必要请适当增加状态栏高度 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 804bed46..fae1eaaf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1116,6 +1116,7 @@ Display battery temp and current Display info Display on the right + Current value is always positive Show when charging only Dual SIM signal bars in dual rows Dual rows in status bar diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 18d166a3..606111af 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -449,6 +449,13 @@ miuizer:child="true" android:defaultValue="false" /> + + Date: Sun, 1 Jan 2023 01:10:18 +0800 Subject: [PATCH 218/627] fix: open cc action --- .../mikanoshi/customiuizer/mods/GlobalActions.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 815be465..07459aa2 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -256,22 +256,22 @@ public void run() { if (action.equals(ACTION_PREFIX + "ExpandSettings")) try { boolean forceExpand = intent.getBooleanExtra("forceExpand", false); - Object controller = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", context.getClassLoader()), "get", findClassIfExists("com.android.systemui.miui.statusbar.policy.ControlPanelController", context.getClassLoader())); - boolean isUseControlCenter = (boolean)XposedHelpers.callMethod(controller, "isUseControlCenter"); + Object mControlCenterController = XposedHelpers.getObjectField(mStatusBar, "mControlCenterController"); + boolean isUseControlCenter = (boolean)XposedHelpers.callMethod(mControlCenterController, "isUseControlCenter"); if (isUseControlCenter) { - if (forceExpand || (boolean)XposedHelpers.callMethod(controller, "isQSFullyCollapsed")) - XposedHelpers.callMethod(controller, "openPanel"); + if (forceExpand || (boolean)XposedHelpers.callMethod(mControlCenterController, "isCollapsed")) + XposedHelpers.callMethod(mControlCenterController, "openPanel"); else - XposedHelpers.callMethod(controller, "collapsePanel", true); + XposedHelpers.callMethod(mControlCenterController, "collapseControlCenter", true); return; } - Object mNotificationPanel = XposedHelpers.getObjectField(mStatusBar, "mNotificationPanel"); + Object mNotificationPanel = XposedHelpers.getObjectField(mStatusBar, "mNotificationPanelViewController"); boolean mPanelExpanded = (boolean)XposedHelpers.getObjectField(mNotificationPanel, "mPanelExpanded"); boolean mQsExpanded = (boolean)XposedHelpers.getObjectField(mNotificationPanel, "mQsExpanded"); if (!forceExpand && mPanelExpanded) { if (mQsExpanded) - XposedHelpers.callMethod(mStatusBar, "animateCollapsePanels"); + XposedHelpers.callMethod(mStatusBar, "animateCollapsePanels", 0, false); else XposedHelpers.callMethod(mNotificationPanel, "setQsExpanded", true); } else { From c577d210b9a15501f1283997fc5ef9ed60738ce1 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 1 Jan 2023 14:40:15 +0800 Subject: [PATCH 219/627] fix: hide mobile network type --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index fa2c0843..10da6c84 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1436,7 +1436,7 @@ public static void HideNetworkTypeHook(LoadPackageParam lpparam) { @Override protected void after(final MethodHookParam param) throws Throwable { int opt = Integer.parseInt(MainModule.mPrefs.getString("system_mobiletypeicon", "1")); - TextView mMobileType = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileType"); + View mMobileType = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileType"); TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); boolean isMobileConnected = false; if (opt == 2) { From 1da7f284afb2d271b434e67eaeea426fda27b713 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 1 Jan 2023 14:59:18 +0800 Subject: [PATCH 220/627] feat: hide networkspeed unit --- .../java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../java/name/mikanoshi/customiuizer/mods/System.java | 10 ++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/xml/prefs_system.xml | 5 +++++ app/src/main/res/xml/prefs_system_detailednetspeed.xml | 6 ------ 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 9e9825ec..c655786a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -293,6 +293,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_statusbarcontrols")) System.StatusBarGesturesHook(lpparam); if (mPrefs.getBoolean("system_nodrawerbackground")) System.RemoveDrawerBackgroundHook(lpparam); if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); + if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); if (mPrefs.getBoolean("system_taptounlock")) System.TapToUnlockHook(lpparam); if (mPrefs.getBoolean("system_nosos")) System.NoSOSHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 10da6c84..1a808d7f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6348,6 +6348,16 @@ protected void before(MethodHookParam param) throws Throwable { }); } + public static void HideNetworkSpeedUnitHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "formatSpeed", Context.class, long.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + String speedText = (String) param.getResult(); + param.setResult(speedText.replace("B/s", "B").replace("/s", "")); + } + }); + } + public static void ToastTimeHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.notification.NotificationManagerService", lpparam.classLoader, "showNextToastLocked", new MethodHook() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9ba655ca..18d5220b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -93,7 +93,7 @@ 网速分隔符 于水滴屏的设备上不显示时间和网速间的竖线 网速更新间隔 - 详细的网速指示器 + 网速双排显示 分别显示传入和传出的网络速度 字体大小 指示器图标 diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 606111af..f78bde81 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -653,6 +653,11 @@ miuizer:stepValue="1" miuizer:format="@string/format_d_s" /> + + - - Date: Sun, 1 Jan 2023 15:37:19 +0800 Subject: [PATCH 221/627] fix(miui14): album art as lockscreen --- .../mikanoshi/customiuizer/mods/System.java | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 1a808d7f..12b46baf 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1870,32 +1870,19 @@ private static Bitmap processAlbumArt(Context context, Bitmap bitmap) { } public static void LockScreenAlbumArtHook(LoadPackageParam lpparam) { - Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader); + Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.miui.systemui.util.MiuiThemeUtils", lpparam.classLoader); Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); if (isDefaultLockScreenTheme) { Object mBlurRatioChangedListener = XposedHelpers.getObjectField(param.thisObject, "mBlurRatioChangedListener"); Object notificationShadeDepthController = XposedHelpers.getObjectField(param.thisObject, "notificationShadeDepthController"); XposedHelpers.callMethod(notificationShadeDepthController, "removeListener", mBlurRatioChangedListener); View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); view.setAlpha(1.0f); - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackground", new MethodHook() { - private boolean isListened = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); - if (!isDefaultLockScreenTheme) { - return ; - } - View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); - if (!isListened) { - isListened = true; + IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); view.getContext().registerReceiver(new BroadcastReceiver() { @@ -1904,11 +1891,26 @@ public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action == null) return; if (action.equals(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART")) { - XposedHelpers.callMethod(param.thisObject, "updateThemeBackground"); + try { + XposedHelpers.callMethod(param.thisObject, "updateThemeBackground"); + } + catch (Throwable e) { + XposedHelpers.callMethod(param.thisObject, "updateThemeBackgroundVisibility"); + } } } }, intentFilter); } + } + }); + MethodHook updateLockscreenHook = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); + if (!isDefaultLockScreenTheme) { + return ; + } + View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); boolean isOnShade = (boolean) XposedHelpers.callMethod(param.thisObject, "isOnShade"); if (isOnShade) { view.setVisibility(View.GONE); @@ -1920,14 +1922,19 @@ public void onReceive(Context context, Intent intent) { } view.setVisibility(mAlbumArt != null ? View.VISIBLE : View.GONE); } + param.setResult(null); } - }); + }; + Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackground", updateLockscreenHook); + if (Helpers.isTPlus()) { + Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackgroundVisibility", updateLockscreenHook); + } Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMediaManager", lpparam.classLoader, "updateMediaMetaData", boolean.class, boolean.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); if (!isDefaultLockScreenTheme) { XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); @@ -1969,7 +1976,7 @@ protected void after(MethodHookParam param) throws Throwable { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); if (isDefaultLockScreenTheme) { From b10cc07cd3aa65b4711f723b2381263e54cd49d0 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 1 Jan 2023 19:46:05 +0800 Subject: [PATCH 222/627] feat: bold style mobile type --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 3 +++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 3 ++- app/src/main/res/xml/prefs_system.xml | 7 +++++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 12b46baf..d29404d6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8196,6 +8196,9 @@ protected void after(final MethodHookParam param) throws Throwable { mMobileTypeSingle.setLayoutParams(mlp); int fontSize = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_fontsize", 27); mMobileTypeSingle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); + if (MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single_bold")) { + mMobileTypeSingle.setTypeface(Typeface.DEFAULT_BOLD); + } } }); } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 18d5220b..dc9f173a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1076,6 +1076,7 @@ 移动网络类型单独显示 左侧间距 上下偏移量 + 加粗 状态栏水平边距 状态栏上边距 上边距大小 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fae1eaaf..b1538400 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1123,9 +1123,10 @@ Need increase statusbar height on some devices Icon style Right margin - Put mobile network type at the right of signal icon + Put mobile network type at right of signal icon Left margin Vertical offset + Bold style Statusbar horizontal padding Statusbar top padding Top padding diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index f78bde81..20450c1c 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -341,6 +341,13 @@ miuizer:displayDividerValue="2" miuizer:format="%s dip" /> + + Date: Sun, 1 Jan 2023 22:12:27 +0800 Subject: [PATCH 223/627] fix: miuivolumedialog close timer --- .../java/name/mikanoshi/customiuizer/mods/System.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d29404d6..93fea10c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7123,7 +7123,13 @@ protected void before(MethodHookParam param) throws Throwable { param.setResult(16000); return; } - boolean mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mSafetyWarning"); + boolean mSafetyWarning; + try { + mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mIsSafetyShowing"); + } + catch (Throwable e) { + mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mSafetyWarning"); + } if (mSafetyWarning) { int opt = MainModule.mPrefs.getInt("system_volumedialogdelay_expanded", 0); param.setResult(opt > 0 ? opt : 5000); From 1455a66051a4b385192fbd0fe0b5346544ead502 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 1 Jan 2023 22:12:43 +0800 Subject: [PATCH 224/627] feat: font size of network speed --- .../name/mikanoshi/customiuizer/MainModule.java | 1 + .../name/mikanoshi/customiuizer/mods/System.java | 14 ++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 3 ++- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 11 +++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c655786a..c90bcd4a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -294,6 +294,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_nodrawerbackground")) System.RemoveDrawerBackgroundHook(lpparam); if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); + if (mPrefs.getInt("system_netspeed_fontsize", 17) > 17 && !mPrefs.getBoolean("system_detailednetspeed")) System.NetSpeedFontHook(lpparam); if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); if (mPrefs.getBoolean("system_taptounlock")) System.TapToUnlockHook(lpparam); if (mPrefs.getBoolean("system_nosos")) System.NoSOSHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 93fea10c..58385341 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6365,6 +6365,20 @@ protected void after(MethodHookParam param) throws Throwable { }); } + public static void NetSpeedFontHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + TextView meter = (TextView)param.thisObject; + if (meter == null) return; + if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { + int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 17); + meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); + } + } + }); + } + public static void ToastTimeHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.notification.NotificationManagerService", lpparam.classLoader, "showNextToastLocked", new MethodHook() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index dc9f173a..e730e5b8 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -104,7 +104,8 @@ 网速值低于该水平时将被认为慢,并会显示不同的指示器图标 不活动时降低可见性 速值均为0时指示器透明 - 隐藏 B/s 单位 + 网速隐藏 B/s 单位 + 网速字体大小 手势控制 滑动双击时执行所选动作 调整灵敏度 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b1538400..e57ef936 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -115,6 +115,7 @@ Reduce visibility when inactive Make indicator semitransparent when both speeds are zero Hide Byte per second suffix(B/s) + Network speed\'s font size Gesture controls Perform selected actions on slide and double tap Adjustment sensitivity diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 20450c1c..8ea70893 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -660,6 +660,17 @@ miuizer:stepValue="1" miuizer:format="@string/format_d_s" /> + + Date: Sun, 1 Jan 2023 23:33:48 +0800 Subject: [PATCH 225/627] fix: volume dialog blur --- .../mikanoshi/customiuizer/MainModule.java | 1 - .../mikanoshi/customiuizer/mods/System.java | 47 ++++++++----------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c90bcd4a..6924176c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -201,7 +201,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); - if (mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || mPrefs.getInt("system_volumeblur_expanded", 0) > 0) System.BlurVolumeDialogBackgroundRes(); if (mPrefs.getBoolean("system_notifrowmenu")) System.NotificationRowMenuRes(); if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 58385341..f8db5296 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5719,45 +5719,43 @@ protected void after(MethodHookParam param) throws Throwable { } } - private static Dialog mDialog = null; private static float blurCollapsed = 0.0f; private static float blurExpanded = 0.0f; - @SuppressWarnings("deprecation") - private static void updateBlurRatio(Object thisObject) { - if (mDialog == null || mDialog.getWindow() == null) return; - View rootView = mDialog.getWindow().getDecorView(); - if (rootView.isAttachedToWindow() && rootView.getLayoutParams() instanceof WindowManager.LayoutParams) { - WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams)rootView.getLayoutParams(); - layoutParams.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND; - boolean isExpanded = (boolean)XposedHelpers.callMethod(thisObject, "isExpanded"); - XposedHelpers.setFloatField(layoutParams, "blurRatio", isExpanded ? blurExpanded : blurCollapsed); - mDialog.getWindow().getWindowManager().updateViewLayout(rootView, layoutParams); - } - } - public static void BlurVolumeDialogBackgroundHook(ClassLoader classLoader) { - Helpers.hookAllMethods("com.android.systemui.miui.volume.MiuiVolumeDialogView", classLoader, "onAttachedToWindow", new MethodHook() { + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_collapsed", 0f); + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_expanded", 0f); + + Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "updateDialogWindowH", boolean.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - updateBlurRatio(param.thisObject); + boolean mExpanded = XposedHelpers.getBooleanField(param.thisObject, "mExpanded"); + float blurRatio = blurCollapsed; + boolean isVisible = (boolean) param.args[0]; + if (mExpanded && !isVisible) { + blurRatio = blurExpanded; + } + if (!mExpanded) { + Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); + mWindow.clearFlags(8); + } + XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurRatio, 0); } }); - - Helpers.hookAllMethods("com.android.systemui.miui.volume.MiuiVolumeDialogView", classLoader, "onExpandStateUpdated", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "showH", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - updateBlurRatio(param.thisObject); + Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); + mWindow.clearFlags(8); + XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurCollapsed, 0); } }); - Helpers.hookAllMethods("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "initDialog", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { + protected void before(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); Handler mHandler = new Handler(mContext.getMainLooper()); - mDialog = (Dialog)XposedHelpers.getObjectField(param.thisObject, "mDialog"); blurCollapsed = MainModule.mPrefs.getInt("system_volumeblur_collapsed", 0) / 100f; blurExpanded = MainModule.mPrefs.getInt("system_volumeblur_expanded", 0) / 100f; new Helpers.SharedPrefObserver(mContext, mHandler) { @@ -5776,11 +5774,6 @@ public void onChange(Uri uri) { }); } - public static void BlurVolumeDialogBackgroundRes() { - MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_collapsed", 0.0f); - MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_expanded", 0.0f); - } - public static void RemoveSecureHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.wm.WindowState", lpparam.classLoader, "isSecureLocked", XC_MethodReplacement.returnConstant(false)); } From 2d4ce5dc743afcb453803e9d33c190b89a15ed10 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 2 Jan 2023 11:48:15 +0800 Subject: [PATCH 226/627] fix(miui14): hide overlay when screenshot --- app/build.gradle | 4 ++-- .../name/mikanoshi/customiuizer/mods/System.java | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1ee367b9..4c644568 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 - versionCode 48 - versionName "22.12.29" + versionCode 49 + versionName "23.01.01" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index f8db5296..433f6afa 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6711,14 +6711,14 @@ public static void NoLowBatteryWarningHook(LoadPackageParam lpparam) { } public static void TempHideOverlaySystemUIHook(LoadPackageParam lpparam) { - final boolean[] isActListened = {false}; Helpers.hookAllMethods("com.android.wm.shell.pip.PipTaskOrganizer", lpparam.classLoader, "onTaskAppeared", new MethodHook() { + private boolean isActListened = false; @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (!isActListened[0]) { - isActListened[0] = true; + if (!isActListened) { + isActListened = true; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("miui.intent.TAKE_SCREENSHOT"); mContext.registerReceiver(new BroadcastReceiver() { @@ -6728,7 +6728,13 @@ public void onReceive(Context context, Intent intent) { if (action == null) return; if (action.equals("miui.intent.TAKE_SCREENSHOT")) { boolean state = intent.getBooleanExtra("IsFinished", true); - Object mState = XposedHelpers.getObjectField(param.thisObject, "mState"); + Object mState; + if (Helpers.isTPlus()) { + mState = XposedHelpers.getObjectField(param.thisObject, "mPipTransitionState"); + } + else { + mState = XposedHelpers.getObjectField(param.thisObject, "mState"); + } boolean isPip = (boolean) XposedHelpers.callMethod(mState, "isInPip"); if (isPip) { Object mSurfaceControlTransactionFactory = XposedHelpers.getObjectField(param.thisObject, "mSurfaceControlTransactionFactory"); From 56e561ba3e4d5d432d1e230c925e486e9f9edca5 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 2 Jan 2023 12:40:56 +0800 Subject: [PATCH 227/627] reorganize network speed mods --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 24 +++--- app/src/main/res/values-pl-rPL/strings.xml | 2 - app/src/main/res/values-zh-rCN/strings.xml | 3 +- app/src/main/res/values-zh-rTW/strings.xml | 2 - app/src/main/res/values/strings.xml | 3 +- app/src/main/res/xml/prefs_system.xml | 34 +------- .../res/xml/prefs_system_detailednetspeed.xml | 79 ++++++++++++------- 8 files changed, 67 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 6924176c..b6a715ab 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -293,6 +293,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_nodrawerbackground")) System.RemoveDrawerBackgroundHook(lpparam); if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); + if (mPrefs.getBoolean("system_detailednetspeed_low") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideLowNetworkSpeedHook(lpparam); if (mPrefs.getInt("system_netspeed_fontsize", 17) > 17 && !mPrefs.getBoolean("system_detailednetspeed")) System.NetSpeedFontHook(lpparam); if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); if (mPrefs.getBoolean("system_taptounlock")) System.TapToUnlockHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 433f6afa..6d237afb 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1735,17 +1735,6 @@ protected void after(final MethodHookParam param) throws Throwable { } } }); - boolean reduceVis = MainModule.mPrefs.getBoolean("system_detailednetspeed_zero"); - if (reduceVis) { - Helpers.hookAllMethods("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, "applyNetworkSpeedState", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - TextView meter = (TextView) param.thisObject; - boolean isZero = rxSpeed == 0 && txSpeed == 0; - meter.setAlpha(isZero ? 0.3f : 1.0f); - } - }); - } Class nscCls = XposedHelpers.findClassIfExists("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader); if (nscCls == null) { @@ -6358,6 +6347,19 @@ protected void after(MethodHookParam param) throws Throwable { }); } + public static void HideLowNetworkSpeedHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "formatSpeed", Context.class, long.class, new MethodHook(100) { + @Override + protected void before(MethodHookParam param) throws Throwable { + int lowLevel = MainModule.mPrefs.getInt("system_detailednetspeed_lowlevel", 1) * 1024; + long speedVal = (long) param.args[1]; + if (speedVal < lowLevel) { + param.setResult(""); + } + } + }); + } + public static void NetSpeedFontHook(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { @Override diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index b8c8266b..417ce3e4 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -106,8 +106,6 @@ Nie pokazuj wskaźnika, jeśli prędkość jest niska Niski poziom prędkości Wartości prędkości poniżej tego poziomu będą uważane za niskie i będą oznaczone inną ikoną wskazania - Zmniejsz widoczność, gdy nie jest aktywny - Ustaw wskaźnik na półprzezroczysty, gdy obie prędkości są równe zeru Ukryj przyrostek bajtów na sekundę (B/s) Sterowanie gestami Wykonaj wybrane czynności, przesuwając i dwukrotnie stukając diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e730e5b8..a29ece36 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -94,6 +94,7 @@ 于水滴屏的设备上不显示时间和网速间的竖线 网速更新间隔 网速双排显示 + 网速相关设置 分别显示传入和传出的网络速度 字体大小 指示器图标 @@ -102,8 +103,6 @@ 网速低时不再显示指示器 慢速水平 网速值低于该水平时将被认为慢,并会显示不同的指示器图标 - 不活动时降低可见性 - 速值均为0时指示器透明 网速隐藏 B/s 单位 网速字体大小 手势控制 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e2101271..6ed451a0 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -609,8 +609,6 @@ 慢速水平 分別顯示傳入和傳出的網路速度 詳細的網速指示器 - 速值均為0時指示器透明 - 不活動時降低可見性 自動滅屏前保持暗屏的時間(螢幕關閉超時總數的百分比) 暗屏時長 同時允許禁用系統通知 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e57ef936..a04a0be6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -103,7 +103,8 @@ Network speed separator Do not show vertical line between time and network speed on devices with waterdrop notches Network speed update interval - Detailed network speed indicator + Display in dual rows + Network speed mods Show incoming and outgoing network speeds separately Font size Indicator icons diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 8ea70893..c5e3366e 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -645,41 +645,9 @@ android:title="@string/system_hidemoreicon_title" android:defaultValue="false" /> - - - - - - - - + android:title="@string/system_netspeed_cat_title" /> - + - + - + + android:defaultValue="false" /> + android:key="pref_key_system_detailednetspeed" + android:title="@string/system_detailednetspeed_title" + android:summary="@string/system_detailednetspeed_summ" + android:defaultValue="false" /> - + + + \ No newline at end of file From 6c70e9c3ca554855f59719f3d3cf4d4e56238c2a Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 2 Jan 2023 15:30:52 +0800 Subject: [PATCH 228/627] feat: enable volume bar blur support for mtk devices --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../main/java/name/mikanoshi/customiuizer/mods/System.java | 7 +++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 5 +++++ 5 files changed, 15 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index b6a715ab..0b5d52b0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -253,6 +253,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.NotificationVolumeDialogRes(); } if (mPrefs.getBoolean("system_nosilentvibrate") + || mPrefs.getBoolean("system_volumebar_blur_mtk") || (mPrefs.getBoolean("system_separatevolume") && mPrefs.getBoolean("system_separatevolume_slider")) || (mPrefs.getInt("system_volumedialogdelay_collapsed", 0) > 0 || mPrefs.getInt("system_volumedialogdelay_expanded", 0) > 0) || (mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || mPrefs.getInt("system_volumeblur_expanded", 0) > 0) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 6d237afb..f3e512d2 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -943,6 +943,9 @@ protected void before(MethodHookParam param) throws Throwable { if (MainModule.mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || MainModule.mPrefs.getInt("system_volumeblur_expanded", 0) > 0) { BlurVolumeDialogBackgroundHook(pluginLoader); } + if (MainModule.mPrefs.getBoolean("system_volumebar_blur_mtk")) { + BlurMTKVolumeBarHook(pluginLoader); + } } } }); @@ -5763,6 +5766,10 @@ public void onChange(Uri uri) { }); } + public static void BlurMTKVolumeBarHook(ClassLoader classLoader) { + Helpers.findAndHookMethod("com.android.systemui.miui.volume.Util", classLoader, "isSupportBlurS", XC_MethodReplacement.returnConstant(true)); + } + public static void RemoveSecureHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.wm.WindowState", lpparam.classLoader, "isSecureLocked", XC_MethodReplacement.returnConstant(false)); } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a29ece36..059f6381 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -209,6 +209,7 @@ 在折叠音量对话框显示勿扰模式开关按钮 扩展计时器 添加更多间隔到静音和勿扰模式的定时器 + 针对MTK设备开启音量条模糊 音量对话框自动隐藏延迟 已折叠 已展开 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a04a0be6..e7a63a8b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -225,6 +225,7 @@ Make button in collapsed volume dialog toggle Do Not Disturb mode instead of Silent mode Extended timers Add more intervals to timers for Silent and Do Not Disturb modes + Enable volume bar blur support for MTK devices Volume dialog autohide delay Collapsed Expanded diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index c5e3366e..e32f6c6e 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -161,6 +161,11 @@ android:summary="@string/system_volumetimer_summ" android:defaultValue="false" /> + + Date: Mon, 2 Jan 2023 16:13:56 +0800 Subject: [PATCH 229/627] feat: unlock security center features --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/Various.java | 21 ++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/prefs_various.xml | 28 ++++++++++++------- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 0b5d52b0..4bdd2467 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -394,6 +394,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getStringAsInt("various_skip", 0) > 0) Various.AppsDefaultSortHook(lpparam); if (mPrefs.getBoolean("various_skip_interceptperm")) Various.InterceptPermHook(lpparam); if (mPrefs.getBoolean("various_show_battery_temperature")) Various.ShowTempInBatteryHook(lpparam); + if (mPrefs.getBoolean("various_enable_sc_ai_clipboard_location")) Various.UnlockClipboardAndLocationHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_privacy")) System.HideIconsPrivacyHook(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index e64c62f1..2e42d6c5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -64,6 +64,7 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.TimeZone; import de.robv.android.xposed.XC_MethodHook; @@ -492,6 +493,26 @@ protected void after(MethodHookParam param) throws Throwable { }); } } + public static void UnlockClipboardAndLocationHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.miui.permcenter.settings.PrivacyLabActivity", lpparam.classLoader, "onCreateFragment", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Class utilCls = findClassIfExists("com.miui.permcenter.utils.h", lpparam.classLoader); + if (utilCls != null) { + Object fm = Helpers.getStaticObjectFieldSilently(utilCls, "b"); + if (fm != null) { + try { + Map featMap = (Map) fm; + featMap.put("mi_lab_ai_clipboard_enable", 0); + featMap.put("mi_lab_blur_location_enable", 0); + } + catch (Throwable ignore) { + } + } + } + } + }); + } public static void AlarmCompatHook() { Helpers.findAndHookMethod(Settings.System.class, "getStringForUser", ContentResolver.class, String.class, int.class, new MethodHook() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 059f6381..c5afe617 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -678,6 +678,7 @@ 格式:延迟,振动,延迟,振动,… 应用状态控制 允许从应用信息页面禁用任何应用 + 解锁手机管家特性 显示附加应用详情 添加新字段到应用信息页面:\n- 版本代码\n- apk完整路径\n- 数据路径\n- 用户标识符\n- 目标SDK版本\n- 连结到Play商店页面\n- 启动应用 已安装应用的初始排列顺序 @@ -1090,6 +1091,7 @@ app启动、关闭时不缩放图标 跳过开启特殊权限的倒计时 电池页面显示温度值 + 剪切板隐私保护及模糊定位 点击左侧图标时切换手电筒 圆角矩形磁贴 禁用蓝牙临时关闭态 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e7a63a8b..dae6c405 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -732,6 +732,7 @@ Allows to configure battery saver and access to Wi-Fi for system apps App state control Allows to disable almost any app from its info page + Unlock security center features Show additional app details Add new fields to app info page:\n- version code\n- full path to apk\n- data path\n- user ID\n- target SDK version\n- link to Play Store page\n- launch an app Installed apps initial sort order @@ -1141,6 +1142,7 @@ Allow untrusted touch Skip permission intercept timer Show temperature in battery + Enable AI clipboard and blur location Tap left shortcut to toggle flashlight Rounded rectangle tile Disable disconnect bluetooth until tomorrow diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index 96a5bbf7..5337cb21 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -31,16 +31,6 @@ android:title="@string/various_allow_untrusted_touch_title" android:defaultValue="false" /> - - - - + + + + + + + + From 8f4d29a52bd4e5540160fa2d3ac7599ad137927d Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 2 Jan 2023 21:05:29 +0800 Subject: [PATCH 230/627] fix(miui14): extra buttons in navigation bar --- .../name/mikanoshi/customiuizer/mods/Controls.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java index c8322dce..ee8486f6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java @@ -334,7 +334,6 @@ private static boolean handleNavBarAction(Context context, String key) { } private static void addCustomNavBarKeys(boolean isVertical, Context mContext, FrameLayout navButtons, Class kbrCls) { - String pkgName = "com.android.systemui"; float density = mContext.getResources().getDisplayMetrics().density; int two = Math.round(2 * density); int margin = Math.round(MainModule.mPrefs.getInt("controls_navbarmargin", 0) * density); @@ -453,7 +452,7 @@ public boolean onLongClick(View v) { boolean hasLeftAction = MainModule.mPrefs.getInt("controls_navbarleft_action", 1) > 1 || MainModule.mPrefs.getInt("controls_navbarleftlong_action", 1) > 1; boolean hasRightAction = MainModule.mPrefs.getInt("controls_navbarright_action", 1) > 1 || MainModule.mPrefs.getInt("controls_navbarrightlong_action", 1) > 1; - float part = 0.55f; +// float part = 0.55f; if (isVertical) { if (hasRightAction) { navButtons.addView(rightbtn, 0); @@ -482,7 +481,8 @@ public boolean onLongClick(View v) { } public static void NavBarButtonsHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBar", lpparam.classLoader, "onViewAttachedToWindow", new MethodHook() { + + Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBar", lpparam.classLoader, Helpers.isTPlus() ? "onViewAttached" : "onViewAttachedToWindow", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); @@ -490,7 +490,7 @@ protected void after(MethodHookParam param) throws Throwable { Helpers.log("NavBarButtonsHook", "Cannot find context"); return; } - FrameLayout mNavigationBarView = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mNavigationBarView"); + FrameLayout mNavigationBarView = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, Helpers.isTPlus() ? "mView" : "mNavigationBarView"); if (mNavigationBarView == null) { Helpers.log("NavBarButtonsHook", "Cannot find navbar layout"); return; @@ -506,11 +506,11 @@ protected void after(MethodHookParam param) throws Throwable { } }); - Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBarInflaterView", lpparam.classLoader, "updateBackground", new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBarTransitions", lpparam.classLoader, "applyDarkIntensity", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - FrameLayout navbar = (FrameLayout)param.thisObject; - boolean isDark = (boolean)param.args[0]; + FrameLayout navbar = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, "mView"); + boolean isDark = (float)param.args[0] > 0.5f; ImageView hleft = navbar.findViewWithTag("custom_left_horiz"); ImageView vleft = navbar.findViewWithTag("custom_left_vert"); ImageView hright = navbar.findViewWithTag("custom_right_horiz"); From 2b1bb40309781aa1797096336406d86efb5008f9 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 2 Jan 2023 21:33:51 +0800 Subject: [PATCH 231/627] fix: volume dialog blur --- .../mikanoshi/customiuizer/MainModule.java | 1 - .../mikanoshi/customiuizer/mods/System.java | 30 +++++++------------ app/src/main/res/values-pl-rPL/strings.xml | 2 -- app/src/main/res/values-ru-rRU/strings.xml | 2 -- app/src/main/res/values-zh-rCN/strings.xml | 2 -- app/src/main/res/values-zh-rTW/strings.xml | 2 -- app/src/main/res/values/strings.xml | 2 -- app/src/main/res/xml/prefs_system.xml | 6 ---- 8 files changed, 10 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 4bdd2467..644d93b8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -301,7 +301,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_nosos")) System.NoSOSHook(lpparam); if (mPrefs.getBoolean("system_usenativerecents")) System.UseNativeRecentsHook(lpparam); if (mPrefs.getBoolean("system_morenotif")) System.MoreNotificationsHook(lpparam); - if (mPrefs.getBoolean("system_dndtoggle")) System.VolumeDialogDNDSwitchHook(lpparam); if (mPrefs.getBoolean("system_charginginfo")) System.ChargingInfoHook(lpparam); if (mPrefs.getBoolean("system_secureqs")) System.SecureQSTilesHook(lpparam); if (mPrefs.getBoolean("system_mutevisiblenotif")) System.MuteVisibleNotificationsHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index f3e512d2..b126ecbb 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5727,19 +5727,23 @@ protected void after(MethodHookParam param) throws Throwable { if (mExpanded && !isVisible) { blurRatio = blurExpanded; } - if (!mExpanded) { + if (!mExpanded && blurCollapsed > 0.001f) { Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); mWindow.clearFlags(8); } - XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurRatio, 0); + if (mExpanded) { + XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurRatio, 0); + } } }); Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "showH", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); - mWindow.clearFlags(8); - XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurCollapsed, 0); + if (blurCollapsed > 0.001f) { + Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); + mWindow.clearFlags(8); + XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurCollapsed, 0); + } } }); Helpers.hookAllMethods("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "initDialog", new MethodHook() { @@ -5870,7 +5874,7 @@ protected void after(MethodHookParam param) throws Throwable { private static final SimpleDateFormat formatter = new SimpleDateFormat("H:m", Locale.ENGLISH); public static void MuffledVibrationHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.VibratorService", lpparam.classLoader, "systemReady", new MethodHook() { + Helpers.findAndHookMethod("com.android.server.vibrator.VibratorManagerService", lpparam.classLoader, "systemReady", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); @@ -7113,20 +7117,6 @@ public final boolean test(Object obj) { }); } - public static void VolumeDialogDNDSwitchHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiRingerModeLayout.RingerButtonHelper", lpparam.classLoader, "updateState", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - boolean mExpanded = XposedHelpers.getBooleanField(param.thisObject, "mExpanded"); - if (mExpanded) return; - View mStandardView = (View)XposedHelpers.getObjectField(param.thisObject, "mStandardView"); - View mDndView = (View)XposedHelpers.getObjectField(param.thisObject, "mDndView"); - if (mStandardView != null) mStandardView.setVisibility(View.GONE); - if (mDndView != null) mDndView.setVisibility(View.VISIBLE); - } - }); - } - public static void NoMediaMuteInDNDHook() { Helpers.hookAllMethods("android.media.AudioServiceInjector", null, "handleZenModeChangedForMusic", new MethodHook() { @Override diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 417ce3e4..9b176046 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -210,8 +210,6 @@ Dodaj suwak powiadomień do rozszerzonego okna dialogowego głośności Brak wyciszenia multimediów Nie ustawiaj głośności multimediów na zero w trybie nie przeszkadzać - Przełącznik trybu DND - Ustaw przycisk w zwiniętym oknie dialogowym głośności, aby przełączać tryb nie przeszkadzać zamiast trybu cichego Wydłużone timery Dodaj więcej interwałów do timerów dla trybu cichego i trybu nie przeszkadzać Opóźnienie automatycznego ukrywania okna dialogowego głośności diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 4f84b119..3b6e25b1 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -831,8 +831,6 @@ Добавляет ползунок уведомлений в открытую панель громкости Не заглушать музыку Предотвращает установку громкости музыки на ноль в режиме Не беспокоить - Переключатель режима Не беспокоить - Кнопка в свёрнутом диалоге громкости переключает режим Не беспокоить вместо режима Без звука Расширенные таймеры Добавляет больше интервалов в таймеры режимов Без звука и Не беспокоить Задержка перед автоскрытием диалога громкости diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c5afe617..c21f0c67 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -205,8 +205,6 @@ 将通知滑块添加到扩展音量对话框 不将媒体静音 在勿扰模式中不将媒体音量设为零 - 勿扰模式开关 - 在折叠音量对话框显示勿扰模式开关按钮 扩展计时器 添加更多间隔到静音和勿扰模式的定时器 针对MTK设备开启音量条模糊 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6ed451a0..736160d1 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -613,8 +613,6 @@ 暗屏時長 同時允許禁用系統通知 禁用任何通知 - 在折疊音量對話框顯示勿擾模式開關按鈕 - 勿擾模式開關 可以在新版本應用上安裝舊版本應用 允許降級 通知抽屜的背景模糊度 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dae6c405..dc802bf0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -221,8 +221,6 @@ Add notification slider to expanded volume dialog No media mute Do not set media volume to zero in Do Not Disturb mode - DND mode toggle - Make button in collapsed volume dialog toggle Do Not Disturb mode instead of Silent mode Extended timers Add more intervals to timers for Silent and Do Not Disturb modes Enable volume bar blur support for MTK devices diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index e32f6c6e..e3a04c10 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -149,12 +149,6 @@ android:summary="@string/system_nomediamute_summ" android:defaultValue="false" /> - - Date: Tue, 3 Jan 2023 13:58:52 +0800 Subject: [PATCH 232/627] feat: network speed vertical offset --- .../mikanoshi/customiuizer/MainModule.java | 10 ++- .../mikanoshi/customiuizer/mods/System.java | 74 ++++++++----------- app/src/main/res/values-pl-rPL/strings.xml | 1 - app/src/main/res/values-ru-rRU/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/arrays.xml | 13 ---- app/src/main/res/values/strings.xml | 1 - app/src/main/res/xml/prefs_system.xml | 2 +- .../res/xml/prefs_system_detailednetspeed.xml | 27 ++++--- 10 files changed, 56 insertions(+), 75 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 644d93b8..b4fa51ff 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -231,7 +231,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_drawer_clockseconds") || mPrefs.getBoolean("system_clockleadingzero") ) System.ClockSecondsHook(lpparam); - if (mPrefs.getBoolean("system_fixmeter")) System.TrafficSpeedSpacingHook(lpparam); if (mPrefs.getBoolean("system_noscreenlock_act")) System.NoScreenLockHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed")) System.DetailedNetSpeedHook(lpparam); if (mPrefs.getBoolean("system_albumartonlock")) System.LockScreenAlbumArtHook(lpparam); @@ -295,7 +294,14 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_low") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideLowNetworkSpeedHook(lpparam); - if (mPrefs.getInt("system_netspeed_fontsize", 17) > 17 && !mPrefs.getBoolean("system_detailednetspeed")) System.NetSpeedFontHook(lpparam); + if ( + mPrefs.getInt("system_netspeed_fontsize", 14) > 14 + || mPrefs.getInt("system_netspeed_verticaloffset", 8) != 8 + || mPrefs.getBoolean("system_fixmeter") + || mPrefs.getBoolean("system_detailednetspeed") + ) { + System.NetSpeedStyleHook(lpparam); + } if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); if (mPrefs.getBoolean("system_taptounlock")) System.TapToUnlockHook(lpparam); if (mPrefs.getBoolean("system_nosos")) System.NoSOSHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index b126ecbb..3f7092c5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1454,20 +1454,6 @@ protected void after(final MethodHookParam param) throws Throwable { Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", hideMobileActivity); } - public static void TrafficSpeedSpacingHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - TextView meter = (TextView)param.thisObject; - if (meter == null) return; - if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { - int margin = Math.round(meter.getResources().getDisplayMetrics().density * 4); - meter.setPaddingRelative(margin, 0, margin, 0); - } - } - }); - } - public static void ChargeAnimationHook(LoadPackageParam lpparam) { Class ccCls; try { @@ -1714,31 +1700,6 @@ protected void before(final MethodHookParam param) throws Throwable { } public static void DetailedNetSpeedHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - TextView meter = (TextView)param.thisObject; - if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { - float density = meter.getResources().getDisplayMetrics().density; - int font = Integer.parseInt(MainModule.mPrefs.getString("system_detailednetspeed_font", "3")); - float size = 8.0f; - float spacing = 0.9f; - int top = 0; - switch (font) { - case 1: size = 9f; spacing = 0.85f; top = Math.round(density);break; - case 2: size = 8.5f; break; - case 4: size = 7.5f; break; - } - meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size); - meter.setSingleLine(false); - meter.setLines(2); - meter.setMaxLines(2); - meter.setLineSpacing(0, spacing); - meter.setPadding(meter.getPaddingLeft(), meter.getPaddingTop() - top, meter.getPaddingRight(), meter.getPaddingBottom()); - } - } - }); - Class nscCls = XposedHelpers.findClassIfExists("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader); if (nscCls == null) { Helpers.log("DetailedNetSpeedHook", "No NetworkSpeed view or controller"); @@ -6371,15 +6332,44 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void NetSpeedFontHook(LoadPackageParam lpparam) { + public static void NetSpeedStyleHook(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { TextView meter = (TextView)param.thisObject; if (meter == null) return; if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { - int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 17); - meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); + int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 14); + if (fontSize != 14) { + meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); + } + + int horizMargin = 0; + if (MainModule.mPrefs.getBoolean("system_fixmeter")) { + horizMargin = Math.round(meter.getResources().getDisplayMetrics().density * 4); + } + int topMargin = 0; + int verticalOffset = MainModule.mPrefs.getInt("system_netspeed_verticaloffset", 8); + if (verticalOffset != 8) { + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + meter.getResources().getDisplayMetrics() + ); + topMargin = (int) (marginTop); + } + meter.setPaddingRelative(horizMargin, topMargin, horizMargin, 0); + + if (MainModule.mPrefs.getBoolean("system_detailednetspeed")) { + float spacing = 0.9f; + meter.setSingleLine(false); + meter.setLines(2); + meter.setMaxLines(2); + if (fontSize > 8.5f) { + spacing = 0.85f; + } + meter.setLineSpacing(0, spacing); + } } } }); diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 9b176046..b24969e3 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -99,7 +99,6 @@ Częstotliwość aktualizacji prędkości sieci Szczegółowy wskaźnik prędkości sieci Pokaż osobno prędkości sieci przychodzącej i wychodzącej - Rozmiar czcionki Ikony wskaźników Ikony ruchu przychodzącego/wychodzącego wyświetlane obok wartości prędkości (nie wszystkie niestandardowe czcionki mają każdą ikonę) Ukryj niską prędkość diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 3b6e25b1..5c397248 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -722,7 +722,6 @@ Частота обновления индикатора скорости Подробный индикатор скорости соединения Показыает входящую и исходящую скорости передачи данных - Размер шрифта Иконки индикатора Набор иконок входящего/исходящего трафика для отображения рядом со значением скорости (есть не во всех кастомных шрифтах) Скрыть низкие скорости diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c21f0c67..e56c061c 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -96,7 +96,6 @@ 网速双排显示 网速相关设置 分别显示传入和传出的网络速度 - 字体大小 指示器图标 网速旁显示上下行流量图标 (并非所有字体都含有对应图标) 隐藏慢速 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 736160d1..f113e3de 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -600,7 +600,6 @@ 預設USB配置 即使設備處於鎖定狀態時仍然應用 忽略鎖定 - 字體大小 網速旁顯示上下行流量圖示 (並非所有字體都含有對應圖示) 指示器圖示 網速低時不再顯示指示器 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 3e8f41eb..9751da9f 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -401,19 +401,6 @@ 3 - - @string/array_max - @string/array_large - @string/array_normal - @string/array_small - - - 1 - 2 - 3 - 4 - - @string/launcher_mods @string/poco_mods diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dc802bf0..2a40b90e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -106,7 +106,6 @@ Display in dual rows Network speed mods Show incoming and outgoing network speeds separately - Font size Indicator icons Incoming/outgoing traffic icons displayed next to speed value (not all custom fonts have every icon) Hide low speed diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index e3a04c10..901642a2 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -471,7 +471,7 @@ + + - - Date: Tue, 3 Jan 2023 14:15:10 +0800 Subject: [PATCH 233/627] remove useless assets --- .../mikanoshi/customiuizer/MainModule.java | 1 - .../drawable-night-xxhdpi-v4/ic_appinfo.png | Bin 804 -> 0 bytes .../drawable-night-xxhdpi-v4/ic_appinfo12.png | Bin 1666 -> 0 bytes .../ic_forceclose.png | Bin 1416 -> 0 bytes .../ic_forceclose12.png | Bin 1557 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin1.webp | Bin 1988 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin10.webp | Bin 1470 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin11.webp | Bin 1130 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin12.webp | Bin 1568 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin13.webp | Bin 1434 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin14.webp | Bin 1996 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin15.webp | Bin 1414 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin16.webp | Bin 1382 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin17.webp | Bin 1452 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin18.webp | Bin 1748 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin19.webp | Bin 1692 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin2.webp | Bin 1862 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin20.webp | Bin 1302 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin21.webp | Bin 1342 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin22.webp | Bin 2576 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin3.webp | Bin 1270 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin4.webp | Bin 1532 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin5.webp | Bin 1272 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin6.webp | Bin 1604 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin7.webp | Bin 1474 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin8.webp | Bin 1264 -> 0 bytes .../main/res/drawable-xxhdpi-v4/coin9.webp | Bin 2378 -> 0 bytes .../res/drawable-xxhdpi-v4/ic_appinfo.png | Bin 855 -> 0 bytes .../res/drawable-xxhdpi-v4/ic_appinfo12.png | Bin 1734 -> 1666 bytes .../res/drawable-xxhdpi-v4/ic_forceclose.png | Bin 1390 -> 0 bytes .../drawable-xxhdpi-v4/ic_forceclose12.png | Bin 1499 -> 1557 bytes 31 files changed, 1 deletion(-) delete mode 100644 app/src/main/res/drawable-night-xxhdpi-v4/ic_appinfo.png delete mode 100644 app/src/main/res/drawable-night-xxhdpi-v4/ic_appinfo12.png delete mode 100644 app/src/main/res/drawable-night-xxhdpi-v4/ic_forceclose.png delete mode 100644 app/src/main/res/drawable-night-xxhdpi-v4/ic_forceclose12.png delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin1.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin10.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin11.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin12.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin13.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin14.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin15.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin16.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin17.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin18.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin19.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin2.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin20.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin21.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin22.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin3.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin4.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin5.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin6.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin7.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin8.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/coin9.webp delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/ic_appinfo.png delete mode 100644 app/src/main/res/drawable-xxhdpi-v4/ic_forceclose.png diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index b4fa51ff..daee1d62 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -386,7 +386,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (pkg.equals("com.android.incallui")) { if (mPrefs.getStringAsInt("various_showcallui", 0) > 0) Various.ShowCallUIHook(lpparam); if (mPrefs.getBoolean("various_calluibright")) Various.InCallBrightnessHook(lpparam); -// Various.LargeCallerPhotoHook(lpparam); } if (pkg.equals("com.miui.securitycenter")) { diff --git a/app/src/main/res/drawable-night-xxhdpi-v4/ic_appinfo.png b/app/src/main/res/drawable-night-xxhdpi-v4/ic_appinfo.png deleted file mode 100644 index 2e34dfc01ce2f0e421edd01bd2cf3b91e7cca396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 804 zcmeAS@N?(olHy`uVBq!ia0vp^xggBJ3?%2M$)^CR2?0JKu0Z<#U;@(^BtHP%WKa_1 z7tFxO#KOwP&BMnpr=YB*V_Vrq>P}YzeR4y?b})_x`(cQ~oJiKfE#Ro$0=hW}Jcvtv!av zB$9g!>lfFowVicFZ1c$#v8OKwPi2p;%fGFEdGeCzYQJ0CFMVO@Wj@WvdnqjTv>oNsp5%TV^I&&Erob^4mD)}OkAcR%@e)$U{W zVy_)<+8$mytNQP3sXmW%?{v$w8DbtmGmLs(CdRhKb)~G7bN>F&%K26N>@ORiiMD>o zxVu-xw5e9)-O@AiIpO;2C)$1gWF()J^paWV$j`Ky4}aR6*>Rt5Ws%3^{bE7)&mK$s za(jXdtB6zgpSMS2tljs|eR}8amdKI;Vst0FMjDdjJ3c diff --git a/app/src/main/res/drawable-night-xxhdpi-v4/ic_appinfo12.png b/app/src/main/res/drawable-night-xxhdpi-v4/ic_appinfo12.png deleted file mode 100644 index fabe15f3c44f95358a23e66cbc6dc345cd420115..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1666 zcmeH{`9Bj30LC}8nQM%ZBgMOf9I4D(Z|=2bW{gRRiRHdFj5#W|`K7sN#rL;wJQxCI7fyWi)3Sy*sC zkK0Wu0sug)4UYJ0-1}eu1pyDLcK$xifDl`}9RQ55k4h*gf5I-kmlkBJEuj%z__(I7 zzM-+Y%1%ZAY95+fasP&?bjqXr7>rcJfvXIN@q;_JVl(a*U6&J7(0z!n{3DpeBpmiC zaVZNE)Av-u%IjUJMTrFFP~t<#R_EZ^NL9C^=@%W3DLbcHR$UGS0EEIVP^LusL{;`^ zTx$ocr(DO^z6d+LueDG7-M!A4$#{FSNnTUov9AbuE<)Z!GMT96pl?ZZd18o>!TLKx0dY%IHFa6O5D_rS+znD<>EVXytGrd`*=1=N zSq*<#N?uP{yn99bF4q7@^{@=Yzq~Q6_Ig~G_9+PvrfuNV<*k)?rg|Dcshy(xEr9Z{ zWOy$*6AYBzD2Dc-E_9JwMTM$kyF3j&)Aboyc)u9+1fqu}WHx1xTVM=rr(1j}B&86S zB~w^1)AA7p&v@e7kgO<8`L~4LG)0G&A#ZqiM$Yfw)2tF7Z%5`kAmqScpGDfY-B{7jw`D8%LH&vJEC?oEt~T>_0Jv- z!w4XC=61p;wCGd`UeQ<}*}8IYuyDyhOA=BfQ^tfn<8ZWJ|>fS#DrDIvY6LDmT&O7K&*! z5I~jR-J&5cG}?xp4c&D0+0ruH36z+>`Z1A^UvgKNLZJpQiUa$TkSNG+U!sT;f#OtI}ud`|+3l1N^t4|@!Ur1nDYL2d++~u<*K=`w{z~#zt104 zG`xQ@fvNrQ!vYH#J`nYfcO8do;H_OjlP-$yZ+h}6lr?-+mhSdh0r@6JcP-lbMZeB9 zzno|Dr8P0PPpu8hDdBt>*>!FE{tvv>1|lCiCalwV8YVpZNTJ8!MeihP|JnGp-M&#Q z(_V4;PF7m$5%;WFZDyMH=mKU z;_h!%`XLv3wNk$3`H{R#Cbn|*iMubHyBF_z&To#y`9+^M#w9S#V%^=|Y2EH~-SMZ4 z>N&kTr#1K7-0PWtHlR_kOhO_^I3|HhaoP6v+jbUt*RDo0o1IHob%^h){{i+sCm;91 zn9zgkpRbmR@pW5p)Xzcn(UBvH*Cr{ai&-d7G@jv{wqWtxKEtn@1g!J!i{0~ExN7Z# zyp)%D2Jw$gO#fJyzjuhSRMxrk%DK+ysSZzuRML}q_5BSSmfo?l)!)E=Gu51Xvrfkvv6t}y}=}eP=ve4Z38%o-rgkD*f@K!FeFhqeSb_=TzdtFkWG*I%E?F8k{6+?!u{r@MCSy}oYO#LZWK z^G#B_##*jcs$P`0^;5usmnouG6>Oa3%?z(we7PiGyd^SkYqZGnx2G0uXEXb?qOaz5D+!gnCi=eV44~zVruX460*QSNuv*md;zxv(0%(jznc1nK}d9>r! z&qMPLS@0PiO7lOs{>X3DXO}hB?KA1G_1##N^UZro`c&bM7q6}Tcrkp|jAhr3F8lGv zHE-*zuJ~*3_syy;ouB>fN9&hMRUda9fM-ODIrUBEwkfM$mz>L+0W3fmJYD@<);T3K F0RRn$GYbF! diff --git a/app/src/main/res/drawable-night-xxhdpi-v4/ic_forceclose12.png b/app/src/main/res/drawable-night-xxhdpi-v4/ic_forceclose12.png deleted file mode 100644 index b881c0e20b38f719f990f4d52e02b425a846b875..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1557 zcmeAS@N?(olHy`uVBq!ia0vp^t{}|83?#LKZ%Z>UFg67Egn$J9kAi^5`N~zR*Q{N)e#6F1o40J;wtdIWUAy<} z-M9b1!9$0S96fgYWe&gotyAK{ddVF}R-!BFR<|Cdijv*Dd z-cB!_e%nCcNNAdxSJ9gtXU_Pfcy9_z(?0HE`D}gM>8Db`%YK&M``x*9^NaoeUT1Il z{pTxtzjt<^;@Y(~wFPhAeA`j@?_GBDp?V`r6*@YpWM z^Z)(p%uJ11IbKD-1!_0j4{*gQ+;cEZ?!LaVSuf3D?!3hsf$g#GdR-lXskyHN!;do` zvMgioTP!j)OOEZqjrFUugA|UxV)8z5gLBF%ule2<1$(pIV&^_tZ)bLSCFAjfS3IXI zT&CD)Ib+uhzo@TTrBN@`uK)RItP#96x$&4}b?oe*N6U<2tIzI`)0yLJnKk#tmByJ> z1}l#!On&I|U}}V2f6>x2UDu29vx2YQ@F|hgOMiJNYs&gpKE98OxL?b@5H7vKeCB8N z#-fckcH5ghP3BwBd6Dbaf@g*c8Lu}V^?nTuxv*EJJUkuuW1ZfIy!+V6q91#wfh+6m z#ghtmq!s!!_BL}&XSja%=V|G{#I@FDY8)rT-^q2xt$HoMAaf@6PK(rqs?rn78G54p zSQmC>2eKWRy=Q}@>5{K+@9L#~Vm4SE8vIZFinOJ=VsBy;Q}nrG8)B{-MRdHjj};L5 zFYerz>t6iIO85H{ZG*n#hAA#rRi3OiSUc^g!lbwJ?=|cT%I@3s&ARJ$-@dtrew=R3 z-dE|GFhl>_nxEJ1vZfuFJU4sa*CmpNzid2WQuA6y>v_Vib&?l5KIVis&)}7PAI}gj zq8EOQ!8rH+tG2YFoFnS_@yU`4Hzj*29p6^Dfbq<($EA(Q_RKSm6!R}w|6{3BM~LSR zp~EKkZ$=AjiduX9%Xa%Tj>`6zUpWnqb>_a;cbh0`@N2KT*8GsOfeRT6)>+3X`h;Ga zyJFIo<64{zt+Dy>j3@5=UbUp1+0A7=F(8ro?v(1sA7U*h>{@@) z_T`+M{@JHOBHl_C+fzqrv0&fvr^=zo@Acksk2F0dEb|6p(g9)t4?Zq%zZhj zI{DSJ*Kac?1U=vFVm5EuiEArLBM(b1{!kJfWwoWVXV1X`_bRIpH`a*~K5{vpKC71H zx_EAlKk2pVs-tCM0?U1`12PMzwFInRu4`>t{$)o<(uO)++k@C!1sanIoC>gTe~DWM4fl^ebB diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin1.webp b/app/src/main/res/drawable-xxhdpi-v4/coin1.webp deleted file mode 100644 index 9da843528aa9b7637c68e9accef0fd2bacc594c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1988 zcmV;#2RryuNk&Gz2LJ$9MM6+kP&iDl2LJ#sKfn(V_XjJoZCBCS7mb)i5E9@o=kWF- z%y@v?NRlHdYP2Kno#*exi<~EfHj*Ss?!6bn@h5gXwkI=TN49O+>b0+JKW6o!d#Sx| z+t^D;Ktvid011IrjKKUO4Mw9-5fyc*F!fMrPy(egFbal-Mx|0|6qtGlOkIk}MN@&P zP$^Ujm1=TXp@gm~l%}E{G<7*p?V+i+iVBoQg|SenREjE01!{6BtlUh!VO&`$G?)s7 zN~NNyaABj+{7Zxi3CUz=G2&nY$wVBX<_ISS7-As65d=YS{pmk^!%N^aC6jCBk@@eR z2mX;E3}B8We1}p#Nf!!q;1s6;0Re@8nh6NDfNw~gS24B%0i|vFJA_gFNgz;+pV!df zMGs9~jK<@lb$L?{cezQKWBvU%_g{oXc5+zB&PI;lkR-_4!;+(r~mfqMJ}J^;*mdwg0^j# znm_FBP>6^L$PqRduT+i_Y}-!T>ROXl$_+YXr_9`+*iP+o2V%D>Gcz+cr04tzMD*W* z+enJkHPCQ;165y;Wo?_!bfOO^?29T10ejF$MCS%p~v%v z?QjVk+sMbY&ixfEdcLyCPP-m7Y)*u21hw`Z51&+11nzsZkYRBju#Aw_eGj3~-i_hB zHCgKUbCRv+V2sq2-E`vwuL8`*^npTX9&=waW?A;X4{I}TF7sr*_tmH8I0Zp5C#Uxc ziOU3g(G5}pV=nHunxl+xUpW=Ol>!)d$v`t2HE!t?0C0KD5o_rSRHUMnq*1e43$d{3AVE%)aD)3e(g$%>W ze6uBugQ@5*At%GeD^C^xbCfEO|IG^z#Y6H`J_q#|E5`vA^BhAOU@o?Ot&2(lvkey? z{~|VFwKtw#S_m5%ostXK*5rNndks>qiTwLuxQPX5EB4ca0o#H>$2D%>_AHiUBa7Vv zhr|u1YLCYt$Li(d0Wd3*CS8jK`NBsKW2#LunVbj9R{3e~>G=(%{4;p)Z$y&V)Nyxp zs=*-{|F8od7#3(%PkMJ3!v;LeCYyP~)Y=7c)V3@Ad(A)(s#d^=PQ4A5>6r5YX4BwqE*tJhO+2= ztE!|7KCRC;h6@Q1Skb|mphFCnfMu9<=AMY+!SIN~0E>-z(x?y!&SdLpyXk8s6GgG8Se&rhAtYoEap&kT4Vr z{)6TluG_c__L;D6!f<$K zWU*0nTZhdofBkVUJixU#rb3f-a}kpaD!Ms;+u8k|1vog_H9scr8fE8Tbw`og#hvWj z5b0)^v@qs*q9hlR^N;I|vcrb1Ap6FuJFeQ2HyZDkjec!g6V5yedmo09bmVl&Mvg#a$DOslk}*IgUAg9L8=@unYGFTx?4Y{y>UKqZdtwJ#nsC zvaaVkuE&7m3ElQj;d*#jkl&lUdDC*SFS)-GY?OG;#YB;FbAAO30w=m5-}Xn*hs$wi zDXi&Nj_laDZu7p&DwdkG#d{l!t;~gGtVi}XFnj#d=waE$=Fi;^$zbCc_~ZYK+=@hvyIcSI~m;W`lWj<{NZ9f8{D!To1<8XLdO{mdeCEY%9v?0oLyMM<8psa50 WJ`K%gxs{z6?BCs7^8mP%X8{0;CgZyR diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin10.webp b/app/src/main/res/drawable-xxhdpi-v4/coin10.webp deleted file mode 100644 index ceb9ba8f6bb6a320a1b8121165d6f8736e4458e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1470 zcmV;v1wr~!Nk&Gt1pok7MM6+kP&iDf1pojqKfn(VzvU>BWLe4g;~lx;UjWiDuoZtr z1nfwXTt$hNCg8sv_`|Q}>KMn7ZQDlQ`}~5C|3o~5p^VkyK$2wJw3W|(-*%t#pNN~b z|G(Jp9I{CpGAHdFfW|hH3>z4JtYG0s1f?iQArespr6Pi;1W_rJ;_m_}ib|mbQIMii zh>A#h^LmFAh4KnT1X74fAuvPW2Z2C=IJi8#AaH{R6e#c#fpzrJ$2LLW;kq&`tgbOX z=0#j4wMiAPKS*HcAfo>a+_sHlt#H%bThA{L!dRg|6}~U7j!aHWOpdIs zy;FsSLX4teo`_yMnolx0;TjaV%t>>{hyRfxsukOt(ysP|kjkJVgs0tfQ%63U%6Dsx ztA$cZI$P4U6szU z^H761%?jAqK9bDoss}(Gt31UQ@Dnsjc0!+^=tuG+u-~Tsf90YA6{T>BBR|xZ_Xp4yHGR)6`3tD?CeFzS^=qC5zhhim~^9zK|w%ilI zV{s%Vb5ttOu?Asq5(076@jugS1;7Vyf!=lmXzddOGTtm46S4D2)B(4ty- z>P6d)bU_^H!N^CJI7{~t9igN7eF&s4azf7Xj_7??prbE!r9bXqVw`vET`lE=1A4B@ zTIa)a&+?yRR$k;5R|MMsJEkiAZ2Eq+a_M>zDVAs8pnuRly*vc)!f@oyj3FS(wI}z0 zCw7@U05LTUfDn;+213xxUNOQLhrk{FJpK1&eq{CRl{oM9VE7HT_vK`11SAn$^(|9T z@8JgPl3(*qUQhXFiYP~7)P>EUg_Fl((9jqta3+-EkogLj} zJy@kW{no3oZ*tXXHC~SWnuMz0_RUuU_H9Cb24DKRZI~(=lHIpUMw5%Y6CGdjA6Ah` z$(yb8hkHCMDU&2zcPkVI_{)bCWLpbK5%lT08hb1z`kF z6~&#~l&2wWhuwf7a3p|9yq3Vdf#}fI-86sW;Ja!Fw#wW)q_X|qWV@`zLy;@PaMKAQ zkz8Q!ZMNgyonrnar0w2@-5bd~-qzqXOC)e_H1AHe7O{2Ul63Y@9G|nEDTK99$*Xz{ zb8n|w=z04cbn(A8^9E;J)(wFCHEMxpJ@&k%@d;1=x}(XP`Y8k>$=mAZ!{&{hSsf3P zH)cEiyfGv%TdKq4t$)$v%|GppDNnoNLMnq&2v>XQ#`d4+GH?25?>XH&59aOXd#Ana YaNZv3y}{D#=;ZYDo7s2n}BGu8aiTQWf zwvi+8LjTp?|8Eff+(we5NO>fl_NKlgZy}?~G&8#npbp*UO4GaG_)64PST)1t<>c;Xy zF%YzE8;3vbZ9jyFn1HU>R3<+8^cv}%f+P2_}2%yo3r!xxGyn0;V`B|eYo?$=JOK=vG z!)>d=0NbKVLv!Q9s(z8*C_U`T9bt?PzcTgR+FTf9n<{SBfZNYarY_4vtnWn+GKVy;UCaNF0=S&4YfgQcL8)*T?hi-=Ue!tuk7Fd^;qa0<#A(7Q zUlR`_BsDvALR5{1-o1cqSuK?0i+Vm7_K<=~6K84O86mzdG-$iwB?T*+ECY)&vGKB{ zT`@Pcy!2#wvv?nJktlU0vPiL6kw7@hO1p!2#Ii6h#A;2OIbnGnGo*2bWnxcuYfXIP zM*OQH93S!On4 z78}1370hGH^FXU0O`HQ7b&=)uTN53(wIk%XF8d`^N8e~Mz>mvXo;aBcixf`wau^pp zuausW)tLyVXPc0Ew@#75^VYrMyGb|!3gl!%DK>A8f48;W4(uQnGiseb_Ad?(RYVzWtZ7RwND&}Ff+wEjiYtN_ z)sZ6BB*7H{KJbH|nU%h*(UJshx;=WgsqIYV*f1tjM1TMZcIeOXvI;M2MvxDZ(EFv1 zF>!l@0-HF5#0`Uc<>;2b?1hWXOc@+v8f~c^oJ(hlSDc<}yu5L@&3h>sLqXd%Qp}(B zb`OJyn1D`E8Gl5lBwE{^wvCotqqd+FW@aukGlQ*crMq+!`M0_Y_#DxHM{e6lQi7Un zo;odUe?gW6uxVrcs1Ucy%*@Qp%)8lUre8W#W}DIOy8s+Bk(BNYD= zf#1Lg{`JCuzX#*i`bH`e{S)yw)>`Ak00UlvFyU`bb=2NYST+hAAs;B%uoByiqeq4} zBiYTYYAKsb03zhL003?)t2)~=k@(HBvV=q|{c%c~FZf3RRZ&E_+_;4PACP z*Lg^XVCJ6B!OX53Iti(UORbA^Q5!Kq4KxWYHv40h7MS^=1S7pFonMSiZA9;vhcpa2 zFzXp|P_h2y{W~Ndt4ZJK1d&g3-3sXdegQXf&`6X@flTiEksN4a4c~j5l{92jbbMR@ zX2Z7>X~}@S;B3p%%_G_X_X|}hIq1AeWMkIaIt#F4?TVA<4i}V~fHN;Ds@D64HTehY zn4#y?I-6_0hhzsk6rwD)+0(ZE%toijC%y^T(dGb@B#kOXX>Y$ACb;&AM#@EE9F0}M zMeF%MK{1{<7%xsVt%xB+2@`hE1O%KqUQtP`@ha`gMYKOUK9*wQB8kL#+y|#ArMS9A zGyLiUjxDiC5gl_X*)Y~MTHh!LQalC6(Efj-_miw3RIJ@jc#ZdP4c1&S*VgJoaX}^)Fc5e@ycY}s5Sim5c@tTmWGv@Z) zifBG3?qoIAxo|^z#LbCYUo4m5LW6$obe8oj$Vk&ZvG+_#6xW*}r1LC@H`aH;GI}d7 z)=V8eC4@P-+_()OpDv2!pPiY>iQcrab!`@0rS0V#W07m3y_mir@Rsvy@-~s(nLn0} zn@T?1Iz-;`%yu5ZM3(QT(5 zbla;D-8f}K6*2f0SLYT_;omLt!<=| Sp=dI-x!xKdd@+1KlI~_G_y&Lg diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin13.webp b/app/src/main/res/drawable-xxhdpi-v4/coin13.webp deleted file mode 100644 index afb64b834855e57b3273d380ba8e18614bf420c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1434 zcmV;L1!ekDNk&GJ1pok7MM6+kP&iD61pojqKfn(VFXcFrBuB};IFt=ofd9^5f>vLm z+1(RHIEo}$R`M+ZkbnqeV~RV+9XftHZrsR`Y8L%kTmU|QTtq&MdmY-qk!)L4)lYCD z*U)VumN9Qq!td^iLm+7rVB220!c{7hlB*5ln|`f(HvmYpcuXx#X93f1==At*x-O0JYds?bZI~heY6lGjTDWB zBM$g66<8XIEielPgQaD{#)U02$x+73!5L_YlB!k7oGj}fEr z5SLa2U?D_uza#x;zdZ=da`SabhTF+eUKu!`|+J5D^pLW0UTXD(|pt+fLiOW?*WV zQ>OOBqa_jVKw)K>=$I&)}FT2!0BEnDp45}EP-!I;OEgYSH^u;<6#yOR zn7!@k+5C?%I9m(`7a2E%v5=nL?gMnRu&uo>E(}H{FlYkF1T!l9Ywtz}xjA?f9EplS z35rC>#mD}w=h2;a!H9wwQ~(BvzQy}4K;MJke+o{BL1iEk7oQIvwmL5h2lGTk`CQqj z1tS~tNQj9;HS5n*%$KDFMXJoGY%@Hr{+^f>6I9i3`WjQ{mN&KD5_D z)gC8p(U0&qX^sTocJAABU)uNlos}f_bVvS*YTknu3{qTWJ@XHUZc$2$5ytsCB-W)pP5LgoAGQLP<sz1&*cffXTVyiEqXq!cR1}6$PjHm@ zrCX~cQC%N)ed$)3ot>uOLTb`#Fy9=hO54PXgVifh>KN0U-1K z)H>=ekwwFck{8p3bR>FD#Y&&yI0Euc{LN+w=?FAD6(bLeVd)23a~%lRCl>1q5hUj<7{@;!xXId3i*evC5*Fcd)`2;;hS3cxnS1a^hwPl*_!o(lhcQy|)fuKOO?S_yl6X2G&nZM&7Hey5Z zMj%RW2W<0(ZbaG*@L}Hi{*JL*Be9%{O~rKNS_-Ecn;nmM-Pp-=0n{ oNOb#8es+4hV=)~Fv;bi2@${sTh)06Ukyx^Ra=JbOu#%+Q0FT+8sQ>@~ diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin14.webp b/app/src/main/res/drawable-xxhdpi-v4/coin14.webp deleted file mode 100644 index 39b2b39d5e03058ec4315e342cad77176e7e7ce2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1996 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 UqW-UF<}a70N52pRk0c)e04==0F#rGn diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin16.webp b/app/src/main/res/drawable-xxhdpi-v4/coin16.webp deleted file mode 100644 index b7188df3270b66a0a50ff8901c83c43efc565e7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1382 zcmV-s1)2I%Nk&Fq1pok7MM6+kP&iCd1pojqKfn(V55=msZ5z{D1QE0lOHw`j8e_Yj zAs9!J+@vME$%)iRjhx`ONUkGEcA7pwUZ3P2fznb24ztCuUaQ6mBd+bB=m|(DFi-nP7pz|All4ZriXS+9|s(m;HMfoUk?>^)gJ;J zQAZzXW?!$Tx>meR_qclA z$?5!<->2o8t@kTZNVK*+Z5u5#W@cvQDTSZ|V`gS{GG@-4%qaxhm3ynU6#aH@z`qpH ze}@6kwhe>`kM7!*ULXLDcO&A^vxi@=U2Y^|QEXhf`t{+{Nd&Rmhi-5HQTE@tkTgm~ zSqVolEDcqXN$*boFu?&=+{^nv4YOF$ET$qBm9$tXnnvAw=Y~<=ew#*GlbsO(JEimt zv-UmfxcC1rv!cmJ3IS9oWySpUfZ(VDz5QXil!}01yeZnGkuo-P3K(*sF&jmwBv(mH6UMAsvBWm!IJt2rymv^Snir=S!Ig z48eeh{wXkErgV-A5>J}K7gW@yZr=iG@@}0n6uzE$lDqmk3Yzfueq}NLdLN4e_==(M zvlTje*mznP!}{K}>nyHc$&3V-ty;0t;u@L~hR;@y53?N=C3=xp8~h+np}Htk+I#Iy z@|3BGu{k&;WRr!oi8$kkE*?Hbx^bjwXb~Yc`9oqKP}2_SqR-c6G)H{osHKSlYQ|B5 zXYAz;XiN_AY=P-kL)<(=1}_vLw~dh5AvGtZP<*@4{UllG1T6RcTX}BTvB=MK2G!D6 zREW+>^4TMHMEt+yn0vEhYB0dWS@sAZocL0L08^A>Zr2olfF0kHqY(f~U#?msa8mui zOr|d&)pn~7g5vcnM#|AHKcAf>)tXlnb{74;)TlUsmtVpQfkIVjB*G5#Y7MXX@Y5)q zh&a(UzvQ0bfKCz0n1U;}cbcD3Xv&T}T!`RCO84gSed}IXf;YfZ!nsAfmT`hkx%5{7 zC#~YOP*0%)7+02N#H;wDK8Z@7sV8>mLu_UI%u!h0bbde*j?W$DZQJq`mbbki11{x_ z)3!p8O8)!MGIQ<1PY&|dLkEC)>qj||p@Vz^A+gk^<=P2R>m+D4G%-*Xxsat>Fd*?>otnSyLb@NZ}rCXKv oFsyDr(?8&fLquOUB2Iep@axr!jYK4#Xk5DXRX!UcXm65YAkCSewg3PC diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin17.webp b/app/src/main/res/drawable-xxhdpi-v4/coin17.webp deleted file mode 100644 index c45bedff6af33aa848c49b0048c0c403fd6c4c05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1452 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 diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin19.webp b/app/src/main/res/drawable-xxhdpi-v4/coin19.webp deleted file mode 100644 index 33ef06c650501661a939f99557c705798d6a44b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1692 zcmV;N24neBNk&GL1^@t8MM6+kP&iD81^@srKfn(V-{dHgWLe1}-Vp;h;EoRTgM`gO z|F``AMYxG=+f~*JA~?#|%4wr$gy zPqCA)^j|^>F$%D4kxkm{N!mMr5ez8sQw&%XHVA<%XklM3-xiVRgL82WJZ))vsl##AtAY@{@X2*yf(etOS` zrobFmTpAFgLV*ZZTrj3W11(HKKdF*;bKT}%Q&6-Cg=0=e@xS@^CU~9wZjU{@Z>P`w z@P04GW&1r(>-TY;5@RT6+lEQ_!)|vVM8pKJR0XVWsP2krF}3(*^0`|1&FCc=)E-Wg|UYOQsh0y>sjYt!OT-j{+TNbqsb znM-ZnK|~P(ky~nA#&4H{*wxP$eod|8VnOSUMQX44-6FwGjQDvK%oP<81`q`+$lD?L zHOA~s7%`<{RES7;Giw}cl{8gYEJCjwTLMT0AjSUPXfT956{Oy#<7q(>hfBs621GlyO@p!c_z7xS7e<;$kpJ`aGZ3N z+DxrEc^AiOiPDEmf5;ZE= z@bdgiPo??Uds#OHJIKe}m7J&K{8gwv+zk}a%!MtH%Jyu^3v^|0cdW^LwcV7cr0^qQgQ!U^MOliWg1ZF}Oi0sAxxPZw6ov(L z+%&0UdxTLXXQ?OvZvV#e;xquMWQE<7VI%E9@+}9xnsT6G4bQT0RfR3%op-HBwj}Td1KF|b zv0Z*rJH}U$kxIN@NE@E0#5YsBB7GVzUIV79H#Z_tOV+{*mH0AHIc7pSzayIr4bB)>XlbwUdAgzSThZ@HiXh!})W;nrqTRV9m!_M`OIz?l5TCYG|$EX1H!w?yUq)`Dzr>SvV*t~%b4H{!k3l#h8Yv1#AW z73CL&?AY;+yuFP22AJvxN1l3g!E&u|-}PPIIIoW?$(?*bIA>X?QTtB?=h24JH^Eib zL5MLddDmNY?<~|e<-V;c-G*qh<(_wsE(7}ZV0(mRG)H5o;omT5GF}^LlR8dE6Azr4 z1y$@vUeH&-`}ea%>U|PqrB}x@rmx~aviIORcS=&q|F(9S4;4o~Jb5;R{9uo97ssQQPm4w0#Z~=9rTsn}Ya&tnM9gh^ zRNJA&w~?sfHo)A6=QGlU=SBnY=UGd_z}Y7Um{&OQj0>Ms9-MV}mN4MUu1WD-TAdYT6N=kY6 m%yj$YS2GcYh^aav4xG=g@0Lq`;h$d|-dUf&Xc3H>q}~7-Z$6#? diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin2.webp b/app/src/main/res/drawable-xxhdpi-v4/coin2.webp deleted file mode 100644 index c4fdae839e214f136de4acf1a500a817c1eaf4f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1862 zcmV-M2f6rCNk&FK2LJ$9MM6+kP&iC62LJ#sKfn(V7X~|$Bv(J$rpIs|I>WpsrJTkBuSBz9RB;U{^_Rz;MTUSTAAP7T|$d~kCa0fv_Qllba#LL z>HuqA0R}-?DCNf%Ip_9YMqmr8{*3t?~HRh z+lUU{lX12@v+gPT!s%hnv)j&(1b7Za;NaZlt9|_V{Pux}N+5+&DTq_0ibW+sMdBhM zm4b+%1f`OQq#`Pbcq>E%;$~rYGZ_2=A`z9OP?E|Ypi+>6RQ`d1>;D;Wbp+qQA|!`}8&h=>V5nN?T%W`W8^&}`dU+B}kvFYbXF zQu~No-R+;dPC%Jto1tOfgAu$&^q-O2wqep5Hr#EuF7X#AYumQAads2g8ZCdRq;UQd zD7VXo%3vsknVC7JajjU+Ff++j#|lVcI5*L!t4Hwt5&dW2NNSsNfl$)H_zQqoe+-CH zAAa)Hcg+nojo;KXG=KN?rynRl#1u$kd5WDKbZU7n%!{-dDdWQ&U)wo2bAebQ>VEsU z!1GcaBHF|5b%-eC{|hJEMiRojg7GRQRaK+EP(8#vGd)sQeFe!T^IO_s5+Fp* zs(QraUmK_v0;F9@y3fvS>99dT&ATwV?C72X$fQBlHCmbIL`oU%Z!iSJP&m)SoWtn?m z+6!cib@MWXrVjg{R;mo(vy^vah`DS+(OkpjavzNUN~!jjk8KSs8?eua_)jjK$liK+ zXd2Ah=eY<-KK_9NQ6f+gETY=)PG2S$s`4Ezq_c}Qe>c7!JsQ-WaJqJMM`?n_JMBoP>n)WqZ za4vHBdMqS_Te9X{nd}Sh2Pba9wfg$TAQgFO{-vpFF0e~;MdTS>e0`F=5}`oc{sQI= zinyZYSGsJczY_nNntpt8akBk4NBGgl*1;o+RY2bOfOQJei%VKlX$9w72n%)J-ecz% zk9#>1?!0L-L+|DRn(w4x$c2OG*U7ZX#-l{w$De7_JY(?<-7@rp1u*Q@Az=R76v@1r zO6Lme{gN1pV@M#gFAsK0x^*)wQ#fxcn7&aZ#Ws|5CZ*(;ItUZ^fd|%p$zbNoxJco3 z15ka7%0ict&0rey%1pequxFKAIcF#op#j#dUocuarg4lHQW?Z_R!zJ*G+a6FaH9-d zHnjEwD1p9h%Qs5Pd1u+iz7|AB!NFk`)3_;XN#xSby0xXb*4;g=LjZls z?FZ@HBD+8Nv|ru8ET?)6T(>ajWi7-OX4I6Y?g>;lIaapIA|}7N3Sw@f7+F)&p1R9? z7Llspx@``ovF1i9la5^0TX*%_@e-tNl+CS}XGT1A=fR47tsr%4{J9y)qUzMW)*YS( zt(&6-YHk zwQpkZCe3YB7CO3knF9N^*BH6Y4dg~m_=XQ*?%@y#(qraE3S8pdx-_?<-@diFYb24I zjqMX`Za&_=Pbzu4XG2_WXNf2xQkehT2cLZXT~kASbz^-)(|2Eg{7VWv^#}4o04RQu A{{R30 diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin20.webp b/app/src/main/res/drawable-xxhdpi-v4/coin20.webp deleted file mode 100644 index 7c777e4f6b1d677b2893bcc828b5aa5ee8bb69f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1302 zcmV+x1?l=yNk&Ev1pok7MM6+kP&iBi1pojqKfn(VZ=;}XBgglfKjr-l6tr!_LhnyO z+cqrp{usBBq&V2sw~Y5>u}MOEcn1Uk05}m4FaUrNaN-9r1_BBO0s;)dSWx;6e)y7kdiZLA4ApHikGLJS3M+b}hM*xjKJ5fhLj zY%X4@93|Mc+qTiCf~dIn-m7F=MC?T*``;325s+sV5Yc}IZrjFj;-xpbJN^Rf+O}0S zC2j7(-H96zS0DoCu>1di@7hQO5&dT%Nm80ajsb#Oz5sGF8JTfScpt7)fU z0Fc2aj9jff+dWvY$8Og4JNif|8SdCw>CAdqzXNu*AI7x{kwHAp-?nPQhw4twqZlTt z*V;e(`K+?{{hSA`u?CxKW@-NODNScyx3q2ydN;AeKfWdwZaue04S^Z6xXz1zfB7XY z!#n|Gk3e&|6%Nh)z6pnPYJ(y`1F30vO{+*YaD4$fGK?G-1ZmJo|mU;Xh$GWyvINpLMD%W{Y zW7lF3=WG?6Q2A4bLqYW)D(4y2auNHFK!*xrQ}~dVkUZ%WD+L6N??5cXsX~vI~_dzpWWF@RL zxG(#t?Rb{9@@Ra>k>x?rgD)CAOfZd`j9Y+@R|Oh-k{%|Q?nCPli=`5zCzIRG2}kPZ;?yxo34OL*t-xT92t>HYTu^9cf+A$$8vNfM32j! zgfrq2=SD`maFB3z3p5WS>~~-RNt|0>m`PZAs|)b(z4YD-_FJ+eS1Fl6`fhuze1QNV zhKzz@)R8adRuf>x-jpy)Av7RS#P5#zUiQgL#{#(vlE@Oy`V1%7uOk)o& zac@P43%0>;rgAd{B)~?)TeMQDN$LqfJ`#ywM4& z*Lx~U^71M7*Hws1z8h=gtpaqOJr~&L4j}1wt0Hff3bQR~9_?mDDDT}IEXaAgbEw@O z%IL#w70#vK?U7P9h>hJB@}>ML>%T#xTPFU3h=spDsr0tB8DKu7o1R`bJ!|SFVX>A% zx4m8p-PQ#CQ{C7HsHScmo$KhqiNbsFR0UaOmT!vvuJUAF@;FRK~v%O!B M%V{U|SBo^W06dC!djJ3c diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin21.webp b/app/src/main/res/drawable-xxhdpi-v4/coin21.webp deleted file mode 100644 index 2f7ee7652e323a4f7b2076c6018bc4e05b528a3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1342 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 diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin3.webp b/app/src/main/res/drawable-xxhdpi-v4/coin3.webp deleted file mode 100644 index fd3c520123e2db528273d99e46d3aa4305b1528b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1270 zcmVG`k!55e8{1S^8Gax9j11$X;0 zpSi;W0D%abzzuf<2|M6d>J>myPxuqP3b4irg-?Pv&Nv5kFa-rBWC8*y3<(mPkwCFW z0);}MNT5(8N}(ZP3CWC5ZxOZvC=}{bo)F9urT`0wfG`jt2oIu|0?0%vBsBx!aM4;L zK!Isxe;~m>;en6K7!CrW3^vXUMY~R`>k4;pTG%v-AV($M6M|@9ivkG}=yr(r0E!SH zh!6s|iO~T;5JZSJCU7XDj5-LSj}SzFAXTK;mCp6&9Ev%Xc;g=LsmFVWGjz(wbE}Y0 z)V95hZp|#4+gP@3PnK=lw!OA(`&8TXOPYNG)5-f!lXmhoqW=uswrwQaO>XadL`_3I z_5$cWaQ3|A@2uFgzSUXvc5~kBifcgD118i9aDx`S*%-Prgl&GK^F9O{kS!Q|CORo2 zUB5YRg`HuWaBdxMjKnOQ^TCGK%Ptd5--X-lP!?|OMuke@IN0rTTS!IE8m7KxcR06^ zorc&6*R(mJ(@U}1kvF1_d84+Nqb3|lvDWnAI}=^1#ttvFGk>RdyfL*{csovyQ)8`L zyU~bBVSPt~{iAJzHyRSdwv;{tFU6pJ?F>B^vUVIk0oWR*B*;%?jSQtuZE;*;Oe*8-61Tn|eDmErKlS@vS{7eET!ic;(jzvk*3$oJ%y(DB;z&PueBH>h_U}49h z_ejN%bebrJk-d*MwrwCGtQ`eizR{W)RT9dYp-7Z$iB&*aD;n7L(x8C0Msx^E-wo?% z6jnwD4)3k>YU-5LsjKm;HhZTYx=~i88}l^v^ec69gI6-#*01R}TjYDZ&7 z?=KBP&6THoJ9a`ua#kb4vL!opcqX@s*ywC@*tvK{(Bg$`RWdEYtV0dIR+6JhSP>c_ zpQ~>iIy*9~^RZY#R!AGjxzxqaG8*DkNA9bQ-_;P3hS4NjqF2xqk{bE=8usiycp}z- zP9K1PXcHj;ssSD8R1fYBphZHo_$v;9TKXj0mlxwL{s)LNy;pIO8Q>pUmLe-yaS|O* z3%aUEvZBaHDrl*WS3iG7>LEYRG{skZMXJ1nIwW1N=b2KLN=zwqnn>!SCr|Stspn~6 z;^guizmcEyFIV!+uyU?YP@Cab&Q0fQc!2aboSTi6LO0)WZZh9`sP&&^dT;4=cE#$X z4t&j7VS*y#CXho*)wO7*fw^53baf6N|G+QOzIWM`AG&Z(|MLYtzY#UsyD6fsYylpr zd9Ps-WcUYQHJeO8wE~Gi^+b%va6HW2SSNEP$pD;(ttKbSF g9f1130P@S9Hh;YT=;?FLAKUML>Xh+|@^20`0RK`~z5oCK diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin4.webp b/app/src/main/res/drawable-xxhdpi-v4/coin4.webp deleted file mode 100644 index 73f245beb0631a9efb89eb83787f7f92af36e9a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1532 zcmVBaswQZ}(PJ+YGoiUBkB857Q7Z@8KT=nJ@tvQpA5;5F^F| zF%F2a!3P&S1Zt?EhBn41p^Y4B$RR=pb>u94&^D&wK=z*I5y1@WU}?beGdFGggA)$O z1{P)lW^-eB6Am*|W<> z3If2Uk)xSqD)+d|xIHd2j?J+ZmbPI?u^Y*i+ z=wljGP1OCP7$*$d9&Yn*x<#b)X$Zg(?>%~_7UIs4T~XY1(U+iU5lu?z(Q$I_WPf4n z@!bjFHnlf*f`~`q-N%VG6yTKu3>Tegu`xIl_E&9pRXyF>!P}f+u{Jo*;TBcB4T%mj zJknG_!4e~p4L+WZGOUG-(IK+n*Mt9E&{R!Cpt3%12%UBpQ`QXV0%eQObjsOZz3XEcS!-`U>tx4=eMbQ7+g4djQ4)ty96wml=Hmz-gUD2 z)pTt;e_3CTu~tNXzI`W(VALXadrv|VuNd8T%d=fFDGa{ZQi5Zn{r`8n*l2lF3buDJnz|Dtz1u; z9p55!1}x~%YvE*pDs(Eom>pqME;5~4%@ItmFC#6+jN8LhcUE0;(P}^o2n;%d*_VCm zdoIA6Zpp(!9q%EMtwEf;*GYL4c>@>vZp7Z^PfVI~+P${}ciF$?DavcUEpNH;N;`5Q zlK()f!ygx~{@<KA2cVnoDWgA?es8;@U0w^(A3|Cuy#G@_d@>EEG2 zu@3KbksQUtZ)MFgA@G3<ufd+lpue|qWl4AaU|b*-zP8;W zkPM70o%-|GQNllkrNcfo+irPc|Ja(}S{sbnDC_JWd-^QiCN_-T{yi44BOvO}jdR`# zuq}T6iXYnj-~ZW)&LO(7>=2zpSK9sG`b8h=C$Qz4u|3_<+ zb2u5^4&LQKFO;Im{az-J?+HEY_vJ1Sz3*&PX=D1kOHmBMj>;J-aWr&S2@fV zCC}U0pg5yUw(50fNOWK>;9_!$w7i`|UC+$RyPPHS@^)4GZsd5IGnk8J>U^If`@2zD zPbc^y%U z{puxfY1#4>-mMyhl$HQq<-B*x2-J}~^TjOOsCS26_^3HhtnTt!Xxe?aR;kae8zE-q zf_0xBnOQel)U6=8DkenCy7ima&EL3gN1MLkP%Zn0)ASwmE#F(;WE_C2wdvcg6zDxS zsJ@Yl^^J+%Hx`=xC(kAJeQUJq$emjB&3BIOjU$`BIpKXr@7JpH{&@Y=+5Em84^w?j i6cJU|6Or$^`QrK0$FIBJaCq|U<;}hi6{7V>`GWvoas~bX diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin5.webp b/app/src/main/res/drawable-xxhdpi-v4/coin5.webp deleted file mode 100644 index 6f1e72ef03446084cd903f24535ebe30d4caac86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmV{yBqvHVF5$m31TXpQSi}h% z9Jy`eNSr*!`Tr~9?oKea=HGE7+p5wZcXwZsHffLu0kC(6_x=}KoA5W7YV}C$6zKaf{R?_!byT4Bsj^%UzCdk7heWEu|YvV=PI<4s*Lr7O9);; z#d%qV+O*>91si?wrx|>ShJ9_?(Xic)ZN`> z0(ECQM9>3UZ-4k$zT`ST;G2m4Gms>u5ujtbt7L#L5P%+3#JJ|kk@cg6^z3wc;dpIi zvgHgxti(tZ8b{o19ok)d%tlUf>Ws}hWdmtDl%_?GJ%W+NiSX{0EgfEnLx zjdu~;4Q*Xx8Q-Ng&QTO4L{UIAHd5Ey9%~GJ)x@^PY!qVyl_J{6ylq3U8e&+-hR1X* zum;F-BMEi#$)CRvO)b!rC;NlbN>ipm=77R1 zP2RY8$(Rdw;TL3S?Tu?mnpH4B;uyn*45R8>-LWKnSE{8jn(`~_k@`%O%{PiovR@(6 z+S2F5*&0k(H}XJGti5{fM^P2qA14*Ex9IX2ui9PfETX};98f+k^CwcoUEGV2R*^LF zNfHhRB3X$A{ze+>CO9Y-oW_c`Wc$DY;cJy@b(H*D5}6Jktb~x85KzQxiSGqREACRI zCB^0fCYFQ*e&h(|8~H98onxuaDT#W>)%(RjP?Nur_$G-KQ$yme5E%T#5x~+r>tW!t z*xt~Z$Y8i#sHK6lz6OiCdK~s%XhB{y0S~C4s2Ak@Ujf1v(u(Mx@Hzn0 zlobX_dKxx8RX9}N{{=LcXApM6Ub7M^bbs?6Xf4v|Gz)_}Ty(SPGl(p`z<`h@zx1dw zKU#MRAhLxc{xl(QPnE(Q>l3VQj#ph91V@6AAZ;g5+U^=(H!!@C<$)~4+fdrx5MQ^@ z9ZKppUy8Ld#Uuu0Q=MYp0O6&Aa-O4*aF8w2; zzD+}*#ybD(!_)KD`x3D34-)Ja83;)MS>gyewiI5cE-pm-|Jy*FiG z|4yb}^;^LBbuq#9nnR)N(>OjW++cVnnqQZI^pO+^_T7cJ+QE z&`N)jND=NgM&P$*YxA@g;eKl*elvBl2=<%f5&7*jD!&~O_alxQ{*Q4BBKFor6F1fM zh6wxGqlw!(Ld2fc=;Fpu+BmlD!Q)mxGu9PF+}sr=ZayTq8%f+=Z5>?-j@vg!TXzY@ iF$#@U2;!NR$>Fu*h4l1ndf{kwWU}*spx7jX1pxpuI%4<$ diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin6.webp b/app/src/main/res/drawable-xxhdpi-v4/coin6.webp deleted file mode 100644 index 8ab9b03b8783a377e0fcc9813c2eb616096abdbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1604 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 diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin8.webp b/app/src/main/res/drawable-xxhdpi-v4/coin8.webp deleted file mode 100644 index b0200871b8c197ff7ecf71b9598699b95100c55c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1264 zcmVnvREe=Kl%zy_X?G z^xuKowvm)tlN2oLNp+z!g`(InPsD+XxKoJS<(RlQ-2Xxz8+2P;c+}Uih;Y%hz+C08~TWJ+tPo zyEE^5zRehn;)+$%h)4M~`UqI%d$~4Cm$m@(7J$~m-UfEA34#8xZaC$}nDU17*>am3 zWNv~Kt;%+j<_aWgJ*Yi@(PyjWWxC<4%`_ zw%pHISLFr;ymrH8wb~l(-!XKEBT7#{xJ6?`F$clGhU_$T!YG1Hk~B~Cf@MaGn0=t| zVquOWTLj4|XPUZD2nX@E(p+C|@&SOLMUFOQns;T^0BuU9+mm!o=m|G@pFY*zWPC_68T7j7s zLWl}a&-hUtU!U4f^AA+Wi|GmgpIO>S=Ou8CdX4r>lz`+tfP#U(3$a~f=7O#*Dg#%u zF(>SSEHyOB3bjo?8WGigFsCjxH>lAGPzW^|Yic7RkD76X==Xvt`GFF&%4wvlO?=ED zuqL*IcFIbmhT6mvC}|;zY!3{HEkmvX94em#Z;BMTZ&JE`tBDs-w%KLNSyc(qyA_n^ z-wj%2!+t14VaeOwN<#7l>`EHxYBOq>17J#QvDHvQ>T|5bx$pHKl9H12vJVwz$hFw8 zCB+TD6ccx)+9VmH@C`Aul#bIjowT^u3G`#ex^-qAz#~E0k<*(JH$6$8X(ryQEyr%* z4y8)O8debFHa8{BGRA{nJNA2DD74~G9=t*?+bi$?Q#d+=&? z0}QZeu5MWY=5^{OWwKr~bz2wot99cTpqh2->|UpC4d+7LT4$%7o_*`))AR$NSFhUv a7%I+d50<;jBVm_3uiNFI6(F~KyZ`_R*k>~U diff --git a/app/src/main/res/drawable-xxhdpi-v4/coin9.webp b/app/src/main/res/drawable-xxhdpi-v4/coin9.webp deleted file mode 100644 index e339ef9e6ee2efe39fe029fcf0e6b5803f3753d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2378 zcmV-Q3AOf8Nk&FO2><|BMM6+kP&iCA2><{uKfn(V{|70OBu7$YkJvrU;Q$Y3MH)y8sUUSsAt_+i{IhM_{1^ZL2oM5*0RRDD0W?4Zpdp`I(1G+( zG6EW=Je`%yEc__kbexyh*O#w)9PjlfegBWtbmJ7qYqf*`vHwt*>AzL^Dh=tM`Z;yi zr&XSoIJFz9xL7ocqO@Q|#LNGR-v}&p!EC%2dAqC`{`pn90_M@0E7CC%zHZYX(`0I= zc0INtkNSw4nq|=D8c$2vwsblBSB{Gfw!Jie5)7sJN2ufuOE=drcOz+lc}6@seb=@| zsHmv_G0gY>@4o4i+qcDo}eb1;!#h!@f||4XjBgb@HTsX5C1+2 z9pUqNSxxWo?aixho4RPvr#pSnpD)1~X1(brfgt31%UCttHqFE!C&h>n+di>Q13ZpJ z=C3mk&Cl-)w@A9nu`L!)TeQ=(!tdQ4OY>jw$1;o60XybapigKLv=-!0s@vDP;-qul zs(BcX4+w1$i~#;e)qpNQcC-K@)J_r|K$J>bWGEOQ6gC8CFpw0G2U5To04)Fp08sx0 z6-qHc01Z+B0#Inc0~z7i1K8FM3V+&{!_Fuv=qqzwTwhcp)h0Llihg7T8?$*H zPwtE7`QU{~Jl!|U3e0rOzrtS>zWV_HSwQ$An2k67fk*Y_;i~ZXq?h52Zv8#|C0JG0 z{r=p_?zEh)8vc0OT=)4Q%e4lNJ&w)(H;WhF|JSYlJ4a@G?U~<$%Z0lO5SM+e-scVA z4cq^|Sd^k!HiEGEUj%gGDVGn<5)LR;S5 z*%u%Quh<=$fiBnBaA8DVNz*8{MpolcP+f|LaxtK>#TrRJ4p=lVp7!q=&3zoFFse0`F<^m|_7K?^w@t-PX2FO<7=c0iqptvNv z$Iz&dZaC8-oBVrCX=JuzDB;T4=U~u<*|m65VC2c5qci?QHvyPXM2Vg~@}s52GY~NG zY4M)lu!wdqk`fc&Y%R>_h#QHCk?RBO6dAPeR}^H-q^smY0y*2H(C{Pm$h7|(o7Ea0 z(lO7;8`rJZ6EFNm=4s(kNB%%VLDJI$1gLyHnS3qmDc?Pcwt6ftAC#D2wZ;ZF;`;}Q z*TUN11VQ@iQh|+8-=6PGj{V=*tk(FjG5L<(xNc2Iy!1N-*G5Gh{~ZV3Rj7U7%(#Fj zIlF}<$Hu?eR?=^Jcx-I!ojExqbFKA{JNgUZB?K7*0U?GQ559b;v6(!RE(M>Tlb_Uz zbTG*tc8f&CSX*zwJ^QB^7*O}53@ZX7JGX$G3#$jEqWLR@%noU+I? z^wg{hxGDTgd2~`M2>huC0$k=Dp-C}GFM5IG2iT$f>8PZnsCk8ih9Fbk+!)IkD=sG> z0}|+#CpniKdbqJmK(4GHA(J6jmMYs%pPpWlCw4FaGN3tB(kfJq6hD2Rp~SF_YkTCy zN$WWW=Qhn!y0jmF3_{cJq9AkYaTS0+PDLdpMUKcq^Ygcp-o6+F6zI349wxkO_aFQs zY*RhE|GJ3ygzIr3oicB|WlOLnpQx(`480Pzxh9%-Wd3}ZcrENH|9o`UX0^tLEGiik zn_!KJ4Q@n@i#OuJ+Tct-SI9)YqTon`*<>?0D8r$``fip&m= zj=t1A1GP_wM@Jm(gdMUL0U2o79w|+VoPW*TNjW4LPZNUN1GX>h5CD|zzkNk5WRL-Y zoj&J-`eILun^MQ#Zz+l!G)(|HhMBWsCFWJI7JCQ_|YZ0no1N9&?tEPDW%vXhE9U!+}Dn=g-Tc8|a{?2eL5X>7ad3)bVOK6uH2hh}%CDLesH0Cv+s3L3e#-g-MLD}Dyv*5%R%?#(GCDu*bW`v zRQU4jBQk&@p?Uy+{e`Uhgba2-!BBH!EP)FjHD^O8Iw?y=C@R_W`G73_d3Js&R15|6 z>Vhyp&p2qycwH2&KK0Flm$U;qFB diff --git a/app/src/main/res/drawable-xxhdpi-v4/ic_appinfo.png b/app/src/main/res/drawable-xxhdpi-v4/ic_appinfo.png deleted file mode 100644 index 63371d9915343085926e04e85981a7c47bccb4d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 855 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 diff --git a/app/src/main/res/drawable-xxhdpi-v4/ic_forceclose.png b/app/src/main/res/drawable-xxhdpi-v4/ic_forceclose.png deleted file mode 100644 index 38768ada2b3357adfdd4672b9c8b392bd845168f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1390 zcmeAS@N?(olHy`uVBq!ia0vp^xggBJ3?%2M$)_+dF!BZXgt!8^qW~TPg@LVmft;w4 zAirP+Miw@9E^b~vemQwXB~>*IO)YI5J$(ZscW=MI;E?c$$f)SpxcG#`l=`OTmbUhe z&aUpB-oE~clcr3YJ#YESRjb#mUAKPY<}F*dZQrqH@4o#94jwvuECtSrGIT#q2 zw|crbhE&{oJ0rDuwgE%i(b7tPu8$a{qX<)2@cKFyq3&)`Jzu; z=k4K~;GrVa>7q0dNS)k&F!X)O6Z<{87CU@UU9jo8)gj?WaZHsT@11-0c)R=CU0nNG zZk0^1pXncG$5LrIbFD_~gShH==K1dSB{qAOl$d^UjB_iNaxHoG-P)AHjy=bMS;pn# z{HEdw;`L59=Q+u5_2sRr(y2A~GxPsvT*dq85ufE$quZcXiCO-}Zf*!u8PS zFD?HUmEOvqDZt^ReLG`^r=WMw>nw+Bo%eTL=Vw**E}A0i;xw<>)2B6RjrO6>Y)5i8 z@784d7kBh!#*qY})!M%6R!jW4mOGV~gN14PYCbFepw7EF_q<9)=j?p@MOS3Ty9-r4 z*RLs@e{c7ESJ$)~*>7J9bhv5W{JZtYizz;u_6F~^@@;FVSg`H7r|LGI>C&-pR|tqS z2KB3&bz4ZsicZv-EU{FuJ!qNsv^5G>ew}@OIrT_n&wNXt@K(mD&+b0aeIB**Zh(RY z-`dL8%{k_;kES+fty%r}`+Mmu@$&mYv4uO1-1@pUY0}H;*=1Wf#9n`2d;Q+!1i_P9 za~U7*T9j<#7kg>Dch`>;x0QdVESXnR_FMAgtQ!jz&1Cb#UrHF1%sqD2SJ>M9?y4Jx z3~Fz+Wba4pKBeN;eqt4e_i<^%?C?OPlrtq$J$OEEoNc;s(t+zS>q|D3U48u4tM~HW z>qkz_+K{pPu6nu+yY1&F>&)kyZSE4!rIRky>U{^I5v+n7F0dZ}em`1VtK z@tn6_;&a()yM= zTzPPENcgmsht8WAPWDxIJ-gdoF+SL0)2jH0;1!0Qfri;!DTl6k|8d{AZeNJ}x7)UR z5?-qw{`39qRTY`Nl@)up{hg|It?Yi^;g8+F74)aa*i==2-}Lipsov*Pwe?TzcW}Tn eT&K$?{||gSQq;1``WpK{WrnA#pUXO@geCxP92DjN diff --git a/app/src/main/res/drawable-xxhdpi-v4/ic_forceclose12.png b/app/src/main/res/drawable-xxhdpi-v4/ic_forceclose12.png index 0573f9359494a9fb3d5d4edd723caa3857114ec0..b881c0e20b38f719f990f4d52e02b425a846b875 100644 GIT binary patch literal 1557 zcmeAS@N?(olHy`uVBq!ia0vp^t{}|83?#LKZ%Z>UFg67Egn$J9kAi^5`N~zR*Q{N)e#6F1o40J;wtdIWUAy<} z-M9b1!9$0S96fgYWe&gotyAK{ddVF}R-!BFR<|Cdijv*Dd z-cB!_e%nCcNNAdxSJ9gtXU_Pfcy9_z(?0HE`D}gM>8Db`%YK&M``x*9^NaoeUT1Il z{pTxtzjt<^;@Y(~wFPhAeA`j@?_GBDp?V`r6*@YpWM z^Z)(p%uJ11IbKD-1!_0j4{*gQ+;cEZ?!LaVSuf3D?!3hsf$g#GdR-lXskyHN!;do` zvMgioTP!j)OOEZqjrFUugA|UxV)8z5gLBF%ule2<1$(pIV&^_tZ)bLSCFAjfS3IXI zT&CD)Ib+uhzo@TTrBN@`uK)RItP#96x$&4}b?oe*N6U<2tIzI`)0yLJnKk#tmByJ> z1}l#!On&I|U}}V2f6>x2UDu29vx2YQ@F|hgOMiJNYs&gpKE98OxL?b@5H7vKeCB8N z#-fckcH5ghP3BwBd6Dbaf@g*c8Lu}V^?nTuxv*EJJUkuuW1ZfIy!+V6q91#wfh+6m z#ghtmq!s!!_BL}&XSja%=V|G{#I@FDY8)rT-^q2xt$HoMAaf@6PK(rqs?rn78G54p zSQmC>2eKWRy=Q}@>5{K+@9L#~Vm4SE8vIZFinOJ=VsBy;Q}nrG8)B{-MRdHjj};L5 zFYerz>t6iIO85H{ZG*n#hAA#rRi3OiSUc^g!lbwJ?=|cT%I@3s&ARJ$-@dtrew=R3 z-dE|GFhl>_nxEJ1vZfuFJU4sa*CmpNzid2WQuA6y>v_Vib&?l5KIVis&)}7PAI}gj zq8EOQ!8rH+tG2YFoFnS_@yU`4Hzj*29p6^Dfbq<($EA(Q_RKSm6!R}w|6{3BM~LSR zp~EKkZ$=AjiduX9%Xa%Tj>`6zUpWnqb>_a;cbh0`@N2KT*8GsOfeRT6)>+3X`h;Ga zyJFIo<64{zt+Dy>j3@5=UbUp1+0A7=F(8ro?v(1sA7U*h>{@@) z_T`+M{@JHOBHl_C+fzqrv0&fvr^=zo@Acksk2F0dEb|6p(g9)t4?Zq%zZhj zI{DSJ*Kac?1U=vFVm5EuiEArLBM(b1{!kJfWwoWVXV1X`_bRIpH`a*~K5{vpKC71H zx_EAlKk2pVs-tCM0?U1`12PMzwFInRu4`>t{$)o<(uO)++k@C!1sanIoC>gTe~DWM4fl^ebB literal 1499 zcmeAS@N?(olHy`uVBq!ia0vp^t{}|83?#LKZ%Z>UFvbV?gn$G`0qsJ-V_Ba$(Dc%h zAirP+MkZz!RyKAHP8(Z0M<-`jHxEy*fWV;OkkGL3h{&kunAo`Zgv6wj)U=Guteo7u z{KC5WhQ_9j&aUpB-oE|`6DLicI(^2>S+nQNoi~5M!bOXhEM2yI#mZHy*Q{N?VdJLF zTefc7zGLUE-Fx=#+kfETp~FXy9Y1k{HTgLM1M@ad7srr_TW_bgp1W-z;ub4oJauPs zT3W^#z8jg}jSqL+i!Zi`n`QP^qAw!c>esrP5A6R-w$ELzcX!WZ|K^A#-R1dlHrsS# zEJ_~>KGT@qseJOuL0c4y9dq+l_`Tyfv8g9! zuUyXVF>ABjBCF3X(qB^dzh?1OthbAroTvAzqws~FJd@y)U2<147er+(b%+mIo60Kb z{O(brfM?+)*Exl&w_o%5vRXYlJGQ$}CA`0hamuql4wpY(|HT`-Xz#mnmhDeIKTc4% z>dI-E92LwjF1`9L-_vPTg-kpPcU{`7AsVo@#iUo1leK!uy*Vt-nJ=y!yipP^9WQ#V zru%hS+;+n6lbZF8!*V~FA)j79QUdi6&IHnL>CUb}<>Z$x)gSNvaswF(ly8WpK zXDqoj?<`MWH1qwug?|p-yD~#I)YqL&N$!nTulcTZlCjK7|J>^{G>O#xX>xgrQcZbv z))$pamD^v%giA;t`d+T$?i2KX19QdVgU#nOnzwAuR`FeCt8ah1w@+5WvgpUWCm!m} zRpmxIcKWL~U)%9c&ft)y>RHXFEAA{0_R3zN`Zm^3wewh!_)Ou==_+oYBNip>ny6cL zeDjuTQ+D3G;>1|9WXA%XyTaRJ^2=>HcY1yZH}}l-RD3ITVXEP*RrZ0hx{VK`bGNR3 z+Y@=|wxv%{^t)NoVd|Ve!$m|6-q?|J+@N!d#ZuY&rMJ|dRc${!<6P$E##x_YF6`NG zC2R5jwUT!ph9op@clYiJ)-y^L`pT6xYht=gr~B6xqm?g Nl&7no%Q~loCIE568qoj% From 2cd4f21effefd6107f0f1580f3007685c5b4dfbe Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 3 Jan 2023 16:59:44 +0800 Subject: [PATCH 234/627] fix(miui13): clean share sheet --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 3f7092c5..6965d515 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -3265,7 +3265,7 @@ protected void after(MethodHookParam param) throws Throwable { } }; - String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService"; + String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService$ComputerEngine"; Helpers.hookAllMethods(ActQueryService, lpparam.classLoader, "queryIntentActivitiesInternal", hook); } @@ -3427,7 +3427,7 @@ protected void after(MethodHookParam param) throws Throwable { } }; - String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService"; + String ActQueryService = Helpers.isTPlus() ? "com.android.server.pm.ComputerEngine" : "com.android.server.pm.PackageManagerService$ComputerEngine"; Helpers.hookAllMethods(ActQueryService, lpparam.classLoader, "queryIntentActivitiesInternal", hook); } From 82fd33547604e44b797cf6df9b3cb858845acecc Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 3 Jan 2023 23:11:14 +0800 Subject: [PATCH 235/627] feat: open notification in float window --- .../mikanoshi/customiuizer/MainModule.java | 1 - .../mikanoshi/customiuizer/mods/System.java | 156 ++++++++++-------- app/src/main/res/drawable/ic_openinfw.xml | 4 + .../miui_notification_menu_ic_bg_active.xml | 4 + .../miui_notification_menu_ic_bg_inactive.xml | 4 + app/src/main/res/values-440dpi/dimens.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 3 +- app/src/main/res/values/dimens.xml | 2 + app/src/main/res/values/strings.xml | 3 +- 9 files changed, 105 insertions(+), 74 deletions(-) create mode 100644 app/src/main/res/drawable/ic_openinfw.xml create mode 100644 app/src/main/res/drawable/miui_notification_menu_ic_bg_active.xml create mode 100644 app/src/main/res/drawable/miui_notification_menu_ic_bg_inactive.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index daee1d62..d9b68bc7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -201,7 +201,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); - if (mPrefs.getBoolean("system_notifrowmenu")) System.NotificationRowMenuRes(); if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); if (mPrefs.getStringAsInt("system_networkindicator", 1) == 3) System.NetworkIndicatorRes(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 6965d515..5e020f87 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -21,6 +21,7 @@ import android.app.MiuiNotification; import android.app.Notification; import android.app.NotificationChannel; +import android.app.PendingIntent; import android.app.TaskStackBuilder; import android.app.WallpaperColors; import android.app.WallpaperManager; @@ -2356,99 +2357,112 @@ protected void after(final MethodHookParam param) throws Throwable { Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.notification.MiuiNotificationCompat", lpparam.classLoader, "isKeptOnKeyguard", Notification.class, XC_MethodReplacement.returnConstant(true)); } - private static int appInfoIconResId; - private static int appInfoDescId; - private static int forceCloseIconResId; - private static int forceCloseDescId; - public static void NotificationRowMenuRes() { - appInfoIconResId = MainModule.resHooks.addResource("ic_appinfo", R.drawable.ic_appinfo12); - forceCloseIconResId = MainModule.resHooks.addResource("ic_forceclose", R.drawable.ic_forceclose12); - appInfoDescId = MainModule.resHooks.addResource("miui_notification_menu_appinfo_title", R.string.system_notifrowmenu_appinfo); - forceCloseDescId = MainModule.resHooks.addResource("miui_notification_menu_forceclose_title", R.string.system_notifrowmenu_forceclose); - MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "notification_menu_icon_padding", 0); - } - public static void NotificationRowMenuHook(LoadPackageParam lpparam) { - MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "miui_notification_modal_menu_margin_left_right", 8); + int appInfoIconResId = MainModule.resHooks.addResource("ic_appinfo", R.drawable.ic_appinfo12); + int forceCloseIconResId = MainModule.resHooks.addResource("ic_forceclose", R.drawable.ic_forceclose12); + int openInFwIconResId = MainModule.resHooks.addResource("ic_openinfw", R.drawable.ic_openinfw); + int appInfoDescId = MainModule.resHooks.addResource("miui_notification_menu_appinfo_title", R.string.system_notifrowmenu_appinfo); + int forceCloseDescId = MainModule.resHooks.addResource("miui_notification_menu_forceclose_title", R.string.system_notifrowmenu_forceclose); + int openInFwDescId = MainModule.resHooks.addResource("miui_notification_menu_openinfw_title", R.string.system_notifrowmenu_openinfw); + MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "notification_menu_icon_padding", 0); + MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "miui_notification_modal_menu_margin_left_right", 3); + MainModule.resHooks.setResReplacement("com.android.systemui", "drawable", "miui_notification_menu_ic_bg_active", R.drawable.miui_notification_menu_ic_bg_active); + MainModule.resHooks.setResReplacement("com.android.systemui", "drawable", "miui_notification_menu_ic_bg_inactive", R.drawable.miui_notification_menu_ic_bg_inactive); + Class MiuiNotificationMenuItem = findClass("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow.MiuiNotificationMenuItem", lpparam.classLoader); Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow", lpparam.classLoader, "createMenuViews", boolean.class, boolean.class, new MethodHook() { @Override @SuppressWarnings("unchecked") protected void after(final MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); ArrayList mMenuItems = (ArrayList)XposedHelpers.getObjectField(param.thisObject, "mMenuItems"); - Class nmiCls = findClass("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow.MiuiNotificationMenuItem", lpparam.classLoader); + Object infoBtn = null; Object forceCloseBtn = null; - Constructor MenuItem = nmiCls.getConstructors()[0]; + Object openFwBtn = null; + Constructor MenuItem = MiuiNotificationMenuItem.getConstructors()[0]; try { infoBtn = MenuItem.newInstance(param.thisObject, mContext, appInfoDescId, null, appInfoIconResId); forceCloseBtn = MenuItem.newInstance(param.thisObject, mContext, forceCloseDescId, null, forceCloseIconResId); + openFwBtn = MenuItem.newInstance(param.thisObject, mContext, openInFwDescId, null, openInFwIconResId); } catch (Throwable t1) { - XposedBridge.log(t1); + Helpers.log(t1); } - if (infoBtn == null || forceCloseBtn == null) return; + if (infoBtn == null || forceCloseBtn == null || openFwBtn == null) return; Object notification = XposedHelpers.getObjectField(param.thisObject, "mSbn"); - String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); - int menuMargin = (int) XposedHelpers.getObjectField(param.thisObject, "mMenuMargin"); + Object expandNotifyRow = XposedHelpers.getObjectField(param.thisObject, "mParent"); mMenuItems.add(infoBtn); mMenuItems.add(forceCloseBtn); + mMenuItems.add(openFwBtn); XposedHelpers.setObjectField(param.thisObject, "mMenuItems", mMenuItems); + int menuMargin = (int) XposedHelpers.getObjectField(param.thisObject, "mMenuMargin"); LinearLayout mMenuContainer = (LinearLayout)XposedHelpers.getObjectField(param.thisObject, "mMenuContainer"); - if (mMenuContainer != null) { - View mInfoBtn = (View) XposedHelpers.callMethod(infoBtn, "getMenuView"); - View mForceCloseBtn = (View) XposedHelpers.callMethod(forceCloseBtn, "getMenuView"); + View mInfoBtn = (View) XposedHelpers.callMethod(infoBtn, "getMenuView"); + View mForceCloseBtn = (View) XposedHelpers.callMethod(forceCloseBtn, "getMenuView"); + View mOpenFwBtn = (View) XposedHelpers.callMethod(openFwBtn, "getMenuView"); - View.OnClickListener itemClick = new View.OnClickListener() { - @Override - public void onClick(View view) { - if (view == null) return; - int uid = (int)XposedHelpers.callMethod(notification, "getAppUid"); - int user = 0; - try { - user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); - } catch (Throwable t) { - XposedBridge.log(t); - } + View.OnClickListener itemClick = new View.OnClickListener() { + @Override + public void onClick(View view) { + if (view == null) return; + String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); + int uid = (int)XposedHelpers.callMethod(notification, "getAppUid"); + int user = 0; + try { + user = (int)XposedHelpers.callStaticMethod(UserHandle.class, "getUserId", uid); + } catch (Throwable t) { + Helpers.log(t); + } - if (view == mInfoBtn) { - Helpers.openAppInfo(mContext, pkgName, user); - mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - } else if (view == mForceCloseBtn) { - ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); - if (user != 0) - XposedHelpers.callMethod(am, "forceStopPackageAsUser", pkgName, user); - else - XposedHelpers.callMethod(am, "forceStopPackage", pkgName); - try { - CharSequence appName = mContext.getPackageManager().getApplicationLabel(mContext.getPackageManager().getApplicationInfo(pkgName, 0)); - Toast.makeText(mContext, Helpers.getModuleRes(mContext).getString(R.string.force_closed, appName), Toast.LENGTH_SHORT).show(); - } catch (Throwable ignore) {} - } + if (view == mInfoBtn) { + Helpers.openAppInfo(mContext, pkgName, user); + mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + } else if (view == mForceCloseBtn) { + ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); + if (user != 0) + XposedHelpers.callMethod(am, "forceStopPackageAsUser", pkgName, user); + else + XposedHelpers.callMethod(am, "forceStopPackage", pkgName); + try { + CharSequence appName = mContext.getPackageManager().getApplicationLabel(mContext.getPackageManager().getApplicationInfo(pkgName, 0)); + Toast.makeText(mContext, Helpers.getModuleRes(mContext).getString(R.string.force_closed, appName), Toast.LENGTH_SHORT).show(); + } catch (Throwable ignore) {} } - }; - mInfoBtn.setOnClickListener(itemClick); - mForceCloseBtn.setOnClickListener(itemClick); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(-2, -2); - layoutParams.leftMargin = menuMargin; - layoutParams.rightMargin = menuMargin; - XposedHelpers.callMethod(mMenuContainer, "addView", mInfoBtn, layoutParams); - XposedHelpers.callMethod(mMenuContainer, "addView", mForceCloseBtn, layoutParams); - int size = mMenuItems.size(); - int dimensionPixelOffset = mContext.getResources().getDimensionPixelSize(mContext.getResources().getIdentifier("notification_panel_width", "dimen", lpparam.packageName)); - if (dimensionPixelOffset <= 0) { - dimensionPixelOffset = mContext.getResources().getDisplayMetrics().widthPixels; - } - int menuWidth = (dimensionPixelOffset / size) - (menuMargin * 2); - int titleId = mContext.getResources().getIdentifier("modal_menu_title", "id", lpparam.packageName); - mMenuItems.forEach(new Consumer() { - @Override - public void accept(Object obj) { - View menuView = (View) XposedHelpers.callMethod(obj, "getMenuView"); - ((TextView) menuView.findViewById(titleId)).setMaxWidth(menuWidth); + else if (view == mOpenFwBtn) { + Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); + Object AppMiniWindowManager = XposedHelpers.callStaticMethod(Dependency, "get", findClassIfExists("com.android.systemui.statusbar.notification.policy.AppMiniWindowManager", lpparam.classLoader)); + String miniWindowPkg = (String) XposedHelpers.callMethod(expandNotifyRow, "getMiniWindowTargetPkg"); + PendingIntent notifyIntent = (PendingIntent) XposedHelpers.callMethod(expandNotifyRow, "getPendingIntent"); + String ModalControllerForDep = "com.android.systemui.statusbar.notification.modal.ModalController"; + Object ModalController = XposedHelpers.callStaticMethod(Dependency, "get", findClass(ModalControllerForDep, lpparam.classLoader)); + XposedHelpers.callMethod(ModalController, "animExitModelCollapsePanels"); + XposedHelpers.callMethod(AppMiniWindowManager, "launchMiniWindowActivity", miniWindowPkg, notifyIntent); +// mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); } - }); - } + } + }; + mInfoBtn.setOnClickListener(itemClick); + mForceCloseBtn.setOnClickListener(itemClick); + mOpenFwBtn.setOnClickListener(itemClick); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(-2, -2); + layoutParams.leftMargin = menuMargin; + layoutParams.rightMargin = menuMargin; + mMenuContainer.addView(mInfoBtn, layoutParams); + mMenuContainer.addView(mForceCloseBtn, layoutParams); + mMenuContainer.addView(mOpenFwBtn, layoutParams); + int menuWidth = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 52, + mContext.getResources().getDisplayMetrics() + ); + int titleId = mContext.getResources().getIdentifier("modal_menu_title", "id", lpparam.packageName); + mMenuItems.forEach(new Consumer() { + @Override + public void accept(Object obj) { + View menuView = (View) XposedHelpers.callMethod(obj, "getMenuView"); + ((TextView) menuView.findViewById(titleId)).setMaxWidth(menuWidth); + } + }); } }); } @@ -2857,7 +2871,9 @@ else if (param.method.getName().equals("startSettingsApp")) { intent.setComponent(name); if (user != 0) { try { - Object mStatusBar = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", mContext.getClassLoader()), "get", findClass("com.android.systemui.statusbar.phone.StatusBar", mContext.getClassLoader())); + Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); + String StatusbarClsForDep = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfaces" : "com.android.systemui.statusbar.phone.StatusBar"; + Object mStatusBar = XposedHelpers.callStaticMethod(Dependency, "get", findClass(StatusbarClsForDep, lpparam.classLoader)); XposedHelpers.callMethod(mStatusBar, "collapsePanels"); XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user)); } catch (Throwable t) { diff --git a/app/src/main/res/drawable/ic_openinfw.xml b/app/src/main/res/drawable/ic_openinfw.xml new file mode 100644 index 00000000..b98ec8fe --- /dev/null +++ b/app/src/main/res/drawable/ic_openinfw.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/miui_notification_menu_ic_bg_active.xml b/app/src/main/res/drawable/miui_notification_menu_ic_bg_active.xml new file mode 100644 index 00000000..0b0341fd --- /dev/null +++ b/app/src/main/res/drawable/miui_notification_menu_ic_bg_active.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/miui_notification_menu_ic_bg_inactive.xml b/app/src/main/res/drawable/miui_notification_menu_ic_bg_inactive.xml new file mode 100644 index 00000000..b7c993d0 --- /dev/null +++ b/app/src/main/res/drawable/miui_notification_menu_ic_bg_inactive.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/values-440dpi/dimens.xml b/app/src/main/res/values-440dpi/dimens.xml index b3276684..b7c242e4 100644 --- a/app/src/main/res/values-440dpi/dimens.xml +++ b/app/src/main/res/values-440dpi/dimens.xml @@ -1,5 +1,5 @@ 19.64dp - + 28.36dp diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e56c061c..0bb727f3 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -136,7 +136,7 @@ 百分比面板的上边距 停用亮度滑块 扩展通知菜单 - 从通知菜单打开应用信息并强制关闭应用(向左滑动通知将其打开) + 从通知菜单打开应用信息、强制关闭应用和浮窗打开(向左滑动通知将其打开) 禁用任何通知 同时允许禁用系统通知 展开通知 @@ -1081,6 +1081,7 @@ 上边距大小 不修改锁屏状态栏 应用信息 + 浮窗 强制关闭 重启系统界面 允许不受信任的触摸操作 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 0f8619b4..360d5253 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -23,6 +23,8 @@ @dimen/miui_volume_content_width_expanded 56dp 19.5dp + 26dp + 50dp 30dp 40.0dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2a40b90e..48b57646 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -150,8 +150,9 @@ Remove shadow and additional background from slider while changing brightness Deactivate brightness slider Extended notification menu - Open app info and force close app from notification menu (swipe notification to the left to open it) + Open app info, force close app and open in floating window from notification menu (swipe notification to the left to open it) App info + Floating window Force close Disable any notification Allow to disable system notifications too From 1705950774a4324f84765f88e9ec95fbbdeb1ca3 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 4 Jan 2023 11:31:07 +0800 Subject: [PATCH 236/627] fix: hide warning about low battery level again --- .../java/name/mikanoshi/customiuizer/MainModule.java | 7 +++---- .../java/name/mikanoshi/customiuizer/mods/System.java | 10 +++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index d9b68bc7..102988de 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -195,10 +195,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.AddFiveGTileHook(lpparam); } - if (mPrefs.getBoolean("system_hidelowbatwarn")) { - System.NoLowBatteryWarningHook(lpparam); - } - if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); @@ -399,6 +395,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("various_show_battery_temperature")) Various.ShowTempInBatteryHook(lpparam); if (mPrefs.getBoolean("various_enable_sc_ai_clipboard_location")) Various.UnlockClipboardAndLocationHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_privacy")) System.HideIconsPrivacyHook(lpparam); + if (mPrefs.getBoolean("system_hidelowbatwarn")) { + System.NoLowBatteryWarningHook(lpparam); + } } if (pkg.equals("com.miui.powerkeeper")) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 5e020f87..c39ece8a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6726,7 +6726,15 @@ public static void NoSafeVolumeWarningRes() { } public static void NoLowBatteryWarningHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.power.PowerNotificationWarnings", lpparam.classLoader, "showLowBatteryWarning", boolean.class, XC_MethodReplacement.DO_NOTHING); + MethodHook settingHook = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String key = (String)param.args[1]; + if ("low_battery_dialog_disabled".equals(key)) param.setResult(1); + } + }; + Helpers.hookAllMethods(Settings.System.class, "getIntForUser", settingHook); + Helpers.hookAllMethods(Settings.System.class, "getInt", settingHook); } public static void TempHideOverlaySystemUIHook(LoadPackageParam lpparam) { From 1f71424716f67cd44f7e9cd691bc323fb5cf4e0e Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 4 Jan 2023 13:11:46 +0800 Subject: [PATCH 237/627] remove third launcher warning in cn rom --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 1 - app/src/main/res/values-pl-rPL/strings.xml | 2 -- app/src/main/res/values-ru-rRU/strings.xml | 2 -- app/src/main/res/values-zh-rCN/strings.xml | 2 -- app/src/main/res/values-zh-rTW/strings.xml | 2 -- app/src/main/res/values/strings.xml | 2 -- app/src/main/res/xml/prefs_system.xml | 6 ------ 7 files changed, 17 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 102988de..c984b609 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -387,7 +387,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("various_appdetails")) Various.AppInfoHook(lpparam); if (mPrefs.getBoolean("various_disableapp")) Various.AppsDisableHook(lpparam); if (mPrefs.getBoolean("various_restrictapp")) Various.AppsRestrictHook(lpparam); - if (mPrefs.getBoolean("system_unblockthird")) System.UnblockThirdLaunchersHook(lpparam); if (mPrefs.getBoolean("system_applock_scramblepin")) System.ScrambleAppLockPINHook(lpparam); if (mPrefs.getStringAsInt("various_appsort", 0) > 0) Various.AppsDefaultSortHook(lpparam); if (mPrefs.getStringAsInt("various_skip", 0) > 0) Various.AppsDefaultSortHook(lpparam); diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index b24969e3..9495d4ae 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -349,8 +349,6 @@ Nie wyświetlaj ostrzeżenia, że obszar słuchawek jest zasłonięty Dowolna zmiana rozmiaru widżetu Usuń wszelkie ograniczenia rozmiaru widżetu - Odblokuj launcher - Usuń ograniczenia launcherów innych firm na chińskich ROMach Wyczyść menu udostępniania Usuń wybrane aplikacje z menu udostępniania Menu testowe diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 5c397248..e32f3673 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -576,8 +576,6 @@ Не показывать предупреждение о закрытой области динамика Свободный размер виджетов Убирает все ограничения на размер виджетов - Разблокировать ланчеры - Отключает ограничение на использование сторонних ланчеров на китайских прошивках Очистка меню \"Поделиться\" Скрыть выбранные приложения в списке отправки данных Проверка меню diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0bb727f3..d3ad49cb 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -344,8 +344,6 @@ 不显示耳机区域被覆盖的警告 解禁小部件调整 解除小部件大小的限制 - 解锁启动器 - 解除中国版ROM对第三方启动器的限制 清理共享菜单 从共享菜单移除所选应用 测试菜单 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f113e3de..f62438d8 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -891,8 +891,6 @@ 顯示時長始終大於 1 秒 修改 Toast 顯示時長 顯示時間修改 - 解除中國版ROM對第三方啟動器的限制 - 解鎖啟動器 請不要使用MIUI啟動器的最近應用列表。使用全屏手勢效果不好。 使用本地實現 通知 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 48b57646..5ccd3679 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -364,8 +364,6 @@ Do not display a warning that earphone area is covered Free widget resize Remove any widget size limitations - Unblock launchers - Remove restriction of 3rd party launchers on Chinese ROMs Clean share menu Remove selected apps from share menu Test menu diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 901642a2..c77d026b 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1397,12 +1397,6 @@ android:summary="@string/system_resizablewidgets_summ" android:defaultValue="false" /> - - Date: Wed, 4 Jan 2023 15:03:27 +0800 Subject: [PATCH 238/627] feat: disable wallpaper scale --- .../mikanoshi/customiuizer/MainModule.java | 2 +- .../mikanoshi/customiuizer/mods/System.java | 22 +++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 9 ++++---- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_launcher.xml | 5 +++++ app/src/main/res/xml/prefs_system.xml | 5 +++++ 6 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c984b609..6b8d3b5a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -238,7 +238,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_notifafterunlock")) System.ShowNotificationsAfterUnlockHook(lpparam); if (mPrefs.getBoolean("system_notifrowmenu")) System.NotificationRowMenuHook(lpparam); if (mPrefs.getBoolean("system_compactnotif")) System.CompactNotificationsHook(lpparam); -// if (mPrefs.getBoolean("system_removecleaner")) System.HideMemoryCleanHook(lpparam, false); if (mPrefs.getBoolean("system_removedismiss")) System.HideDismissViewHook(lpparam); if (mPrefs.getBoolean("controls_nonavbar")) Controls.HideNavBarHook(lpparam); if (mPrefs.getBoolean("controls_imebackalticon")) Controls.ImeBackAltIconHook(lpparam); @@ -521,6 +520,7 @@ private void handleLoadLauncher(final LoadPackageParam lpparam) { if (mPrefs.getInt("controls_fsg_width", 100) > 100) Controls.BackGestureAreaWidthHook(lpparam, false); if (mPrefs.getBoolean("controls_fsg_horiz")) Launcher.FSGesturesHook(lpparam); if (mPrefs.getBoolean("system_removecleaner")) System.HideMemoryCleanHook(lpparam, true); + if (mPrefs.getBoolean("system_recents_disable_wallpaperscale") || mPrefs.getBoolean("launcher_disable_wallpaperscale")) System.DisableLauncherWallpaperScale(lpparam); if (mPrefs.getBoolean("system_fw_sticky")) System.StickyFloatingWindowsLauncherHook(lpparam); if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); //if (mPrefs.getBoolean("launcher_fixstatusbarmode")) Launcher.FixStatusBarModeHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index c39ece8a..8504a352 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2720,6 +2720,28 @@ protected void after(MethodHookParam param) throws Throwable { }); } + public static void DisableLauncherWallpaperScale(LoadPackageParam lpparam) { + Class WallpaperZoomManagerKtClass = findClassIfExists("com.miui.home.launcher.wallpaper.WallpaperZoomManagerKt", lpparam.classLoader); + if (MainModule.mPrefs.getBoolean("launcher_disable_wallpaperscale")) { + XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); + return; + } + Helpers.hookAllMethods("com.miui.home.recents.OverviewState", lpparam.classLoader, "onStateEnabled", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (WallpaperZoomManagerKtClass != null) { + XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); + } + } + @Override + protected void after(MethodHookParam param) throws Throwable { + if (WallpaperZoomManagerKtClass != null) { + XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", true); + } + } + }); + } + public static void ExtendedPowerMenuHook(LoadPackageParam lpparam) { final boolean[] isListened = {false}; Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d3ad49cb..8eb309d9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -405,13 +405,14 @@ 状态栏 通知抽屉 通知 - 最近应用列表 - 使用本地实现 + 最近任务 + 使用原生实现 请不要使用MIUI启动器的最近应用列表。使用全屏手势效果不好。 移除清理按钮 + 禁用壁纸缩放 隐藏清理最近应用和内存的按钮 - 清空 - 使清洁器按钮结束所有正在运行中的任务 + 清空所有任务 + 使清理按钮结束所有正在运行中的任务 隐藏最近 隐藏最近任务列表中的所选应用 第一个快捷方式动作 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5ccd3679..845d7d64 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -435,6 +435,7 @@ Don\'t use recent apps list from MIUI Launcher. Works badly with full screen gestures. Remove cleaner button Hide button that clears recent apps and cleans memory + Disable wallpaper scale Clean all Make cleaner button kill all running tasks Hide from recents diff --git a/app/src/main/res/xml/prefs_launcher.xml b/app/src/main/res/xml/prefs_launcher.xml index 28385744..9b3df842 100644 --- a/app/src/main/res/xml/prefs_launcher.xml +++ b/app/src/main/res/xml/prefs_launcher.xml @@ -251,6 +251,11 @@ android:summary="@string/launcher_nounlockanim_summ" android:defaultValue="false" /> + + + + Date: Wed, 4 Jan 2023 18:42:16 +0800 Subject: [PATCH 239/627] fix(miui14): sticky floating window --- .../mikanoshi/customiuizer/mods/System.java | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 8504a352..b7b3041d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7378,7 +7378,7 @@ public static String getTaskPackageName(Object thisObject, int taskId) { } public static String getTaskPackageName(Object thisObject, int taskId, ActivityOptions options) { - return getTaskPackageName(thisObject, taskId, true, options); + return getTaskPackageName(thisObject, taskId, options != null, options); } public static String getTaskPackageName(Object thisObject, int taskId, boolean withOptions, ActivityOptions options) { @@ -7480,7 +7480,7 @@ protected void after(MethodHookParam param) throws Throwable { options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); param.setResult(options); } catch (Throwable t) { - XposedBridge.log(t); + Helpers.log(t); } } else if (windowingMode == 5 && !fwApps.containsKey(pkgName)) { @@ -7495,9 +7495,16 @@ else if (windowingMode == 5 && !fwApps.containsKey(pkgName)) { protected void after(MethodHookParam param) throws Throwable { Object safeOptions = param.args[3]; ActivityOptions options = (ActivityOptions)XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject); - int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); - String pkgName = getTaskPackageName(param.thisObject, (int)param.args[2], options); + if (Helpers.isTPlus()) { + if (options != null) { + Object windowToken = XposedHelpers.callMethod(options, "getLaunchRootTask"); + if (windowToken != null) return; + } + } + String pkgName = (String) XposedHelpers.getAdditionalInstanceField(param.thisObject, "startPackageName"); + XposedHelpers.removeAdditionalInstanceField(param.thisObject, "startPackageName"); if (fwBlackList.contains(pkgName)) return; + int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); if (windowingMode == 5 && pkgName != null) { fwApps.put(pkgName, new Pair(0f, null)); Context mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext"); @@ -7508,17 +7515,26 @@ protected void after(MethodHookParam param) throws Throwable { protected void before(MethodHookParam param) throws Throwable { Object safeOptions = param.args[3]; ActivityOptions options = (ActivityOptions)XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject); - int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); + if (Helpers.isTPlus()) { + if (options != null) { + Object windowToken = XposedHelpers.callMethod(options, "getLaunchRootTask"); + if (windowToken != null) return; + } + } String pkgName = getTaskPackageName(param.thisObject, (int)param.args[2], options); - if (fwBlackList.contains(pkgName)) return; - if (windowingMode != 5 && fwApps.containsKey(pkgName)) { - Context mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext"); - options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); - XposedHelpers.setObjectField(safeOptions, "mOriginalOptions", options); - param.args[3] = safeOptions; - Intent intent = new Intent(ACTION_PREFIX + "dismissRecentsWhenFreeWindowOpen"); - intent.putExtra("package", pkgName); - mContext.sendBroadcast(intent); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "startPackageName", pkgName); + if (!fwBlackList.contains(pkgName)) { + int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); + if (windowingMode != 5 && fwApps.containsKey(pkgName)) { + Object mService = XposedHelpers.getObjectField(param.thisObject, "mService"); + Context mContext = (Context)XposedHelpers.getObjectField(mService, "mContext"); + options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); + XposedHelpers.setObjectField(safeOptions, "mOriginalOptions", options); + param.args[3] = safeOptions; + Intent intent = new Intent(ACTION_PREFIX + "dismissRecentsWhenFreeWindowOpen"); + intent.putExtra("package", pkgName); + mContext.sendBroadcast(intent); + } } } }); From 8916d87f1e9a6d55cdb2702bebbb69990812ace6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 4 Jan 2023 20:41:02 +0800 Subject: [PATCH 240/627] fix: splitscreen --- .../mikanoshi/customiuizer/MainModule.java | 2 ++ .../mikanoshi/customiuizer/mods/System.java | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 6b8d3b5a..63b9e1b5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -195,6 +195,8 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.AddFiveGTileHook(lpparam); } + if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); + if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index b7b3041d..189f24b7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7684,8 +7684,8 @@ protected void after(MethodHookParam param) throws Throwable { } public static void MultiWindowPlusHook(LoadPackageParam lpparam) { - MainModule.resHooks.setResReplacement("android", "array", "miui_resize_black_list", R.array.miui_resize_black_list); - if (!lpparam.packageName.equals("android")) { + if (lpparam.packageName.equals("com.miui.home")) { + Helpers.findAndHookMethod("com.android.systemui.shared.recents.model.Task", lpparam.classLoader, "isSupportSplit", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethods("com.miui.home.recents.views.RecentMenuView", lpparam.classLoader, "onMessageEvent", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -7704,18 +7704,20 @@ public void run() { } }); } - else { + else if (lpparam.packageName.equals("android")) { + MainModule.resHooks.setResReplacement("android", "array", "miui_resize_black_list", R.array.miui_resize_black_list); Class AtmClass = XposedHelpers.findClassIfExists("com.android.server.wm.ActivityTaskManagerServiceImpl", lpparam.classLoader); if (AtmClass != null) { - Helpers.hookAllMethods(AtmClass, "inResizeBlackList", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.setResult(false); - } - }); - return; + Helpers.hookAllMethods(AtmClass, "inResizeBlackList", XC_MethodReplacement.returnConstant(false)); + Helpers.findAndHookMethod(AtmClass, "inResizeWhiteList", String.class, XC_MethodReplacement.returnConstant(true)); } } +// else { +// Class AtmClass = XposedHelpers.findClassIfExists("android.app.ActivityTaskManager", lpparam.classLoader); +// if (AtmClass != null) { +// Helpers.hookAllMethods(AtmClass, "supportsSplitScreen", XC_MethodReplacement.returnConstant(true)); +// } +// } } public static void SecureControlCenterHook(LoadPackageParam lpparam) { From dcb01276ef26706f10a14a3b36921e821637775b Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 4 Jan 2023 21:53:19 +0800 Subject: [PATCH 241/627] feat: hide clock in statusbar --- .../java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../java/name/mikanoshi/customiuizer/mods/System.java | 11 +++++++++++ app/src/main/res/xml/prefs_system_hideicons.xml | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 63b9e1b5..28f89841 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -288,6 +288,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_statusbarcontrols")) System.StatusBarGesturesHook(lpparam); if (mPrefs.getBoolean("system_nodrawerbackground")) System.RemoveDrawerBackgroundHook(lpparam); if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); + if (mPrefs.getBoolean("system_statusbaricons_clock")) System.HideIconsClockHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_low") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideLowNetworkSpeedHook(lpparam); if ( diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 189f24b7..129e3bbd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -4004,6 +4004,17 @@ protected void before(MethodHookParam param) throws Throwable { }); } + public static void HideIconsClockHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showClock", boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "hideClockInternal", 8, false); + XposedHelpers.callMethod(param.thisObject, "hideNetworkSpeedSplitter", 8, false); + param.setResult(null); + } + }); + } + public static void HideIconsVoWiFiHook(LoadPackageParam lpparam) { Helpers.findAndHookMethodSilently("com.android.systemui.MiuiOperatorCustomizedPolicy$MiuiOperatorConfig", lpparam.classLoader, "getHideVowifi", XC_MethodReplacement.returnConstant(true)); } diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index a2001736..f7a753dd 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -20,6 +20,11 @@ android:title="@string/system_statusbaricons_battery3_title" android:defaultValue="false" /> + + Date: Wed, 4 Jan 2023 22:13:19 +0800 Subject: [PATCH 242/627] feat: display temp and current of battery in single row --- .../name/mikanoshi/customiuizer/mods/System.java | 12 +++++++++--- app/src/main/res/values-zh-rCN/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 4 +++- app/src/main/res/xml/prefs_system.xml | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 129e3bbd..89ab981c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5106,7 +5106,7 @@ private static TextView createBatteryDetailView(Context mContext, LinearLayout.L batteryView.setTextAppearance(styleId); float fontSize = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_fontsize", 16) * 0.5f; int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); - if (opt == 1) { + if (opt == 1 && MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_singlerow")) { batteryView.setLineSpacing(0, fontSize > 8.5f ? 0.85f : 0.9f); batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); } @@ -5177,11 +5177,17 @@ public void run() { currVal = Math.abs(currVal); } int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); + String simpleTempVal = tempVal % 10 == 0 ? (tempVal / 10 + "") : (tempVal / 10f + ""); if (opt == 1) { - batteryInfo = tempVal / 10f + "℃" + "\n" + currVal + "mA"; + String splitChar = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_singlerow") + ? " " : "\n"; + batteryInfo = simpleTempVal + "℃" + splitChar + currVal + "mA"; + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_reverseorder")) { + batteryInfo = currVal + "mA" + splitChar + simpleTempVal + "℃"; + } } else if (opt == 2) { - batteryInfo = tempVal / 10f + "℃"; + batteryInfo = simpleTempVal + "℃"; } else { batteryInfo = currVal + "mA"; diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 8eb309d9..6db97cc5 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1062,6 +1062,8 @@ 显示电池温度和电流 显示内容 仅在充电时显示 + 单排显示 + 反序 仅温度 仅电流 右侧显示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 845d7d64..5cfb40e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1115,10 +1115,12 @@ Display battery temp and current - Display info + Display Content Display on the right Current value is always positive Show when charging only + Display in single row + Reverse order Dual SIM signal bars in dual rows Dual rows in status bar Need increase statusbar height on some devices diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 6f5c4c1c..fe1a68f8 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -462,6 +462,20 @@ miuizer:child="true" android:defaultValue="false" /> + + + + Date: Wed, 4 Jan 2023 22:35:54 +0800 Subject: [PATCH 243/627] feat: set horizontal padding for the first row of status bar --- .../mikanoshi/customiuizer/mods/System.java | 12 +++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 27 +++++++++++++++++++ 4 files changed, 41 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 89ab981c..c4aa5f7c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8807,6 +8807,12 @@ protected void after(MethodHookParam param) throws Throwable { switchUserView = sbView.findViewById(userViewId); ((ViewGroup) switchUserView.getParent()).removeView(switchUserView); } + int firstRowLeftPadding = 0; + int firstRowRightPadding = 0; + if (MainModule.mPrefs.getBoolean("system_statusbar_dualrows_firstrow_horizmargin")) { + firstRowLeftPadding = MainModule.mPrefs.getInt("system_statusbar_dualrows_firstrow_horizmargin_left", 0); + firstRowRightPadding = MainModule.mPrefs.getInt("system_statusbar_dualrows_firstrow_horizmargin_right", 0); + } LinearLayout statusBarcontents = (LinearLayout) rightContainer.getParent(); statusBarcontents.removeView(leftContainer); statusBarcontents.removeView(rightContainer); @@ -8814,11 +8820,17 @@ protected void after(MethodHookParam param) throws Throwable { statusBarcontents.addView(rightLayout); XposedHelpers.setObjectField(param.thisObject, "mSystemIconArea", rightLayout); leftLayout.addView(leftContainer); + if (firstRowLeftPadding > 0) { + leftContainer.setPaddingRelative(firstRowLeftPadding, 0, 0, 0); + } LinearLayout secondLeft = new LinearLayout(mContext); leftLayout.addView(secondLeft); LinearLayout firstRight = new LinearLayout(mContext); rightLayout.addView(firstRight); firstRight.setGravity(Gravity.END); + if (firstRowRightPadding > 0) { + firstRight.setPaddingRelative(0, 0, firstRowRightPadding, 0); + } LinearLayout secondRight = new LinearLayout(mContext); rightLayout.addView(secondRight); secondRight.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6db97cc5..3bb15cab 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1077,6 +1077,7 @@ 左侧间距 上下偏移量 加粗 + 第一排水平边距 状态栏水平边距 状态栏上边距 上边距大小 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5cfb40e9..20e8d9a2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1131,6 +1131,7 @@ Vertical offset Bold style Statusbar horizontal padding + First row horizontal padding Statusbar top padding Top padding Unset statusbar in Keyguard diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index fe1a68f8..a2822588 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -542,6 +542,33 @@ android:title="@string/system_statusbar_dualrows_title" android:summary="@string/system_statusbar_dualrows_summ" /> + + + + + + Date: Thu, 5 Jan 2023 13:26:14 +0800 Subject: [PATCH 244/627] fix: multiwindow --- .../mikanoshi/customiuizer/MainModule.java | 3 +- .../mikanoshi/customiuizer/mods/Launcher.java | 105 ++++++++++++++---- .../mikanoshi/customiuizer/mods/System.java | 27 +---- .../mikanoshi/customiuizer/subs/Launcher.java | 1 - app/src/main/res/values-pl-rPL/strings.xml | 2 - app/src/main/res/values-ru-rRU/strings.xml | 2 - app/src/main/res/values-zh-rCN/strings.xml | 2 - app/src/main/res/values-zh-rTW/strings.xml | 2 - app/src/main/res/values/strings.xml | 2 - 9 files changed, 86 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 28f89841..296d8fac 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -524,9 +524,8 @@ private void handleLoadLauncher(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("controls_fsg_horiz")) Launcher.FSGesturesHook(lpparam); if (mPrefs.getBoolean("system_removecleaner")) System.HideMemoryCleanHook(lpparam, true); if (mPrefs.getBoolean("system_recents_disable_wallpaperscale") || mPrefs.getBoolean("launcher_disable_wallpaperscale")) System.DisableLauncherWallpaperScale(lpparam); - if (mPrefs.getBoolean("system_fw_sticky")) System.StickyFloatingWindowsLauncherHook(lpparam); + if (mPrefs.getBoolean("system_fw_sticky")) Launcher.StickyFloatingWindowsLauncherHook(lpparam); if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); - //if (mPrefs.getBoolean("launcher_fixstatusbarmode")) Launcher.FixStatusBarModeHook(lpparam); if (mPrefs.getBoolean("launcher_fixanim")) Launcher.FixAnimHook(lpparam); if (mPrefs.getBoolean("launcher_hideseekpoints")) Launcher.HideSeekPointsHook(lpparam); if (mPrefs.getBoolean("launcher_privacyapps_gest") || diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 8fb8b93b..8ccdc0c1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1,12 +1,17 @@ package name.mikanoshi.customiuizer.mods; +import static name.mikanoshi.customiuizer.mods.GlobalActions.ACTION_PREFIX; + import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityOptions; import android.app.Application; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.database.Cursor; @@ -44,7 +49,9 @@ import android.widget.TextView; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; @@ -572,30 +579,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void FixStatusBarModeHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.miui.home.launcher.Launcher", lpparam.classLoader, "changeStatusBarMode", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Activity act = (Activity)param.thisObject; - boolean mDuringMinusOneStartActivityForResult = XposedHelpers.getBooleanField(act, "mDuringMinusOneStartActivityForResult"); - boolean isMinusScreenShowing = (boolean)XposedHelpers.callMethod(act, "isMinusScreenShowing"); - if (!mDuringMinusOneStartActivityForResult) { - if (isMinusScreenShowing) { - XposedHelpers.setBooleanField(act, "mNeedChangeStatusBarMode", true); - } else { - XposedHelpers.callStaticMethod(XposedHelpers.findClass("com.miui.launcher.utils.MiuiWindowManagerUtils", lpparam.classLoader), - "changeStatusBarMode", - act.getWindow(), - XposedHelpers.callStaticMethod(XposedHelpers.findClass("com.miui.home.launcher.WallpaperUtils", lpparam.classLoader), "hasLightBgForStatusBar") - ); - XposedHelpers.setBooleanField(act, "mNeedChangeStatusBarMode", false); - } - } - param.setResult(null); - } - }); - } - @SuppressWarnings({"FieldCanBeLocal", "FieldMayBeFinal"}) public static class DoubleTapController { private final long MAX_DURATION = 500; @@ -1528,6 +1511,80 @@ public final void onClick(View view) { }); } + public static void StickyFloatingWindowsLauncherHook(LoadPackageParam lpparam) { + final List fwBlackList = new ArrayList(); + fwBlackList.add("com.miui.securitycenter"); + fwBlackList.add("com.miui.home"); + fwBlackList.add("com.android.camera"); + Helpers.findAndHookMethod("com.miui.home.recents.views.RecentsContainer", lpparam.classLoader, "onAttachedToWindow", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getContext"); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + try { + String pkgName = intent.getStringExtra("package"); + if (pkgName != null) { + XposedHelpers.callMethod(param.thisObject, "dismissRecentsToLaunchTargetTaskOrHome", pkgName, true); + } + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }, new IntentFilter(ACTION_PREFIX + "dismissRecentsWhenFreeWindowOpen")); + } + }); + + Helpers.findAndHookMethod("com.miui.home.launcher.Launcher$PerformLaunchAction", lpparam.classLoader, "run", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Intent intent = (Intent) XposedHelpers.getObjectField(param.thisObject, "mIntent"); + if (intent != null) { + String pkgName = intent.getComponent().getPackageName(); + if (fwBlackList.contains(pkgName)) { + return; + } + Object launcher = XposedHelpers.getSurroundingThis(param.thisObject); + Object mAppTransitionManager = XposedHelpers.getObjectField(launcher, "mAppTransitionManager"); + String fwApps = (String) XposedHelpers.getAdditionalInstanceField(launcher, "fwApps"); + if (fwApps != null && fwApps.contains(pkgName)) { + XposedHelpers.setAdditionalInstanceField(mAppTransitionManager, "isFwApps", true); + } + } + } + + @Override + protected void after(MethodHookParam param) throws Throwable { + Object launcher = XposedHelpers.getSurroundingThis(param.thisObject); + Object mAppTransitionManager = XposedHelpers.getObjectField(launcher, "mAppTransitionManager"); + XposedHelpers.removeAdditionalInstanceField(mAppTransitionManager, "isFwApps"); + } + }); + + Helpers.findAndHookMethod("com.miui.home.launcher.Launcher", lpparam.classLoader, "launch", "com.miui.home.launcher.ShortcutInfo", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Activity act = (Activity) param.thisObject; + String fwApps = Settings.Global.getString(act.getContentResolver(), Helpers.modulePkg + ".fw.apps"); + if (fwApps == null) { + fwApps = ""; + } + XposedHelpers.setAdditionalInstanceField(param.thisObject, "fwApps", fwApps); + } + }); + + Helpers.findAndHookMethod("com.miui.home.recents.QuickstepAppTransitionManagerImpl", lpparam.classLoader, "hasControlRemoteAppTransitionPermission", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object isFwApps = XposedHelpers.getAdditionalInstanceField(param.thisObject, "isFwApps"); + if (isFwApps != null) { + param.setResult(false); + } + } + }); + } + public static void CloseDrawerOnLaunchHook(LoadPackageParam lpparam) { MethodHook hook = new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index c4aa5f7c..646beccf 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7366,6 +7366,7 @@ protected void before(MethodHookParam param) throws Throwable { public static void NoFloatingWindowBlacklistHook(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("android", "array", "freeform_black_list", R.array.miui_resize_black_list); + MainModule.resHooks.setResReplacement("com.miui.rom", "array", "freeform_black_list", R.array.miui_resize_black_list); MethodHook clearHook = new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -7655,28 +7656,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void StickyFloatingWindowsLauncherHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.miui.home.recents.views.RecentsContainer", lpparam.classLoader, "onAttachedToWindow", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getContext"); - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - try { - String pkgName = intent.getStringExtra("package"); - if (pkgName != null) { - XposedHelpers.callMethod(param.thisObject, "dismissRecentsToLaunchTargetTaskOrHome", pkgName, true); - } - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }, new IntentFilter(ACTION_PREFIX + "dismissRecentsWhenFreeWindowOpen")); - } - }); - } - public static void MessagingStyleLinesSysHook() { Helpers.findAndHookMethod("android.app.Notification.MessagingStyle", null, "makeMessagingView", boolean.class, boolean.class, new MethodHook() { @Override @@ -7723,10 +7702,12 @@ public void run() { } else if (lpparam.packageName.equals("android")) { MainModule.resHooks.setResReplacement("android", "array", "miui_resize_black_list", R.array.miui_resize_black_list); + MainModule.resHooks.setResReplacement("com.miui.rom", "array", "miui_resize_black_list", R.array.miui_resize_black_list); Class AtmClass = XposedHelpers.findClassIfExists("com.android.server.wm.ActivityTaskManagerServiceImpl", lpparam.classLoader); if (AtmClass != null) { + Helpers.findAndHookMethod(AtmClass, "updateResizeBlackList", Context.class, XC_MethodReplacement.DO_NOTHING); + Helpers.findAndHookMethod(AtmClass, "getSplitScreenBlackListFromXml", XC_MethodReplacement.DO_NOTHING); Helpers.hookAllMethods(AtmClass, "inResizeBlackList", XC_MethodReplacement.returnConstant(false)); - Helpers.findAndHookMethod(AtmClass, "inResizeWhiteList", String.class, XC_MethodReplacement.returnConstant(true)); } } // else { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java index a855e46d..00b98c86 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java @@ -103,7 +103,6 @@ public boolean onPreferenceClick(Preference preference) { findPreference("pref_key_launcher_renameapps_list").setOnPreferenceClickListener(openLaunchableList); break; case "pref_key_launcher_cat_bugfixes": - //findPreference("pref_key_launcher_fixstatusbarmode").setEnabled(opt == 1); findPreference("pref_key_launcher_fixanim").setEnabled(opt == 1); break; case "pref_key_launcher_cat_other": diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 9495d4ae..2f6aeff7 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -530,8 +530,6 @@ Liczba kolumn w folderach Użyj całej szerokości folderu Zmniejsz boczną wyściółkę - Napraw tryb paska stanu - Dostosuj kolor zawartości paska stanu dla jasnych/ciemnych tapet w wersji dla programistów Napraw animację Zastosuj skalowanie czasu trwania animatorów wartości do niektórych animacji launchera Napraw informacje o aplikacji diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index e32f3673..f4258ab4 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -502,8 +502,6 @@ Число колонок в папках Использовать всю ширину папки Уменьшить боковые отступы - Исправить режим строки состояния - Изменяет цвет содержимого строки состояния в зависимости от светлых/тёмных обоев на версии ланчера для разработчиков Исправить анимацию Применяет масштабирование продолжительности аниматоров значений к некоторым анимациям ланчера Исправить данные о приложении diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 3bb15cab..0420f9c7 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -513,8 +513,6 @@ 文件夹排列数量 使用整个文件夹的宽度 减少边距 - 修复状态栏模式 - 调整开发版启动器上浅色/深色壁纸的状态栏内容颜色 修复动画 将动画值时长比例应用到某些启动器动画 修复应用信息 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f62438d8..1efcb59c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -316,8 +316,6 @@ 修復動畫 長按功能表始終開啟MIUI樣式應用訊息 修復應用訊息 - 調整開發版啟動器上淺色/深色壁紙的狀態欄內容顏色 - 修復狀態欄模式 資料夾排列數量 背景模糊 可見度 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 20e8d9a2..1e1488dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -547,8 +547,6 @@ Number of columns in folders Use entire folder\'s width Reduce side padding - Fix status bar mode - Adjust status bar contents color for light/dark wallpapers on developer launcher version Fix animation Apply value animators\' duration scaling to some launcher animations Fix app info From bdc2ceebb959bd325ccc2a920c23c3917185b9cc Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 5 Jan 2023 13:45:21 +0800 Subject: [PATCH 245/627] feat: hide statusbar in recents view --- .../mikanoshi/customiuizer/MainModule.java | 3 +- .../mikanoshi/customiuizer/mods/Launcher.java | 28 +++++++++++++++++++ .../mikanoshi/customiuizer/mods/System.java | 22 --------------- app/src/main/res/xml/prefs_system.xml | 5 ++++ 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 296d8fac..8642da36 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -523,8 +523,9 @@ private void handleLoadLauncher(final LoadPackageParam lpparam) { if (mPrefs.getInt("controls_fsg_width", 100) > 100) Controls.BackGestureAreaWidthHook(lpparam, false); if (mPrefs.getBoolean("controls_fsg_horiz")) Launcher.FSGesturesHook(lpparam); if (mPrefs.getBoolean("system_removecleaner")) System.HideMemoryCleanHook(lpparam, true); - if (mPrefs.getBoolean("system_recents_disable_wallpaperscale") || mPrefs.getBoolean("launcher_disable_wallpaperscale")) System.DisableLauncherWallpaperScale(lpparam); + if (mPrefs.getBoolean("system_recents_disable_wallpaperscale") || mPrefs.getBoolean("launcher_disable_wallpaperscale")) Launcher.DisableLauncherWallpaperScale(lpparam); if (mPrefs.getBoolean("system_fw_sticky")) Launcher.StickyFloatingWindowsLauncherHook(lpparam); + if (mPrefs.getBoolean("system_recents_hide_statusbar")) Launcher.HideStatusBarInRecentsHook(lpparam); if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); if (mPrefs.getBoolean("launcher_fixanim")) Launcher.FixAnimHook(lpparam); if (mPrefs.getBoolean("launcher_hideseekpoints")) Launcher.HideSeekPointsHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 8ccdc0c1..9d4a22a0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1,5 +1,6 @@ package name.mikanoshi.customiuizer.mods; +import static de.robv.android.xposed.XposedHelpers.findClassIfExists; import static name.mikanoshi.customiuizer.mods.GlobalActions.ACTION_PREFIX; import android.annotation.SuppressLint; @@ -1596,6 +1597,33 @@ protected void before(final MethodHookParam param) throws Throwable { Helpers.findAndHookMethod("com.miui.home.launcher.allapps.category.fragment.RecommendCategoryAppListFragment", lpparam.classLoader, "onClick", View.class, hook); } + public static void DisableLauncherWallpaperScale(LoadPackageParam lpparam) { + Class WallpaperZoomManagerKtClass = findClassIfExists("com.miui.home.launcher.wallpaper.WallpaperZoomManagerKt", lpparam.classLoader); + if (MainModule.mPrefs.getBoolean("launcher_disable_wallpaperscale")) { + XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); + return; + } + Helpers.hookAllMethods("com.miui.home.recents.OverviewState", lpparam.classLoader, "onStateEnabled", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (WallpaperZoomManagerKtClass != null) { + XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); + } + } + @Override + protected void after(MethodHookParam param) throws Throwable { + if (WallpaperZoomManagerKtClass != null) { + XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", true); + } + } + }); + } + + public static void HideStatusBarInRecentsHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.miui.home.launcher.common.DeviceLevelUtils", lpparam.classLoader, "isHideStatusBarWhenEnterRecents", XC_MethodReplacement.returnConstant(true)); + Helpers.findAndHookMethod("com.miui.home.launcher.DeviceConfig", lpparam.classLoader, "keepStatusBarShowingForBetterPerformance", XC_MethodReplacement.returnConstant(false)); + } + public static void LauncherPinchHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.miui.home.launcher.Launcher", lpparam.classLoader, "onCreate", Bundle.class, new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 646beccf..bce1692b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2720,28 +2720,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void DisableLauncherWallpaperScale(LoadPackageParam lpparam) { - Class WallpaperZoomManagerKtClass = findClassIfExists("com.miui.home.launcher.wallpaper.WallpaperZoomManagerKt", lpparam.classLoader); - if (MainModule.mPrefs.getBoolean("launcher_disable_wallpaperscale")) { - XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); - return; - } - Helpers.hookAllMethods("com.miui.home.recents.OverviewState", lpparam.classLoader, "onStateEnabled", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (WallpaperZoomManagerKtClass != null) { - XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); - } - } - @Override - protected void after(MethodHookParam param) throws Throwable { - if (WallpaperZoomManagerKtClass != null) { - XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", true); - } - } - }); - } - public static void ExtendedPowerMenuHook(LoadPackageParam lpparam) { final boolean[] isListened = {false}; Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index a2822588..351fc395 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1061,6 +1061,11 @@ android:title="@string/system_recents_disable_wallpaperscale_title" android:defaultValue="false" /> + + Date: Thu, 5 Jan 2023 14:03:05 +0800 Subject: [PATCH 246/627] fix: sticky floating window --- .../mikanoshi/customiuizer/mods/Launcher.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 9d4a22a0..e1e803ad 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1584,6 +1584,21 @@ protected void before(MethodHookParam param) throws Throwable { } } }); + + Helpers.hookAllMethods("com.miui.home.recents.views.TaskView", lpparam.classLoader, "getActivityOptions", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String pkgName = (String) XposedHelpers.callMethod(param.thisObject, "getBasePackageName"); + if (fwBlackList.contains(pkgName)) { + return; + } + View taskView = (View) param.thisObject; + String fwApps = Settings.Global.getString(taskView.getContext().getContentResolver(), Helpers.modulePkg + ".fw.apps"); + if (fwApps != null && fwApps.contains(pkgName)) { + param.setResult(XposedHelpers.callMethod(param.thisObject, "getActivityLaunchOptions", taskView)); + } + } + }); } public static void CloseDrawerOnLaunchHook(LoadPackageParam lpparam) { From 20b4df74eefbdf35349aa4497311b73e75cc3d78 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 5 Jan 2023 18:05:42 +0800 Subject: [PATCH 247/627] disable launcher log and remove rare mods --- .../mikanoshi/customiuizer/MainModule.java | 12 +++-- .../mikanoshi/customiuizer/mods/Launcher.java | 12 +++++ .../mikanoshi/customiuizer/mods/System.java | 51 ------------------- app/src/main/res/values-pl-rPL/strings.xml | 6 --- app/src/main/res/values-ru-rRU/strings.xml | 8 +-- app/src/main/res/values-zh-rCN/strings.xml | 11 ++-- app/src/main/res/values-zh-rTW/strings.xml | 6 --- app/src/main/res/values/strings.xml | 9 +--- app/src/main/res/xml/prefs_launcher.xml | 9 +++- app/src/main/res/xml/prefs_system.xml | 21 ++------ 10 files changed, 35 insertions(+), 110 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 8642da36..cd93018d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -275,18 +275,15 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_statusbar_horizmargin")) System.HorizMarginHook(lpparam); if (mPrefs.getBoolean("system_statusbar_topmargin")) System.TopMarginHook(lpparam); if (mPrefs.getBoolean("system_showpct")) System.BrightnessPctHook(lpparam); - if (mPrefs.getBoolean("system_cleanmirror")) System.ClearBrightnessMirrorHook(lpparam); if (mPrefs.getBoolean("system_hidelsstatusbar")) System.HideLockScreenStatusBarHook(lpparam); if (mPrefs.getBoolean("system_hidelsclock")) System.HideLockScreenClockHook(lpparam); if (mPrefs.getBoolean("system_hidelshint")) System.HideLockScreenHintHook(lpparam); - if (mPrefs.getBoolean("system_drawer_hidebackground")) System.HideThemeBackgroundBrightnessHook(lpparam); if (mPrefs.getBoolean("system_allowdirectreply")) System.AllowDirectReplyHook(lpparam); if (mPrefs.getBoolean("system_allownotifonkeyguard")) System.AllowAllKeyguardHook(lpparam); if (mPrefs.getBoolean("system_allownotiffloat")) System.AllowAllFloatHook(lpparam); if (mPrefs.getBoolean("system_hideqs")) System.HideQSHook(lpparam); if (mPrefs.getBoolean("system_lsalarm")) System.LockScreenAlaramHook(lpparam); if (mPrefs.getBoolean("system_statusbarcontrols")) System.StatusBarGesturesHook(lpparam); - if (mPrefs.getBoolean("system_nodrawerbackground")) System.RemoveDrawerBackgroundHook(lpparam); if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_clock")) System.HideIconsClockHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); @@ -467,9 +464,14 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("launcher_topmargin", 0) > 0) Launcher.TopSpacingRes(); if (mPrefs.getInt("launcher_bottommargin", 0) > 0) Launcher.BottomSpacingRes(); if (mPrefs.getInt("launcher_indicatorheight", 9) > 9) Launcher.IndicatorHeightRes(); - if (mPrefs.getBoolean("launcher_unlockgrids")) Launcher.UnlockGridsRes(); + if (mPrefs.getBoolean("launcher_unlockgrids")) { + Launcher.UnlockGridsRes(); + Launcher.UnlockGridsHook(lpparam); + } if (mPrefs.getBoolean("launcher_docktitles")) Launcher.ShowHotseatTitlesRes(); - if (mPrefs.getBoolean("launcher_unlockgrids")) Launcher.UnlockGridsHook(lpparam); + if (mPrefs.getBoolean("launcher_disable_log")) { + Launcher.DisableLauncherLogHook(lpparam); + } if (isLauncherPerf) handleLoadLauncher(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index e1e803ad..3914f569 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1639,6 +1639,18 @@ public static void HideStatusBarInRecentsHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.miui.home.launcher.DeviceConfig", lpparam.classLoader, "keepStatusBarShowingForBetterPerformance", XC_MethodReplacement.returnConstant(false)); } + public static void DisableLauncherLogHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.miui.home.launcher.AnalyticalDataCollectorJobService", lpparam.classLoader, "onStartJob", XC_MethodReplacement.DO_NOTHING); + Helpers.findAndHookMethod("com.miui.home.launcher.AnalyticalDataCollector", lpparam.classLoader, "canTrackLaunchAppEvent", XC_MethodReplacement.returnConstant(false)); + Helpers.findAndHookMethod("com.miui.home.launcher.common.OneTrackInterfaceUtils", lpparam.classLoader, "init", Context.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "IS_ENABLE", false); + param.setResult(null); + } + }); + } + public static void LauncherPinchHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.miui.home.launcher.Launcher", lpparam.classLoader, "onCreate", Bundle.class, new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bce1692b..7f27ef2b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5545,28 +5545,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void HideThemeBackgroundBrightnessHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "showMirror", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object mNotificationPanel = XposedHelpers.getObjectField(param.thisObject, "mNotificationPanel"); - if (mNotificationPanel == null) return; - View mThemeBackgroundView = (View)XposedHelpers.getObjectField(mNotificationPanel, "mThemeBackgroundView"); - if (mThemeBackgroundView != null) mThemeBackgroundView.setVisibility(View.GONE); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "hideMirror", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mNotificationPanel = XposedHelpers.getObjectField(param.thisObject, "mNotificationPanel"); - if (mNotificationPanel == null) return; - View mThemeBackgroundView = (View)XposedHelpers.getObjectField(mNotificationPanel, "mThemeBackgroundView"); - if (mThemeBackgroundView != null) mThemeBackgroundView.setVisibility(View.VISIBLE); - } - }); - } - public static void DisableSystemIntegrityHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("android.util.apk.ApkSignatureVerifier", lpparam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class, XC_MethodReplacement.returnConstant(1)); } @@ -5835,24 +5813,6 @@ public void run() { }); } - public static void RemoveDrawerBackgroundHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "drawChild", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mStatusBarStateOrig", XposedHelpers.getIntField(param.thisObject, "mStatusBarState")); - XposedHelpers.setIntField(param.thisObject, "mStatusBarState", 0); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mKeyguardShowingOrig", XposedHelpers.getBooleanField(param.thisObject, "mKeyguardShowing")); - XposedHelpers.setBooleanField(param.thisObject, "mKeyguardShowing", false); - } - - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setIntField(param.thisObject, "mStatusBarState", (int)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mStatusBarStateOrig")); - XposedHelpers.setBooleanField(param.thisObject, "mKeyguardShowing", (boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mKeyguardShowingOrig")); - } - }); - } - public static void LockScreenTimeoutHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarWindowManager", lpparam.classLoader, "applyUserActivityTimeout", new MethodHook() { @Override @@ -8013,17 +7973,6 @@ protected void after(final MethodHookParam param) throws Throwable { Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarWifiView", lpparam.classLoader, "applyWifiState", hideWifiActivity); } - public static void ClearBrightnessMirrorHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "showMirror", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - View mBrightnessMirror = (View)XposedHelpers.getObjectField(param.thisObject, "mBrightnessMirror"); - mBrightnessMirror.setElevation(0); - mBrightnessMirror.setBackgroundColor(Color.TRANSPARENT); - } - }); - } - public static void SetLockscreenWallpaperHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.android.server.wallpaper.WallpaperManagerService", lpparam.classLoader, "setWallpaper", new MethodHook() { @Override diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 2f6aeff7..edfe127d 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -136,8 +136,6 @@ Pokaż procent jasności Wyświetl poziom jasności w procentach podczas przeciągania suwaka jasności Górny margines panelu procentowego - Spójny styl suwaka jasności - Usuń cień i dodatkowe tło z suwaka podczas zmiany jasności Dezaktywuj suwak jasności Rozszerzone menu powiadomień Otwórz informacje o aplikacji i wymuś zamknięcie aplikacji z menu powiadomień (przesuń powiadomienie w lewo, aby je otworzyć) @@ -309,8 +307,6 @@ Rozmycie tła Intensywność rozmycia tła w ostatnich aplikacjach Intensywność rozmycia tła w szufladzie powiadomień - Tymczasowo ukryj tematyczne tło - Ukryj tło podczas zmiany jasności Przezroczystość tematycznego tła Przezroczystość tematycznego tła w szufladzie powiadomień Ekran blokady @@ -393,8 +389,6 @@ Spraw, aby aplikacje innych firm mogły ustawiać tapetę ekranu blokady. Aplikacja Motywy musi być zainstalowana i mieć uprawnienia dostępu do pamięci masowej. Wyczyść widok trybu rozszerzonego Ukryj szybkie ustawienia i suwak jasności w rozszerzonym trybie powiadomień na ekranie blokady - Wyłącz kolorowe tło - Zmień tło z automatycznie generowanym kolorem z tapety na przezroczysty na ekranie blokady Dotknij, aby odblokować Rozpocznij odblokowywanie urządzenia, dotykając dolnego obszaru ekranu blokady Dotknij dwukrotnie, aby uśpić diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index f4258ab4..94aa1afa 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -680,7 +680,7 @@ Цвет при зарядке Уровень низкого заряда Тест - Анимировать полоску от 100% до 0% в режиме разрядки + Анимировать полоску от 100% до 0% в режиме разрядки Высота строки состояния Фоновый цвет строки состояния Делает одинаковыми цвета фона строки состояния и панели действий приложения, где это возможно @@ -755,8 +755,6 @@ Показывать процент яркости Отображает уровень яркости в процентах при изменении яркости слайдером Отступ панели процентов сверху - Неизменный стиль слайдера яркости - Убирает тень и дополнительный фон у слайдера при изменении яркости Отключить ползунок яркости Расширенное меню уведомления Добавляет новые действия в меню уведомления (открывается по свайпу влево) - открыть информацию о приложении и принудительно закрыть приложение @@ -873,8 +871,6 @@ Размытие фона Уровень размытия фона на экране последних приложений Уровень размытия фона в панели уведомлений - Временно скрывать фон из темы - Скрывать фон во время изменения яркости Прозрачность фона из темы Уровень прозрачности фона панели уведомлений из текущей темы Улучшенная блокировка @@ -976,8 +972,6 @@ Позволяет сторонним приложениям устанавливать обои для экрана блокировки. Приложение Темы должно быть установлено с разрешением на доступ к памяти устройства. Очистить вид развёрнутого режима Скрывает панель Быстрых Настроек и слайдер яркости в режиме развёрнутых уведомлений на экране блокировки - Отключить цветной фон - Изменяет фон со сгенерированным цветом, взятым из обоев, на прозрачный на экране блокировки Разблокировка нажатием Нажатие на нижнюю область экрана блокировки начинает разблокировку устройства Сон по двойному нажатию diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0420f9c7..e2fe54b2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -305,8 +305,6 @@ 背景模糊 最近应用的背景模糊度 通知抽屉的背景模糊度 - 临时隐藏主题背景 - 更改亮度时隐藏背景 主题背景不透明度 主题通知抽屉背景的不透明度 锁屏 @@ -381,10 +379,8 @@ 隐藏“上滑解锁”提示 移除紧急呼叫 锁屏时禁用紧急呼叫按钮 - 净化扩展模式视图 - 隐藏锁屏上展开通知模式中的快速设置和亮度滑块 - 禁用彩色背景 - 锁屏时将背景从壁纸随机生成的颜色更改为透明 + 净化展开模式视图 + 隐藏锁屏时展开通知抽屉中的快速设置和亮度滑块 点击解锁 点击屏幕底部锁屏区域解锁设备 双击熄屏 @@ -513,6 +509,7 @@ 文件夹排列数量 使用整个文件夹的宽度 减少边距 + 禁用日志和统计 修复动画 将动画值时长比例应用到某些启动器动画 修复应用信息 @@ -1022,8 +1019,6 @@ 此模块的激活范围已激活,可能会阻止某些模块正常运行。 网络活动指示器 配置移动数据和Wi-Fi流量指示器 - 一致的亮度滑块风格 - 更改亮度时移除滑块的阴影和附加背景 飞行模式配置 定义在飞行模式下允许的通信。不需要重启。 模块只能修改现有的系统设置,某些选项可能无效 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 1efcb59c..6f2aeacb 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -573,8 +573,6 @@ 電池電壓 耗電量 測試功能表 - 更改亮度時移除滑塊的陰影和附加背景 - 一致的亮度滑塊風格 選擇要隱藏的數據類型 從開啟方式功能表移除所選應用 選擇測試數據類型 @@ -613,8 +611,6 @@ 可以在新版本應用上安裝舊版本應用 允許降級 通知抽屜的背景模糊度 - 更改亮度時隱藏背景 - 臨時隱藏主題背景 主題通知抽屜背景的不透明度 主題背景不透明度 雙擊鎖屏上任意空白處關閉螢幕 @@ -725,8 +721,6 @@ 網路活動指示器 在黑暗模式中不反轉某些顏色 禁用強制黑暗模式 - 鎖屏時將背景從壁紙隨機生成的顏色更改為透明 - 禁用彩色背景 播放通知聲音時不降低目前播放音樂的音量 禁用閃避 連接或者斷開充電器時不亮屏 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e1488dc..b6fb7bda 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,7 +74,7 @@ Charging color Low charge level Test - Animate bar from 100% to 0% in discharging state + Animate bar from 100% to 0% in discharging state Status bar height Status bar background color Make status bar and app\'s action bar background colors the same where possible @@ -146,8 +146,6 @@ Show brightness percentage Display brightness level in percentages while dragging brightness slider Percentages panel\'s top margin - Consistent brightness slider style - Remove shadow and additional background from slider while changing brightness Deactivate brightness slider Extended notification menu Open app info, force close app and open in floating window from notification menu (swipe notification to the left to open it) @@ -322,8 +320,6 @@ Background blur Background blur intensity in recent apps Background blur intensity in notification drawer - Temporarily hide themed background - Hide background while brightness is being changed Themed background opacity Opacity of a themed notification drawer background Lock screen @@ -408,8 +404,6 @@ Make third-party apps be able to set lock screen wallpaper. Themes app must be installed and given storage access permission. Clean expanded mode view Hide Quick Settings and brightness slider in expanded notifications mode on lock screen - Disable colored background - Change background with autogenerated color from wallpaper to transparent one while on lock screen Tap to unlock Start device unlocking by tapping on bottom lock screen area Double tap to sleep @@ -547,6 +541,7 @@ Number of columns in folders Use entire folder\'s width Reduce side padding + Disable analytics Fix animation Apply value animators\' duration scaling to some launcher animations Fix app info diff --git a/app/src/main/res/xml/prefs_launcher.xml b/app/src/main/res/xml/prefs_launcher.xml index 9b3df842..068c38df 100644 --- a/app/src/main/res/xml/prefs_launcher.xml +++ b/app/src/main/res/xml/prefs_launcher.xml @@ -1,6 +1,6 @@ - @@ -195,6 +195,11 @@ + + @@ -177,6 +178,7 @@ android:defaultValue="0" miuizer:minValue="0" miuizer:maxValue="30000" + miuizer:child="true" miuizer:stepValue="500" miuizer:format="@string/format_d_ms" miuizer:offtext="@string/array_default" /> @@ -191,6 +193,7 @@ miuizer:stepValue="25" miuizer:displayDividerValue="100" miuizer:format="x%s" + app:isPreferenceVisible="false" miuizer:offtext="@string/array_default" /> - - - - - - Date: Thu, 5 Jan 2023 20:54:45 +0800 Subject: [PATCH 248/627] fix: networkspeed font size reset --- app/build.gradle | 4 +- .../mikanoshi/customiuizer/MainFragment.java | 11 ++--- .../mikanoshi/customiuizer/MainModule.java | 1 - .../mikanoshi/customiuizer/SubFragment.java | 22 ++++++---- .../mikanoshi/customiuizer/mods/Launcher.java | 3 +- .../customiuizer/subs/CategorySelector.java | 43 ++++++++++--------- .../mikanoshi/customiuizer/subs/System.java | 25 +++++++++-- app/src/main/res/xml/prefs_system.xml | 2 - 8 files changed, 65 insertions(+), 46 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4c644568..c66f547c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 - versionCode 49 - versionName "23.01.01" + versionCode 50 + versionName "23.01.05" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java index 66ce88e9..2b4f23cc 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java @@ -395,15 +395,12 @@ void findMod(String filter) { ((ModSearchAdapter)resultView.getAdapter()).getFilter().filter(filter); } - // PreferenceScreens management - private boolean openModCat(String cat) { - return openModCat(cat, null, null); - } - private boolean openModCat(String cat, String sub, String mod) { Bundle bundle = new Bundle(); bundle.putString("cat", cat); - bundle.putString("sub", sub); + if (sub != null) { + bundle.putString("sub", sub); + } bundle.putString("mod", mod); catSelector.setTargetFragment(this, 0); switch (cat) { @@ -437,7 +434,7 @@ private boolean openModCat(String cat, String sub, String mod) { public boolean onPreferenceTreeClick(Preference preference) { if (preference != null) { PreferenceCategory modsCat = findPreference("prefs_cat"); - if (modsCat.findPreference(preference.getKey()) != null && openModCat(preference.getKey())) { + if (modsCat.findPreference(preference.getKey()) != null && openModCat(preference.getKey(), null, null)) { return true; } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index cd93018d..2ae108c0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -304,7 +304,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_charginginfo")) System.ChargingInfoHook(lpparam); if (mPrefs.getBoolean("system_secureqs")) System.SecureQSTilesHook(lpparam); if (mPrefs.getBoolean("system_mutevisiblenotif")) System.MuteVisibleNotificationsHook(lpparam); -// if (mPrefs.getBoolean("launcher_nounlockanim")) System.NoUnlockAnimationHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery1")) System.HideIconsBattery1Hook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery3") || mPrefs.getBoolean("system_statusbaricons_battery2")) System.HideIconsBattery2Hook(lpparam); if (mPrefs.getStringAsInt("system_statusbaricons_wifistandard", 1) > 1) System.DisplayWifiStandardHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java index f7bc8f21..9ecf4df4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java @@ -31,8 +31,10 @@ public class SubFragment extends PreferenceFragmentBase { private int contentResId = 0; - public String titleId = ""; + public String settingTitle = ""; protected String sub; + protected Bundle catInfo = null; + protected boolean isStandalone = false; private float order = 100.0f; public boolean padded = true; Helpers.SettingsType settingsType = Helpers.SettingsType.Preference; @@ -43,9 +45,11 @@ public void onCreate(Bundle savedInstanceState) { settingsType = Helpers.SettingsType.values()[getArguments().getInt("settingsType")]; abType = Helpers.ActionBarType.values()[getArguments().getInt("abType")]; contentResId = getArguments().getInt("contentResId"); - titleId = getArguments().getString("titleResId"); + settingTitle = getArguments().getString("titleResId"); order = getArguments().getFloat("order") + 10.0f; + catInfo = getArguments().getBundle("catInfo"); sub = getArguments().getString("sub"); + isStandalone = getArguments().getBoolean("isStandalone"); supressMenu = supressMenu || abType == Helpers.ActionBarType.Edit; if (contentResId == 0) { @@ -69,18 +73,19 @@ public void onActivityCreated(Bundle savedInstanceState) { loadSharedPrefs(); ActionBar actionBar = getActionBar(); if (actionBar != null) { - Bundle args = getArguments(); - String sub = args.getString("sub"); - if (sub != null) { + if (isStandalone && catInfo.getBoolean("isDynamic")) { + actionBar.setTitle(settingTitle + " ⟲"); + } + else if (!isStandalone && sub != null) { PreferenceScreen screen = getPreferenceScreen(); PreferenceCategoryEx category = (PreferenceCategoryEx)screen.getPreference(0); if (category.isDynamic()) - getActionBar().setTitle(category.getTitle() + " ⟲"); + actionBar.setTitle(category.getTitle() + " ⟲"); else - getActionBar().setTitle(category.getTitle()); + actionBar.setTitle(category.getTitle()); } else { - actionBar.setTitle(titleId); + actionBar.setTitle(settingTitle); } } } @@ -361,6 +366,7 @@ public void openActivitiesItemList(Preference pref) { } public void selectSub() { + if (isStandalone) return; PreferenceScreen screen = getPreferenceScreen(); int cnt = screen.getPreferenceCount(); for (int i = cnt - 1; i >= 0; i--) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 3914f569..1a7863b0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1400,8 +1400,7 @@ protected void before(XC_MethodHook.MethodHookParam param) throws Throwable { } public static void NoUnlockAnimationHook(LoadPackageParam lpparam) { - if (!Helpers.findAndHookMethodSilently("com.miui.home.launcher.common.Utilities", lpparam.classLoader, "notShowUserPresentAnimation", Context.class, XC_MethodReplacement.returnConstant(true))) - Helpers.hookAllMethods("com.miui.launcher.utils.MiuiSettingsUtils", lpparam.classLoader, "isSystemAnimationOpen", XC_MethodReplacement.returnConstant(false)); + Helpers.hookAllMethods("com.miui.launcher.utils.MiuiSettingsUtils", lpparam.classLoader, "isSystemAnimationOpen", XC_MethodReplacement.returnConstant(false)); } public static void NoZoomAnimationHook(LoadPackageParam lpparam) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java index 5ec6509c..22fa9c27 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java @@ -23,28 +23,29 @@ public void onActivityCreated(Bundle savedInstanceState) { PreferenceScreen screen = findPreference("pref_key_cat"); int cnt = screen.getPreferenceCount(); - for (int i = 0; i < cnt; i++) - screen.getPreference(i).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - if (!(preference instanceof PreferenceEx)) return false; - Bundle bundle = new Bundle(); - bundle.putString("sub", preference.getKey()); - MainFragment mainFrag = ((MainFragment)getTargetFragment()); - switch (cat) { - case "pref_key_system": - openSubFragment(mainFrag.prefSystem, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system); - break; - case "pref_key_launcher": - openSubFragment(mainFrag.prefLauncher, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_title, R.xml.prefs_launcher); - break; - case "pref_key_controls": - openSubFragment(mainFrag.prefControls, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls); - break; + for (int i = 0; i < cnt; i++) { + screen.getPreference(i).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (!(preference instanceof PreferenceEx)) return false; + Bundle bundle = new Bundle(); + bundle.putString("sub", preference.getKey()); + MainFragment mainFrag = ((MainFragment)getTargetFragment()); + switch (cat) { + case "pref_key_system": + openSubFragment(mainFrag.prefSystem, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system); + break; + case "pref_key_launcher": + openSubFragment(mainFrag.prefLauncher, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_title, R.xml.prefs_launcher); + break; + case "pref_key_controls": + openSubFragment(mainFrag.prefControls, bundle, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls); + break; + } + return true; } - return true; - } - }); + }); + } } } \ No newline at end of file diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 3fe2e77a..b47f0c16 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -26,6 +26,7 @@ import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.prefs.CheckBoxPreferenceEx; import name.mikanoshi.customiuizer.prefs.ListPreferenceEx; +import name.mikanoshi.customiuizer.prefs.PreferenceCategoryEx; import name.mikanoshi.customiuizer.prefs.PreferenceEx; import name.mikanoshi.customiuizer.prefs.SeekBarPreference; import name.mikanoshi.customiuizer.qs.AutoRotateService; @@ -42,7 +43,6 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - switch (sub) { case "pref_key_system_cat_screen": findPreference("pref_key_system_orientationlock").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -123,11 +123,15 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { case "pref_key_system_cat_statusbar": findPreference("pref_key_system_statusbarcolor_apps").setOnPreferenceClickListener(openAppsEdit); - findPreference("pref_key_system_detailednetspeed_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - openSubFragment(new SubFragment(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_detailednetspeed_title, R.xml.prefs_system_detailednetspeed); + Bundle args = new Bundle(); + args.putBoolean("isStandalone", true); + args.putString("sub", "pref_key_system_detailednetspeed_cat"); + Bundle catInfo = new Bundle(); + args.putBundle("catInfo", catInfo); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_netspeed_cat_title, R.xml.prefs_system_detailednetspeed); return true; } }); @@ -501,6 +505,21 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { findPreference("pref_key_system_defaultusb_unsecure").setEnabled(false); } + break; + case "pref_key_system_detailednetspeed_cat": + findPreference("pref_key_system_detailednetspeed").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + SeekBarPreference netspeedFontSizePref = findPreference("pref_key_system_netspeed_fontsize"); + if ((Boolean)newValue) { + netspeedFontSizePref.setValue(16); + } + else { + netspeedFontSizePref.setValue(14); + } + return true; + } + }); break; } } diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index ee0e00c2..1d43e49d 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -167,7 +167,6 @@ android:defaultValue="0" miuizer:minValue="0" miuizer:maxValue="30000" - miuizer:child="true" miuizer:stepValue="500" miuizer:format="@string/format_d_ms" miuizer:offtext="@string/array_default" /> @@ -178,7 +177,6 @@ android:defaultValue="0" miuizer:minValue="0" miuizer:maxValue="30000" - miuizer:child="true" miuizer:stepValue="500" miuizer:format="@string/format_d_ms" miuizer:offtext="@string/array_default" /> From 394908e5dd2d20e306f278d33a558e1df78809c0 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 5 Jan 2023 22:40:48 +0800 Subject: [PATCH 249/627] refactor --- .../mikanoshi/customiuizer/subs/Launcher.java | 15 +++++++-------- app/src/main/res/values-pl-rPL/strings.xml | 2 -- app/src/main/res/values-ru-rRU/strings.xml | 4 ---- app/src/main/res/values-zh-rCN/strings.xml | 8 ++++---- app/src/main/res/values/strings.xml | 4 ---- app/src/main/res/xml/prefs_launcher.xml | 3 ++- app/src/main/res/xml/prefs_system.xml | 1 + 7 files changed, 14 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java index 00b98c86..6a3aa148 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java @@ -9,6 +9,7 @@ import androidx.preference.Preference; import android.widget.SeekBar; +import miui.os.Build; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.SubFragment; import name.mikanoshi.customiuizer.prefs.CheckBoxPreferenceEx; @@ -111,15 +112,13 @@ public boolean onPreferenceClick(Preference preference) { findPreference("pref_key_launcher_bottommargin").setEnabled(opt == 1); findPreference("pref_key_launcher_nounlockanim").setEnabled(opt == 1); findPreference("pref_key_launcher_oldlaunchanim").setEnabled(opt == 1); - findPreference("pref_key_launcher_googlediscover").setEnabled(opt == 1); - findPreference("pref_key_launcher_googleminus").setEnabled(opt == 1); - findPreference("pref_key_launcher_closedrawer").setEnabled(opt == 1); - Preference pref = findPreference("pref_key_launcher_googleminus"); - pref.setEnabled(opt == 1); - if (!miui.os.Build.IS_INTERNATIONAL_BUILD) { - ((CheckBoxPreferenceEx)pref).setUnsupported(true); - pref.setSummary(R.string.launcher_googleminus_note); + CheckBoxPreferenceEx minusPref = findPreference("pref_key_launcher_googleminus"); + CheckBoxPreferenceEx discoverPref = findPreference("pref_key_launcher_googlediscover"); + if (Build.IS_INTERNATIONAL_BUILD) { + discoverPref.setEnabled(opt == 1); + minusPref.setEnabled(opt == 1); } + findPreference("pref_key_launcher_closedrawer").setEnabled(opt == 1); break; } } diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index edfe127d..a804e796 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -518,7 +518,6 @@ Górny margines siatki Dolny margines dokowania Poziomy margines widżetu - Działa tylko z najnowszymi wersjami launchera z dynamicznym pozycjonowaniem widżetów Wysokość wskaźnika strony Foldery Liczba kolumn w folderach @@ -910,7 +909,6 @@ Portret Krajobraz Sieć 5G - CustoMIUIzer nie ma uprawnień do zmiany trybu ciemnego Ustawienia CustoMIUIzera Zaznacz nowe modyfikacje diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 94aa1afa..b50958ea 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -109,7 +109,6 @@ Портрет Ландшафт 5G - У CustoMIUIzer нет прав на изменение тёмного режима Открыть в Play Маркет Запустить Имя APK файла @@ -496,7 +495,6 @@ Отступ сетки сверху Отступ дока снизу Горизонтальные отступы виджетов - Работает только на последних версиях ланчера с динамическим позиционироанием виджетов Высота индикатора страниц Папки Число колонок в папках @@ -724,8 +722,6 @@ Полностью скрывает индикатор при низкой скорости Низкий уровень скорости Задаёт уровень, ниже которого скорость будет считаться низкой и будет иметь другую иконку - Понизить видимость при неактивности - Делает индикатор полупрозрачным, если обе скорости равны нулю Управление жестами Выполняет выбранные действия на скольжение и двойное нажатие Чувствительность регулировки diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e2fe54b2..f50d0ec0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -485,8 +485,8 @@ 需要全球版(国际版)ROM 强制Google探索 将App Vault替换为Google探索(需要安装Google应用) - 禁用小部件,仅屏幕 - 令所有屏幕平板上的支持小部件和应用 + 禁用仅小部件页面 + 使平板上的所有页面都支持小部件和应用 去除解锁动画 设备解锁时去除图标动画 使用旧的启动动画 @@ -1036,7 +1036,7 @@ 关闭并禁用 全限制 允许为系统应用配置省电策略和Wi-Fi接入 - 水平小部件边缘 + 小部件水平间距 隐藏特性 该设备不支持 不易找到的界面 @@ -1081,7 +1081,7 @@ 重启系统界面 允许不受信任的触摸操作 去除启动动画 - app启动、关闭时不缩放图标 + App启动、关闭时不缩放图标 跳过开启特殊权限的倒计时 电池页面显示温度值 剪切板隐私保护及模糊定位 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b6fb7bda..968b1dba 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -112,8 +112,6 @@ Do not show indicator if speed is low Low speed level Speed values below this level will be considered low and will have a different indication icon - Reduce visibility when inactive - Make indicator semitransparent when both speeds are zero Hide Byte per second suffix(B/s) Network speed\'s font size Gesture controls @@ -535,7 +533,6 @@ Top grid margin Bottom dock margin Horizontal widget margin - Works only on latest launcher versions with dynamic widget positioning Page indicator height Folders Number of columns in folders @@ -931,7 +928,6 @@ Portrait Landscape 5G Network - CustoMIUIzer has no permission to change dark mode CustoMIUIzer settings Mark new mods diff --git a/app/src/main/res/xml/prefs_launcher.xml b/app/src/main/res/xml/prefs_launcher.xml index 068c38df..2d71a6f5 100644 --- a/app/src/main/res/xml/prefs_launcher.xml +++ b/app/src/main/res/xml/prefs_launcher.xml @@ -234,12 +234,14 @@ android:key="pref_key_launcher_googleminus" android:title="@string/launcher_googleminus_title" android:summary="@string/launcher_googleminus_summ" + app:isPreferenceVisible="false" android:disableDependentsState="true" android:defaultValue="false" /> @@ -355,7 +357,6 @@ Date: Thu, 5 Jan 2023 22:46:48 +0800 Subject: [PATCH 250/627] fix: brightness set to minimum --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 ++- app/src/main/res/values-pl-rPL/strings.xml | 1 - app/src/main/res/values/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 7f27ef2b..8db53bc5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6157,7 +6157,8 @@ protected void before(final MethodHookParam param) throws Throwable { isSliding = false; if (mPct != null) { mPct.setVisibility(View.GONE); - if (tapCurrentBrightness > -0.5f) { + int opt = MainModule.mPrefs.getStringAsInt(tapStartPointers == 2 ? "system_statusbarcontrols_dual" : "system_statusbarcontrols_single", 1); + if (tapCurrentBrightness > -0.5f && opt == 2) { mDisplayManager = XposedHelpers.getObjectField(mBrightnessController, "mDisplayManager"); XposedHelpers.callMethod(mDisplayManager, "setBrightness", mContext.getDisplay().getDisplayId(), tapCurrentBrightness); } diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index a804e796..07eb9e73 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -1,5 +1,4 @@ - CustoMIUIzer13 O aplikacji Wersja %1$s by Mikanoshi & MonwF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 968b1dba..f67057a8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - CustoMIUIzer13 + CustoMIUIzer14 About Version %1$s by Mikanoshi & MonwF From ca24124e18ff12df84e0bc983c82d448817e94f6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 5 Jan 2023 23:59:31 +0800 Subject: [PATCH 251/627] fix: disable miuihome log --- .../name/mikanoshi/customiuizer/mods/Launcher.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 1a7863b0..640d09d6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1639,15 +1639,12 @@ public static void HideStatusBarInRecentsHook(LoadPackageParam lpparam) { } public static void DisableLauncherLogHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.miui.home.launcher.AnalyticalDataCollectorJobService", lpparam.classLoader, "onStartJob", XC_MethodReplacement.DO_NOTHING); + Helpers.hookAllMethods("com.miui.home.launcher.AnalyticalDataCollectorJobService", lpparam.classLoader, "onStartJob", XC_MethodReplacement.returnConstant(false)); Helpers.findAndHookMethod("com.miui.home.launcher.AnalyticalDataCollector", lpparam.classLoader, "canTrackLaunchAppEvent", XC_MethodReplacement.returnConstant(false)); - Helpers.findAndHookMethod("com.miui.home.launcher.common.OneTrackInterfaceUtils", lpparam.classLoader, "init", Context.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - XposedHelpers.setObjectField(param.thisObject, "IS_ENABLE", false); - param.setResult(null); - } - }); + Class OneTrackInterfaceUtils = findClassIfExists("com.miui.home.launcher.common.OneTrackInterfaceUtils", lpparam.classLoader); + if (OneTrackInterfaceUtils != null) { + XposedHelpers.setStaticObjectField(OneTrackInterfaceUtils, "IS_ENABLE", false); + } } public static void LauncherPinchHook(LoadPackageParam lpparam) { From 1f525de0f7d118110fa4d833b62185b763f50ed1 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 14:14:36 +0800 Subject: [PATCH 252/627] refactor and clean --- .../mikanoshi/customiuizer/MainModule.java | 15 +- .../mikanoshi/customiuizer/mods/Launcher.java | 42 +---- .../mikanoshi/customiuizer/mods/System.java | 82 ---------- .../mikanoshi/customiuizer/mods/Various.java | 4 - .../prefs/PreferenceCategoryEx.java | 22 ++- .../mikanoshi/customiuizer/subs/System.java | 37 +++-- app/src/main/res/values-pl-rPL/strings.xml | 6 - app/src/main/res/values-ru-rRU/strings.xml | 6 - app/src/main/res/values-zh-rCN/strings.xml | 8 +- app/src/main/res/values-zh-rTW/strings.xml | 6 - app/src/main/res/values/attrs.xml | 2 +- app/src/main/res/values/strings.xml | 6 - app/src/main/res/xml/prefs_system.xml | 144 ++---------------- ...system_statusbar_batterytempandcurrent.xml | 101 ++++++++++++ app/src/main/res/xml/prefs_various.xml | 8 - 15 files changed, 160 insertions(+), 329 deletions(-) create mode 100644 app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 2ae108c0..0f8d833e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -158,13 +158,12 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_apksign") || mPrefs.getBoolean("system_disableintegrity")) System.DisableSystemIntegrityHook(lpparam); if (mPrefs.getBoolean("system_vibration_amp")) System.MuffledVibrationHook(lpparam); if (mPrefs.getBoolean("system_clearalltasks")) System.ClearAllTasksHook(lpparam); - if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsServiceHook(lpparam); +// if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsServiceHook(lpparam); if (mPrefs.getBoolean("system_nodarkforce")) System.NoDarkForceHook(lpparam); if (mPrefs.getBoolean("system_audiosilencer")) System.AudioSilencerServiceHook(lpparam); if (mPrefs.getBoolean("system_fw_sticky")) System.StickyFloatingWindowsHook(lpparam); if (mPrefs.getBoolean("system_charginginfo")) System.ChargingInfoServiceHook(lpparam); if (mPrefs.getBoolean("system_lswallpaper")) System.SetLockscreenWallpaperHook(lpparam); - if (mPrefs.getBoolean("system_usenativerecents")) System.UseNativeRecentsFixHook(lpparam); if (mPrefs.getBoolean("controls_powerflash")) Controls.PowerKeyHook(lpparam); if (mPrefs.getBoolean("controls_fingerprintfailure")) Controls.FingerprintHapticFailureHook(lpparam); if (mPrefs.getBoolean("controls_fingerprintscreen")) Controls.FingerprintScreenOnHook(lpparam); @@ -200,12 +199,10 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); - if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); +// if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); if (mPrefs.getStringAsInt("system_networkindicator", 1) == 3) System.NetworkIndicatorRes(lpparam); - if (mPrefs.getInt("system_recents_blur", 100) < 100) System.RecentsBlurRatioHook(lpparam); if (mPrefs.getInt("system_drawer_blur", 100) < 100) System.DrawerBlurRatioHook(lpparam); - if (mPrefs.getInt("system_drawer_opacity", 100) < 100) System.DrawerThemeBackgroundHook(lpparam); if (mPrefs.getInt("system_chargeanimtime", 20) < 20) System.ChargeAnimationHook(lpparam); if (mPrefs.getInt("system_betterpopups_delay", 0) > 0 && !mPrefs.getBoolean("system_betterpopups_nohide")) System.BetterPopupsHideDelayHook(lpparam); if (mPrefs.getInt("system_netspeedinterval", 4) != 4) System.NetSpeedIntervalHook(lpparam); @@ -296,10 +293,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { ) { System.NetSpeedStyleHook(lpparam); } - if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); +// if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); if (mPrefs.getBoolean("system_taptounlock")) System.TapToUnlockHook(lpparam); if (mPrefs.getBoolean("system_nosos")) System.NoSOSHook(lpparam); - if (mPrefs.getBoolean("system_usenativerecents")) System.UseNativeRecentsHook(lpparam); if (mPrefs.getBoolean("system_morenotif")) System.MoreNotificationsHook(lpparam); if (mPrefs.getBoolean("system_charginginfo")) System.ChargingInfoHook(lpparam); if (mPrefs.getBoolean("system_secureqs")) System.SecureQSTilesHook(lpparam); @@ -454,8 +450,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { final boolean isLauncherPerf = mPrefs.getBoolean("launcher_compat"); final boolean isGoogleMinus = mPrefs.getBoolean("launcher_googleminus"); final boolean isStatusBarColor = mPrefs.getBoolean("system_statusbarcolor") && !mPrefs.getStringSet("system_statusbarcolor_apps").contains(pkg); - final int collapseTitlesOpt = mPrefs.getStringAsInt("various_collapsemiuititles", 1); - final boolean collapseTitles = collapseTitlesOpt > 1; final boolean noOverscroll = mPrefs.getBoolean("system_nooverscroll"); if (isLauncherPkg) { @@ -474,14 +468,13 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (isLauncherPerf) handleLoadLauncher(lpparam); } - if ((isLauncherPkg && !isLauncherPerf) || (isMIUILauncherPkg && isGoogleMinus) || isStatusBarColor || collapseTitles || noOverscroll) + if ((isLauncherPkg && !isLauncherPerf) || (isMIUILauncherPkg && isGoogleMinus) || isStatusBarColor || noOverscroll) Helpers.findAndHookMethod(Application.class, "attach", Context.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { if (isLauncherPkg && !isLauncherPerf) handleLoadLauncher(lpparam); if (isMIUILauncherPkg && isGoogleMinus) Launcher.GoogleMinusScreenHook(lpparam); if (isStatusBarColor) System.StatusBarBackgroundCompatHook(lpparam); - if (collapseTitles) Various.CollapseMIUITitlesHook(lpparam, param, collapseTitlesOpt); if (noOverscroll) System.NoOverscrollAppHook(lpparam); } }); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 640d09d6..ae26391a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1190,13 +1190,6 @@ public void onChange(Uri uri) { Class buCls = XposedHelpers.findClassIfExists("com.miui.home.launcher.common.BlurUtils", lpparam.classLoader); if (buCls != null) { - Helpers.findAndHookMethod("com.miui.home.launcher.common.BlurUtils", lpparam.classLoader, "isUserBlurWhenOpenFolder", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - param.setResult(true); - } - }); - Method[] methods = buCls.getDeclaredMethods(); Method fastBlur = null; for (Method method: methods) @@ -1221,13 +1214,6 @@ protected void before(MethodHookParam param) throws Throwable { return; } - Helpers.findAndHookMethod("com.miui.home.launcher.blur.BlockingBlurController", lpparam.classLoader, "setBlurEnabled", boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (MainModule.mPrefs.getBoolean("launcher_folderblur_disable")) param.args[0] = false; - } - }); - Helpers.findAndHookMethod("com.miui.home.launcher.view.BlurFrameLayout", lpparam.classLoader, "setBlurAlpha", float.class, new MethodHook(10) { @Override protected void before(MethodHookParam param) throws Throwable { @@ -1243,18 +1229,6 @@ protected void before(MethodHookParam param) throws Throwable { if (ratio > 0) param.args[0] = ratio; } }); - - Helpers.findAndHookMethod("com.miui.home.launcher.common.Utilities", lpparam.classLoader, "fastBlur", float.class, Window.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (MainModule.mPrefs.getBoolean("launcher_folderwallblur_disable")) { - param.args[0] = 0.0f; - return; - } - float ratio = MainModule.mPrefs.getInt("launcher_folderwallblur_radius", 0) / 100f; - if (ratio > 0) param.args[0] = (float)param.args[0] * ratio; - } - }); } private static float scaleStiffness(float val, float scale) { @@ -1451,16 +1425,6 @@ public static void MaxHotseatIconsCountHook(LoadPackageParam lpparam) { } public static void RecentsBlurRatioHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.miui.home.recents.views.RecentsView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - try { - XposedHelpers.setFloatField(param.thisObject, "mDefaultScrimAlpha", 0.15f); - XposedHelpers.setObjectField(param.thisObject, "mBackgroundScrim", new ColorDrawable(Color.argb(38, 0, 0, 0)).mutate()); - } catch (Throwable ignore) {} - } - }); - Helpers.hookAllConstructors("com.miui.home.recents.RecentsViewStateController", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -1477,16 +1441,15 @@ public void onChange(String name, int defValue) { }); Class utilsClass = XposedHelpers.findClassIfExists("com.miui.home.launcher.common.BlurUtils", lpparam.classLoader); - if (utilsClass == null) utilsClass = XposedHelpers.findClassIfExists("com.miui.home.launcher.common.Utilities", lpparam.classLoader); if (utilsClass == null) { Helpers.log("RecentsBlurRatioHook", "Cannot find blur utility class"); return; } - Helpers.hookAllMethods(utilsClass, "fastBlur", new MethodHook() { + Helpers.hookAllMethods(utilsClass, "fastBlurWhenUseCompleteRecentsBlur", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - param.args[0] = (float)param.args[0] * MainModule.mPrefs.getInt("system_recents_blur", 100) / 100f; + param.args[1] = MainModule.mPrefs.getInt("system_recents_blur", 100) / 100f; } }); } @@ -1615,6 +1578,7 @@ public static void DisableLauncherWallpaperScale(LoadPackageParam lpparam) { Class WallpaperZoomManagerKtClass = findClassIfExists("com.miui.home.launcher.wallpaper.WallpaperZoomManagerKt", lpparam.classLoader); if (MainModule.mPrefs.getBoolean("launcher_disable_wallpaperscale")) { XposedHelpers.setStaticBooleanField(WallpaperZoomManagerKtClass, "ZOOM_ENABLED", false); + Helpers.findAndHookMethod("com.miui.home.recents.DimLayer", lpparam.classLoader, "isSupportDim", XC_MethodReplacement.returnConstant(false)); return; } Helpers.hookAllMethods("com.miui.home.recents.OverviewState", lpparam.classLoader, "onStateEnabled", new MethodHook() { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 8db53bc5..db64ecb4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1315,34 +1315,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void RecentsBlurRatioHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.recents.views.RecentsView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)param.args[0]; - Handler mHandler = new Handler(mContext.getMainLooper()); - - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomBlurModifier", MainModule.mPrefs.getInt("system_recents_blur", 100)); - new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_recents_blur", 100) { - @Override - public void onChange(String name, int defValue) { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomBlurModifier", Helpers.getSharedIntPref(mContext, name, defValue)); - } - }; - - XposedHelpers.setFloatField(param.thisObject, "mDefaultScrimAlpha", 0.15f); - XposedHelpers.setObjectField(param.thisObject, "mBackgroundScrim", new ColorDrawable(Color.argb(38, 0, 0, 0)).mutate()); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.recents.views.RecentsView", lpparam.classLoader, "updateBlurRatio", float.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = (float)param.args[0] * (int)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomBlurModifier") / 100f; - } - }); - } - public static void DrawerBlurRatioHook(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.StatusBarWindowManager", lpparam.classLoader, new MethodHook() { @Override @@ -1401,40 +1373,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void DrawerThemeBackgroundHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Context mContext = (Context)param.args[0]; - Handler mHandler = new Handler(mContext.getMainLooper()); - - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomOpacityModifier", MainModule.mPrefs.getInt("system_drawer_opacity", 100)); - new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_drawer_opacity", 100) { - @Override - public void onChange(String name, int defValue) { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomOpacityModifier", Helpers.getSharedIntPref(mContext, name, defValue)); - } - }; - } - }); - - if (!Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "onBlurRatioChanged", float.class, new MethodHook(100) { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = (float)param.args[0] * (int)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomOpacityModifier") / 100f; - } - })) Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "updateStatusBarWindowBlur", new MethodHook(1000) { - @Override - protected void after(MethodHookParam param) throws Throwable { - int mStatusBarState = XposedHelpers.getIntField(param.thisObject, "mStatusBarState"); - if (mStatusBarState != 0) return; - View mThemeBackgroundView = (View)XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); - if (mThemeBackgroundView != null) - mThemeBackgroundView.setAlpha(mThemeBackgroundView.getAlpha() * (int)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomOpacityModifier") / 100f); - } - }); - } - public static void HideNetworkTypeHook(LoadPackageParam lpparam) { MethodHook hideMobileActivity = new MethodHook() { @Override @@ -7015,26 +6953,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void UseNativeRecentsHook(LoadPackageParam lpparam) { - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently("com.android.systemui.recents.misc.SystemServicesProxy", lpparam.classLoader, "isRecentsWithinLauncher", Context.class, XC_MethodReplacement.returnConstant(false)); - } - - public static void UseNativeRecentsFixHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.wm.TaskRecord", lpparam.classLoader, "isVisible", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - if ((boolean)param.getResult()) return; - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - for (StackTraceElement el: stackTrace) - if (el != null) if ("getPerceptibleRecentAppList".equals(el.getMethodName())) { - param.setResult(true); - return; - } - } - }); - } - public static void NoSOSHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.android.keyguard.EmergencyButton", lpparam.classLoader, "updateEmergencyCallButton", new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 2e42d6c5..7ff2ff49 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -1014,10 +1014,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void CollapseMIUITitlesHook(LoadPackageParam lpparam, XC_MethodHook.MethodHookParam param, int opt) { - - } - public static void GboardPaddingHook() { Helpers.findAndHookMethod(findClass("android.os.SystemProperties", null), "get", String.class, new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java index f7608013..c1395bef 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceCategoryEx.java @@ -15,8 +15,7 @@ public class PreferenceCategoryEx extends PreferenceCategory { private final boolean dynamic; - private final boolean empty; - private boolean hidden; + private int state; // 0-正常 1-纯区块 2-顶层隐藏 private boolean unsupported = false; private final Resources res = getContext().getResources(); private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); @@ -25,8 +24,7 @@ public PreferenceCategoryEx(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.PreferenceCategoryEx); dynamic = xmlAttrs.getBoolean(R.styleable.PreferenceCategoryEx_dynamic, false); - empty = xmlAttrs.getBoolean(R.styleable.PreferenceCategoryEx_empty, false); - hidden = xmlAttrs.getBoolean(R.styleable.PreferenceCategoryEx_hidden, false); + state = xmlAttrs.getInt(R.styleable.PreferenceCategoryEx_state, 0); xmlAttrs.recycle(); setLayoutResource(R.layout.preference_category); } @@ -42,11 +40,15 @@ public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); TextView title = (TextView) view.findViewById(android.R.id.title); title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); - title.setVisibility(hidden || empty ? View.GONE : View.VISIBLE); + title.setVisibility((state == 2 || state == 1) ? View.GONE : View.VISIBLE); View finalView = view.itemView; - if (hidden) { + if (state == 2) { finalView.setPadding(childpadding, 0, childpadding, 0); } + else { + int vertialPadding = getContext().getResources().getDimensionPixelSize(R.dimen.preference_item_padding_top); + finalView.setPadding(childpadding, vertialPadding, childpadding, vertialPadding); + } } public void setUnsupported(boolean value) { @@ -59,13 +61,7 @@ public boolean isDynamic() { } public void hide() { - hidden = true; + state = 2; this.notifyChanged(); } - - public void show() { - hidden = false; - this.notifyChanged(); - } - } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index b47f0c16..9261a347 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -129,9 +129,22 @@ public boolean onPreferenceClick(Preference preference) { Bundle args = new Bundle(); args.putBoolean("isStandalone", true); args.putString("sub", "pref_key_system_detailednetspeed_cat"); + String title = preference.getTitle().toString(); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_detailednetspeed); + return true; + } + }); + findPreference("pref_key_system_statusbar_batterytempandcurrent_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Bundle args = new Bundle(); + args.putBoolean("isStandalone", true); Bundle catInfo = new Bundle(); + catInfo.putBoolean("isDynamic", true); args.putBundle("catInfo", catInfo); - openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_netspeed_cat_title, R.xml.prefs_system_detailednetspeed); + args.putString("sub", "pref_key_system_statusbar_batterytempandcurrent_cat"); + String title = preference.getTitle().toString(); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_statusbar_batterytempandcurrent); return true; } }); @@ -217,17 +230,17 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { return true; } }); - findPreference("pref_key_system_snoozedmanager").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - PackageManager pm = getActivity().getPackageManager(); - if ((Boolean)newValue) - pm.setComponentEnabledSetting(new ComponentName(getActivity(), SnoozedActivity.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); - else - pm.setComponentEnabledSetting(new ComponentName(getActivity(), SnoozedActivity.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); - return true; - } - }); +// findPreference("pref_key_system_snoozedmanager").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { +// @Override +// public boolean onPreferenceChange(Preference preference, Object newValue) { +// PackageManager pm = getActivity().getPackageManager(); +// if ((Boolean)newValue) +// pm.setComponentEnabledSetting(new ComponentName(getActivity(), SnoozedActivity.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); +// else +// pm.setComponentEnabledSetting(new ComponentName(getActivity(), SnoozedActivity.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); +// return true; +// } +// }); break; case "pref_key_system_cat_qs": findPreference("pref_key_system_qshaptics_ignore").setEnabled(!Objects.equals(Helpers.prefs.getString("pref_key_system_qshaptics", "1"), "1")); diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 07eb9e73..cf6d5105 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -163,8 +163,6 @@ Uwzględnij pełny ekran Nie otwieraj szuflady powiadomień, gdy aplikacja pełnoekranowa jest aktywna (nie dotyczy aplikacji immersyjnych z ukrytymi paskami stanu i nawigacji) Wybrane aplikacje - Zwiń tytuły MIUI - Skonfiguruj stan tytułu paska akcji we wszystkich aplikacjach MIUI 12 Zrzuty ekranu Konfiguracja zrzutów ekranu Dostosuj format, jakość i zapisz ścieżkę folderu dla zrzutów ekranu @@ -306,8 +304,6 @@ Rozmycie tła Intensywność rozmycia tła w ostatnich aplikacjach Intensywność rozmycia tła w szufladzie powiadomień - Przezroczystość tematycznego tła - Przezroczystość tematycznego tła w szufladzie powiadomień Ekran blokady Dodatkowa funkcjonalność Bezpieczeństwo @@ -409,8 +405,6 @@ Szuflada powiadomień Powiadomienia Lista ostatnich aplikacji - Użyj natywnej implementacji - Nie używaj listy ostatnich aplikacji z Launchera MIUI. Źle działa z gestami pełnoekranowymi. Usuń przycisk czyszczenia Ukryj przycisk, który usuwa ostatnie aplikacje i czyści pamięć Wyczyść wszystko diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index b50958ea..b35bfa02 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -611,8 +611,6 @@ Панель уведомлений Уведомления Список последних приложений - Использовать родной список - Не использовать список последних приложений, встроенный в Рабочий стол MIUI. Плохо работает с полноэкранными жестами. Убрать кнопку очистки Скрывает кнопку для очистки списка последних приложений и памяти Очистить все @@ -777,8 +775,6 @@ Определение полноэкранного режима Не открывать панель уведомлений, если запущено полноэкранное приложение (не распространяется на \"режим погружения\" со скрытыми панелями статуса и навигации) Выбранные приложения - Свернуть заголовки MIUI - Настройка вида заголовков во всех MIUI 12 приложениях Снимки экрана Конфигурация снимков экрана Настройка формата, качества и папки сохранения скриншотов @@ -867,8 +863,6 @@ Размытие фона Уровень размытия фона на экране последних приложений Уровень размытия фона в панели уведомлений - Прозрачность фона из темы - Уровень прозрачности фона панели уведомлений из текущей темы Улучшенная блокировка Отключает меню управления питанием во время блокировки Безопасный Центр управления diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f50d0ec0..e8921865 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -160,8 +160,6 @@ 遵循全屏 应用激活全屏模式时不打开通知抽屉(不适用于具有隐藏状态和导航栏的沉浸式应用) 已选应用 - 折叠 MIUI 标题 - 调整 MIUI13 应用中顶栏的标题 截图 截图配置 自定义截图的格式、质量和存放目录 @@ -303,10 +301,8 @@ 配置动画长度 值过低等同于禁用动画 背景模糊 - 最近应用的背景模糊度 + 最近任务的背景模糊度 通知抽屉的背景模糊度 - 主题背景不透明度 - 主题通知抽屉背景的不透明度 锁屏 附加功能 安全 @@ -402,8 +398,6 @@ 通知抽屉 通知 最近任务 - 使用原生实现 - 请不要使用MIUI启动器的最近应用列表。使用全屏手势效果不好。 移除清理按钮 禁用壁纸缩放 隐藏清理最近应用和内存的按钮 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6f2aeacb..523f39b2 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -611,8 +611,6 @@ 可以在新版本應用上安裝舊版本應用 允許降級 通知抽屜的背景模糊度 - 主題通知抽屜背景的不透明度 - 主題背景不透明度 雙擊鎖屏上任意空白處關閉螢幕 雙擊熄屏 新增以下重啟選項到電源功能表(引導模式、恢復模式、軟重啟) @@ -883,8 +881,6 @@ 顯示時長始終大於 1 秒 修改 Toast 顯示時長 顯示時間修改 - 請不要使用MIUI啟動器的最近應用列表。使用全屏手勢效果不好。 - 使用本地實現 通知 其他 時段 @@ -987,8 +983,6 @@ 通話類型 亮度值 清理揚聲器 - 調整 MIUI13 應用中頂欄的標題 - 折疊 MIUI 標題 允許從應用訊息頁面禁用任何應用 應用狀態控制 橫屏時底部補充 diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index d70f16a4..30675524 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -7,7 +7,7 @@ - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f67057a8..a93531b4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -173,8 +173,6 @@ Respect fullscreen Do not open notification drawer when fullscreen app is active (does not apply to immersive apps with hidden status and navigation bars) Selected apps - Collapse MIUI titles - Configure action bar title state in all MIUI 12 apps Screenshots Screenshot configuration Customize format, quality and save folder for screenshots @@ -318,8 +316,6 @@ Background blur Background blur intensity in recent apps Background blur intensity in notification drawer - Themed background opacity - Opacity of a themed notification drawer background Lock screen Additional functionality Security @@ -423,8 +419,6 @@ Notification drawer Notifications Recent apps list - Use native implementation - Don\'t use recent apps list from MIUI Launcher. Works badly with full screen gestures. Remove cleaner button Hide button that clears recent apps and cleans memory Disable wallpaper scale diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 33a60d1b..a0154c4c 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -434,104 +434,9 @@ miuizer:displayDividerValue="2" miuizer:format="%s dip" /> - - - - - - - - - - - - - - - - - - - - - + - - @@ -1033,12 +927,6 @@ android:key="pref_key_system_cat_recents" android:title="@string/system_mods_recents"> - - - - - - + + + + diff --git a/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml b/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml new file mode 100644 index 00000000..75e876d0 --- /dev/null +++ b/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index 5337cb21..0e43a5f3 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -44,14 +44,6 @@ miuizer:child="true" miuizer:countAsSummary="true" /> - - From ffb7caff248f1a568e25219dbd57cfdbbe06458d Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 15:00:15 +0800 Subject: [PATCH 253/627] clean --- .../customiuizer/mods/GlobalActions.java | 50 +++++++++---------- .../mikanoshi/customiuizer/utils/Helpers.java | 5 +- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 07459aa2..b188935e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -151,29 +151,29 @@ public void onReceive(final Context context, Intent intent) { if (action.equals(ACTION_PREFIX + "RestartSystemUI")) { Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL); } - else if (action.equals(ACTION_PREFIX + "CopyToExternal")) { - try { - String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + Helpers.externalFolder; - new File(dir).mkdirs(); - - int copyAction = intent.getIntExtra("action", 0); - if (copyAction == 1) { - Helpers.copyFile(intent.getStringExtra("from"), dir + Helpers.wallpaperFile); - Intent lockIntent = new Intent("miui.intent.action.SET_LOCK_WALLPAPER"); - lockIntent.setPackage("com.android.thememanager"); - lockIntent.putExtra("lockWallpaperPath", dir + Helpers.wallpaperFile); - context.sendBroadcast(lockIntent); - } else if (copyAction == 2) { - File xposedVersion = new File(dir + Helpers.versionFile); - xposedVersion.createNewFile(); - try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(xposedVersion, false))) { - out.write(intent.getStringExtra("data")); - } - } - } catch (Throwable t) { - XposedBridge.log(t); - } - } +// else if (action.equals(ACTION_PREFIX + "CopyToExternal")) { +// try { +// String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + Helpers.externalFolder; +// new File(dir).mkdirs(); +// +// int copyAction = intent.getIntExtra("action", 0); +// if (copyAction == 1) { +// Helpers.copyFile(intent.getStringExtra("from"), dir + Helpers.wallpaperFile); +// Intent lockIntent = new Intent("miui.intent.action.SET_LOCK_WALLPAPER"); +// lockIntent.setPackage("com.android.thememanager"); +// lockIntent.putExtra("lockWallpaperPath", dir + Helpers.wallpaperFile); +// context.sendBroadcast(lockIntent); +// } else if (copyAction == 2) { +// File xposedVersion = new File(dir + Helpers.versionFile); +// xposedVersion.createNewFile(); +// try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(xposedVersion, false))) { +// out.write(intent.getStringExtra("data")); +// } +// } +// } catch (Throwable t) { +// XposedBridge.log(t); +// } +// } else if (action.equals(ACTION_PREFIX + "CollectXposedLog")) { try { String errorLogPath = Helpers.getXposedInstallerErrorLog(context); @@ -749,7 +749,7 @@ public void run() { public static void miuizerHook(LoadPackageParam lpparam) { try { XposedHelpers.setStaticBooleanField(findClass(Helpers.modulePackage + ".utils.Helpers", lpparam.classLoader), "miuizerModuleActive", true); - XposedHelpers.setStaticObjectField(findClass(Helpers.modulePackage + ".utils.Helpers", lpparam.classLoader), "xposedVersion", XposedBridge.getXposedVersion()); +// XposedHelpers.setStaticObjectField(findClass(Helpers.modulePackage + ".utils.Helpers", lpparam.classLoader), "xposedVersion", XposedBridge.getXposedVersion()); } catch (Throwable t) { XposedBridge.log(t); } @@ -1005,7 +1005,7 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "CollectXposedLog"); intentfilter.addAction(ACTION_PREFIX + "RestartSystemUI"); intentfilter.addAction(ACTION_PREFIX + "RestartLauncher"); - intentfilter.addAction(ACTION_PREFIX + "CopyToExternal"); +// intentfilter.addAction(ACTION_PREFIX + "CopyToExternal"); intentfilter.addAction(ACTION_PREFIX + "ScrollToTop"); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 9db64a39..67bcfa65 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -116,8 +116,8 @@ public class Helpers { public static final String externalFolder = "/CustoMIUIzer/"; public static final String backupFile = "settings_backup"; public static final String logFile = "xposed_log"; - public static final String versionFile = "xposed_version"; - public static final String wallpaperFile = "lockscreen_wallpaper"; +// public static final String versionFile = "xposed_version"; +// public static final String wallpaperFile = "lockscreen_wallpaper"; //public static final String xposedRepo = "https://code.highspec.ru/repo/full.xml.gz"; public static final String ANDROID_NS = "http://schemas.android.com/apk/res/android"; public static final String MIUIZER_NS = "http://schemas.android.com/apk/res-auto"; @@ -131,7 +131,6 @@ public class Helpers { public static ArrayList installedAppsList = null; public static ArrayList launchableAppsList = null; public static ArrayList allModsList = new ArrayList(); - public static int xposedVersion = 0; public static final int markColor = Color.rgb(205, 73, 97); public static final int markColorVibrant = Color.rgb(255, 0, 0); public static final int REQUEST_PERMISSIONS_BACKUP = 1; From 4a97d88bd8b54938091cbcb19336bbb20a29023a Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 19:24:26 +0800 Subject: [PATCH 254/627] fix(miui14): control center background blur --- .../mikanoshi/customiuizer/mods/System.java | 51 ++++++++++--------- .../mikanoshi/customiuizer/subs/System.java | 4 ++ 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index db64ecb4..efce8ffa 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1316,56 +1316,59 @@ protected void after(MethodHookParam param) throws Throwable { } public static void DrawerBlurRatioHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.StatusBarWindowManager", lpparam.classLoader, new MethodHook() { + Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)param.args[0]; + View mView = (View) param.args[0]; + Context mContext = mView.getContext(); Handler mHandler = new Handler(mContext.getMainLooper()); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomBlurModifier", MainModule.mPrefs.getInt("system_drawer_blur", 100)); + Object mControlPanelWindowManager = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.controlcenter.phone.ControlPanelWindowManager", lpparam.classLoader)); + Object notificationShadeDepthController = XposedHelpers.getObjectField(param.thisObject, "notificationShadeDepthController"); + int initBlurRatio = MainModule.mPrefs.getInt("system_drawer_blur", 100); + XposedHelpers.setAdditionalInstanceField(notificationShadeDepthController, "mCustomBlurModifier", initBlurRatio); + XposedHelpers.setAdditionalInstanceField(mControlPanelWindowManager, "mCustomBlurModifier", initBlurRatio); new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_drawer_blur", 100) { @Override public void onChange(String name, int defValue) { int opt = Helpers.getSharedIntPref(mContext, name, defValue); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomBlurModifier", opt); - Object mControlPanelWindowManager = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.miui.statusbar.phone.ControlPanelWindowManager", lpparam.classLoader)); + XposedHelpers.setAdditionalInstanceField(notificationShadeDepthController, "mCustomBlurModifier", opt); XposedHelpers.setAdditionalInstanceField(mControlPanelWindowManager, "mCustomBlurModifier", opt); } }; } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBarWindowManager", lpparam.classLoader, "setBlurRatio", float.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationShadeDepthController$updateBlurCallback$1", lpparam.classLoader, "doFrame", long.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - param.args[0] = (float)param.args[0] * (int)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomBlurModifier") / 100f; + Object parentCtrl = XposedHelpers.getSurroundingThis(param.thisObject); + Object blurRatio = XposedHelpers.getAdditionalInstanceField(parentCtrl, "mCustomBlurModifier"); + Object mBlurUtils = XposedHelpers.getObjectField(parentCtrl, "blurUtilsExt"); + XposedHelpers.setAdditionalInstanceField(mBlurUtils, "mCustomBlurModifier", blurRatio); } - }); - - if (!Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "onBlurRatioChanged", float.class, new MethodHook(1000) { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = XposedHelpers.callMethod(param.thisObject, "getAppearFraction"); - } - })) Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, "updateStatusBarWindowBlur", new MethodHook(100) { @Override protected void after(MethodHookParam param) throws Throwable { - int mStatusBarState = XposedHelpers.getIntField(param.thisObject, "mStatusBarState"); - if (mStatusBarState != 0) return; - View mThemeBackgroundView = (View)XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); - if (mThemeBackgroundView != null) - mThemeBackgroundView.setAlpha((float)XposedHelpers.callMethod(param.thisObject, "getAppearFraction")); + Object parentCtrl = XposedHelpers.getSurroundingThis(param.thisObject); + Object mBlurUtils = XposedHelpers.getObjectField(parentCtrl, "blurUtilsExt"); + XposedHelpers.removeAdditionalInstanceField(mBlurUtils, "mCustomBlurModifier"); } }); - Helpers.hookAllConstructors("com.android.systemui.miui.statusbar.phone.ControlPanelWindowManager", lpparam.classLoader, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BlurUtilsExt", lpparam.classLoader, "applyBlurByRadius", View.class, int.class, new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCustomBlurModifier", MainModule.mPrefs.getInt("system_drawer_blur", 100)); + protected void before(MethodHookParam param) throws Throwable { + Object multiplier = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomBlurModifier"); + if (multiplier != null) { + Object blurUtils = XposedHelpers.getObjectField(param.thisObject, "blurUtils"); + float ratio = (float) XposedHelpers.callMethod(blurUtils, "ratioOfBlurRadius", 1.0f * (int)param.args[1]); + float newRatio = ratio * (int)multiplier / 100f; + param.args[1] = Math.round((float)XposedHelpers.callMethod(blurUtils, "blurRadiusOfRatio", newRatio)); + } } }); - Helpers.findAndHookMethod("com.android.systemui.miui.statusbar.phone.ControlPanelWindowManager", lpparam.classLoader, "applyBlurRatio", float.class, new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.ControlPanelWindowManager", lpparam.classLoader, "setBlurRatio", float.class, boolean.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { param.args[0] = (float)param.args[0] * (int)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomBlurModifier") / 100f; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 9261a347..d9c4d4e9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -219,6 +219,10 @@ public boolean onPreferenceClick(Preference preference) { } }); + if (!Helpers.isTPlus()) { + findPreference("pref_key_system_drawer_blur").setVisible(false); + } + break; case "pref_key_system_cat_notifications": findPreference("pref_key_system_expandnotifs_apps").setOnPreferenceClickListener(openAppsEdit); From 85d6b013f2395255e26f1389c3873953ef0ee0ea Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 19:25:01 +0800 Subject: [PATCH 255/627] bump version --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c66f547c..2dcd90cb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -27,7 +27,7 @@ android { //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 31 versionCode 50 - versionName "23.01.05" + versionName "23.01.06" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } From fbe0ffa22c8e883744c51fc145cf58bdd5891517 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 19:53:07 +0800 Subject: [PATCH 256/627] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E5=90=8D=E5=92=8Cslogan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- .../main/java/name/mikanoshi/customiuizer/utils/Helpers.java | 1 - app/src/main/res/values-zh-rCN/strings.xml | 4 +++- app/src/main/res/values/strings.xml | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9f3aeaac..4eb9fadb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -201,7 +201,7 @@ - + diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 67bcfa65..59111102 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -109,7 +109,6 @@ public class Helpers { public static Context mModuleContext = null; public static final String modulePkg = BuildConfig.APPLICATION_ID; public static final String modulePackage = "name.mikanoshi.customiuizer"; - public static final String TAG = "CustoMIUIzer"; public static final String prefsName = "customiuizer_prefs"; public static final String prefsPath = "/data/user_de/0/" + modulePkg + "/shared_prefs"; public static final String prefsFile = prefsPath + "/" + prefsName + ".xml"; diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e8921865..199eded0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1,5 +1,7 @@ + 米客 + 米客 - 客制化你的MIUI 关于 版本:%1$s 作者:Mikanoshi & MonwF @@ -852,7 +854,7 @@ 竖屏 横屏 5G网络 - CustoMIUIzer设置 + 米客设置 标记新模块 添加到当前版本中的模块在标题处显示\"新!\"标签 新! diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a93531b4..6a89507c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ CustoMIUIzer14 + Customize MIUI to your liking About Version %1$s by Mikanoshi & MonwF From 7603f5fd37c2712813159bc694a2ab33fd70ca66 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 21:06:46 +0800 Subject: [PATCH 257/627] fix: #107 app crashes when open network speed cat --- app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java index 9ecf4df4..419e3ed3 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java @@ -73,7 +73,7 @@ public void onActivityCreated(Bundle savedInstanceState) { loadSharedPrefs(); ActionBar actionBar = getActionBar(); if (actionBar != null) { - if (isStandalone && catInfo.getBoolean("isDynamic")) { + if (isStandalone && catInfo != null && catInfo.getBoolean("isDynamic")) { actionBar.setTitle(settingTitle + " ⟲"); } else if (!isStandalone && sub != null) { From 8a95ed27ae2b83d05aadb6a573d790724f6ceddc Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 6 Jan 2023 21:23:28 +0800 Subject: [PATCH 258/627] update readme --- README.md | 8 +++++--- README_zh.md | 14 ++++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0ef91c3c..f9d0b99c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ ![logo](https://code.highspec.ru/customiuizer_promo.png) -## CustoMIUIzer for MIUI 13 ([中文](./README_zh.md)) -tested on android 12 only ( **some hooks are not working** ) +## CustoMIUIzer14 ([中文](./README_zh.md)) +Customize MIUI to your liking -### Dowload +For MIUI 13 & 14 based on android 12 and 13 +### Dowload * [Releases](https://github.com/MonwF/customiuizer/releases) * LSPosed Repo +* [Test Releases](https://tpsx.lanzouv.com/b021ly4gj) password: `miui` ### Backup functionality Backups are stored in /sdcard/Documents/CustoMIUIzer/ diff --git a/README_zh.md b/README_zh.md index aa545fe0..14016e15 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,8 +1,12 @@ -## CustoMIUIzer for MIUI 13 -由于`Mikanoshi`的 [CustoMIUIzer](code.highspec.ru/Mikanoshi/CustoMIUIzer) 一直不支持 Android 12,只好自行修改。感谢原作者带来的无限可能。 -**仅支持**基于`Android 12`的MIUI 13,且某些功能依然失效 +## 米客 +客制化你的MIUI + +> 由于`Mikanoshi`的 [CustoMIUIzer](code.highspec.ru/Mikanoshi/CustoMIUIzer) 一直不支持 Android 12,只好自行修改。感谢原作者带来的无限可能。 + +支持基于`android 12`以上的 MIUI 13和14 ### 主要功能 +* 双排状态栏 * 信任蓝牙和Wi-Fi禁止锁屏 * 查看已保存Wi-Fi密码 * 自动亮度范围限制 @@ -10,7 +14,8 @@ * 状态栏显示电池温度和电池 * 跳过10s安全警告 * 音乐可视化 -* 单独通知音量 +* 独立通知音量 +* 专辑封面设置为壁纸 * 状态栏显秒与图标隐藏 * 彩色电池条 * 使用导航栏同时启用返回手势 @@ -18,6 +23,7 @@ * 通知 * 通知重要性设置 * 自动展开 + * 小窗打开通知 * 直接打开频道设置 * 浮窗记住打开状态和位置、移除黑名单(含分屏) * 扩展电源菜单 From ed30805e6e7e38f28c54eb624f911c8b767330c4 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 8 Jan 2023 15:26:15 +0800 Subject: [PATCH 259/627] feat: set dual signal style to follow theme --- .../mikanoshi/customiuizer/mods/System.java | 70 ++++++++++++++----- .../mikanoshi/customiuizer/utils/Helpers.java | 5 +- .../customiuizer/utils/ResourceHooks.java | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/arrays.xml | 2 + app/src/main/res/values/strings.xml | 2 + 6 files changed, 64 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index efce8ffa..45c475bb 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -16,7 +16,6 @@ import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AndroidAppHelper; -import android.app.Dialog; import android.app.KeyguardManager; import android.app.MiuiNotification; import android.app.Notification; @@ -57,10 +56,6 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; import android.hardware.usb.UsbManager; import android.media.AudioAttributes; import android.media.AudioManager; @@ -194,6 +189,7 @@ import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.Helpers.MethodHook; import name.mikanoshi.customiuizer.utils.Helpers.MimeType; +import name.mikanoshi.customiuizer.utils.ResourceHooks; import name.mikanoshi.customiuizer.utils.SoundData; public class System { @@ -8131,8 +8127,9 @@ public static void DualRowSignalHook(LoadPackageParam lpparam) { } HashMap dualSignalResMap = new HashMap(); + HashMap dualSignalId2NameMap = new HashMap(); String[] colorModeList = {"", "dark", "tint"}; - String[] iconStyles = {"", "thick"}; +// String[] iconStyles = {"", "thick", "theme"}; String selectedIconStyle = MainModule.mPrefs.getString("system_statusbar_dualsimin2rows_style", ""); Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { @@ -8143,14 +8140,19 @@ protected void after(MethodHookParam param) throws Throwable { isHooked = true; Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); Resources modRes = Helpers.getModuleRes(mContext); - for (int slot = 1;slot <= 2;slot++) { - for (int lvl = 0;lvl <= 5;lvl++) { + for (int slot = 1; slot <= 2; slot++) { + for (int lvl = 0; lvl <= 5; lvl++) { for (String colorMode : colorModeList) { - for (String iconStyle : iconStyles) { - String dualIconId = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!iconStyle.equals("") ? ("_" + iconStyle) : ""); - int iconResId = modRes.getIdentifier(dualIconId, "drawable", Helpers.modulePkg); - String statusbarFakeId = "cust_" + dualIconId; - dualSignalResMap.put(statusbarFakeId, MainModule.resHooks.addResource(statusbarFakeId, iconResId)); + String iconStyle = selectedIconStyle; + String dualIconResName = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!iconStyle.equals("") ? ("_" + iconStyle) : ""); + if (iconStyle.equals("theme")) { + int fakeResId = ResourceHooks.getFakeResId(dualIconResName); + dualSignalResMap.put(dualIconResName, fakeResId); + dualSignalId2NameMap.put(fakeResId, dualIconResName); + } + else { + int iconResId = modRes.getIdentifier(dualIconResName, "drawable", Helpers.modulePkg); + dualSignalResMap.put(dualIconResName, MainModule.resHooks.addResource(dualIconResName, iconResId)); } } } @@ -8248,7 +8250,7 @@ protected void before(final MethodHookParam param) throws Throwable { Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); Object mMobile = XposedHelpers.getObjectField(param.thisObject, "mMobile"); String colorMode = ""; - if (mUseTint) { + if (mUseTint && !selectedIconStyle.equals("theme")) { colorMode = "_tint"; } else if (!mLight) { @@ -8258,8 +8260,8 @@ else if (!mLight) { if (!selectedIconStyle.equals("")) { iconStyle = "_" + selectedIconStyle; } - String sim1IconId = "cust_statusbar_signal_1_" + level1 + colorMode + iconStyle; - String sim2IconId = "cust_statusbar_signal_2_" + subStrengthId + colorMode + iconStyle; + String sim1IconId = "statusbar_signal_1_" + level1 + colorMode + iconStyle; + String sim2IconId = "statusbar_signal_2_" + subStrengthId + colorMode + iconStyle; int sim1ResId = dualSignalResMap.get(sim1IconId); int sim2ResId = dualSignalResMap.get(sim2IconId); XposedHelpers.callMethod(mMobile, "setImageResource", sim1ResId); @@ -8284,6 +8286,42 @@ protected void after(final MethodHookParam param) throws Throwable { } }); } + + if (selectedIconStyle.equals("theme")) { + Helpers.findAndHookMethod("android.content.res.AssetManager", lpparam.classLoader, "getResourceValue", int.class, int.class, TypedValue.class, boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int resId = (int) param.args[0]; + String resName = dualSignalId2NameMap.get(resId); + if (resName != null) { + TypedValue tv = (TypedValue) param.args[2]; + tv.assetCookie = 17; + tv.type = 3; + tv.string = "res/drawable/" + resName + ".png"; + tv.resourceId = resId; + tv.changingConfigurations = 0; + tv.data = resId & 0x0000ffff; + param.setResult(true); + } + } + }); + Helpers.hookAllMethods("android.content.res.ResourcesImpl", lpparam.classLoader, "loadDrawableForCookie", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int resId = (int) param.args[2]; + String resName = dualSignalId2NameMap.get(resId); + if (resName != null) { + Object dr; + Object mLookupStack = XposedHelpers.getObjectField(param.thisObject, "mLookupStack"); + Object stack = XposedHelpers.callMethod(mLookupStack, "get"); + XposedHelpers.callMethod(stack, "push", resId); + dr = XposedHelpers.callMethod(param.args[0], "loadOverlayDrawable", param.args[1], param.args[2]); + XposedHelpers.callMethod(stack, "pop"); + param.setResult(dr); + } + } + }); + } } public static void AddFiveGTileHook(LoadPackageParam lpparam) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 59111102..cde3cdd7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -1299,8 +1299,9 @@ public static synchronized Context getModuleContext(Context context) throws Thro } public static synchronized Context getModuleContext(Context context, Configuration config) throws Throwable { - if (mModuleContext == null) - mModuleContext = context.createPackageContext(modulePkg, Context.CONTEXT_IGNORE_SECURITY).createDeviceProtectedStorageContext(); + if (mModuleContext == null) { + mModuleContext = context.createPackageContext(modulePkg, Context.CONTEXT_IGNORE_SECURITY).createDeviceProtectedStorageContext(); + } return config == null ? mModuleContext : mModuleContext.createConfigurationContext(config); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index 112c9032..02999ad4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -24,8 +24,8 @@ public enum ReplacementType { private final SparseIntArray fakes = new SparseIntArray(); private final ConcurrentHashMap> replacements = new ConcurrentHashMap>(); - private static int getFakeResId(String resourceName) { - return 0x7e000000 | (resourceName.hashCode() & 0x00ffffff); + public static int getFakeResId(String resourceName) { + return 0x7f000000 | (resourceName.hashCode() & 0x00ffffff); } @SuppressWarnings("FieldCanBeLocal") diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 199eded0..f3eed63f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -827,6 +827,7 @@ 原本 永久 加粗 + 跟随主题 无限制 Wi-Fi已启用 Wi-Fi已禁用 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 9751da9f..58f9723f 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -457,10 +457,12 @@ @string/array_default @string/array_dualsimin2rows_style_thick + @string/array_dualsimin2rows_style_theme thick + theme diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a89507c..e35d4e45 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -895,6 +895,8 @@ Temperature Only Current Only Thick + Follow the theme + Unlimited Wi-Fi enabled From cfd69fb94dd90bc3b0a4aeeeb620463ebc946c0e Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 13:30:23 +0800 Subject: [PATCH 260/627] =?UTF-8?q?feat:=20more=20style=20tweak=20for=20du?= =?UTF-8?q?al=20signal=E3=80=81network=20speed=E3=80=81battery=20info=20in?= =?UTF-8?q?=20status=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../name/mikanoshi/customiuizer/MainModule.java | 1 + .../name/mikanoshi/customiuizer/mods/System.java | 16 ++++++++++++++-- app/src/main/res/xml/prefs_system.xml | 16 ++++++++++++++-- .../res/xml/prefs_system_detailednetspeed.xml | 5 +++++ ...fs_system_statusbar_batterytempandcurrent.xml | 6 ++++++ 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 0f8d833e..0be57271 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -290,6 +290,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getInt("system_netspeed_verticaloffset", 8) != 8 || mPrefs.getBoolean("system_fixmeter") || mPrefs.getBoolean("system_detailednetspeed") + || mPrefs.getBoolean("system_netspeed_bold") ) { System.NetSpeedStyleHook(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 45c475bb..587c3009 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5026,6 +5026,9 @@ private static TextView createBatteryDetailView(Context mContext, LinearLayout.L batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); } batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize); + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_bold")) { + batteryView.setTypeface(Typeface.DEFAULT_BOLD); + } int leftMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_leftmargin", 8); leftMargin = (int)TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, @@ -6274,6 +6277,9 @@ protected void after(MethodHookParam param) throws Throwable { if (fontSize != 14) { meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); } + if (MainModule.mPrefs.getBoolean("system_netspeed_bold")) { + meter.setTypeface(Typeface.DEFAULT_BOLD); + } int horizMargin = 0; if (MainModule.mPrefs.getBoolean("system_fixmeter")) { @@ -8270,7 +8276,8 @@ else if (!mLight) { }; Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyDarknessInternal", resetImageDrawable); int rightMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_rightmargin", 0); - if (rightMargin > 0) { + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_leftmargin", 0); + if (rightMargin > 0 || leftMargin > 0) { Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "init", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { @@ -8282,7 +8289,12 @@ protected void after(final MethodHookParam param) throws Throwable { rightMargin * 0.5f, res.getDisplayMetrics() ); - mobileView.setPadding(0, 0, rightSpacing, 0); + int leftSpacing = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin * 0.5f, + res.getDisplayMetrics() + ); + mobileView.setPadding(leftSpacing, 0, rightSpacing, 0); } }); } diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index a0154c4c..31c30ba5 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -355,7 +355,7 @@ android:defaultValue="7" miuizer:child="true" miuizer:minValue="2" - miuizer:maxValue="10" + miuizer:maxValue="16" miuizer:stepValue="1" miuizer:displayDividerValue="2" miuizer:format="%s dip" /> @@ -422,6 +422,18 @@ miuizer:valueAsSummary="true" android:defaultValue="" /> + + diff --git a/app/src/main/res/xml/prefs_system_detailednetspeed.xml b/app/src/main/res/xml/prefs_system_detailednetspeed.xml index cdf69965..103de603 100644 --- a/app/src/main/res/xml/prefs_system_detailednetspeed.xml +++ b/app/src/main/res/xml/prefs_system_detailednetspeed.xml @@ -31,6 +31,11 @@ miuizer:displayDividerValue="2" miuizer:format="%s dip" /> + + + + Date: Mon, 9 Jan 2023 13:36:02 +0800 Subject: [PATCH 261/627] disable app verify option on miui 14 temporarily --- app/src/main/java/name/mikanoshi/customiuizer/MainModule.java | 4 +++- .../main/java/name/mikanoshi/customiuizer/subs/System.java | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 0be57271..68727fe4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -154,7 +154,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_forceclose")) System.ForceCloseHook(lpparam); if (mPrefs.getBoolean("system_hideproxywarn")) System.HideProximityWarningHook(lpparam); if (mPrefs.getBoolean("system_firstpress")) System.FirstVolumePressHook(lpparam); - if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyServiceHook(lpparam); + if (Helpers.isTPlus()) { + if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyServiceHook(lpparam); + } if (mPrefs.getBoolean("system_apksign") || mPrefs.getBoolean("system_disableintegrity")) System.DisableSystemIntegrityHook(lpparam); if (mPrefs.getBoolean("system_vibration_amp")) System.MuffledVibrationHook(lpparam); if (mPrefs.getBoolean("system_clearalltasks")) System.ClearAllTasksHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index d9c4d4e9..a314bdff 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -381,6 +381,10 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { case "pref_key_system_cat_other": findPreference("pref_key_system_forceclose_apps").setOnPreferenceClickListener(openAppsEdit); + if (Helpers.isTPlus()) { + ((CheckBoxPreferenceEx)findPreference("pref_key_system_apksign")).setUnsupported(true); + } + findPreference("pref_key_system_cleanshare_apps").setOnPreferenceClickListener(openShareEdit); findPreference("pref_key_system_cleanshare_test").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override From 279f87faaa2204b3285d4f62ebaf2fa3543fe27d Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 17:09:27 +0800 Subject: [PATCH 262/627] refactor: show brightness pct --- .../mikanoshi/customiuizer/mods/System.java | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 587c3009..d137b2f8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5400,29 +5400,33 @@ protected void after(final MethodHookParam param) throws Throwable { } }); - Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStart", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Object mMirror = XposedHelpers.getObjectField(param.thisObject, "mControl"); - Object controlCenterWindowViewController = XposedHelpers.getObjectField(mMirror, "controlCenterWindowViewController"); - Object windowView = XposedHelpers.callMethod(controlCenterWindowViewController, "getView"); - if (windowView == null) { - Helpers.log("BrightnessPctHook", "mControlPanelContentView is null"); - return; - } - initPct((ViewGroup) windowView, 1, mContext); - mPct.setVisibility(View.VISIBLE); - mPct.animate().alpha(1.0f).setDuration(300).start(); - } - }); - - Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStop", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - if (mPct != null) mPct.setVisibility(View.GONE); - } - }); +// Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStart", new MethodHook() { +// @Override +// protected void before(final MethodHookParam param) throws Throwable { +// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); +// Object mMirror = XposedHelpers.getObjectField(param.thisObject, "mControl"); +// Object controlCenterWindowViewController = XposedHelpers.getObjectField(mMirror, "controlCenterWindowViewController"); +// String ClsName = controlCenterWindowViewController.getClass().getName(); +// if (!ClsName.equals("ControlCenterWindowViewController")) { +// controlCenterWindowViewController = XposedHelpers.callMethod(controlCenterWindowViewController, "get"); +// } +// Object windowView = XposedHelpers.callMethod(controlCenterWindowViewController, "getView"); +// if (windowView == null) { +// Helpers.log("BrightnessPctHook", "mControlPanelContentView is null"); +// return; +// } +// initPct((ViewGroup) windowView, 1, mContext); +// mPct.setVisibility(View.VISIBLE); +// mPct.animate().alpha(1.0f).setDuration(300).start(); +// } +// }); +// +// Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStop", new MethodHook() { +// @Override +// protected void after(final MethodHookParam param) throws Throwable { +// if (mPct != null) mPct.setVisibility(View.GONE); +// } +// }); final Class BrightnessUtils = XposedHelpers.findClassIfExists("com.android.systemui.controlcenter.policy.BrightnessUtils", lpparam.classLoader); Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onChanged", new MethodHook() { From 4b68e6430a247fda34f0a2072870209ba717c19f Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 17:45:11 +0800 Subject: [PATCH 263/627] fix: netspeed font size auto save failed --- .../mikanoshi/customiuizer/prefs/SeekBarPreference.java | 6 ++++++ .../main/java/name/mikanoshi/customiuizer/subs/System.java | 4 ++-- app/src/main/res/values-zh-rCN/strings.xml | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java index bc8e1a23..5d2d28db 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java @@ -206,9 +206,15 @@ public int getValue() { } public void setValue(int value) { + setValue(value, false); + } + public void setValue(int value, boolean save) { value = getBoundedValue(value) - mSteppedMinValue; mSeekBar.setProgress(value); updateDisplay(value); + if (save) { + saveValue(); + } } public void setDefaultValue(int value) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index a314bdff..71fd1494 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -533,10 +533,10 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) { SeekBarPreference netspeedFontSizePref = findPreference("pref_key_system_netspeed_fontsize"); if ((Boolean)newValue) { - netspeedFontSizePref.setValue(16); + netspeedFontSizePref.setValue(16, true); } else { - netspeedFontSizePref.setValue(14); + netspeedFontSizePref.setValue(14, true); } return true; } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f3eed63f..320ddb4a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -276,7 +276,7 @@ 禁用向左滑动手势 向左滑动作 更改右侧图标 - 用 CustoMIUIzer 图标替换相机图标 + 用米客图标替换相机图标 拖动图标用以执行自定义动作 禁用右滑手势 左侧屏幕快捷方式 @@ -967,7 +967,7 @@ 证书已解锁! 未找到Xposed应用 您似乎没有安装Xposed Framework。\n\n请注意,模块仅适用于Xposed! - CustoMIUIzer模块未被激活!\n请打开LSPosed应用,激活模块并重启。 + 米客模块未被激活!\n请打开LSPosed应用,激活模块并重启。 打开网址需要浏览器应用 好的 取消 From 934ab4cf00e1f3afff3684fa08f63e08563f4b6d Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 18:18:57 +0800 Subject: [PATCH 264/627] feat: dual signal icon scale --- .../mikanoshi/customiuizer/mods/System.java | 23 ++++++++++++++++++- app/src/main/res/xml/prefs_system.xml | 12 ++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d137b2f8..cc8d78e9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8281,7 +8281,8 @@ else if (!mLight) { Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyDarknessInternal", resetImageDrawable); int rightMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_rightmargin", 0); int leftMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_leftmargin", 0); - if (rightMargin > 0 || leftMargin > 0) { + int iconScale = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_scale", 10); + if (rightMargin > 0 || leftMargin > 0 || iconScale != 10) { Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "init", new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { @@ -8299,6 +8300,26 @@ protected void after(final MethodHookParam param) throws Throwable { res.getDisplayMetrics() ); mobileView.setPadding(leftSpacing, 0, rightSpacing, 0); + + if (iconScale != 10) { + View mMobile = (View) XposedHelpers.getObjectField(param.thisObject, "mMobile"); + View mSmallRoaming = (View) XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mMobile.getLayoutParams(); + int mIconHeight = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 20 * iconScale / 10f, + res.getDisplayMetrics() + ); + Helpers.log("fad " + (layoutParams != null)); + if (layoutParams == null) { + layoutParams = new FrameLayout.LayoutParams(-2, mIconHeight); + } else { + layoutParams.height = mIconHeight; + } + layoutParams.gravity = Gravity.CENTER; + mMobile.setLayoutParams(layoutParams); + mSmallRoaming.setLayoutParams(layoutParams); + } } }); } diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 31c30ba5..bebcd0a2 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -422,6 +422,18 @@ miuizer:valueAsSummary="true" android:defaultValue="" /> + + Date: Mon, 9 Jan 2023 20:05:23 +0800 Subject: [PATCH 265/627] feat: keep app updated tips --- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_main.xml | 1 + 3 files changed, 3 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 320ddb4a..cd002ef9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -875,6 +875,7 @@ 如果您希望收到对崩溃报告的回复,此项当然是必填的。请使用电子邮箱、ICQ、XDA或者4PDA的昵称。 支持 代码仓库 + Star仓库,关注App更新 酷安 @tpsxx 版本下载 云盘密码: miui,可长按复制链接 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e35d4e45..bc0523b1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -950,6 +950,7 @@ Support Code and Issues + Star repository to keep app updated Contact me Releases Github Releases diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 49a2494a..6e7ecba4 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -66,6 +66,7 @@ android:key="pref_key_releases" /> Date: Mon, 9 Jan 2023 21:49:37 +0800 Subject: [PATCH 266/627] feat: hide battery icon pct mark --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 2 +- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 6 ++++++ app/src/main/res/values-pl-rPL/strings.xml | 1 - app/src/main/res/values-ru-rRU/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 4 ++-- app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 4 ++-- app/src/main/res/xml/prefs_system_hideicons.xml | 6 +++++- 8 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 68727fe4..7b3f259f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -304,7 +304,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_secureqs")) System.SecureQSTilesHook(lpparam); if (mPrefs.getBoolean("system_mutevisiblenotif")) System.MuteVisibleNotificationsHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery1")) System.HideIconsBattery1Hook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_battery3") || mPrefs.getBoolean("system_statusbaricons_battery2")) System.HideIconsBattery2Hook(lpparam); + if (mPrefs.getBoolean("system_statusbaricons_battery3") || mPrefs.getBoolean("system_statusbaricons_battery2") || mPrefs.getBoolean("system_statusbaricons_battery4")) System.HideIconsBattery2Hook(lpparam); if (mPrefs.getStringAsInt("system_statusbaricons_wifistandard", 1) > 1) System.DisplayWifiStandardHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_signal") || mPrefs.getBoolean("system_statusbaricons_sim1") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index cc8d78e9..de6bb051 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -3783,7 +3783,13 @@ public static void HideIconsBattery2Hook(LoadPackageParam lpparam) { protected void after(MethodHookParam param) throws Throwable { if (MainModule.mPrefs.getBoolean("system_statusbaricons_battery2")) { TextView mBatteryTextDigitView = (TextView)XposedHelpers.getObjectField(param.thisObject, "mBatteryTextDigitView"); + TextView mBatteryPercentView = (TextView)XposedHelpers.getObjectField(param.thisObject, "mBatteryPercentView"); mBatteryTextDigitView.setVisibility(View.GONE); + mBatteryPercentView.setVisibility(View.GONE); + } + if (MainModule.mPrefs.getBoolean("system_statusbaricons_battery2") || MainModule.mPrefs.getBoolean("system_statusbaricons_battery4")) { + TextView mBatteryPercentMarkView = (TextView)XposedHelpers.getObjectField(param.thisObject, "mBatteryPercentMarkView"); + mBatteryPercentMarkView.setVisibility(View.GONE); } if (MainModule.mPrefs.getBoolean("system_statusbaricons_battery3")) { ImageView mBatteryChargingView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mBatteryChargingView"); diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index cf6d5105..9e575ee9 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -36,7 +36,6 @@ Ikona baterii Procent naładowania baterii Wskaźnik ładowania - Może być nałożone na ikonę baterii w niektórych ROMach Alarm Ukryj się całkowicie Selektywna widoczność ikony alarmu diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index b35bfa02..53b73a3c 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -647,7 +647,6 @@ Изображение батареи Процент заряда батареи Индикатор зарядки - На некоторых прошивках может быть наложен поверх изображения батареи Будильник Скрыть полностью Избирательное отображение будильника diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index cd002ef9..50876364 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -33,9 +33,9 @@ 管理状态栏图标可见性 显示Wi-Fi标准 电池图片 - 电池充电百分比 + 电池电量数字 + 电池百分比符号 充电指示器 - 可以叠加在某些ROM的电池图标上 闹钟 完全隐藏 选择闹钟图标的可见性 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 523f39b2..9751c9fa 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -862,7 +862,6 @@ 電池圖片 電池充電百分比 充電指示器 - 可以疊加在某些ROM的電池圖示上 勿擾模式 耳機 熱點 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bc0523b1..9eaa46e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,9 +36,9 @@ Manage status bar icons visibility Show Wi-Fi standard Battery image - Battery charge percentage + Battery digit + Battery percentage mark Charging indicator - Can be overlayed on top of battery image on some ROMs Alarm Hide completely Selective alarm icon visibility diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index f7a753dd..1419ba48 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -12,7 +12,11 @@ + + Date: Mon, 9 Jan 2023 22:02:02 +0800 Subject: [PATCH 267/627] feat: move headset to right side of status bar --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../main/java/name/mikanoshi/customiuizer/mods/System.java | 4 ++++ app/src/main/res/xml/prefs_system_statusbar_righticons.xml | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 7b3f259f..04b1783f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -264,6 +264,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_statusbar_dnd_atright") || mPrefs.getBoolean("system_statusbar_nfc_atright") || mPrefs.getBoolean("system_statusbar_btbattery_atright") + || mPrefs.getBoolean("system_statusbar_headset_atright") ) { System.StatusBarIconsAtRightHook(lpparam); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index de6bb051..bca7440e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5251,6 +5251,7 @@ protected void before(MethodHookParam param) throws Throwable { || ("volume".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) || ("zen".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) || ("nfc".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) + || ("headset".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) ) { param.args[1] = false; } @@ -5293,6 +5294,9 @@ protected void after(MethodHookParam param) throws Throwable { if (MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) { rightBlockList.remove("nfc"); } + if (MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) { + rightBlockList.remove("headset"); + } if (blockList != null) { XposedHelpers.setStaticObjectField(MiuiEndIconManager, "RIGHT_BLOCK_LIST", rightBlockList); } diff --git a/app/src/main/res/xml/prefs_system_statusbar_righticons.xml b/app/src/main/res/xml/prefs_system_statusbar_righticons.xml index ee16b747..8d5899f2 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_righticons.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_righticons.xml @@ -52,4 +52,9 @@ android:title="@string/system_statusbaricons_nfc_title" android:defaultValue="false" /> + + \ No newline at end of file From 151409ac2aa58770c8caf5d4c3ed5754432b4405 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 23:20:23 +0800 Subject: [PATCH 268/627] fix: recents background blur --- .../name/mikanoshi/customiuizer/mods/Launcher.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index ae26391a..cbc72cc1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1446,10 +1446,16 @@ public void onChange(String name, int defValue) { return; } - Helpers.hookAllMethods(utilsClass, "fastBlurWhenUseCompleteRecentsBlur", new MethodHook() { + Helpers.hookAllMethods(utilsClass, "fastBlurWhenEnterRecents", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - param.args[1] = MainModule.mPrefs.getInt("system_recents_blur", 100) / 100f; + boolean mIsFromFsGesture = XposedHelpers.getBooleanField(param.args[1], "mIsFromFsGesture"); + if (!mIsFromFsGesture) { + Activity launcher = (Activity) param.args[0]; + float blurRatio = MainModule.mPrefs.getInt("system_recents_blur", 100) / 100f; + XposedHelpers.callStaticMethod(utilsClass, "fastBlur", blurRatio, launcher.getWindow(), param.args[2]); + param.setResult(null); + } } }); } From b65c84e6d112da13567a4a81c585fd700b120158 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 23:32:46 +0800 Subject: [PATCH 269/627] i18n: minor fix --- app/src/main/res/values-zh-rCN/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 50876364..b67c0430 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -492,8 +492,8 @@ 动态页面指示器 仅在滚动时显示页面指示器 仅在编辑模式中显示 - 解锁网格大小 - 可在主屏幕布局设置中使用3x4到10x10之间的所有网格大小 + 解锁桌面布局 + 可在系统桌面布局设置中使用3x4到10x10之间的所有布局 增加底栏图标 解除底栏图标数量的限制 图标缩放 From 9ba6728c8d0e4dff7746b0a45a47423264e039c5 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 9 Jan 2023 23:53:40 +0800 Subject: [PATCH 270/627] fix: background blur in recents view when fs gesture is enabled --- .../mikanoshi/customiuizer/mods/Launcher.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index cbc72cc1..b3b85838 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1458,6 +1458,25 @@ protected void before(MethodHookParam param) throws Throwable { } } }); + Helpers.hookAllMethods(utilsClass, "fastBlurWhenGestureResetTaskView", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.setAdditionalStaticField(utilsClass, "customBlurRatio", true); + } + }); + + Helpers.hookAllMethods(utilsClass, "fastBlur", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (param.args.length == 3) { + if (XposedHelpers.getAdditionalStaticField(utilsClass, "customBlurRatio") != null) { + float blurRatio = MainModule.mPrefs.getInt("system_recents_blur", 100) / 100f; + param.args[0] = blurRatio; + XposedHelpers.removeAdditionalStaticField(utilsClass, "customBlurRatio"); + } + } + } + }); } public static void CloseFolderOrDrawerOnLaunchShortcutMenuHook(LoadPackageParam lpparam) { From 2c17126d93ed8f9dee78df888080158aa3727645 Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 10 Jan 2023 13:12:13 +0800 Subject: [PATCH 271/627] fix #104 Extra navbar buttons swap sides on screen rotation --- .../mikanoshi/customiuizer/mods/Controls.java | 140 ++++++++++-------- .../customiuizer/utils/ResourceHooks.java | 2 +- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java index ee8486f6..0575298b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java @@ -2,7 +2,6 @@ import android.annotation.SuppressLint; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -22,7 +21,7 @@ import android.telephony.TelephonyManager; import android.view.Gravity; import android.view.KeyEvent; -import android.view.MotionEvent; +import android.view.Surface; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; @@ -333,11 +332,66 @@ private static boolean handleNavBarAction(Context context, String key) { } } - private static void addCustomNavBarKeys(boolean isVertical, Context mContext, FrameLayout navButtons, Class kbrCls) { + private static void reposNavBarButtons(FrameLayout navbar) { + Context mContext = navbar.getContext(); + int displayRotation = navbar.getContext().getDisplay().getRotation(); float density = mContext.getResources().getDisplayMetrics().density; - int two = Math.round(2 * density); int margin = Math.round(MainModule.mPrefs.getInt("controls_navbarmargin", 0) * density); + Helpers.log("displayRotation is " + displayRotation); + if (displayRotation == Surface.ROTATION_0) { + ImageView hleft = navbar.findViewWithTag("custom_left_horiz"); + if (hleft != null) { + LinearLayout leftbtn = (LinearLayout) hleft.getParent(); + FrameLayout.LayoutParams lpl = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT); + lpl.leftMargin += margin; + lpl.gravity = Gravity.START | Gravity.CENTER_VERTICAL; + leftbtn.setLayoutParams(lpl); + } + + ImageView hright = navbar.findViewWithTag("custom_right_horiz"); + if (hright != null) { + LinearLayout rightbtn = (LinearLayout) hright.getParent(); + FrameLayout.LayoutParams lpr = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT); + lpr.rightMargin += margin; + lpr.gravity = Gravity.END | Gravity.CENTER_VERTICAL; + rightbtn.setLayoutParams(lpr); + } + } + else { + ImageView vleft = navbar.findViewWithTag("custom_left_vert"); + ImageView vright = navbar.findViewWithTag("custom_right_vert"); + + LinearLayout leftbtn = null; + if (vleft != null) { + leftbtn = (LinearLayout) vleft.getParent(); + } + FrameLayout.LayoutParams lpl = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); + + LinearLayout rightbtn = null; + if (vright != null) { + rightbtn = (LinearLayout) vright.getParent(); + } + FrameLayout.LayoutParams lpr = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); + if (displayRotation == Surface.ROTATION_270) { + lpl.topMargin += margin; + lpl.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; + lpr.bottomMargin += margin; + lpr.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + } + else if (displayRotation == Surface.ROTATION_90) { + lpr.topMargin += margin; + lpr.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; + + lpl.bottomMargin += margin; + lpl.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + } + if (leftbtn != null) leftbtn.setLayoutParams(lpl); + if (rightbtn != null) rightbtn.setLayoutParams(lpr); + } + } + + private static void addCustomNavBarKeys(boolean isVertical, Context mContext, FrameLayout navButtons, Class kbrCls) { Drawable dot1; Drawable dot2; try { @@ -350,8 +404,6 @@ private static void addCustomNavBarKeys(boolean isVertical, Context mContext, Fr return; } - int diff1 = (dot1.getIntrinsicWidth() - dot1.getIntrinsicHeight()) / 2; - int diff2 = (dot2.getIntrinsicWidth() - dot2.getIntrinsicHeight()) / 2; LinearLayout leftbtn = new LinearLayout(mContext); ImageView left = new ImageView(mContext); @@ -361,20 +413,8 @@ private static void addCustomNavBarKeys(boolean isVertical, Context mContext, Fr else lplc = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); left.setLayoutParams(lplc); - - LinearLayout.LayoutParams lpl = new LinearLayout.LayoutParams(lplc); - if (isVertical) - lpl.bottomMargin += margin; - else - lpl.leftMargin += margin; - leftbtn.setLayoutParams(lpl); - - left.setScaleType(ImageView.ScaleType.CENTER); left.setImageDrawable(dot1); - left.setScaleX(0.7f); - left.setScaleY(0.7f); left.setAlpha(0.9f); - left.setPadding(isVertical ? 0 : two, isVertical ? two + diff1 : 0, isVertical ? 0 : two, isVertical ? two + diff1 : 0); left.setTag("custom_left" + (isVertical ? "_vert" : "_horiz")); if (kbrCls != null) try { Drawable lripple = (Drawable)kbrCls.getConstructor(Context.class, View.class).newInstance(mContext, leftbtn); @@ -404,24 +444,8 @@ public boolean onLongClick(View v) { else lprc = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); right.setLayoutParams(lprc); - - FrameLayout.LayoutParams lpr = new FrameLayout.LayoutParams(lprc); - if (isVertical) { - lpr.topMargin += margin; - lpr.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; - } - else { - lpr.rightMargin += margin; - lpr.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL; - } - rightbtn.setLayoutParams(lpr); - - right.setScaleType(ImageView.ScaleType.CENTER); right.setImageDrawable(dot2); - right.setScaleX(0.7f); - right.setScaleY(0.7f); right.setAlpha(0.9f); - right.setPadding(isVertical ? 0 : two, isVertical ? two + diff2 : 0, isVertical ? 0 : two, isVertical ? two + diff2 : 0); right.setTag("custom_right" + (isVertical ? "_vert" : "_horiz")); if (kbrCls != null) try { Drawable rripple = (Drawable)kbrCls.getConstructor(Context.class, View.class).newInstance(mContext, rightbtn); @@ -443,12 +467,6 @@ public boolean onLongClick(View v) { }); rightbtn.addView(right); -// View startPadding = navButtons.findViewById(navButtons.getResources().getIdentifier("start_padding", "id", pkgName)); -// View sidePadding = navButtons.findViewById(navButtons.getResources().getIdentifier("side_padding", "id", pkgName)); -// -// LinearLayout.LayoutParams lp1 = (LinearLayout.LayoutParams)startPadding.getLayoutParams(); -// LinearLayout.LayoutParams lp2 = (LinearLayout.LayoutParams)sidePadding.getLayoutParams(); - boolean hasLeftAction = MainModule.mPrefs.getInt("controls_navbarleft_action", 1) > 1 || MainModule.mPrefs.getInt("controls_navbarleftlong_action", 1) > 1; boolean hasRightAction = MainModule.mPrefs.getInt("controls_navbarright_action", 1) > 1 || MainModule.mPrefs.getInt("controls_navbarrightlong_action", 1) > 1; @@ -457,52 +475,39 @@ public boolean onLongClick(View v) { if (hasRightAction) { navButtons.addView(rightbtn, 0); // lp2.weight = Math.round(lp2.weight * part); -// sidePadding.setLayoutParams(lp2); -// sidePadding.setPadding(sidePadding.getPaddingLeft(), sidePadding.getPaddingTop() / 3, sidePadding.getPaddingRight(), sidePadding.getPaddingBottom()); } if (hasLeftAction) { navButtons.addView(leftbtn, navButtons.getChildCount()); // lp1.weight = Math.round(lp1.weight * part); -// startPadding.setLayoutParams(lp1); } } else { if (hasLeftAction) { navButtons.addView(leftbtn, 0); // lp1.weight = Math.round(lp1.weight * part); -// startPadding.setLayoutParams(lp1); } if (hasRightAction) { navButtons.addView(rightbtn, navButtons.getChildCount()); // lp2.weight = Math.round(lp2.weight * part); -// sidePadding.setLayoutParams(lp2); -// sidePadding.setPadding(sidePadding.getPaddingLeft(), sidePadding.getPaddingTop(), sidePadding.getPaddingRight() / 3, sidePadding.getPaddingBottom()); } } } public static void NavBarButtonsHook(LoadPackageParam lpparam) { - - Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBar", lpparam.classLoader, Helpers.isTPlus() ? "onViewAttached" : "onViewAttachedToWindow", new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBarView", lpparam.classLoader, "updateOrientationViews", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (mContext == null) { - Helpers.log("NavBarButtonsHook", "Cannot find context"); - return; - } - FrameLayout mNavigationBarView = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, Helpers.isTPlus() ? "mView" : "mNavigationBarView"); - if (mNavigationBarView == null) { - Helpers.log("NavBarButtonsHook", "Cannot find navbar layout"); - return; - } - ViewGroup mHorizontal = mNavigationBarView.findViewById(mNavigationBarView.getResources().getIdentifier("horizontal", "id", lpparam.packageName)); - ViewGroup mVertical = mNavigationBarView.findViewById(mNavigationBarView.getResources().getIdentifier("vertical", "id", lpparam.packageName)); - FrameLayout navButtons0 = mHorizontal.findViewById(mNavigationBarView.getResources().getIdentifier("nav_buttons", "id", lpparam.packageName)); - FrameLayout navButtons90 = mVertical.findViewById(mNavigationBarView.getResources().getIdentifier("nav_buttons", "id", lpparam.packageName)); + FrameLayout navBar = (FrameLayout) param.thisObject; + Context mContext = navBar.getContext(); + ViewGroup mHorizontal = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mHorizontal"); + ViewGroup mVertical = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mVertical"); + int navButtonsId = navBar.getResources().getIdentifier("nav_buttons", "id", lpparam.packageName); + FrameLayout navButtons0 = mHorizontal.findViewById(navButtonsId); + FrameLayout navButtons90 = mVertical.findViewById(navButtonsId); Class kbrCls = XposedHelpers.findClassIfExists("com.android.systemui.statusbar.phone.MiuiKeyButtonRipple", lpparam.classLoader); addCustomNavBarKeys(false, mContext, navButtons0, kbrCls); addCustomNavBarKeys(true, mContext, navButtons90, kbrCls); + reposNavBarButtons(navBar); } }); @@ -535,6 +540,17 @@ protected void after(MethodHookParam param) throws Throwable { } } }); + Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBarView", lpparam.classLoader, "onConfigurationChanged", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + FrameLayout navbar = (FrameLayout) param.thisObject; +// int displayRotation = navbar.getContext().getDisplay().getRotation(); +// int mCurrentRotation = XposedHelpers.getIntField(param.thisObject, "mCurrentRotation"); +// if (mCurrentRotation != displayRotation) { + reposNavBarButtons(navbar); +// } + } + }); } @SuppressLint("MissingPermission") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index 02999ad4..e05fd9dd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -25,7 +25,7 @@ public enum ReplacementType { private final ConcurrentHashMap> replacements = new ConcurrentHashMap>(); public static int getFakeResId(String resourceName) { - return 0x7f000000 | (resourceName.hashCode() & 0x00ffffff); + return 0x7e000000 | (resourceName.hashCode() & 0x00ffffff); } @SuppressWarnings("FieldCanBeLocal") From c3bfe5b8c335ebf9ee8ba2181d93cc8231d27e4f Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 10 Jan 2023 13:12:13 +0800 Subject: [PATCH 272/627] fix #104 Extra navbar buttons swap sides on screen rotation --- .../mikanoshi/customiuizer/mods/Controls.java | 139 ++++++++++-------- .../customiuizer/utils/ResourceHooks.java | 2 +- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java index ee8486f6..9706e141 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java @@ -2,7 +2,6 @@ import android.annotation.SuppressLint; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -22,7 +21,7 @@ import android.telephony.TelephonyManager; import android.view.Gravity; import android.view.KeyEvent; -import android.view.MotionEvent; +import android.view.Surface; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; @@ -333,11 +332,65 @@ private static boolean handleNavBarAction(Context context, String key) { } } - private static void addCustomNavBarKeys(boolean isVertical, Context mContext, FrameLayout navButtons, Class kbrCls) { + private static void reposNavBarButtons(FrameLayout navbar) { + Context mContext = navbar.getContext(); + int displayRotation = navbar.getContext().getDisplay().getRotation(); float density = mContext.getResources().getDisplayMetrics().density; - int two = Math.round(2 * density); int margin = Math.round(MainModule.mPrefs.getInt("controls_navbarmargin", 0) * density); + if (displayRotation == Surface.ROTATION_0) { + ImageView hleft = navbar.findViewWithTag("custom_left_horiz"); + if (hleft != null) { + LinearLayout leftbtn = (LinearLayout) hleft.getParent(); + FrameLayout.LayoutParams lpl = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT); + lpl.leftMargin += margin; + lpl.gravity = Gravity.START | Gravity.CENTER_VERTICAL; + leftbtn.setLayoutParams(lpl); + } + + ImageView hright = navbar.findViewWithTag("custom_right_horiz"); + if (hright != null) { + LinearLayout rightbtn = (LinearLayout) hright.getParent(); + FrameLayout.LayoutParams lpr = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT); + lpr.rightMargin += margin; + lpr.gravity = Gravity.END | Gravity.CENTER_VERTICAL; + rightbtn.setLayoutParams(lpr); + } + } + else { + ImageView vleft = navbar.findViewWithTag("custom_left_vert"); + ImageView vright = navbar.findViewWithTag("custom_right_vert"); + + LinearLayout leftbtn = null; + if (vleft != null) { + leftbtn = (LinearLayout) vleft.getParent(); + } + FrameLayout.LayoutParams lpl = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); + + LinearLayout rightbtn = null; + if (vright != null) { + rightbtn = (LinearLayout) vright.getParent(); + } + FrameLayout.LayoutParams lpr = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); + if (displayRotation == Surface.ROTATION_270) { + lpl.topMargin += margin; + lpl.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; + lpr.bottomMargin += margin; + lpr.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + } + else if (displayRotation == Surface.ROTATION_90) { + lpr.topMargin += margin; + lpr.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; + + lpl.bottomMargin += margin; + lpl.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + } + if (leftbtn != null) leftbtn.setLayoutParams(lpl); + if (rightbtn != null) rightbtn.setLayoutParams(lpr); + } + } + + private static void addCustomNavBarKeys(boolean isVertical, Context mContext, FrameLayout navButtons, Class kbrCls) { Drawable dot1; Drawable dot2; try { @@ -350,8 +403,6 @@ private static void addCustomNavBarKeys(boolean isVertical, Context mContext, Fr return; } - int diff1 = (dot1.getIntrinsicWidth() - dot1.getIntrinsicHeight()) / 2; - int diff2 = (dot2.getIntrinsicWidth() - dot2.getIntrinsicHeight()) / 2; LinearLayout leftbtn = new LinearLayout(mContext); ImageView left = new ImageView(mContext); @@ -361,20 +412,8 @@ private static void addCustomNavBarKeys(boolean isVertical, Context mContext, Fr else lplc = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); left.setLayoutParams(lplc); - - LinearLayout.LayoutParams lpl = new LinearLayout.LayoutParams(lplc); - if (isVertical) - lpl.bottomMargin += margin; - else - lpl.leftMargin += margin; - leftbtn.setLayoutParams(lpl); - - left.setScaleType(ImageView.ScaleType.CENTER); left.setImageDrawable(dot1); - left.setScaleX(0.7f); - left.setScaleY(0.7f); left.setAlpha(0.9f); - left.setPadding(isVertical ? 0 : two, isVertical ? two + diff1 : 0, isVertical ? 0 : two, isVertical ? two + diff1 : 0); left.setTag("custom_left" + (isVertical ? "_vert" : "_horiz")); if (kbrCls != null) try { Drawable lripple = (Drawable)kbrCls.getConstructor(Context.class, View.class).newInstance(mContext, leftbtn); @@ -404,24 +443,8 @@ public boolean onLongClick(View v) { else lprc = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); right.setLayoutParams(lprc); - - FrameLayout.LayoutParams lpr = new FrameLayout.LayoutParams(lprc); - if (isVertical) { - lpr.topMargin += margin; - lpr.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; - } - else { - lpr.rightMargin += margin; - lpr.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL; - } - rightbtn.setLayoutParams(lpr); - - right.setScaleType(ImageView.ScaleType.CENTER); right.setImageDrawable(dot2); - right.setScaleX(0.7f); - right.setScaleY(0.7f); right.setAlpha(0.9f); - right.setPadding(isVertical ? 0 : two, isVertical ? two + diff2 : 0, isVertical ? 0 : two, isVertical ? two + diff2 : 0); right.setTag("custom_right" + (isVertical ? "_vert" : "_horiz")); if (kbrCls != null) try { Drawable rripple = (Drawable)kbrCls.getConstructor(Context.class, View.class).newInstance(mContext, rightbtn); @@ -443,12 +466,6 @@ public boolean onLongClick(View v) { }); rightbtn.addView(right); -// View startPadding = navButtons.findViewById(navButtons.getResources().getIdentifier("start_padding", "id", pkgName)); -// View sidePadding = navButtons.findViewById(navButtons.getResources().getIdentifier("side_padding", "id", pkgName)); -// -// LinearLayout.LayoutParams lp1 = (LinearLayout.LayoutParams)startPadding.getLayoutParams(); -// LinearLayout.LayoutParams lp2 = (LinearLayout.LayoutParams)sidePadding.getLayoutParams(); - boolean hasLeftAction = MainModule.mPrefs.getInt("controls_navbarleft_action", 1) > 1 || MainModule.mPrefs.getInt("controls_navbarleftlong_action", 1) > 1; boolean hasRightAction = MainModule.mPrefs.getInt("controls_navbarright_action", 1) > 1 || MainModule.mPrefs.getInt("controls_navbarrightlong_action", 1) > 1; @@ -457,52 +474,39 @@ public boolean onLongClick(View v) { if (hasRightAction) { navButtons.addView(rightbtn, 0); // lp2.weight = Math.round(lp2.weight * part); -// sidePadding.setLayoutParams(lp2); -// sidePadding.setPadding(sidePadding.getPaddingLeft(), sidePadding.getPaddingTop() / 3, sidePadding.getPaddingRight(), sidePadding.getPaddingBottom()); } if (hasLeftAction) { navButtons.addView(leftbtn, navButtons.getChildCount()); // lp1.weight = Math.round(lp1.weight * part); -// startPadding.setLayoutParams(lp1); } } else { if (hasLeftAction) { navButtons.addView(leftbtn, 0); // lp1.weight = Math.round(lp1.weight * part); -// startPadding.setLayoutParams(lp1); } if (hasRightAction) { navButtons.addView(rightbtn, navButtons.getChildCount()); // lp2.weight = Math.round(lp2.weight * part); -// sidePadding.setLayoutParams(lp2); -// sidePadding.setPadding(sidePadding.getPaddingLeft(), sidePadding.getPaddingTop(), sidePadding.getPaddingRight() / 3, sidePadding.getPaddingBottom()); } } } public static void NavBarButtonsHook(LoadPackageParam lpparam) { - - Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBar", lpparam.classLoader, Helpers.isTPlus() ? "onViewAttached" : "onViewAttachedToWindow", new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBarView", lpparam.classLoader, "updateOrientationViews", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (mContext == null) { - Helpers.log("NavBarButtonsHook", "Cannot find context"); - return; - } - FrameLayout mNavigationBarView = (FrameLayout)XposedHelpers.getObjectField(param.thisObject, Helpers.isTPlus() ? "mView" : "mNavigationBarView"); - if (mNavigationBarView == null) { - Helpers.log("NavBarButtonsHook", "Cannot find navbar layout"); - return; - } - ViewGroup mHorizontal = mNavigationBarView.findViewById(mNavigationBarView.getResources().getIdentifier("horizontal", "id", lpparam.packageName)); - ViewGroup mVertical = mNavigationBarView.findViewById(mNavigationBarView.getResources().getIdentifier("vertical", "id", lpparam.packageName)); - FrameLayout navButtons0 = mHorizontal.findViewById(mNavigationBarView.getResources().getIdentifier("nav_buttons", "id", lpparam.packageName)); - FrameLayout navButtons90 = mVertical.findViewById(mNavigationBarView.getResources().getIdentifier("nav_buttons", "id", lpparam.packageName)); + FrameLayout navBar = (FrameLayout) param.thisObject; + Context mContext = navBar.getContext(); + ViewGroup mHorizontal = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mHorizontal"); + ViewGroup mVertical = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mVertical"); + int navButtonsId = navBar.getResources().getIdentifier("nav_buttons", "id", lpparam.packageName); + FrameLayout navButtons0 = mHorizontal.findViewById(navButtonsId); + FrameLayout navButtons90 = mVertical.findViewById(navButtonsId); Class kbrCls = XposedHelpers.findClassIfExists("com.android.systemui.statusbar.phone.MiuiKeyButtonRipple", lpparam.classLoader); addCustomNavBarKeys(false, mContext, navButtons0, kbrCls); addCustomNavBarKeys(true, mContext, navButtons90, kbrCls); + reposNavBarButtons(navBar); } }); @@ -535,6 +539,17 @@ protected void after(MethodHookParam param) throws Throwable { } } }); + Helpers.hookAllMethods("com.android.systemui.navigationbar.NavigationBarView", lpparam.classLoader, "onConfigurationChanged", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + FrameLayout navbar = (FrameLayout) param.thisObject; +// int displayRotation = navbar.getContext().getDisplay().getRotation(); +// int mCurrentRotation = XposedHelpers.getIntField(param.thisObject, "mCurrentRotation"); +// if (mCurrentRotation != displayRotation) { + reposNavBarButtons(navbar); +// } + } + }); } @SuppressLint("MissingPermission") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index 02999ad4..e05fd9dd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -25,7 +25,7 @@ public enum ReplacementType { private final ConcurrentHashMap> replacements = new ConcurrentHashMap>(); public static int getFakeResId(String resourceName) { - return 0x7f000000 | (resourceName.hashCode() & 0x00ffffff); + return 0x7e000000 | (resourceName.hashCode() & 0x00ffffff); } @SuppressWarnings("FieldCanBeLocal") From f18baaef6595b0202cd944d5bb3e1cef9de3229a Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 10 Jan 2023 20:45:02 +0800 Subject: [PATCH 273/627] feat: swap mobile and wifi; move signal at the left of status bar --- .../mikanoshi/customiuizer/MainModule.java | 9 +- .../mikanoshi/customiuizer/mods/System.java | 210 ++++++++++++------ .../mikanoshi/customiuizer/subs/System.java | 2 +- .../customiuizer/utils/ResourceHooks.java | 2 +- app/src/main/res/values-pl-rPL/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/prefs_system.xml | 3 +- .../xml/prefs_system_statusbar_righticons.xml | 13 ++ 10 files changed, 176 insertions(+), 73 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 04b1783f..a22d0e23 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -258,15 +258,18 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationHook(lpparam); if (mPrefs.getBoolean("system_lockscreenshortcuts")) System.LockScreenShortcutHook(lpparam); if (mPrefs.getBoolean("system_4gtolte")) System.Network4GtoLTEHook(lpparam); - if (mPrefs.getBoolean("system_statusbar_netspeed_atright") + boolean moveRight = mPrefs.getBoolean("system_statusbar_netspeed_atright") || mPrefs.getBoolean("system_statusbar_alarm_atright") || mPrefs.getBoolean("system_statusbar_sound_atright") || mPrefs.getBoolean("system_statusbar_dnd_atright") || mPrefs.getBoolean("system_statusbar_nfc_atright") || mPrefs.getBoolean("system_statusbar_btbattery_atright") - || mPrefs.getBoolean("system_statusbar_headset_atright") + || mPrefs.getBoolean("system_statusbar_headset_atright"); + if (moveRight + || mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft") + || mPrefs.getBoolean("system_statusbaricons_swap_wifi_mobile") ) { - System.StatusBarIconsAtRightHook(lpparam); + System.StatusBarIconsPositionAdjustHook(lpparam, moveRight); } if (mPrefs.getBoolean("system_statusbar_clock_atright")) { System.StatusBarClockAtRightHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index bca7440e..a57f4f7b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5242,82 +5242,165 @@ protected void after(MethodHookParam param) throws Throwable { } } - public static void StatusBarIconsAtRightHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String slot = (String) param.args[0]; - if (("alarm_clock".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) - || ("volume".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) - || ("zen".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) - || ("nfc".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) - || ("headset".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) - ) { - param.args[1] = false; + public static void StatusBarIconsPositionAdjustHook(LoadPackageParam lpparam, boolean moveRight) { + boolean swapWifiSignal = MainModule.mPrefs.getBoolean("system_statusbaricons_swap_wifi_mobile"); + boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); + String[] signalIcons; + if (!swapWifiSignal) { + signalIcons = new String[]{"no_sim", "mobile", "demo_mobile", "airplane", "hotspot", "slave_wifi", "wifi", "demo_wifi"}; + } + else { + signalIcons = new String[]{"hotspot", "slave_wifi", "wifi", "demo_wifi", "no_sim", "mobile", "demo_mobile", "airplane"}; + } + ArrayList signalRelatedIcons = new ArrayList(Arrays.asList(signalIcons)); + if (moveRight) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String slot = (String) param.args[0]; + if (("alarm_clock".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) + || ("volume".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) + || ("zen".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) + || ("nfc".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) + || ("headset".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) + ) { + param.args[1] = false; + } } - } - }); + }); + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isHooked = false; - final boolean[] isListened = {false}; - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - if (!isListened[0]) { - isListened[0] = true; - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - Class MiuiEndIconManager = findClass("com.android.systemui.statusbar.phone.MiuiEndIconManager", lpparam.classLoader); - Object blockList = Helpers.getStaticObjectFieldSilently(MiuiEndIconManager, "RIGHT_BLOCK_LIST"); - ArrayList rightBlockList; - Resources res = mContext.getResources(); - if (blockList != null) { - rightBlockList = (ArrayList) blockList; - } - else { - int blockResId = res.getIdentifier("config_drip_right_block_statusBarIcons", "array", lpparam.packageName); - rightBlockList = new ArrayList(Arrays.asList(res.getStringArray(blockResId))); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright")) { - rightBlockList.remove("network_speed"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) { - rightBlockList.remove("alarm_clock"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) { - rightBlockList.remove("volume"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) { - rightBlockList.remove("zen"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_btbattery_atright")) { - rightBlockList.remove("bluetooth_handsfree_battery"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) { - rightBlockList.remove("nfc"); + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isHooked) { + isHooked = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + Class MiuiEndIconManager = findClass("com.android.systemui.statusbar.phone.MiuiEndIconManager", lpparam.classLoader); + Object blockList = Helpers.getStaticObjectFieldSilently(MiuiEndIconManager, "RIGHT_BLOCK_LIST"); + ArrayList rightBlockList; + Resources res = mContext.getResources(); + if (blockList != null) { + rightBlockList = (ArrayList) blockList; + } + else { + int blockResId = res.getIdentifier("config_drip_right_block_statusBarIcons", "array", lpparam.packageName); + rightBlockList = new ArrayList(Arrays.asList(res.getStringArray(blockResId))); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright")) { + rightBlockList.remove("network_speed"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) { + rightBlockList.remove("alarm_clock"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) { + rightBlockList.remove("volume"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) { + rightBlockList.remove("zen"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_btbattery_atright")) { + rightBlockList.remove("bluetooth_handsfree_battery"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) { + rightBlockList.remove("nfc"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) { + rightBlockList.remove("headset"); + } + if (blockList != null) { + XposedHelpers.setStaticObjectField(MiuiEndIconManager, "RIGHT_BLOCK_LIST", rightBlockList); + } + else { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "array", "config_drip_right_block_statusBarIcons", rightBlockList.toArray(new String[0])); + } } - if (MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) { - rightBlockList.remove("headset"); + } + }); + } + ArrayList dripLeftIcons = new ArrayList(); + if (swapWifiSignal || moveSignalLeft) { + Helpers.findAndHookConstructor("com.android.systemui.statusbar.phone.StatusBarIconList", lpparam.classLoader, String[].class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean isRightController = "StatusBarIconControllerImpl".equals(param.thisObject.getClass().getSimpleName()); + ArrayList allStatusIcons = new ArrayList(Arrays.asList((String[]) param.args[0])); + if (isRightController) { + int startIndex = allStatusIcons.indexOf("no_sim"); + int endIndex = allStatusIcons.indexOf("demo_wifi") + 1; + List removedIcons = allStatusIcons.subList(startIndex, endIndex); + removedIcons.clear(); + if (!moveSignalLeft) { + startIndex = allStatusIcons.indexOf("ethernet"); + allStatusIcons.addAll(startIndex + 1, signalRelatedIcons); + } + param.args[0] = allStatusIcons.toArray(new String[0]); } - if (blockList != null) { - XposedHelpers.setStaticObjectField(MiuiEndIconManager, "RIGHT_BLOCK_LIST", rightBlockList); + else if (moveSignalLeft) { + dripLeftIcons.addAll(allStatusIcons); + allStatusIcons.addAll(0, signalRelatedIcons); + param.args[0] = allStatusIcons.toArray(new String[0]); } - else { - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "array", "config_drip_right_block_statusBarIcons", rightBlockList.toArray(new String[0])); + } + }); + } + + if (moveSignalLeft) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiStatusBarSignalPolicy", lpparam.classLoader, "initMiuiSlot", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); + XposedHelpers.setObjectField(param.thisObject, "mIconController", dripLeftController); + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); + Object mDripIconManager = XposedHelpers.getObjectField(param.thisObject, "mDripLeftDarkIconManager"); + ArrayList blockList = new ArrayList(); + int mCurrentStatusBarType = (int) XposedHelpers.getAdditionalInstanceField(dripLeftController, "mCurrentStatusBarType"); + if (mCurrentStatusBarType != 1) { + blockList.addAll(dripLeftIcons); } + XposedHelpers.callMethod(mDripIconManager, "setBlockList", blockList); + XposedHelpers.callMethod(dripLeftController, "refreshIconGroup", mDripIconManager); } - } - }); + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "setStatusBarType", int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int mCurrentStatusBarType = XposedHelpers.getIntField(param.thisObject, "mCurrentStatusBarType"); + Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); + XposedHelpers.setAdditionalInstanceField(dripLeftController, "mCurrentStatusBarType", mCurrentStatusBarType); + } + }); + } - if (MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright")) { + boolean netspeedRight = MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright"); + if (moveSignalLeft || netspeedRight) { Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); if (mCurrentStatusBarType == 1) { - Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); - XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); + if (netspeedRight) { + Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); + XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); + } + } + else { + boolean dualRows = MainModule.mPrefs.getBoolean("system_statusbar_dualrows"); + if (moveSignalLeft && !dualRows) { + View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); + mDripStatusBarLeftStatusIconArea.setVisibility(View.VISIBLE); + } } } }); + } + + if (netspeedRight) { Helpers.hookAllMethods("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "setDripNetworkSpeedView", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { @@ -8182,7 +8265,9 @@ protected void after(MethodHookParam param) throws Throwable { }); SparseIntArray signalResToLevelMap = new SparseIntArray(); - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarIconControllerImpl", lpparam.classLoader, "setMobileIcons", new MethodHook() { + boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); + String ControllerImplName = moveSignalLeft ? "MiuiDripLeftStatusBarIconControllerImpl" : "StatusBarIconControllerImpl"; + Helpers.hookAllMethods("com.android.systemui.statusbar.phone." + ControllerImplName, lpparam.classLoader, "setMobileIcons", new MethodHook() { private boolean isHooked = false; @Override protected void before(MethodHookParam param) throws Throwable { @@ -8800,6 +8885,7 @@ protected void after(MethodHookParam param) throws Throwable { LinearLayout secondLeft = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "secondLeft"); LinearLayout secondRight = (LinearLayout) rightLayout.getChildAt(1); LinearLayout statusBarcontents = (LinearLayout) leftLayout.getParent(); + boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); statusBarcontents.setOrientation(mCurrentStatusBarType == 0 ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); if (mCurrentStatusBarType == 0) { @@ -8837,7 +8923,7 @@ protected void after(MethodHookParam param) throws Throwable { Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); - mDripStatusBarLeftStatusIconArea.setVisibility(View.GONE); + mDripStatusBarLeftStatusIconArea.setVisibility(moveSignalLeft ? View.VISIBLE : View.GONE); leftLayout.setOrientation(LinearLayout.VERTICAL); rightLayout.setOrientation(LinearLayout.VERTICAL); LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 71fd1494..42cea1ba 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -159,7 +159,7 @@ public boolean onPreferenceClick(Preference preference) { findPreference("pref_key_system_statusbaricons_atright_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - openSubFragment(new SubFragment(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_statusbaricons_atright_title, R.xml.prefs_system_statusbar_righticons); + openSubFragment(new SubFragment(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_statusbaricons_change_position_title, R.xml.prefs_system_statusbar_righticons); return true; } }); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index e05fd9dd..ab2879cd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -25,7 +25,7 @@ public enum ReplacementType { private final ConcurrentHashMap> replacements = new ConcurrentHashMap>(); public static int getFakeResId(String resourceName) { - return 0x7e000000 | (resourceName.hashCode() & 0x00ffffff); + return 0x7e00f000 | (resourceName.hashCode() & 0x00ffffff); } @SuppressWarnings("FieldCanBeLocal") diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 9e575ee9..3f1d2bf9 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -1084,7 +1084,6 @@ Umieść typ sieci komórkowej po prawej stronie ikony sygnału lewy margines Przesuń niektóre ikony w prawo - Głównie do urządzeń z wycięciem na środku górnej krawędzi Wskaźnik ruchu sieciowego Zegar Zezwalaj na niezaufany dotyk diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b67c0430..7b804803 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1047,7 +1047,9 @@ 假定已安装LSPosed框架以使用其管理器 正在运行的服务 系统图标移至右侧显示 - 部分针对中置挖孔屏 + 图标位置调整 + 移动信号和Wi-Fi移至左侧显示 + 交换移动信号和Wi-Fi位置 网速 时钟 显示电池温度和电流 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9751c9fa..ddcac97d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1032,7 +1032,6 @@ 雙排訊號欄 左側間距 行動網路類型單獨顯示 - 僅針對中置挖孔屏 系統圖示移至右側顯示 HD圖示 顯示Wi-Fi標準 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9eaa46e8..1db3a5c0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1123,7 +1123,9 @@ Top padding Unset statusbar in Keyguard Move some icons to the right - Mainly for devices with cutout at the center of the top edge + Move mobile and Wi-Fi to the left + Swap Mobile Signal and Wi-Fi + Change icons\' position Network speed indicator Clock Allow untrusted touch diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index bebcd0a2..6220d81c 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -313,8 +313,7 @@ + android:title="@string/system_statusbaricons_change_position_title" /> + + + + + + Date: Tue, 10 Jan 2023 22:41:59 +0800 Subject: [PATCH 274/627] disable move clock right when dual row is enabled --- app/src/main/java/name/mikanoshi/customiuizer/MainModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index a22d0e23..98022b77 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -271,7 +271,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { ) { System.StatusBarIconsPositionAdjustHook(lpparam, moveRight); } - if (mPrefs.getBoolean("system_statusbar_clock_atright")) { + if (mPrefs.getBoolean("system_statusbar_clock_atright") && !mPrefs.getBoolean("system_statusbar_dualrows")) { System.StatusBarClockAtRightHook(lpparam); } if (mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) System.DisplayBatteryDetailHook(lpparam); From 422bebc912187ba5cbc8daed2bd0cda2e746909a Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 10 Jan 2023 22:54:13 +0800 Subject: [PATCH 275/627] fix: old home launcher compat --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index a57f4f7b..60c2af81 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7640,7 +7640,7 @@ protected void after(MethodHookParam param) throws Throwable { public static void MultiWindowPlusHook(LoadPackageParam lpparam) { if (lpparam.packageName.equals("com.miui.home")) { - Helpers.findAndHookMethod("com.android.systemui.shared.recents.model.Task", lpparam.classLoader, "isSupportSplit", XC_MethodReplacement.returnConstant(true)); + Helpers.findAndHookMethodSilently("com.android.systemui.shared.recents.model.Task", lpparam.classLoader, "isSupportSplit", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethods("com.miui.home.recents.views.RecentMenuView", lpparam.classLoader, "onMessageEvent", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { From 7370f63b6e32430729195dd171d557fca52cdf0d Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 11 Jan 2023 13:35:24 +0800 Subject: [PATCH 276/627] fix: horiz margin of status bar on lockscreen --- .../mikanoshi/customiuizer/MainModule.java | 2 +- .../mikanoshi/customiuizer/mods/System.java | 66 +++++++++++-------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 98022b77..bcb1bf41 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -275,8 +275,8 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.StatusBarClockAtRightHook(lpparam); } if (mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) System.DisplayBatteryDetailHook(lpparam); + if (mPrefs.getBoolean("system_statusbar_topmargin") && mPrefs.getBoolean("system_statusbar_topmargin_unset_lockscreen")) System.LockScreenTopMarginHook(lpparam); if (mPrefs.getBoolean("system_statusbar_horizmargin")) System.HorizMarginHook(lpparam); - if (mPrefs.getBoolean("system_statusbar_topmargin")) System.TopMarginHook(lpparam); if (mPrefs.getBoolean("system_showpct")) System.BrightnessPctHook(lpparam); if (mPrefs.getBoolean("system_hidelsstatusbar")) System.HideLockScreenStatusBarHook(lpparam); if (mPrefs.getBoolean("system_hidelsclock")) System.HideLockScreenClockHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 60c2af81..39e2aa49 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5139,6 +5139,14 @@ else if (opt == 2) { private static int statusbarTextIconLayoutResId = 0; public static void setupStatusBar(LoadPackageParam lpparam) { statusbarTextIconLayoutResId = MainModule.resHooks.addResource("statusbar_text_icon", R.layout.statusbar_text_icon); + if (MainModule.mPrefs.getBoolean("system_statusbar_topmargin")) { + int topMargin = MainModule.mPrefs.getInt("system_statusbar_topmargin_val", 1); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", topMargin); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_horizmargin")) { + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); + } } public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); @@ -8096,13 +8104,17 @@ protected void after(final MethodHookParam param) throws Throwable { } public static void HorizMarginHook(LoadPackageParam lpparam) { - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); - String StatusBarWindowViewCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.window.StatusBarWindowView" : "com.android.systemui.statusbar.phone.StatusBarWindowView"; - Helpers.hookAllMethods(StatusBarWindowViewCls, lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", new MethodHook() { + MethodHook horizHook = new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { - Context context = Helpers.findContext(); + Context context; + if (param.method.getName().equals("paddingNeededForCutoutAndRoundedCorner")) { + View rc = (View) param.thisObject; + context = rc.getContext(); + } + else { + context = (Context) XposedHelpers.getObjectField(param.thisObject, "context"); + } int leftMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_left", 16); float marginLeft = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, @@ -8119,12 +8131,15 @@ protected void before(final MethodHookParam param) throws Throwable { rightMargin = (int) marginRight; param.setResult(new Pair(Integer.valueOf(leftMargin), Integer.valueOf(rightMargin))); } - }); + }; + String StatusBarWindowViewCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.window.StatusBarWindowView" : "com.android.systemui.statusbar.phone.StatusBarWindowView"; + Helpers.hookAllMethods(StatusBarWindowViewCls, lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", horizHook); + if (Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider", lpparam.classLoader, "getStatusBarContentInsetsForCurrentRotation", horizHook); + } } - public static void TopMarginHook(LoadPackageParam lpparam) { - int topMargin = MainModule.mPrefs.getInt("system_statusbar_topmargin_val", 1); - boolean unsetLS = MainModule.mPrefs.getBoolean("system_statusbar_topmargin_unset_lockscreen"); + public static void LockScreenTopMarginHook(LoadPackageParam lpparam) { final int[] statusBarPaddingTop = new int[1]; Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { @Override @@ -8132,27 +8147,24 @@ protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); int dimenResId = mContext.getResources().getIdentifier("status_bar_padding_top", "dimen", lpparam.packageName); statusBarPaddingTop[0] = mContext.getResources().getDimensionPixelSize(dimenResId); - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", topMargin); } }); - if (unsetLS) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - View view = (View) param.args[0]; - if (view != null) { - view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); - param.setResult(null); - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View view = (View) param.args[0]; + if (view != null) { + view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); + param.setResult(null); } - }); - } + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); + } + }); } From ac995b620114fd2262d387f8ed0fb93d4fcd99ad Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 11 Jan 2023 14:53:52 +0800 Subject: [PATCH 277/627] fix: horiz margin of status bar on lockscreen --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 39e2aa49..2400b631 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8109,8 +8109,7 @@ public static void HorizMarginHook(LoadPackageParam lpparam) { protected void before(final MethodHookParam param) throws Throwable { Context context; if (param.method.getName().equals("paddingNeededForCutoutAndRoundedCorner")) { - View rc = (View) param.thisObject; - context = rc.getContext(); + context = Helpers.findContext(); } else { context = (Context) XposedHelpers.getObjectField(param.thisObject, "context"); From ce9bffa50006b4f5f8c06583dfa18f5e863d7a03 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 11 Jan 2023 15:25:16 +0800 Subject: [PATCH 278/627] fix(miui14): fix 113 secure quick settings on lockscreen --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 6 ++++-- app/src/main/res/xml/prefs_system.xml | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 2400b631..6da80a77 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7851,7 +7851,8 @@ public void onReceive(Context context, Intent intent) { Helpers.hookAllConstructors(tileHostCls, hook); - Helpers.findAndHookMethod("com.android.systemui.qs.tileimpl.QSFactoryImpl", lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { + String FactoryImpl = Helpers.isTPlus() ? "com.android.systemui.qs.tileimpl.MiuiQSFactory" : "com.android.systemui.qs.tileimpl.QSFactoryImpl"; + Helpers.findAndHookMethod(FactoryImpl, lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { Object tile = param.getResult(); @@ -7896,7 +7897,8 @@ protected void before(final MethodHookParam param) throws Throwable { public void run() { try { Class DependencyClass = findClass("com.android.systemui.Dependency", lpparam.classLoader); - Object mStatusBar = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader)); + String StatusbarClsForDep = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfaces" : "com.android.systemui.statusbar.phone.StatusBar"; + Object mStatusBar = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists(StatusbarClsForDep, lpparam.classLoader)); boolean usingControlCenter; Object mController = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); usingControlCenter = (boolean)XposedHelpers.callMethod(mController, "isUseControlCenter"); diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 6220d81c..8b23705e 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -424,6 +424,7 @@ Date: Wed, 11 Jan 2023 18:28:26 +0800 Subject: [PATCH 279/627] feat: add toolbar menu in sub settings --- .../mikanoshi/customiuizer/MainFragment.java | 3 +- .../customiuizer/PreferenceFragmentBase.java | 72 +++++++++++++------ .../customiuizer/SnoozedFragment.java | 2 +- .../mikanoshi/customiuizer/SubFragment.java | 8 +-- .../customiuizer/subs/CategorySelector.java | 23 +++++- .../customiuizer/subs/SortableList.java | 2 +- .../mikanoshi/customiuizer/subs/System.java | 13 ++++ .../mikanoshi/customiuizer/subs/WebPage.java | 5 +- .../mikanoshi/customiuizer/utils/Helpers.java | 4 +- 9 files changed, 93 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java index 2b4f23cc..a70b3c51 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java @@ -95,7 +95,8 @@ private boolean isFragmentReady(AppCompatActivity act) { @Override @SuppressLint("MissingSuperCall") public void onCreate(Bundle savedInstanceState) { - supressMenu = true; + toolbarMenu = true; + activeMenus = "all"; super.onCreate(savedInstanceState, R.xml.prefs_main); tailLayoutId = R.layout.prefs_main12; final AppCompatActivity act = (AppCompatActivity) getActivity(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java index 29c8feca..8e17d50b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java @@ -12,6 +12,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Environment; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -30,6 +31,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.text.SimpleDateFormat; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -40,14 +42,25 @@ public class PreferenceFragmentBase extends PreferenceFragmentCompat { private Context actContext = null; - public boolean supressMenu = false; - public int animDur = 350; + protected boolean toolbarMenu = false; + protected int animDur = 350; + protected String activeMenus = ""; public static final int PICK_BACKFILE = 11; - public boolean isCustomActionBar = false; + protected boolean isCustomActionBar = false; protected int headLayoutId = 0; protected int tailLayoutId = 0; protected String pageUrl; + protected HashMap mapKeys = new HashMap() {{ + put(R.id.search_btn, "search"); + put(R.id.restartlauncher, "launcher"); + put(R.id.restartsystemui, "systemui"); + put(R.id.edit_confirm, "edit"); + put(R.id.softreboot, "reboot"); + put(R.id.backuprestore, "settings"); + put(R.id.about, "about"); + put(R.id.openinweb, "openinweb"); + }}; protected ActionBar getActionBar() { AppCompatActivity act = (AppCompatActivity) getActivity(); @@ -55,32 +68,40 @@ protected ActionBar getActionBar() { } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (supressMenu) { + if (toolbarMenu) { inflater.inflate(R.menu.menu_mods, menu); } if (isCustomActionBar) { MenuItem item; - boolean webPage = this instanceof WebPage; for (int i = 0; i < menu.size(); i++) { item = menu.getItem(i); - if (webPage) { - item.setVisible(item.getItemId() == R.id.openinweb); + item.setVisible(item.getItemId() == R.id.edit_confirm); + } + MenuItem confirmMenu = menu.findItem(R.id.edit_confirm); + int applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_confirm_dark" : "action_mode_title_button_confirm_light", "drawable", "miui"); + if (applyResId == 0) + applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_done_dark" : "action_mode_immersion_done_light", "drawable", "miui"); + confirmMenu.setIcon(applyResId); + } + else { + MenuItem item; + for (int i = 0; i < menu.size(); i++) { + item = menu.getItem(i); + int menuId = item.getItemId(); + String menuKey = mapKeys.get(menuId); + if (activeMenus.equals("all") && (menuId == R.id.edit_confirm || menuId == R.id.openinweb)) { + item.setVisible(false); + } + else if (activeMenus.equals("all")) { + item.setVisible(true); + } + else if (menuKey != null && activeMenus.contains(menuKey)) { + item.setVisible(true); } else { - item.setVisible(item.getItemId() == R.id.edit_confirm); + item.setVisible(false); } } - if (!webPage) { - MenuItem confirmMenu = menu.findItem(R.id.edit_confirm); - int applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_title_button_confirm_dark" : "action_mode_title_button_confirm_light", "drawable", "miui"); - if (applyResId == 0) - applyResId = getResources().getIdentifier(Helpers.isNightMode(getValidContext()) ? "action_mode_immersion_done_dark" : "action_mode_immersion_done_light", "drawable", "miui"); - confirmMenu.setIcon(applyResId); - } - } - else { - MenuItem openInWebMenu = menu.findItem(R.id.openinweb); - openInWebMenu.setVisible(false); } } @@ -95,15 +116,20 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S @Override public boolean onOptionsItemSelected(MenuItem item) { + Intent actionIntent; switch (item.getItemId()) { case R.id.edit_confirm: confirmEdit(); return true; case R.id.restartlauncher: - getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "RestartLauncher")); + actionIntent = new Intent(GlobalActions.ACTION_PREFIX + "RestartLauncher"); + actionIntent.setPackage("com.android.systemui"); + getValidContext().sendBroadcast(actionIntent); return true; case R.id.restartsystemui: - getValidContext().sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "RestartSystemUI")); + actionIntent = new Intent(GlobalActions.ACTION_PREFIX + "RestartSystemUI"); + actionIntent.setPackage("com.android.systemui"); + getValidContext().sendBroadcast(actionIntent); return true; case R.id.backuprestore: showBackupRestoreDialog(); @@ -173,7 +199,7 @@ public void onClick(DialogInterface dialog, int whichButton) { } private void initFragment() { - setHasOptionsMenu(supressMenu); + setHasOptionsMenu(toolbarMenu); ActionBar actionBar = getActionBar(); boolean showBack = false; @@ -226,7 +252,7 @@ public void onViewCreated(View view, Bundle savedInstanceState) { public void openWebPage(String url) { Bundle args = new Bundle(); args.putString("pageUrl", url); - openSubFragment(new WebPage(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.Edit, "", R.layout.fragment_webpage); + openSubFragment(new WebPage(), args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, "", R.layout.fragment_webpage); } public void openSubFragment(Fragment fragment, Bundle args, Helpers.SettingsType settingsType, Helpers.ActionBarType abType, int titleResId, int contentResId) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java index 34008022..4293a18d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SnoozedFragment.java @@ -91,7 +91,7 @@ public void onCreate(Bundle savedInstanceState) { @Override public void onActivityCreated(Bundle savedInstanceState) { - supressMenu = true; + toolbarMenu = true; super.onActivityCreated(savedInstanceState); if (getView() == null) return; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java index 419e3ed3..b30aa5b9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java @@ -50,7 +50,10 @@ public void onCreate(Bundle savedInstanceState) { catInfo = getArguments().getBundle("catInfo"); sub = getArguments().getString("sub"); isStandalone = getArguments().getBoolean("isStandalone"); - supressMenu = supressMenu || abType == Helpers.ActionBarType.Edit; + if (abType == Helpers.ActionBarType.Edit) { + isCustomActionBar = true; + } + toolbarMenu = toolbarMenu || isCustomActionBar; if (contentResId == 0) { getActivity().finish(); @@ -62,9 +65,6 @@ public void onCreate(Bundle savedInstanceState) { } else { super.onCreate(savedInstanceState); } - if (abType == Helpers.ActionBarType.Edit) { - isCustomActionBar = true; - } } @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java index 22fa9c27..6fd202be 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/CategorySelector.java @@ -1,6 +1,8 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; +import android.util.Log; + import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -15,11 +17,26 @@ public class CategorySelector extends SubFragment { String cat = null; @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - + public void onCreate(Bundle savedInstanceState) { Bundle args = getArguments(); cat = args.getString("cat"); + if ("pref_key_system".equals(cat)) { + toolbarMenu = true; + activeMenus ="systemui"; + } + else if ("pref_key_launcher".equals(cat)) { + toolbarMenu = true; + activeMenus ="launcher"; + } + else { + toolbarMenu = false; + } + super.onCreate(savedInstanceState); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); PreferenceScreen screen = findPreference("pref_key_cat"); int cnt = screen.getPreferenceCount(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java index a4f920be..801da416 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/SortableList.java @@ -37,7 +37,7 @@ public void onCreate(Bundle savedInstanceState) { @Override public void onActivityCreated(Bundle savedInstanceState) { - supressMenu = true; + toolbarMenu = true; super.onActivityCreated(savedInstanceState); Bundle args = getArguments(); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 42cea1ba..cd48d10d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.preference.Preference; import android.provider.Settings; +import android.util.Log; import android.widget.SeekBar; import androidx.appcompat.app.AlertDialog; @@ -40,6 +41,18 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S selectSub(); } + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.d("myabc", sub); + if ("pref_key_system_cat_recents".equals(sub)) { + toolbarMenu = true; + activeMenus = "launcher"; + } + else { + toolbarMenu = false; + } + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/WebPage.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/WebPage.java index 3ab1ec77..7c8911cd 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/WebPage.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/WebPage.java @@ -1,9 +1,7 @@ package name.mikanoshi.customiuizer.subs; import android.os.Bundle; -import android.util.Log; import android.webkit.DownloadListener; -import android.webkit.ValueCallback; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; @@ -26,7 +24,8 @@ public class WebPage extends SubFragment { @Override public void onCreate(Bundle savedInstanceState) { this.padded = false; - supressMenu = true; + toolbarMenu = true; + activeMenus = "openinweb"; super.onCreate(savedInstanceState); pageUrl = getArguments().getString("pageUrl"); OnBackPressedCallback callback = new OnBackPressedCallback(true) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index cde3cdd7..19ca0565 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -151,9 +151,7 @@ protected int sizeOf(String key, Bitmap icon) { public static boolean showNewMods = true; public static boolean miuizerModuleActive = false; public static final HashSet newMods = new HashSet(Arrays.asList( - "pref_key_various_hiddenfeatures_cat", - "pref_key_launcher_nozoomanim", - "pref_key_launcher_horizwidgetmargin" + "pref_key_launcher_nozoomanim" )); public static final HashMap l10nProgress = new HashMap() {{ put("ru-RU", "99"); From a913cc184d25f8808e6ff6c1dc4e141b50baf582 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 11 Jan 2023 18:34:45 +0800 Subject: [PATCH 280/627] feat: complement toolbar menu --- .../java/name/mikanoshi/customiuizer/subs/System.java | 8 ++++++++ app/src/main/res/xml/prefs_system.xml | 1 + 2 files changed, 9 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index cd48d10d..496d497f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -48,6 +48,14 @@ public void onCreate(Bundle savedInstanceState) { toolbarMenu = true; activeMenus = "launcher"; } + else if ("pref_key_system_cat_statusbar".equals(sub) + || "pref_key_system_cat_lockscreen".equals(sub) + || "pref_key_system_cat_qs".equals(sub) + || "pref_key_system_cat_drawer".equals(sub) + ) { + toolbarMenu = true; + activeMenus = "systemui"; + } else { toolbarMenu = false; } diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 8b23705e..c10ad809 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -612,6 +612,7 @@ From 4003a2f6e95b9d8545f283db43a3f47aee73c7f6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 11 Jan 2023 19:25:28 +0800 Subject: [PATCH 281/627] feat: display mobile type at left of signal independently --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 6 ++++-- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 3 ++- app/src/main/res/xml/prefs_system.xml | 7 +++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 6da80a77..dff78e64 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8196,8 +8196,10 @@ protected void after(final MethodHookParam param) throws Throwable { Resources res = mContext.getResources(); LinearLayout mMobileGroup = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mMobileGroup"); TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); - mMobileGroup.removeView(mMobileTypeSingle); - mMobileGroup.addView(mMobileTypeSingle); + if (!MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single_atleft")) { + mMobileGroup.removeView(mMobileTypeSingle); + mMobileGroup.addView(mMobileTypeSingle); + } ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) mMobileTypeSingle.getLayoutParams(); int leftMargin = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_leftmargin", 4); float marginLeft = TypedValue.applyDimension( diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7b804803..97b68bae 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1067,6 +1067,7 @@ 图标样式 右侧间距 移动网络类型单独显示 + 显示在信号左侧 左侧间距 上下偏移量 加粗 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1db3a5c0..5febde79 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1113,7 +1113,8 @@ Need increase statusbar height on some devices Icon style Right margin - Put mobile network type at right of signal icon + Display mobile network type independently + Display at left of signal Left margin Vertical offset Bold style diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index c10ad809..c39be495 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -328,6 +328,13 @@ android:title="@string/system_statusbar_mobiletype_single_title" android:defaultValue="false" /> + + Date: Wed, 11 Jan 2023 19:44:33 +0800 Subject: [PATCH 282/627] remove log --- app/src/main/java/name/mikanoshi/customiuizer/subs/System.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 496d497f..09f7c868 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -43,7 +43,6 @@ public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable S public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Log.d("myabc", sub); if ("pref_key_system_cat_recents".equals(sub)) { toolbarMenu = true; activeMenus = "launcher"; From d4c67b885cfde01beb0f7c12d77fdf6f64d3acad Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 12 Jan 2023 13:42:14 +0800 Subject: [PATCH 283/627] feat(miui14): dismiss access device logs request dialog --- .../java/name/mikanoshi/customiuizer/MainModule.java | 3 +++ .../java/name/mikanoshi/customiuizer/mods/System.java | 9 +++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_various.xml | 5 +++++ 5 files changed, 19 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index bcb1bf41..c931e82f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -182,6 +182,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); if (mPrefs.getBoolean("system_fw_noblacklist")) System.NoFloatingWindowBlacklistHook(lpparam); + if (mPrefs.getBoolean("various_disable_access_devicelogs")) { + System.NoAccessDeviceLogsRequest(lpparam); + } } if (pkg.equals("com.android.systemui")) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index dff78e64..edf08f19 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -232,6 +232,15 @@ public void onChange(String name, int defValue) { }); } + public static void NoAccessDeviceLogsRequest(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.server.logcat.LogcatManagerService", lpparam.classLoader, "onLogAccessRequested", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "declineRequest", param.args[0]); + param.setResult(null); + } + }); + } public static void NoLightUpOnChargeHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "wakeUpNoUpdateLocked", new MethodHook() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 97b68bae..d8199d74 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1081,6 +1081,7 @@ 强制关闭 重启系统界面 允许不受信任的触摸操作 + 关闭访问设备日志确认 去除启动动画 App启动、关闭时不缩放图标 跳过开启特殊权限的倒计时 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5febde79..5dc67d74 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1130,6 +1130,7 @@ Network speed indicator Clock Allow untrusted touch + Dismiss access device logs request dialog Skip permission intercept timer Show temperature in battery Enable AI clipboard and blur location diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index 0e43a5f3..0a3388bb 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -26,6 +26,11 @@ android:summary="@string/various_installappinfo_summ" android:defaultValue="false" /> + + Date: Thu, 12 Jan 2023 18:23:22 +0800 Subject: [PATCH 284/627] enable control center style switch --- .../java/name/mikanoshi/customiuizer/MainModule.java | 3 +++ .../java/name/mikanoshi/customiuizer/mods/System.java | 11 +++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 5 +++++ 5 files changed, 21 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c931e82f..b2fbeb8c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -372,6 +372,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_cc_tile_roundedrect")) { System.CCTileCornerHook(lpparam); } + if (mPrefs.getBoolean("system_cc_enable_style_switch")) { + System.EnableCCStyleSwitchHook(lpparam); + } } if (pkg.equals(Helpers.modulePkg)) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index edf08f19..d609181e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8762,6 +8762,17 @@ protected void after(MethodHookParam param) throws Throwable { }); } + public static void EnableCCStyleSwitchHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "forceUseControlCenterPanel", false); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "context"); + Settings.System.putInt(mContext.getContentResolver(), "force_use_control_panel", 0); + } + }); + } + public static void CCTileCornerHook(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_unavailable", R.drawable.ic_qs_tile_bg_disabled); MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_disabled", R.drawable.ic_qs_tile_bg_disabled); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d8199d74..28d1369d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1089,6 +1089,7 @@ 剪切板隐私保护及模糊定位 点击左侧图标时切换手电筒 圆角矩形磁贴 + 开启控制中心样式切换 禁用蓝牙临时关闭态 单击开关后自动收起 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5dc67d74..54688e26 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1136,6 +1136,7 @@ Enable AI clipboard and blur location Tap left shortcut to toggle flashlight Rounded rectangle tile + Enable CC style switch Disable disconnect bluetooth until tomorrow Collapse after touch \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index c39be495..ed6f9cd5 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -927,6 +927,11 @@ android:title="@string/system_cc_tile_roundedrect_title" android:defaultValue="false" /> + + Date: Thu, 12 Jan 2023 19:08:49 +0800 Subject: [PATCH 285/627] refactor: enable cc style switch --- .../name/mikanoshi/customiuizer/MainModule.java | 3 --- .../name/mikanoshi/customiuizer/mods/System.java | 14 +++----------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index b2fbeb8c..c931e82f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -372,9 +372,6 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_cc_tile_roundedrect")) { System.CCTileCornerHook(lpparam); } - if (mPrefs.getBoolean("system_cc_enable_style_switch")) { - System.EnableCCStyleSwitchHook(lpparam); - } } if (pkg.equals(Helpers.modulePkg)) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d609181e..334560a9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5156,6 +5156,9 @@ public static void setupStatusBar(LoadPackageParam lpparam) { MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); } + if (MainModule.mPrefs.getBoolean("system_cc_enable_style_switch")) { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "integer", "force_use_control_panel", 0); + } } public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); @@ -8762,17 +8765,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void EnableCCStyleSwitchHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setObjectField(param.thisObject, "forceUseControlCenterPanel", false); - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "context"); - Settings.System.putInt(mContext.getContentResolver(), "force_use_control_panel", 0); - } - }); - } - public static void CCTileCornerHook(LoadPackageParam lpparam) { MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_unavailable", R.drawable.ic_qs_tile_bg_disabled); MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_disabled", R.drawable.ic_qs_tile_bg_disabled); From 458c93a24352d4ca2140059afc1e6c5cceb0d706 Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 13 Jan 2023 00:09:31 +0800 Subject: [PATCH 286/627] Squashed commit of the following: commit 0b81ae064bd7caf6c49d3b12deece9d13cfe73c1 Author: MonwF Date: Fri Jan 13 00:08:08 2023 +0800 feat: Keep calls in notification when answer a call commit 898485963f7f02976697c4d6c6d013e06e69fc14 Author: MonwF Date: Thu Jan 12 20:42:33 2023 +0800 init --- .../mikanoshi/customiuizer/MainModule.java | 2 + .../customiuizer/mods/GlobalActions.java | 72 +++++++++---------- .../mikanoshi/customiuizer/mods/Various.java | 28 ++++++-- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_various.xml | 5 ++ 6 files changed, 65 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index c931e82f..3777f5a0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -115,6 +115,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_popupnotif_fs") || mPrefs.getBoolean("controls_volumecursor") || mPrefs.getBoolean("controls_fsg_horiz") || + mPrefs.getBoolean("various_answerinheadup") || mPrefs.getStringAsInt("various_showcallui", 0) > 0) GlobalActions.setupForegroundMonitor(lpparam); if (mPrefs.getInt("controls_fingerprint1_action", 1) > 1 || @@ -385,6 +386,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (pkg.equals("com.android.incallui")) { if (mPrefs.getStringAsInt("various_showcallui", 0) > 0) Various.ShowCallUIHook(lpparam); if (mPrefs.getBoolean("various_calluibright")) Various.InCallBrightnessHook(lpparam); + if (mPrefs.getBoolean("various_answerinheadup")) Various.AnswerCallInHeadUpHook(lpparam); } if (pkg.equals("com.miui.securitycenter")) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index b188935e..932adc7b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -151,6 +151,14 @@ public void onReceive(final Context context, Intent intent) { if (action.equals(ACTION_PREFIX + "RestartSystemUI")) { Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL); } + else if (action.equals(ACTION_PREFIX + "UpdateForeground")) { + String pkgName = intent.getStringExtra("pkgName"); + boolean fullScreen = intent.getBooleanExtra("fullScreen", false); + if (pkgName != null) { + Settings.Global.putString(context.getContentResolver(), Helpers.modulePkg + ".foreground.package", pkgName); + } + Settings.Global.putInt(context.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", fullScreen ? 1 : 0); + } // else if (action.equals(ACTION_PREFIX + "CopyToExternal")) { // try { // String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + Helpers.externalFolder; @@ -832,54 +840,39 @@ protected void before(MethodHookParam param) throws Throwable { } public static void setupForegroundMonitor(LoadPackageParam lpparam) { - String windowClass = "com.android.server.wm.DisplayPolicy"; - Helpers.hookAllMethods(windowClass, lpparam.classLoader, "focusChangedLw", new MethodHook() { + Helpers.hookAllMethods("com.android.server.wm.DisplayPolicy", lpparam.classLoader, "updateSystemBarsLw", new MethodHook() { + private String pkgName = null; + private boolean fullScreen = false; @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args[1] == null) return; - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); if (mContext != null) try { - WindowManager.LayoutParams mAttrs = (WindowManager.LayoutParams)XposedHelpers.callMethod(param.args[1], "getAttrs"); - boolean isFullScreen = mAttrs.flags != 0 && !"com.android.systemui".equals(mAttrs.packageName) && (mAttrs.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == WindowManager.LayoutParams.FLAG_FULLSCREEN; - Settings.Global.putString(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.package", mAttrs.packageName); - Settings.Global.putInt(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", isFullScreen ? 1 : 0); + String focusedApp = (String) XposedHelpers.getObjectField(param.thisObject, "mFocusedApp"); + Intent updateForeIntent = new Intent(ACTION_PREFIX + "UpdateForeground"); + + boolean changed = false; + if (focusedApp != null && !focusedApp.equals(pkgName)) { + pkgName = focusedApp; + changed = true; + updateForeIntent.putExtra("pkgName", pkgName); + } + boolean isFullScreen = XposedHelpers.getBooleanField(param.thisObject, "mTopIsFullscreen"); + if (fullScreen != isFullScreen) { + fullScreen = isFullScreen; + changed = true; + updateForeIntent.putExtra("fullScreen", fullScreen); + } + if (changed) { + updateForeIntent.setPackage("com.android.systemui"); + mContext.sendBroadcast(updateForeIntent); + } } catch (Throwable t) { Helpers.log("ForegroundMonitor", t); } } }); - -// Helpers.hookAllMethods("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "init", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); -// mContext.registerReceiver(new BroadcastReceiver() { -// public void onReceive(final Context context, Intent intent) { -// Settings.Global.putString(context.getContentResolver(), Helpers.modulePkg + ".foreground.package", intent.getStringExtra("package")); -// Settings.Global.putInt(context.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", intent.getBooleanExtra("fullscreen", false) ? 1 : 0); -// } -// }, new IntentFilter(GlobalActions.EVENT_PREFIX + "CHANGE_FOCUSED_APP")); -// } -// }); } -// public static void setupMonitors() { -// Helpers.findAndHookMethod(Activity.class, "onResume", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// Activity act = (Activity)param.thisObject; -// if (act == null) return; -// int flags = act.getWindow().getAttributes().flags; -// boolean isFullScreen = flags != 0 && !"com.android.systemui".equals(act.getPackageName()) && (flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == WindowManager.LayoutParams.FLAG_FULLSCREEN; -// Intent intent = new Intent(GlobalActions.EVENT_PREFIX + "CHANGE_FOCUSED_APP"); -// intent.putExtra("package", act.getPackageName()); -// intent.putExtra("fullscreen", isFullScreen); -// intent.setPackage("android"); -// act.sendBroadcast(intent); -// } -// }); -// } - public static void setupGlobalActions(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.android.server.accessibility.AccessibilityManagerService", lpparam.classLoader, new MethodHook() { @Override @@ -1005,6 +998,7 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "CollectXposedLog"); intentfilter.addAction(ACTION_PREFIX + "RestartSystemUI"); intentfilter.addAction(ACTION_PREFIX + "RestartLauncher"); + intentfilter.addAction(ACTION_PREFIX + "UpdateForeground"); // intentfilter.addAction(ACTION_PREFIX + "CopyToExternal"); intentfilter.addAction(ACTION_PREFIX + "ScrollToTop"); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 7ff2ff49..ac32270c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -563,21 +563,39 @@ protected void after(final MethodHookParam param) throws Throwable { }); } + public static void AnswerCallInHeadUpHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.incallui.InCallPresenter", lpparam.classLoader, "answerIncomingCall", Context.class, String.class, int.class, boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean showUi = (boolean) param.args[3]; + if (showUi) { + Context mContext = (Context) param.args[0]; + String topPackage = Settings.Global.getString(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.package"); + if (topPackage == null || !topPackage.equals("com.miui.home")) { + param.args[3] = false; + } + } + } + }); + } + public static void ShowCallUIHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.android.incallui.InCallPresenter", lpparam.classLoader, "startUi", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { if (!(boolean)param.getResult() || !"INCOMING".equals(param.args[0].toString())) return; try { - boolean isCarMode = (boolean)XposedHelpers.callStaticMethod(XposedHelpers.findClass("com.android.incallui.util.Utils.CarMode", lpparam.classLoader), "isCarMode"); + boolean isCarMode = (boolean)XposedHelpers.callStaticMethod(XposedHelpers.findClass("com.android.incallui.carmode.CarModeUtils", lpparam.classLoader), "isCarMode"); if (isCarMode) return; } catch (Throwable t) { - XposedBridge.log(t); + Helpers.log(t); } - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (MainModule.mPrefs.getStringAsInt("various_showcallui", 0) == 1) - if (Settings.Global.getInt(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", 0) == 1) return; + if (MainModule.mPrefs.getStringAsInt("various_showcallui", 0) == 1) { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + int fullScreen = Settings.Global.getInt(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", 0); + if (fullScreen == 1) return; + } XposedHelpers.callMethod(param.thisObject, "showInCall", false, false); Object mStatusBarNotifier = XposedHelpers.getObjectField(param.thisObject, "mStatusBarNotifier"); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 28d1369d..ce243ba0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -647,6 +647,7 @@ 令所选应用正确显示MIUI时钟应用设置的下一次闹钟时间 竖屏时底部填充 横屏时底部填充 + 从浮动通知接听电话时不进入全屏(除桌面) 显示通话界面 定义来电时应该显示的界面 通话时屏幕亮度 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 54688e26..ba7e3f90 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -694,6 +694,7 @@ Make selected apps display correct next alarm time set by stock MIUI Clock app Bottom padding in portrait Bottom padding in landscape + Keep calls in notification when answer a call Show call UI Define when UI for incoming call should be displayed instead of popup notification Screen brightness during call diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index 0a3388bb..fae8105d 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -70,6 +70,11 @@ + + Date: Fri, 13 Jan 2023 00:35:13 +0800 Subject: [PATCH 287/627] fix: hangup in monitor foreground app --- .../customiuizer/mods/GlobalActions.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 932adc7b..eb60f4b8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -151,14 +151,6 @@ public void onReceive(final Context context, Intent intent) { if (action.equals(ACTION_PREFIX + "RestartSystemUI")) { Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL); } - else if (action.equals(ACTION_PREFIX + "UpdateForeground")) { - String pkgName = intent.getStringExtra("pkgName"); - boolean fullScreen = intent.getBooleanExtra("fullScreen", false); - if (pkgName != null) { - Settings.Global.putString(context.getContentResolver(), Helpers.modulePkg + ".foreground.package", pkgName); - } - Settings.Global.putInt(context.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", fullScreen ? 1 : 0); - } // else if (action.equals(ACTION_PREFIX + "CopyToExternal")) { // try { // String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + Helpers.externalFolder; @@ -848,23 +840,33 @@ protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); if (mContext != null) try { String focusedApp = (String) XposedHelpers.getObjectField(param.thisObject, "mFocusedApp"); - Intent updateForeIntent = new Intent(ACTION_PREFIX + "UpdateForeground"); - boolean changed = false; + boolean focusAppChanged = false; + boolean fullscreenChanged = false; if (focusedApp != null && !focusedApp.equals(pkgName)) { pkgName = focusedApp; - changed = true; - updateForeIntent.putExtra("pkgName", pkgName); + focusAppChanged = true; } boolean isFullScreen = XposedHelpers.getBooleanField(param.thisObject, "mTopIsFullscreen"); if (fullScreen != isFullScreen) { fullScreen = isFullScreen; - changed = true; - updateForeIntent.putExtra("fullScreen", fullScreen); + fullscreenChanged = true; } - if (changed) { - updateForeIntent.setPackage("com.android.systemui"); - mContext.sendBroadcast(updateForeIntent); + if (fullscreenChanged || focusAppChanged) { + Handler mHandler = (Handler) XposedHelpers.getObjectField(param.thisObject, "mHandler"); + boolean finalFullscreenChanged = fullscreenChanged; + boolean finalFocusAppChanged = focusAppChanged; + mHandler.post(new Runnable() { + @Override + public void run() { + if (finalFullscreenChanged) { + Settings.Global.putInt(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", fullScreen ? 1 : 0); + } + if (finalFocusAppChanged) { + Settings.Global.putString(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.package", pkgName); + } + } + }); } } catch (Throwable t) { Helpers.log("ForegroundMonitor", t); @@ -998,7 +1000,6 @@ protected void after(MethodHookParam param) throws Throwable { intentfilter.addAction(ACTION_PREFIX + "CollectXposedLog"); intentfilter.addAction(ACTION_PREFIX + "RestartSystemUI"); intentfilter.addAction(ACTION_PREFIX + "RestartLauncher"); - intentfilter.addAction(ACTION_PREFIX + "UpdateForeground"); // intentfilter.addAction(ACTION_PREFIX + "CopyToExternal"); intentfilter.addAction(ACTION_PREFIX + "ScrollToTop"); From dad877d52aff743475c58418cfba7582e3f24bca Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 13 Jan 2023 14:01:31 +0800 Subject: [PATCH 288/627] refactor: status bar settings refactor --- app/build.gradle | 7 +- .../mikanoshi/customiuizer/subs/System.java | 57 ++++- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/prefs_system.xml | 200 ++---------------- .../res/xml/prefs_system_statusbar_clock.xml | 48 +++++ .../prefs_system_statusbar_mobilesignal.xml | 140 ++++++++++++ 7 files changed, 265 insertions(+), 193 deletions(-) create mode 100644 app/src/main/res/xml/prefs_system_statusbar_clock.xml create mode 100644 app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml diff --git a/app/build.gradle b/app/build.gradle index 2dcd90cb..bb4540ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,12 +20,12 @@ android { v2SigningEnabled true } } - compileSdkVersion 32 + compileSdkVersion 33 defaultConfig { applicationId "name.monwf.customiuizer" minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion - targetSdkVersion 31 + targetSdkVersion 33 versionCode 50 versionName "23.01.06" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' @@ -71,6 +71,7 @@ dependencies { implementation "androidx.preference:preference:1.2.0" implementation 'androidx.palette:palette:1.0.0' - implementation 'androidx.appcompat:appcompat:1.4.2' + implementation 'androidx.appcompat:appcompat:1.6.0' + implementation 'com.google.android.flexbox:flexbox:3.0.0' // implementation 'com.google.android.material:material:1.6.1' } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 09f7c868..3c4b81fa 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -148,7 +148,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceClick(Preference preference) { Bundle args = new Bundle(); args.putBoolean("isStandalone", true); - args.putString("sub", "pref_key_system_detailednetspeed_cat"); + args.putString("sub", preference.getKey()); String title = preference.getTitle().toString(); openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_detailednetspeed); return true; @@ -162,28 +162,68 @@ public boolean onPreferenceClick(Preference preference) { Bundle catInfo = new Bundle(); catInfo.putBoolean("isDynamic", true); args.putBundle("catInfo", catInfo); - args.putString("sub", "pref_key_system_statusbar_batterytempandcurrent_cat"); + args.putString("sub", preference.getKey()); String title = preference.getTitle().toString(); openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_statusbar_batterytempandcurrent); return true; } }); - + findPreference("pref_key_system_statusbar_mobile_signal_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Bundle args = new Bundle(); + args.putBoolean("isStandalone", true); + Bundle catInfo = new Bundle(); + catInfo.putBoolean("isDynamic", true); + args.putBundle("catInfo", catInfo); + args.putString("sub", preference.getKey()); + String title = preference.getTitle().toString(); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_statusbar_mobilesignal); + return true; + } + }); findPreference("pref_key_system_statusbaricons_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - openSubFragment(new SubFragment(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_statusbaricons_title, R.xml.prefs_system_hideicons); + Bundle args = new Bundle(); + args.putBoolean("isStandalone", true); + Bundle catInfo = new Bundle(); + catInfo.putBoolean("isDynamic", true); + args.putBundle("catInfo", catInfo); + args.putString("sub", preference.getKey()); + String title = preference.getTitle().toString(); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_hideicons); return true; } }); findPreference("pref_key_system_statusbaricons_atright_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - openSubFragment(new SubFragment(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_statusbaricons_change_position_title, R.xml.prefs_system_statusbar_righticons); + Bundle args = new Bundle(); + args.putBoolean("isStandalone", true); + Bundle catInfo = new Bundle(); + catInfo.putBoolean("isDynamic", true); + args.putBundle("catInfo", catInfo); + args.putString("sub", preference.getKey()); + String title = preference.getTitle().toString(); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_statusbar_righticons); + return true; + } + }); + findPreference("pref_key_system_statusbar_clocktweak_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Bundle args = new Bundle(); + args.putBoolean("isStandalone", true); + Bundle catInfo = new Bundle(); + catInfo.putBoolean("isDynamic", true); + args.putBundle("catInfo", catInfo); + args.putString("sub", preference.getKey()); + String title = preference.getTitle().toString(); + openSubFragment(new System(), args, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, title, R.xml.prefs_system_statusbar_clock); return true; } }); - findPreference("pref_key_system_batteryindicator_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { @@ -200,11 +240,6 @@ public boolean onPreferenceClick(Preference preference) { } }); - Configuration config = getResources().getConfiguration(); - if (config.getLocales().get(0).getCountry().equals("CN")) { - findPreference("pref_key_system_clock_show_ampm").setVisible(true); - } - break; case "pref_key_system_cat_drawer": findPreference("pref_key_system_popupnotif_cat").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ce243ba0..33a3054a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -107,7 +107,7 @@ 网速隐藏 B/s 单位 网速字体大小 手势控制 - 滑动双击时执行所选动作 + 滑动与双击时执行所选动作 调整灵敏度 亮度 音量 @@ -1048,6 +1048,8 @@ 假定已安装LSPosed框架以使用其管理器 正在运行的服务 系统图标移至右侧显示 + 移动网络信号图标设置 + 时钟设置 图标位置调整 移动信号和Wi-Fi移至左侧显示 交换移动信号和Wi-Fi位置 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ba7e3f90..ff7c5d4e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1128,6 +1128,8 @@ Move mobile and Wi-Fi to the left Swap Mobile Signal and Wi-Fi Change icons\' position + Mobile signal icon display settings + Clock settings Network speed indicator Clock Allow untrusted touch diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index ed6f9cd5..2d4a16a6 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -315,81 +315,9 @@ android:key="pref_key_system_statusbaricons_atright_cat" android:title="@string/system_statusbaricons_change_position_title" /> - - - - - - - - - - - - - - - + - - - - - - - + - + - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml new file mode 100644 index 00000000..99849672 --- /dev/null +++ b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 3e7bb85188f09d18b663b62710a17039da049e1a Mon Sep 17 00:00:00 2001 From: MonwF Date: Fri, 13 Jan 2023 15:12:27 +0800 Subject: [PATCH 289/627] refactor status bar settings --- ...refs_system_statusbar_batterytempandcurrent.xml | 14 ++------------ .../main/res/xml/prefs_system_statusbar_clock.xml | 5 ++++- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml b/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml index bc565682..82f8e196 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml @@ -12,7 +12,7 @@ + > + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system_statusbar_clock.xml b/app/src/main/res/xml/prefs_system_statusbar_clock.xml index ca41fc39..0a9f34fe 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_clock.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_clock.xml @@ -12,7 +12,8 @@ + android:dependency="pref_key_system_statusbar_clocktweak" + > + + \ No newline at end of file From 833c93682faf230b2029afa25276d1b303319c3e Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 14 Jan 2023 20:58:55 +0800 Subject: [PATCH 290/627] custom format for clock in status bar --- app/build.gradle | 1 + .../mikanoshi/customiuizer/MainModule.java | 5 +- .../mikanoshi/customiuizer/mods/System.java | 293 +++++++++++------- .../customiuizer/prefs/PreferenceEx.java | 5 + .../customiuizer/subs/AppSelector.java | 2 +- .../mikanoshi/customiuizer/subs/System.java | 28 ++ .../mikanoshi/customiuizer/utils/Helpers.java | 27 +- app/src/main/res/values-zh-rCN/strings.xml | 45 ++- app/src/main/res/values/arrays.xml | 13 + app/src/main/res/values/strings.xml | 34 +- .../res/xml/prefs_system_statusbar_clock.xml | 174 ++++++++--- 11 files changed, 451 insertions(+), 176 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index bb4540ab..6f9aa229 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,6 +72,7 @@ dependencies { implementation "androidx.preference:preference:1.2.0" implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.appcompat:appcompat:1.6.0' + implementation "androidx.recyclerview:recyclerview:1.2.1" implementation 'com.google.android.flexbox:flexbox:3.0.0' // implementation 'com.google.android.material:material:1.6.1' } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 3777f5a0..aeb6647d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -227,10 +227,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { mPrefs.getInt("system_recommended_fourth_action", 1) > 1) System.CustomRecommendedHook(lpparam, false); if (mPrefs.getBoolean("system_scramblepin")) System.ScramblePINHook(lpparam); if (mPrefs.getBoolean("system_dttosleep")) System.DoubleTapToSleepHook(lpparam); - if (mPrefs.getBoolean("system_clockseconds") + if (mPrefs.getBoolean("system_statusbar_clocktweak") || mPrefs.getBoolean("system_drawer_clockseconds") - || mPrefs.getBoolean("system_clockleadingzero") - ) System.ClockSecondsHook(lpparam); + ) System.StatusBarClockTweakHook(lpparam); if (mPrefs.getBoolean("system_noscreenlock_act")) System.NoScreenLockHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed")) System.DetailedNetSpeedHook(lpparam); if (mPrefs.getBoolean("system_albumartonlock")) System.LockScreenAlbumArtHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 334560a9..fb8757c6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1089,63 +1089,137 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void ClockSecondsHook(LoadPackageParam lpparam) { - boolean showSeconds = MainModule.mPrefs.getBoolean("system_clockseconds") || MainModule.mPrefs.getBoolean("system_drawer_clockseconds"); + private static void initClockStyle(TextView mClock) { + mClock.setSingleLine(false); + mClock.setMaxLines(2); + Resources res = mClock.getResources(); + int fontSize = MainModule.mPrefs.getInt("system_statusbar_clock_fontsize", 27); + float finalSize = fontSize * 0.5f; + if (fontSize != 27) { + mClock.setTextSize(TypedValue.COMPLEX_UNIT_DIP, finalSize); + } + String customFormat = MainModule.mPrefs.getString("system_statusbar_clock_customformat", ""); + boolean enableCustomFormat = MainModule.mPrefs.getBoolean("system_statusbar_clock_customformat_enable"); + if (enableCustomFormat && customFormat.contains("\n")) { + if (finalSize > 10) { + finalSize = 8f; + } + mClock.setLineSpacing(0, finalSize > 8.5f ? 0.85f : 0.9f); + } + int align = MainModule.mPrefs.getStringAsInt("system_statusbar_clock_align", 1); + if (align == 2) { + mClock.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); + } + else if (align == 3) { + mClock.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + } + else if (align == 4) { + mClock.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_clock_bold")) { + mClock.setTypeface(Typeface.DEFAULT_BOLD); + } + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_clock_leftmargin", 0); + leftMargin = (int)TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin * 0.5f, + res.getDisplayMetrics() + ); + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_clock_rightmargin", 0); + rightMargin = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin * 0.5f, + res.getDisplayMetrics() + ); + mClock.setPadding(leftMargin, 0, rightMargin, 0); + + int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_clock_verticaloffset", 8); + if (verticalOffset != 8) { + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mClock.getLayoutParams(); + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + res.getDisplayMetrics() + ); + lp.topMargin = (int) (marginTop); + mClock.setLayoutParams(lp); + } + } + + private static void initSecondTimer(Object clockController) { + boolean ccShowSeconds = MainModule.mPrefs.getBoolean("system_drawer_clockseconds"); + boolean sbShowSeconds = MainModule.mPrefs.getBoolean("system_statusbar_clock_show_seconds"); + String customFormat = MainModule.mPrefs.getString("system_statusbar_clock_customformat", ""); + boolean enableCustomFormat = MainModule.mPrefs.getBoolean("system_statusbar_clock_customformat_enable"); + boolean finalSbShowSeconds = (enableCustomFormat && customFormat.contains(":ss")) || (!enableCustomFormat && sbShowSeconds); + Context mContext = (Context) XposedHelpers.getObjectField(clockController, "mContext"); + Timer scheduleTimer = (Timer) XposedHelpers.getAdditionalInstanceField(clockController, "scheduleTimer"); + if (scheduleTimer != null) { + scheduleTimer.cancel(); + } + if (ccShowSeconds || finalSbShowSeconds) { + final Handler mClockHandler = new Handler(mContext.getMainLooper()); + long delay = 1000 - SystemClock.elapsedRealtime() % 1000; + Timer timer = new Timer(); + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + mClockHandler.post(new Runnable() { + @Override + public void run() { + Object mCalendar = XposedHelpers.getObjectField(clockController, "mCalendar"); + XposedHelpers.callMethod(mCalendar, "setTimeInMillis", java.lang.System.currentTimeMillis()); + XposedHelpers.setObjectField(clockController, "mIs24", DateFormat.is24HourFormat(mContext)); + ArrayList mClockListeners = (ArrayList) XposedHelpers.getObjectField(clockController, "mClockListeners"); + Iterator it = mClockListeners.iterator(); + while (it.hasNext()) { + Object clock = it.next(); + String clockName = (String) XposedHelpers.getAdditionalInstanceField(clock, "clockName"); + if (clock != null) { + if ("ccClock".equals(clockName) && ccShowSeconds) { + XposedHelpers.callMethod(clock, "onTimeChange"); + } + else if ("clock".equals(clockName) && finalSbShowSeconds) { + XposedHelpers.callMethod(clock, "onTimeChange"); + } + } + } + } + }); + } + }, delay, 1000); + XposedHelpers.setAdditionalInstanceField(clockController, "scheduleTimer", timer); + } + } + public static void StatusBarClockTweakHook(LoadPackageParam lpparam) { + boolean ccShowSeconds = MainModule.mPrefs.getBoolean("system_drawer_clockseconds"); + boolean statusbarClockTweak = MainModule.mPrefs.getBoolean("system_statusbar_clocktweak"); MethodHook ScheduleHook = new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - boolean isTimeSet = param.args.length == 2; - Context mContext = (Context) param.args[0]; - if (isTimeSet) { - Intent intent = (Intent) param.args[1]; - String action = intent.getAction(); - if ("android.intent.action.TIME_SET".equals(action)) { - Timer scheduleTimer = (Timer) XposedHelpers.getAdditionalInstanceField(param.thisObject, "scheduleTimer"); - scheduleTimer.cancel(); - } - else { - return; - } - } - final Handler mClockHandler = new Handler(mContext.getMainLooper()); - long delay = 1000 - SystemClock.elapsedRealtime() % 1000; - Timer timer = new Timer(); - timer.scheduleAtFixedRate(new TimerTask() { + initSecondTimer(param.thisObject); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + IntentFilter timeSetIntent = new IntentFilter(); + timeSetIntent.addAction("android.intent.action.TIME_SET"); + BroadcastReceiver mUpdateTimeReceiver = new BroadcastReceiver() { @Override - public void run() { - mClockHandler.post(new Runnable() { - @Override - public void run() { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "updateFromTimer", true); - XposedHelpers.callMethod(param.thisObject, "updateTime"); - } - }); + public void onReceive(Context context, Intent intent) { + initSecondTimer(param.thisObject); } - }, delay, 1000); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "scheduleTimer", timer); + }; + mContext.registerReceiver(mUpdateTimeReceiver, timeSetIntent); } }; - if (showSeconds) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "onReceive", Context.class, Intent.class, ScheduleHook); + if (ccShowSeconds || statusbarClockTweak) { Helpers.hookAllConstructors("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, ScheduleHook); - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "fireTimeChange", new MethodHook() { + } + + if (statusbarClockTweak) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onAttachedToWindow", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - ArrayList mClockListeners = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "mClockListeners"); - Iterator it = mClockListeners.iterator(); - while (it.hasNext()) { - Object clock = it.next(); - if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "updateFromTimer") != null - && XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null) { - XposedHelpers.callMethod(clock, "onTimeChange"); - } - else if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "updateFromTimer") == null - && XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") == null) { - XposedHelpers.callMethod(clock, "onTimeChange"); - } - } - XposedHelpers.removeAdditionalInstanceField(param.thisObject, "updateFromTimer"); - param.setResult(null); + protected void after(MethodHookParam param) throws Throwable { + TextView clock = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMiuiClock"); + initClockStyle(clock); } }); } @@ -1156,96 +1230,91 @@ protected void after(MethodHookParam param) { if (param.args.length != 3) return; int clockId = clock.getResources().getIdentifier("clock", "id", "com.android.systemui"); int bigClockId = clock.getResources().getIdentifier("big_time", "id", "com.android.systemui"); - if ((clock.getId() == clockId && MainModule.mPrefs.getBoolean("system_clockseconds")) - || (clock.getId() == bigClockId && MainModule.mPrefs.getBoolean("system_drawer_clockseconds"))) { - XposedHelpers.setAdditionalInstanceField(clock, "showSeconds", true); - if (clock.getId() == clockId) { - XposedHelpers.setAdditionalInstanceField(clock, "mFixedWidth", true); - } + int thisClockId = clock.getId(); + if (clockId == thisClockId && statusbarClockTweak) { + XposedHelpers.setAdditionalInstanceField(clock, "clockName", "clock"); } - if (clock.getId() == clockId && MainModule.mPrefs.getBoolean("system_clockleadingzero")) { - XposedHelpers.setAdditionalInstanceField(clock, "showLeadingZero", true); - } - if (clock.getId() == clockId && MainModule.mPrefs.getBoolean("system_clock_show_ampm")) { - XposedHelpers.setAdditionalInstanceField(clock, "showAmPm", true); + else if (bigClockId == thisClockId && ccShowSeconds) { + XposedHelpers.setAdditionalInstanceField(clock, "clockName", "ccClock"); } } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.views.MiuiClock", lpparam.classLoader, "updateTime", new MethodHook(XCallback.PRIORITY_HIGHEST) { @Override protected void before(MethodHookParam param) throws Throwable { TextView clock = (TextView)param.thisObject; - boolean clockShowSeconds = XposedHelpers.getAdditionalInstanceField(clock, "showSeconds") != null; - boolean clockShowLeadingZero = XposedHelpers.getAdditionalInstanceField(clock, "showLeadingZero") != null; - boolean clockShowAmPm = XposedHelpers.getAdditionalInstanceField(clock, "showAmPm") != null; - if (clockShowSeconds || clockShowLeadingZero) { - Context mContext = clock.getContext(); - Object mMiuiStatusBarClockController = XposedHelpers.getObjectField(clock, "mMiuiStatusBarClockController"); + String clockName = (String) XposedHelpers.getAdditionalInstanceField(clock, "clockName"); + Context mContext = clock.getContext(); + Object mMiuiStatusBarClockController = XposedHelpers.getObjectField(clock, "mMiuiStatusBarClockController"); + Object mCalendar = XposedHelpers.callMethod(mMiuiStatusBarClockController, "getCalendar"); + String timeFmt = null; + if ("ccClock".equals(clockName) && ccShowSeconds) { + String fmt; int mAmPmStyle = (int) XposedHelpers.getObjectField(clock, "mAmPmStyle"); boolean is24 = (boolean) XposedHelpers.callMethod(mMiuiStatusBarClockController, "getIs24"); - Object mCalendar = XposedHelpers.callMethod(mMiuiStatusBarClockController, "getCalendar"); - String fmt; - if (clockShowSeconds) { - if (is24) { - fmt = "fmt_time_24hour_minute_second"; - } - else { - if (mAmPmStyle == 0) { - fmt = "fmt_time_12hour_minute_second_pm"; - } - else { - fmt = "fmt_time_12hour_minute_second"; - } - } + if (is24) { + fmt = "fmt_time_24hour_minute"; } else { - if (is24) { - fmt = "fmt_time_24hour_minute"; + if (mAmPmStyle == 0) { + fmt = "fmt_time_12hour_minute_pm"; } else { - if (mAmPmStyle == 0) { - fmt = "fmt_time_12hour_minute_pm"; - } - else { - fmt = "fmt_time_12hour_minute"; - } + fmt = "fmt_time_12hour_minute"; } } int fmtResId = mContext.getResources().getIdentifier(fmt, "string", "com.android.systemui"); - String timeFmt = mContext.getString(fmtResId); - if (clockShowSeconds) { - timeFmt = timeFmt.replaceFirst("mm:ms", "mm:ss").replaceFirst("mm:s$", "mm:ss"); - } - if (clockShowLeadingZero) { - timeFmt = timeFmt.replaceFirst("^H:mm", "HH:mm").replaceFirst("^h:mm", "hh:mm") - .replaceFirst("ah:mm", "ahh:mm").replaceFirst(" h:mm", " hh:mm"); + timeFmt = mContext.getString(fmtResId); + timeFmt = timeFmt.replaceFirst(":mm", ":mm:ss"); + } + else if ("clock".equals(clockName) && statusbarClockTweak) { + String customFormat = MainModule.mPrefs.getString("system_statusbar_clock_customformat", ""); + boolean enableCustomFormat = MainModule.mPrefs.getBoolean("system_statusbar_clock_customformat_enable"); + enableCustomFormat = enableCustomFormat && (customFormat.length() > 0); + if (enableCustomFormat) { + timeFmt = customFormat; } - if (clockShowAmPm) { - timeFmt = "aa" + timeFmt; + else { + boolean showSeconds = MainModule.mPrefs.getBoolean("system_statusbar_clock_show_seconds"); + boolean is24 = MainModule.mPrefs.getBoolean("system_statusbar_clock_24hour_format"); + boolean showAmpm = MainModule.mPrefs.getBoolean("system_statusbar_clock_show_ampm"); + boolean hourIn2d = MainModule.mPrefs.getBoolean("system_statusbar_clock_leadingzero"); + String fmt; + if (showAmpm) { + fmt = "fmt_time_12hour_minute_pm"; + } + else { + fmt = "fmt_time_12hour_minute"; + } + int fmtResId = mContext.getResources().getIdentifier(fmt, "string", "com.android.systemui"); + timeFmt = mContext.getString(fmtResId); + if (showSeconds) { + timeFmt = timeFmt.replaceFirst(":mm", ":mm:ss"); + } + String hourStr = "h"; + if (is24) { + hourStr = "H"; + } + if (hourIn2d) { + hourStr = hourStr + hourStr; + } + timeFmt = timeFmt.replaceFirst("h+:", hourStr + ":"); } + } + if (timeFmt != null) { StringBuilder formatSb = new StringBuilder(timeFmt); StringBuilder textSb = new StringBuilder(); XposedHelpers.callMethod(mCalendar, "format", mContext, textSb, formatSb); - - if (XposedHelpers.getAdditionalInstanceField(clock, "mFixedWidth") != null) { - Object mTextLength = XposedHelpers.getAdditionalInstanceField(clock, "mTextLength"); - Object mHourText = XposedHelpers.getAdditionalInstanceField(clock, "mHourText"); - int len = textSb.toString().length(); - String hour = textSb.toString().replaceFirst(".*?(\\d+):\\d+:\\d+.*", "$1"); - if ( - mTextLength == null || (int) mTextLength != len - || mHourText == null || !hour.equals(mHourText) - ) { - XposedHelpers.setAdditionalInstanceField(clock, "mTextLength", len); - XposedHelpers.setAdditionalInstanceField(clock, "mHourText", hour); - String maxLenText = textSb.toString().replaceAll(":\\d+:\\d+", ":88:88"); - clock.setText(maxLenText); + if ("clock".equals(clockName) && MainModule.mPrefs.getBoolean("system_statusbar_clock_fixed_width")) { + Object mFixedWidth = XposedHelpers.getAdditionalInstanceField(clock, "mFixedWidth"); + if (mFixedWidth == null) { + clock.setText(textSb.toString()); clock.measure(0, 0); + float extraWidth = MainModule.mPrefs.getInt("system_statusbar_clock_extra_width", 0) * 0.5f; ViewGroup.LayoutParams lp = clock.getLayoutParams(); - float extraWidth = MainModule.mPrefs.getInt("system_clock_extra_width", 2) * 0.5f; lp.width = clock.getMeasuredWidth() + (int)(mContext.getResources().getDisplayMetrics().density * extraWidth); clock.setLayoutParams(lp); + XposedHelpers.setAdditionalInstanceField(clock, "mFixedWidth", true); } } clock.setText(textSb.toString()); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java index 693714b2..4df091f5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java @@ -124,6 +124,11 @@ public void setNotice(boolean value) { notice = value; setEnabled(!value); } + public void saveString(String val) { + if (val != null) { + persistString(val); + } + } public void setUnsupported(boolean value) { unsupported = value; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java index dbe65e67..d0cbfb2f 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java @@ -194,7 +194,7 @@ public void onClick(DialogInterface dialog, int which) { } } else if (customTitles) { AppData app = (AppData)parent.getAdapter().getItem(position); - Helpers.showInputDialog(getActivity(), key + ":" + app.pkgName + "|" + app.actName + "|" + app.user, R.string.launcher_renameapps_modified, new Helpers.InputCallback() { + Helpers.showInputDialog(getActivity(), key + ":" + app.pkgName + "|" + app.actName + "|" + app.user, R.string.launcher_renameapps_modified, 0, 1, new Helpers.InputCallback() { @Override public void onInputFinished(String key, String text){ if (TextUtils.isEmpty(text)) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 3c4b81fa..dcfbe336 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.preference.Preference; import android.provider.Settings; +import android.text.TextUtils; import android.util.Log; import android.widget.SeekBar; @@ -597,6 +598,33 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } }); break; + case "pref_key_system_statusbar_clocktweak_cat": + PreferenceEx pref = findPreference("pref_key_system_statusbar_clock_customformat"); + String format = Helpers.prefs.getString(pref.getKey(), ""); + pref.setCustomSummary(getResources().getString(TextUtils.isEmpty(format) ? R.string.value_is_empty : R.string.value_is_set)); + int formatSummId = R.string.system_clock_customformat_help_summ; + pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Helpers.showInputDialog(getActivity(), pref.getKey(), R.string.system_clock_customformat_setting_title, formatSummId, 2, new Helpers.InputCallback() { + @Override + public void onInputFinished(String key, String text) { + if (TextUtils.isEmpty(text)) + Helpers.prefs.edit().remove(key).apply(); + else { + String[] lines = text.split("\n"); + if (lines.length > 2) { + text = lines[0] + "\n" + lines[1]; + } + Helpers.prefs.edit().putString(key, text).apply(); + } + pref.setCustomSummary(getResources().getString(TextUtils.isEmpty(text) ? R.string.value_is_empty : R.string.value_is_set)); + } + }); + return true; + } + }); + break; } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java index 19ca0565..6093de14 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java @@ -53,6 +53,7 @@ import android.util.LruCache; import android.util.Pair; import android.util.TypedValue; +import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.View; import android.view.ViewGroup; @@ -60,6 +61,7 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.FrameLayout; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -352,16 +354,29 @@ public interface InputCallback { void onInputFinished(String key, String text); } - public static void showInputDialog(Context context, final String key, int titleRes, InputCallback callback) { + public static void showInputDialog(Context context, final String key, int titleRes, int summRes, int maxLines, InputCallback callback) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(titleRes); final EditText input = new EditText(context); - input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); input.setText(prefs.getString(key, "")); - FrameLayout container = new FrameLayout(context); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - params.leftMargin = params.rightMargin = context.getResources().getDimensionPixelSize(R.dimen.preference_item_child_padding); - input.setLayoutParams(params); + if (maxLines > 1) { + input.setSingleLine(false); + input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE); + } + else { + input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); + } + + LinearLayout container = new LinearLayout(context); + int horizPadding = context.getResources().getDimensionPixelSize(R.dimen.preference_item_child_padding); + container.setPadding(horizPadding, 0, horizPadding, 0); + container.setOrientation(LinearLayout.VERTICAL); + if (summRes > 0) { + final TextView msg = new TextView(context); + msg.setText(summRes); + msg.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); + container.addView(msg); + } container.addView(input); builder.setView(container); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 33a3054a..c72f6e80 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -19,6 +19,10 @@ 已创建 已更新 转发 + 未设置 + 已设置 + 清空 + 模块 动作 启用模块 @@ -59,7 +63,7 @@ 限制可见性 仅在通知抽屉中和锁屏上显示 圆角 - 居中 + @string/array_align_center 电量条高度 水平边距 满电颜色 @@ -81,9 +85,41 @@ 点击通知抽屉上方的日期时打开所选应用 显示秒 显示时段 + 24小时制 + 固定宽度以防相邻元素左右防抖 + 水平对齐 额外宽度 - 增加时钟宽度以完整显示秒数 - 小时补0 + 增加时钟宽度以完整显示 + 小时补0 + 开启自定义格式 + 设置格式 + + 回车换行,超过2行会被截断 + \nyy/M/d N月e E a aaH:mm I时 → 2023/2/23 二月初四 周一 下午 傍晚18:08 酉时 + \n + \nyyyy - 4位年份(2023) + \nyy - 2位年份(23) + \nMM - 补0月份(02、12) + \nM - 月份(2、12) + \nN - 农历月份(正、二) + \ndd - 补0日期(02、23) + \nd - 日期(2、23) + \ne - 农历日期(初十、十九) + \nE - 星期(周三) + \na - 时段(上午、下午) + \naa - 精确时段(傍晚、凌晨等) + \nHH - 24小时制补0小时(09、14) + \nH - 24小时制不补0小时(9、14) + \nhh - 12小时制补0小时(09、2) + \nh - 12小时制不补0小时(9、2) + \nmm - 补0分钟(09) + \nss - 补0秒数(09) + \nI - 时辰(卯、亥) + + 双排显示 + 显示星期 + 显示日期 + 显示年份 状态栏显示秒钟 通知图标限制 变成点前显示的通知图标的数目 @@ -808,6 +844,9 @@ 覆盖全屏 顶部 底部 + 左侧 + 右侧 + 居中 调整亮度 调整音量 定时 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 58f9723f..1905e3af 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -688,6 +688,19 @@ 2 + + @string/array_default + @string/array_align_left + @string/array_align_center + @string/array_align_right + + + 1 + 2 + 3 + 4 + + @string/array_disable @string/array_adjust_brightness diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ff7c5d4e..f1e52f32 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,6 +23,9 @@ Mods Actions + Value unconfigured + Value configured + Clear Enable mod System @@ -88,7 +91,33 @@ Open selected app when date in notification drawer\'s header is tapped Show seconds Show AM|PM - Show leading zero to hours + 24-hour time format + Show leading zero to hours + Enable custom format + Set format + + Can enter newline,content after 2 lines will be truncated + \nyyyy - four-digit year(2023) + \nyy - two-digit year(23) + \nMM - two-digit month(02、12) + \nM - one-digit month(2、12) + \ndd - two-digit day(02、23) + \nd - one-digit day(2、23) + \nE - short week(Sun) + \na - AM、PM + \nHH - 24-hour two-digit hour(09、14) + \nH - 24-hour one-digit hour(9、14) + \nhh - 12-hour two-digit hour(09、2) + \nh - 24-hour one-digit hour(9、2) + \nmm - two-digit minute(09) + \nss - two-digit second(09) + + Show in dual rows + Show week + Show date + Show year + Fixed width to prevent horizontal jitter + Horizontal alignment Extra width Avoid to display an ellipsis Display seconds in the status bar clock @@ -865,6 +894,9 @@ Cover whole screen Top Bottom + Left + Right + Center Adjust brightness Adjust volume Regular time diff --git a/app/src/main/res/xml/prefs_system_statusbar_clock.xml b/app/src/main/res/xml/prefs_system_statusbar_clock.xml index 0a9f34fe..d20149e3 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_clock.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_clock.xml @@ -1,51 +1,125 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From fa523038adf33cb62450941f19047b4e68249c37 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 14 Jan 2023 21:10:45 +0800 Subject: [PATCH 291/627] feat: show callui on homescreen --- .../java/name/mikanoshi/customiuizer/mods/Various.java | 8 +++++++- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/arrays.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index ac32270c..565e4e00 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -590,9 +590,15 @@ protected void after(MethodHookParam param) throws Throwable { } catch (Throwable t) { Helpers.log(t); } + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + if (MainModule.mPrefs.getStringAsInt("various_showcallui", 0) == 3) { + String topPackage = Settings.Global.getString(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.package"); + if (topPackage != null && !topPackage.equals("com.miui.home")) { + return; + } + } if (MainModule.mPrefs.getStringAsInt("various_showcallui", 0) == 1) { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); int fullScreen = Settings.Global.getInt(mContext.getContentResolver(), Helpers.modulePkg + ".foreground.fullscreen", 0); if (fullScreen == 1) return; } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c72f6e80..91c50e30 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -829,6 +829,7 @@ 任何 其他 未处于全屏模式时 + 在桌面 来电 去电 两者 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 1905e3af..f920ede6 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -313,11 +313,13 @@ @string/array_default + @string/array_home @string/array_nofs @string/array_always 0 + 3 1 2 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f1e52f32..943423ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -879,6 +879,7 @@ Any Others When not in fullscreen mode + On homescreen Incoming Outgoing Both From 6d4277c43a6d5dd0f7e28106943b76d3e01df4a2 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 14 Jan 2023 21:49:12 +0800 Subject: [PATCH 292/627] hide mobile and Wi-Fi network indicators separately --- .../mikanoshi/customiuizer/MainModule.java | 8 +++- .../mikanoshi/customiuizer/mods/System.java | 48 ++++++++++--------- app/src/main/res/values-pl-rPL/strings.xml | 2 - app/src/main/res/values-ru-rRU/strings.xml | 2 - app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 2 - app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/prefs_system.xml | 12 ++--- .../prefs_system_statusbar_mobilesignal.xml | 5 ++ 9 files changed, 45 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index aeb6647d..5141df39 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -206,7 +206,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); // if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); - if (mPrefs.getStringAsInt("system_networkindicator", 1) == 3) System.NetworkIndicatorRes(lpparam); + if (mPrefs.getBoolean("system_networkindicator_wifi")) System.NetworkIndicatorWifi(lpparam); if (mPrefs.getInt("system_drawer_blur", 100) < 100) System.DrawerBlurRatioHook(lpparam); if (mPrefs.getInt("system_chargeanimtime", 20) < 20) System.ChargeAnimationHook(lpparam); @@ -330,7 +330,11 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_cc_collapse_after_clicked")) System.CollapseCCAfterClickHook(lpparam); if (mPrefs.getStringAsInt("system_expandnotifs", 1) > 1) System.ExpandNotificationsHook(lpparam); if (mPrefs.getStringAsInt("system_inactivebrightness", 1) > 1) System.InactiveBrightnessSliderHook(lpparam); - if (mPrefs.getStringAsInt("system_mobiletypeicon", 1) > 1) System.HideNetworkTypeHook(lpparam); + if (mPrefs.getStringAsInt("system_mobiletypeicon", 1) > 1 + || mPrefs.getBoolean("system_networkindicator_mobile") + ) { + System.HideNetworkIndicatorHook(lpparam); + } if (mPrefs.getStringAsInt("system_statusbaricons_bluetooth", 1) > 1) System.HideIconsBluetoothHook(lpparam); if (mPrefs.getBoolean("system_epm")) System.ExtendedPowerMenuHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index fb8757c6..3dc30c00 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1450,20 +1450,35 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void HideNetworkTypeHook(LoadPackageParam lpparam) { + public static void HideNetworkIndicatorHook(LoadPackageParam lpparam) { MethodHook hideMobileActivity = new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { - int opt = Integer.parseInt(MainModule.mPrefs.getString("system_mobiletypeicon", "1")); - View mMobileType = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileType"); - TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); - boolean isMobileConnected = false; - if (opt == 2) { - isMobileConnected = (boolean) XposedHelpers.getObjectField(param.args[0], "dataConnected"); + int opt = MainModule.mPrefs.getStringAsInt("system_mobiletypeicon", 1); + boolean hideIndicator = MainModule.mPrefs.getBoolean("system_networkindicator_mobile"); + boolean hideNetworkType = false; + if (opt > 1) { + View mMobileType = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileType"); + TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); + boolean isMobileConnected = false; + if (opt == 2) { + isMobileConnected = (boolean) XposedHelpers.getObjectField(param.args[0], "dataConnected"); + } + if (opt == 3 || (opt == 2 && !isMobileConnected)) { + hideNetworkType = true; + mMobileTypeSingle.setVisibility(View.GONE); + mMobileType.setVisibility(View.GONE); + } + } + if (hideIndicator) { + View mLeftInOut = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftInOut"); + View mRightInOut = (View) XposedHelpers.getObjectField(param.thisObject, "mRightInOut"); + mLeftInOut.setVisibility(View.GONE); + mRightInOut.setVisibility(View.GONE); } - if (opt == 3 || (opt == 2 && !isMobileConnected)) { - mMobileTypeSingle.setVisibility(View.GONE); - mMobileType.setVisibility(View.GONE); + if (hideIndicator && hideNetworkType) { + View mMobileLeftContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileLeftContainer"); + mMobileLeftContainer.setVisibility(View.GONE); } } }; @@ -8063,18 +8078,7 @@ protected void before(final MethodHookParam param) throws Throwable { }); } - public static void NetworkIndicatorRes(LoadPackageParam lpparam) { - MethodHook hideMobileActivity = new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Object mLeftInOut = XposedHelpers.getObjectField(param.thisObject, "mLeftInOut"); - Object mRightInOut = XposedHelpers.getObjectField(param.thisObject, "mRightInOut"); - XposedHelpers.callMethod(mLeftInOut, "setVisibility", 8); - XposedHelpers.callMethod(mRightInOut, "setVisibility", 8); - } - }; - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", hideMobileActivity); - + public static void NetworkIndicatorWifi(LoadPackageParam lpparam) { MethodHook hideWifiActivity = new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 3f1d2bf9..22a3af68 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -87,8 +87,6 @@ Liczba ikon powiadomień do wyświetlenia przed zamianą ich w kropki Ukryj typ sieci komórkowej Usuń ikonę typu sieci komórkowej z paska stanu - Wskaźniki ruchu sieciowego - Skonfiguruj dane mobilne i wskaźnik ruchu Wi-Fi Pokaż ikonę LTE dla 4G Brak wskaźnika ukrytych ikon Nie pokazuj ikony z trzema kropkami, gdy ikony powiadomień są ukryte diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 53b73a3c..db125cfb 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -703,8 +703,6 @@ Число отображаемых иконок уведомлений до превращения их в точки Скрывать тип мобильной сети Удаляет иконку типа мобильной сети из строки состояния - Индикаторы активности сети - Настройка индикаторов Мобильного интернета и Wi-Fi Показывать LTE вместо 4G Убрать индикатор скрытых иконок Отключает показ иконки с 3 точками, когда активна опция скрытия иконок уведомлений diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 91c50e30..fc3b76cb 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1056,8 +1056,8 @@ 结束秒 定时和相对时间 此模块的激活范围已激活,可能会阻止某些模块正常运行。 - 网络活动指示器 - 配置移动数据和Wi-Fi流量指示器 + 隐藏Wi-Fi网络活动指示器 + 隐藏移动网络活动指示器 飞行模式配置 定义在飞行模式下允许的通信。不需要重启。 模块只能修改现有的系统设置,某些选项可能无效 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index ddcac97d..32f75e8a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -715,8 +715,6 @@ 亮屏時彈出通知不播放提示音 亮屏時靜音 網速更新間隔 - 配置行動數據和Wi-Fi流量指示器 - 網路活動指示器 在黑暗模式中不反轉某些顏色 禁用強制黑暗模式 播放通知聲音時不降低目前播放音樂的音量 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 943423ff..1baced78 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -125,8 +125,8 @@ Number of notification icons to display before turning them into dots Hide mobile network type Remove mobile network type icon from status bar - Network activity indicators - Configure Mobile data and Wi-Fi traffic indicators + Hide WiFi network activity indicators + Hide mobile network activity indicators Show LTE icon for 4G No hidden icons indicator Do not show icon with 3 dots when notification icons are hidden diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 2d4a16a6..5489c550 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -319,14 +319,10 @@ android:key="pref_key_system_statusbar_mobile_signal_cat" android:title="@string/system_statusbar_mobile_signal_cat_title" /> - + + + Date: Sat, 14 Jan 2023 22:31:56 +0800 Subject: [PATCH 293/627] fix(miui14): hide clock area on lockscreen --- .../name/mikanoshi/customiuizer/mods/System.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 3dc30c00..2564fc53 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5669,6 +5669,19 @@ protected void after(MethodHookParam param) throws Throwable { } }); } + else { + MethodHook hideClockHook = new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + View mClockFrame = (View) XposedHelpers.getObjectField(param.thisObject, "mClockFrame"); + mClockFrame.setVisibility(4); + mClockFrame = (View) XposedHelpers.getObjectField(param.thisObject, "mLargeClockFrame"); + mClockFrame.setVisibility(4); + } + }; + Helpers.hookAllMethods("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader, "setClockPlugin", hideClockHook); + Helpers.findAndHookMethod("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader, "updateClockViews", boolean.class, boolean.class, hideClockHook); + } } public static void FirstVolumePressHook(LoadPackageParam lpparam) { From cec0d25b740ccdce367490354936d0f069044180 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 14 Jan 2023 22:34:06 +0800 Subject: [PATCH 294/627] bump version --- app/build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6f9aa229..5b941d33 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 33 - versionCode 50 - versionName "23.01.06" + versionCode 51 + versionName "23.01.14" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } @@ -72,7 +72,7 @@ dependencies { implementation "androidx.preference:preference:1.2.0" implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.appcompat:appcompat:1.6.0' - implementation "androidx.recyclerview:recyclerview:1.2.1" - implementation 'com.google.android.flexbox:flexbox:3.0.0' +// implementation "androidx.recyclerview:recyclerview:1.2.1" +// implementation 'com.google.android.flexbox:flexbox:3.0.0' // implementation 'com.google.android.material:material:1.6.1' } From 22fe4b477300c86c198a96baceefd09e3d72c1e2 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 15 Jan 2023 14:59:38 +0800 Subject: [PATCH 295/627] improve network speed setting --- .../java/name/mikanoshi/customiuizer/MainModule.java | 2 +- .../name/mikanoshi/customiuizer/mods/System.java | 12 +++++++++--- .../main/res/xml/prefs_system_detailednetspeed.xml | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 5141df39..fee82c1d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -295,7 +295,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); if (mPrefs.getBoolean("system_detailednetspeed_low") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideLowNetworkSpeedHook(lpparam); if ( - mPrefs.getInt("system_netspeed_fontsize", 14) > 14 + mPrefs.getInt("system_netspeed_fontsize", 13) > 13 || mPrefs.getInt("system_netspeed_verticaloffset", 8) != 8 || mPrefs.getBoolean("system_fixmeter") || mPrefs.getBoolean("system_detailednetspeed") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 2564fc53..6af6f71a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -6462,7 +6462,7 @@ public static void HideNetworkSpeedUnitHook(LoadPackageParam lpparam) { @Override protected void after(MethodHookParam param) throws Throwable { String speedText = (String) param.getResult(); - param.setResult(speedText.replace("B/s", "B").replace("/s", "")); + param.setResult(speedText.replaceFirst("B?[/']s", "")); } }); } @@ -6487,8 +6487,14 @@ protected void after(MethodHookParam param) throws Throwable { TextView meter = (TextView)param.thisObject; if (meter == null) return; if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { - int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 14); - if (fontSize != 14) { + int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 13); + if (MainModule.mPrefs.getBoolean("system_detailednetspeed")) { + if (fontSize > 20) fontSize = 16; + } + else { + if (fontSize < 20) fontSize = 27; + } + if (fontSize != 13) { meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); } if (MainModule.mPrefs.getBoolean("system_netspeed_bold")) { diff --git a/app/src/main/res/xml/prefs_system_detailednetspeed.xml b/app/src/main/res/xml/prefs_system_detailednetspeed.xml index 103de603..07ea6b22 100644 --- a/app/src/main/res/xml/prefs_system_detailednetspeed.xml +++ b/app/src/main/res/xml/prefs_system_detailednetspeed.xml @@ -23,8 +23,8 @@ Date: Sun, 15 Jan 2023 16:48:03 +0800 Subject: [PATCH 296/627] feat: force qs clock follow system font --- .../mikanoshi/customiuizer/MainModule.java | 2 + .../mikanoshi/customiuizer/mods/System.java | 60 ++++++++++--------- app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 6 ++ 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index fee82c1d..089b75f5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -250,6 +250,8 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.NotificationVolumeDialogRes(); } if (mPrefs.getBoolean("system_nosilentvibrate") + || mPrefs.getBoolean("system_qs_force_systemfonts") + || mPrefs.getBoolean("system_qsnolabels") || mPrefs.getBoolean("system_volumebar_blur_mtk") || (mPrefs.getBoolean("system_separatevolume") && mPrefs.getBoolean("system_separatevolume_slider")) || (mPrefs.getInt("system_volumedialogdelay_collapsed", 0) > 0 || mPrefs.getInt("system_volumedialogdelay_expanded", 0) > 0) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 6af6f71a..189a2418 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -952,6 +952,20 @@ protected void before(MethodHookParam param) throws Throwable { if (MainModule.mPrefs.getBoolean("system_volumebar_blur_mtk")) { BlurMTKVolumeBarHook(pluginLoader); } + if (MainModule.mPrefs.getBoolean("system_qs_force_systemfonts")) { + Helpers.findAndHookMethod("miui.systemui.util.SystemUIResourcesHelperImpl", pluginLoader, "getBoolean", String.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String key = (String) param.args[0]; + if (key.equals("header_big_time_use_system_font")) { + param.setResult(Boolean.TRUE); + } + } + }); + } + if (MainModule.mPrefs.getBoolean("system_qsnolabels")) { + HideCCLabelsHook(pluginLoader); + } } } }); @@ -2603,6 +2617,20 @@ private static void updateLabelsVisibility(Object mRecord, int mRows, int orient } } + private static void HideCCLabelsHook(ClassLoader pluginLoader) { + Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); + Helpers.hookAllMethods(QSController, "init", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (param.args.length != 1) return; + View mLabelContainer = (View)XposedHelpers.getObjectField(param.thisObject, "labelContainer"); + if (mLabelContainer != null) { + mLabelContainer.setVisibility(View.GONE); + } + } + }); + } + public static void QSGridLabelsHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.android.systemui.qs.MiuiTileLayout", lpparam.classLoader, "addTile", new MethodHook() { @Override @@ -2648,35 +2676,6 @@ protected void after(MethodHookParam param) throws Throwable { ); } }); - - String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; - Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { - isHooked = true; - if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); - } - MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85.0f); - Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); - Helpers.hookAllMethods(QSController, "init", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args.length != 1) return; - View mLabelContainer = (View)XposedHelpers.getObjectField(param.thisObject, "labelContainer"); - if (mLabelContainer != null) { - mLabelContainer.setVisibility( - MainModule.mPrefs.getBoolean("system_qsnolabels")? View.GONE : View.VISIBLE - ); - } - } - }); - } - } - }); } public static void NoDuckingHook(LoadPackageParam lpparam) { @@ -5243,6 +5242,9 @@ public static void setupStatusBar(LoadPackageParam lpparam) { if (MainModule.mPrefs.getBoolean("system_cc_enable_style_switch")) { MainModule.resHooks.setObjectReplacement(lpparam.packageName, "integer", "force_use_control_panel", 0); } + if (MainModule.mPrefs.getBoolean("system_qs_force_systemfonts")) { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "bool", "header_big_time_use_system_font", true); + } } public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index fc3b76cb..7940c581 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -350,6 +350,7 @@ 阻止所选应用显示toast 5G开关 添加5G开关磁贴至快速设置 + 时钟强制使用系统字体 查看已保存Wi-Fi密码 查看 密码 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1baced78..16f565c9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -358,6 +358,7 @@ Mod only changes existing system setting, some options might not work 5G tile Add 5G tile to qs panel + Force clock use system fonts View password of saved Wi-Fi network View Password diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 5489c550..aca45176 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -694,6 +694,12 @@ android:defaultValue="false" /> + + Date: Sun, 15 Jan 2023 17:23:56 +0800 Subject: [PATCH 297/627] fix: hd icon overlay signal icon --- .../java/name/mikanoshi/customiuizer/mods/System.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 189a2418..1e52aef3 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1470,27 +1470,25 @@ public static void HideNetworkIndicatorHook(LoadPackageParam lpparam) { protected void after(final MethodHookParam param) throws Throwable { int opt = MainModule.mPrefs.getStringAsInt("system_mobiletypeicon", 1); boolean hideIndicator = MainModule.mPrefs.getBoolean("system_networkindicator_mobile"); - boolean hideNetworkType = false; + View mMobileType = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileType"); if (opt > 1) { - View mMobileType = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileType"); - TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); boolean isMobileConnected = false; + TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); if (opt == 2) { isMobileConnected = (boolean) XposedHelpers.getObjectField(param.args[0], "dataConnected"); } if (opt == 3 || (opt == 2 && !isMobileConnected)) { - hideNetworkType = true; mMobileTypeSingle.setVisibility(View.GONE); mMobileType.setVisibility(View.GONE); } } + View mLeftInOut = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftInOut"); if (hideIndicator) { - View mLeftInOut = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftInOut"); View mRightInOut = (View) XposedHelpers.getObjectField(param.thisObject, "mRightInOut"); mLeftInOut.setVisibility(View.GONE); mRightInOut.setVisibility(View.GONE); } - if (hideIndicator && hideNetworkType) { + if (mMobileType.getVisibility() == View.GONE && mLeftInOut.getVisibility() == View.GONE) { View mMobileLeftContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mMobileLeftContainer"); mMobileLeftContainer.setVisibility(View.GONE); } From a1c6dbfcd69dddfd2689d090c6d263b364079d57 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 15 Jan 2023 19:47:23 +0800 Subject: [PATCH 298/627] clean settings when clock is at right --- .../name/mikanoshi/customiuizer/mods/System.java | 6 ------ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../res/xml/prefs_system_statusbar_righticons.xml | 12 ------------ 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 1e52aef3..cbe4c75e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5526,12 +5526,6 @@ protected void after(MethodHookParam param) throws Throwable { int contentId = res.getIdentifier("status_bar_contents", "id", lpparam.packageName); LinearLayout mContentsContainer = sbView.findViewById(contentId); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); - int leftMargin = MainModule.mPrefs.getInt("system_statusbar_clock_leftmargin", 6); - lp.leftMargin = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - leftMargin * 0.5f, - res.getDisplayMetrics() - ); mContentsContainer.addView(mClockView, lp); } }); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7940c581..c32b5337 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1116,6 +1116,7 @@ 上下偏移量 加粗 第一排水平边距 + 时钟跨双排显示 状态栏水平边距 状态栏上边距 上边距大小 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 16f565c9..c4866bb2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1155,6 +1155,7 @@ Bold style Statusbar horizontal padding First row horizontal padding + Spread clock over two rows Statusbar top padding Top padding Unset statusbar in Keyguard diff --git a/app/src/main/res/xml/prefs_system_statusbar_righticons.xml b/app/src/main/res/xml/prefs_system_statusbar_righticons.xml index 8858e084..65e99016 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_righticons.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_righticons.xml @@ -22,18 +22,6 @@ android:title="@string/system_statusbaricons_clock_title" android:defaultValue="false" /> - - Date: Sun, 15 Jan 2023 22:18:53 +0800 Subject: [PATCH 299/627] fix: freeform and splitscreen blacklist --- .../java/name/mikanoshi/customiuizer/mods/System.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index cbe4c75e..f8a98a0a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -7463,6 +7463,14 @@ protected void before(MethodHookParam param) throws Throwable { }); Helpers.findAndHookMethod("android.util.MiuiMultiWindowUtils", lpparam.classLoader, "isForceResizeable", XC_MethodReplacement.returnConstant(true)); Helpers.findAndHookMethod("android.util.MiuiMultiWindowUtils", lpparam.classLoader, "supportFreeform", XC_MethodReplacement.returnConstant(true)); + if (Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.server.wm.MiuiFreeformServicesUtils", lpparam.classLoader, "supportsFreeform", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.setResult(true); + } + }); + } } public static ConcurrentHashMap> fwApps = new ConcurrentHashMap>(); From 71e83eaa46754fb8d95dac3a799ef6dc4a1510c7 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 16 Jan 2023 12:45:22 +0800 Subject: [PATCH 300/627] refactor --- .../customiuizer/mods/GlobalActions.java | 7 ++---- .../mikanoshi/customiuizer/mods/Launcher.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 22 +++++++++++-------- ...system_statusbar_batterytempandcurrent.xml | 2 +- .../res/xml/prefs_system_statusbar_clock.xml | 4 ++-- .../prefs_system_statusbar_mobilesignal.xml | 2 +- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index eb60f4b8..2d71c6b4 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -399,13 +399,10 @@ public void onReceive(final Context context, Intent intent) { XposedHelpers.callMethod(context.getSystemService(Context.POWER_SERVICE), "wakeUp", SystemClock.uptimeMillis()); } if (action.equals(ACTION_PREFIX + "GoToSleep")) { - XposedHelpers.callMethod(context.getSystemService(Context.POWER_SERVICE), "goToSleep", SystemClock.uptimeMillis()); + XposedHelpers.callMethod(context.getSystemService(Context.POWER_SERVICE), "goToSleep", SystemClock.uptimeMillis(), 4, 0); } if (action.equals(ACTION_PREFIX + "LockDevice")) { - XposedHelpers.callMethod(context.getSystemService(Context.POWER_SERVICE), "goToSleep", SystemClock.uptimeMillis()); - Class clsWMG = XposedHelpers.findClass("android.view.WindowManagerGlobal", null); - Object wms = XposedHelpers.callStaticMethod(clsWMG, "getWindowManagerService"); - XposedHelpers.callMethod(wms, "lockNow", (Object)null); + XposedHelpers.callMethod(context.getSystemService(Context.POWER_SERVICE), "goToSleep", SystemClock.uptimeMillis(), 7, 0); } if (action.equals(ACTION_PREFIX + "TakeScreenshot")) { context.sendBroadcast(new Intent("android.intent.action.CAPTURE_SCREENSHOT")); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index b3b85838..5a88cef0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -639,6 +639,7 @@ public static void LauncherDoubleTapHook(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.miui.home.launcher.Workspace", lpparam.classLoader, new MethodHook() { @Override protected void after(final MethodHookParam param) throws Throwable { + if (param.args.length != 3) return; Object mDoubleTapControllerEx = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mDoubleTapControllerEx"); if (mDoubleTapControllerEx != null) return; mDoubleTapControllerEx = new DoubleTapController((Context)param.args[0], "pref_key_launcher_doubletap"); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index f8a98a0a..7776ddd5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1104,21 +1104,25 @@ protected void after(MethodHookParam param) throws Throwable { } private static void initClockStyle(TextView mClock) { - mClock.setSingleLine(false); - mClock.setMaxLines(2); Resources res = mClock.getResources(); int fontSize = MainModule.mPrefs.getInt("system_statusbar_clock_fontsize", 27); float finalSize = fontSize * 0.5f; - if (fontSize != 27) { - mClock.setTextSize(TypedValue.COMPLEX_UNIT_DIP, finalSize); - } String customFormat = MainModule.mPrefs.getString("system_statusbar_clock_customformat", ""); boolean enableCustomFormat = MainModule.mPrefs.getBoolean("system_statusbar_clock_customformat_enable"); - if (enableCustomFormat && customFormat.contains("\n")) { - if (finalSize > 10) { - finalSize = 8f; - } + boolean dualRows = enableCustomFormat && customFormat.contains("\n"); + if (dualRows && finalSize > 10f) { + finalSize = 8; + } + else if (!dualRows && finalSize < 10f) { + finalSize = 13.5f; + } + if (fontSize != 27 || dualRows) { + mClock.setTextSize(TypedValue.COMPLEX_UNIT_DIP, finalSize); + } + if (dualRows) { mClock.setLineSpacing(0, finalSize > 8.5f ? 0.85f : 0.9f); + mClock.setSingleLine(false); + mClock.setMaxLines(2); } int align = MainModule.mPrefs.getStringAsInt("system_statusbar_clock_align", 1); if (align == 2) { diff --git a/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml b/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml index 82f8e196..5dc0954c 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_batterytempandcurrent.xml @@ -52,7 +52,7 @@ android:title="@string/launcher_titlefontsize_title" android:defaultValue="16" miuizer:minValue="14" - miuizer:maxValue="30" + miuizer:maxValue="32" miuizer:stepValue="1" miuizer:displayDividerValue="2" miuizer:format="%s dip" /> diff --git a/app/src/main/res/xml/prefs_system_statusbar_clock.xml b/app/src/main/res/xml/prefs_system_statusbar_clock.xml index d20149e3..17d81dd1 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_clock.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_clock.xml @@ -19,7 +19,7 @@ android:title="@string/launcher_titlefontsize_title" android:defaultValue="27" miuizer:minValue="14" - miuizer:maxValue="30" + miuizer:maxValue="32" miuizer:stepValue="1" miuizer:displayDividerValue="2" miuizer:offtext="@string/array_default" @@ -87,7 +87,7 @@ android:defaultValue="0" miuizer:child="true" miuizer:minValue="0" - miuizer:maxValue="8" + miuizer:maxValue="12" miuizer:stepValue="1" android:dependency="pref_key_system_statusbar_clock_fixed_width" miuizer:displayDividerValue="2" diff --git a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml index 0959a3a8..7930e575 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml @@ -41,7 +41,7 @@ android:defaultValue="27" miuizer:child="true" miuizer:minValue="18" - miuizer:maxValue="30" + miuizer:maxValue="32" miuizer:stepValue="1" miuizer:displayDividerValue="2" miuizer:format="%s dip" /> From 35450bb39cbade0959f018d3387a3d182059f9b6 Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 16 Jan 2023 18:54:13 +0800 Subject: [PATCH 301/627] fix(miui14): disable apk signature verify --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 6 ++---- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 1 + .../main/java/name/mikanoshi/customiuizer/subs/System.java | 4 ---- .../name/mikanoshi/customiuizer/utils/ResourceHooks.java | 4 ++-- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 089b75f5..35d43464 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -155,10 +155,8 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_forceclose")) System.ForceCloseHook(lpparam); if (mPrefs.getBoolean("system_hideproxywarn")) System.HideProximityWarningHook(lpparam); if (mPrefs.getBoolean("system_firstpress")) System.FirstVolumePressHook(lpparam); - if (Helpers.isTPlus()) { - if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyServiceHook(lpparam); - } - if (mPrefs.getBoolean("system_apksign") || mPrefs.getBoolean("system_disableintegrity")) System.DisableSystemIntegrityHook(lpparam); + if (mPrefs.getBoolean("system_apksign")) System.NoSignatureVerifyServiceHook(lpparam); + if (mPrefs.getBoolean("system_disableintegrity")) System.DisableSystemIntegrityHook(lpparam); if (mPrefs.getBoolean("system_vibration_amp")) System.MuffledVibrationHook(lpparam); if (mPrefs.getBoolean("system_clearalltasks")) System.ClearAllTasksHook(lpparam); // if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsServiceHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 7776ddd5..d6162e2e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5720,6 +5720,7 @@ protected void after(MethodHookParam param) throws Throwable { }); Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verifyMessageDigest", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verify", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", XC_MethodReplacement.returnConstant(true)); } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index dcfbe336..1e30584a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -437,10 +437,6 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { case "pref_key_system_cat_other": findPreference("pref_key_system_forceclose_apps").setOnPreferenceClickListener(openAppsEdit); - if (Helpers.isTPlus()) { - ((CheckBoxPreferenceEx)findPreference("pref_key_system_apksign")).setUnsupported(true); - } - findPreference("pref_key_system_cleanshare_apps").setOnPreferenceClickListener(openShareEdit); findPreference("pref_key_system_cleanshare_test").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java index ab2879cd..1d91ee4a 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java @@ -96,7 +96,7 @@ else if ("getDrawableForDensity".equals(method) || "getFraction".equals(method)) value = XposedHelpers.callMethod(modRes, method, modResId); return value; } catch (Throwable t) { - XposedBridge.log(t); + Helpers.log(t); return null; } } @@ -170,7 +170,7 @@ else if ("getDrawableForDensity".equals(method) || "getFraction".equals(method)) value = XposedHelpers.callMethod(modRes, method, modResId); return value; } catch (Throwable t) { - XposedBridge.log(t); + Helpers.log(t); return null; } } From 317701f9057431303f6b94884ed7991d9b78788b Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 17 Jan 2023 02:05:56 +0800 Subject: [PATCH 302/627] fix(miui14): disable apk signature verify --- .../mikanoshi/customiuizer/mods/System.java | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index d6162e2e..498d7d16 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5706,7 +5706,25 @@ public static void NoSignatureVerifyServiceHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapabilityRecover", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkSysAppCrack", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(0)); + Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object s1 = param.args[0]; + Object s2 = param.args[1]; + int ret = 0; + if (s1 == null) { + if (s2 == null) { + ret = 1; + } + else { + ret = -1; + } + } else if (s2 == null) { + ret = -2; + } + param.setResult(ret); + } + }); Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "matchSignaturesCompat", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "matchSignaturesRecover", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethodsSilently("miui.util.CertificateUtils", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(true)); @@ -5720,7 +5738,31 @@ protected void after(MethodHookParam param) throws Throwable { }); Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verifyMessageDigest", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verify", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object pkgSetting = param.args[0]; + boolean compareRecover = (boolean) param.args[5]; + Object signDetails = XposedHelpers.callMethod(pkgSetting, "getSigningDetails"); + Object signatures = XposedHelpers.callMethod(signDetails, "getSignatures"); + if (signatures == null && !compareRecover) { + param.setResult(false); + } + else { + param.setResult(true); + } + } + }); + Helpers.hookAllMethods("com.android.server.pm.InstallPackageHelper", lpparam.classLoader, "doesSignatureMatchForPermissions", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String packageName = (String) XposedHelpers.callMethod(param.args[1], "getPackageName"); + String sourcePackageName = (String) param.args[0]; + if (sourcePackageName.equals(packageName)) { + param.setResult(true); + } + } + }); } } From 77616d51ed8d003c91334e878d776a65bc79d5f8 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 19 Jan 2023 13:45:08 +0800 Subject: [PATCH 303/627] fix: don't wake up when the charger is connected or disconnected --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 498d7d16..dbdac882 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -242,10 +242,11 @@ protected void before(MethodHookParam param) throws Throwable { }); } public static void NoLightUpOnChargeHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "wakeUpNoUpdateLocked", new MethodHook() { + String methodName = Helpers.isTPlus() ? "wakePowerGroupLocked" : "wakeDisplayGroupNoUpdateLocked"; + Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, methodName, new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { - String reason = param.args[1] instanceof String ? (String)param.args[1] : (String)param.args[2]; + String reason = (String)param.args[3]; if (reason == null) return; if (Integer.parseInt(MainModule.mPrefs.getString("system_nolightuponcharges", "1")) == 3 && @@ -260,7 +261,6 @@ protected void before(final MethodHookParam param) throws Throwable { reason.equals("com.android.systemui:WIRELESS_CHARGE") || reason.equals("com.android.systemui:WIRELESS_RAPID_CHARGE") )) param.setResult(false); - //Helpers.log("wakeUpNoUpdateLocked: " + param.args[0] + " | " + param.args[1] + " | " + param.args[2] + " | " + param.args[3] + " | " + param.args[4]); } }); } From e302d9870a518a58e1892841526f8439e4e16787 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 19 Jan 2023 14:47:27 +0800 Subject: [PATCH 304/627] refactor: hide tempandcurrent --- .../mikanoshi/customiuizer/mods/System.java | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index dbdac882..e6b1054c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5212,18 +5212,9 @@ else if (opt == 2) { } } } - if (!showInfo || batteryInfo.isEmpty()) { - for (TextView tv:mBatteryDetailViews) { - tv.setVisibility(View.GONE); - } - } - else { - for (TextView tv:mBatteryDetailViews) { - if (!"HiddeninLS".equals(tv.getTag())) { - tv.setVisibility(View.VISIBLE); - XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); - } - } + for (TextView tv:mBatteryDetailViews) { + XposedHelpers.callMethod(tv, "setBlocked", !showInfo); + XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); } handler.postDelayed(this, 1500); } @@ -5330,9 +5321,7 @@ protected void after(MethodHookParam param) throws Throwable { protected void after(MethodHookParam param) throws Throwable { Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); if (bv != null) { - TextView batteryView = (TextView) bv; - batteryView.setVisibility(View.VISIBLE); - batteryView.setTag(null); + XposedHelpers.callMethod(bv, "setVisibilityByController", true); } } }); @@ -5341,9 +5330,7 @@ protected void after(MethodHookParam param) throws Throwable { protected void after(MethodHookParam param) throws Throwable { Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); if (bv != null) { - TextView batteryView = (TextView) bv; - batteryView.setVisibility((int)param.args[0]); - batteryView.setTag("HiddeninLS"); + XposedHelpers.callMethod(bv, "setVisibilityByController", false); } } }); From d563ec9e0563324506c6870c50518bdd7d0d3182 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 19 Jan 2023 15:05:09 +0800 Subject: [PATCH 305/627] fix: app default sort order --- app/src/main/java/name/mikanoshi/customiuizer/MainModule.java | 2 +- .../main/java/name/mikanoshi/customiuizer/mods/Various.java | 3 ++- app/src/main/res/values-pl-rPL/strings.xml | 1 - app/src/main/res/values-ru-rRU/strings.xml | 3 +-- app/src/main/res/values-zh-rCN/strings.xml | 3 +-- app/src/main/res/values-zh-rTW/strings.xml | 3 +-- app/src/main/res/values/arrays.xml | 2 -- app/src/main/res/values/strings.xml | 3 +-- app/src/main/res/xml/prefs_various.xml | 2 +- 9 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 35d43464..5a23d654 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -397,7 +397,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("various_disableapp")) Various.AppsDisableHook(lpparam); if (mPrefs.getBoolean("various_restrictapp")) Various.AppsRestrictHook(lpparam); if (mPrefs.getBoolean("system_applock_scramblepin")) System.ScrambleAppLockPINHook(lpparam); - if (mPrefs.getStringAsInt("various_appsort", 0) > 0) Various.AppsDefaultSortHook(lpparam); + if (mPrefs.getStringAsInt("various_appsort", 1) > 1) Various.AppsDefaultSortHook(lpparam); if (mPrefs.getStringAsInt("various_skip", 0) > 0) Various.AppsDefaultSortHook(lpparam); if (mPrefs.getBoolean("various_skip_interceptperm")) Various.InterceptPermHook(lpparam); if (mPrefs.getBoolean("various_show_battery_temperature")) Various.ShowTempInBatteryHook(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java index 565e4e00..803f57f0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java @@ -221,7 +221,8 @@ public static Bundle checkBundle(Context context, Bundle bundle) { return null; } if (bundle == null) bundle = new Bundle(); - int order = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_various_appsort", "0")); + int order = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_various_appsort", "1")); + order = order - 1; bundle.putInt("current_sory_type", order); // Xiaomi noob typos :) bundle.putInt("current_sort_type", order); // Future proof, they may fix it someday :D return bundle; diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 22a3af68..274fc291 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -709,7 +709,6 @@ Ścieżka do danych ID użytkownika Docelowa wersja SDK - Status (domyślny) Nazwa aplikacji Częstotliwość użytkowania Użycie pamięci diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index db125cfb..2349642d 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -374,8 +374,7 @@ Стандартный запуск данного приложения невозможен Частота использования Время установки - Имя приложения - Состояние (по умолчанию) + Имя приложения (по умолчанию) Занимаемое место Отмена Добавить diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c32b5337..a46b256d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -719,8 +719,7 @@ 数据路径 用户标识符 目标SDK版本 - 状态(默认) - 应用名称 + 应用名称(默认) 使用频率 存储占用 安装时间 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 32f75e8a..59086da1 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -17,8 +17,7 @@ 目標SDK版本 使用頻率 安裝時間 - 應用名稱 - 狀態(預設) + 應用名稱(預設) 儲存佔用 更新後1天 更新後3天 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index f920ede6..4c21e5ad 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -286,14 +286,12 @@ - @string/appsort_running @string/appsort_name @string/appsort_frequency @string/appsort_storage @string/appsort_install - 0 1 2 3 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c4866bb2..477c39e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -762,8 +762,7 @@ Data path User id Target SDK Version - Status (Default) - App name + App name (Default) Usage frequency Used storage Installation time diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index fae8105d..90d1b6fa 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -119,7 +119,7 @@ android:title="@string/various_appsort_title" android:entries="@array/appsort" android:entryValues="@array/appsort_val" - android:defaultValue="0" + android:defaultValue="1" miuizer:valueAsSummary="true" miuizer:dynamic="true" /> From 51ac15743e519e499fd60c2ca96147f2d742d142 Mon Sep 17 00:00:00 2001 From: MonwF Date: Thu, 19 Jan 2023 16:23:28 +0800 Subject: [PATCH 306/627] fix: disable apk sign --- .../java/name/mikanoshi/customiuizer/mods/System.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index e6b1054c..ae932c71 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5729,15 +5729,13 @@ protected void after(MethodHookParam param) throws Throwable { @Override protected void before(MethodHookParam param) throws Throwable { Object pkgSetting = param.args[0]; - boolean compareRecover = (boolean) param.args[5]; Object signDetails = XposedHelpers.callMethod(pkgSetting, "getSigningDetails"); Object signatures = XposedHelpers.callMethod(signDetails, "getSignatures"); - if (signatures == null && !compareRecover) { + if (signatures == null) { param.setResult(false); + return; } - else { - param.setResult(true); - } + param.setResult(true); } }); Helpers.hookAllMethods("com.android.server.pm.InstallPackageHelper", lpparam.classLoader, "doesSignatureMatchForPermissions", new MethodHook() { From 09053c0bfc99c0ba15566817c24f292d087cf86f Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 21 Jan 2023 15:40:23 +0800 Subject: [PATCH 307/627] feat: disable unlock wallpaper scale anim --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 3 +++ .../java/name/mikanoshi/customiuizer/mods/Launcher.java | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 5a23d654..f3b2cd89 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -186,6 +186,9 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { } } + if (pkg.equals("com.miui.miwallpaper")) { + if (mPrefs.getBoolean("launcher_disable_wallpaperscale")) Launcher.DisableUnlockWallpaperScale(lpparam); + } if (pkg.equals("com.android.systemui")) { System.setupStatusBar(lpparam); GlobalActions.setupStatusBar(lpparam); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 5a88cef0..458d4818 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -1600,6 +1600,12 @@ protected void before(final MethodHookParam param) throws Throwable { Helpers.findAndHookMethod("com.miui.home.launcher.allapps.category.fragment.RecommendCategoryAppListFragment", lpparam.classLoader, "onClick", View.class, hook); } + public static void DisableUnlockWallpaperScale(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.miui.miwallpaper.manager.WallpaperServiceController", lpparam.classLoader, "noNeedDesktopWallpaperScaleAnim", + XC_MethodReplacement.returnConstant(true) + ); + } + public static void DisableLauncherWallpaperScale(LoadPackageParam lpparam) { Class WallpaperZoomManagerKtClass = findClassIfExists("com.miui.home.launcher.wallpaper.WallpaperZoomManagerKt", lpparam.classLoader); if (MainModule.mPrefs.getBoolean("launcher_disable_wallpaperscale")) { From 06078572f0e64cb2c1c3e8c9dca537bed2eaaacd Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 21 Jan 2023 15:53:02 +0800 Subject: [PATCH 308/627] feat: wallpaper scale level --- .../mikanoshi/customiuizer/MainModule.java | 1 + .../mikanoshi/customiuizer/mods/System.java | 18 ++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/arrays.xml | 3 +-- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system.xml | 11 +++++++++++ 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index f3b2cd89..87b288d8 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -184,6 +184,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("various_disable_access_devicelogs")) { System.NoAccessDeviceLogsRequest(lpparam); } + if (mPrefs.getInt("system_other_wallpaper_scale", 6) > 6) System.WallpaperScaleLevelHook(lpparam); } if (pkg.equals("com.miui.miwallpaper")) { diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index ae932c71..067ad6df 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -9118,4 +9118,22 @@ protected void after(MethodHookParam param) throws Throwable { } }); } + public static void WallpaperScaleLevelHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.server.wm.WallpaperController", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + float scale = MainModule.mPrefs.getInt("system_other_wallpaper_scale", 6) / 10.0f; + XposedHelpers.setObjectField(param.thisObject, "mMaxWallpaperScale", scale); + Context mContext = (Context) XposedHelpers.getObjectField(param.args[0], "mContext"); + Handler mHandler = new Handler(mContext.getMainLooper()); + new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_other_wallpaper_scale", 6) { + @Override + public void onChange(String name, int defValue) { + int val = Helpers.getSharedIntPref(mContext, name, defValue); + XposedHelpers.setObjectField(param.thisObject, "mMaxWallpaperScale", val / 10.0f); + } + }; + } + }); + } } \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a46b256d..76475c70 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -355,6 +355,7 @@ 查看 密码 Wi-Fi 详情 + 壁纸缩放级别 禁用强制黑暗模式 在黑暗模式中不反转某些颜色 扩展电源菜单 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 4c21e5ad..5f9d0601 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -885,9 +885,8 @@ com.android.server.telecom com.android.settings com.android.systemui - com.android.thememanager com.google.android.packageinstaller - com.miui.cleanmaster + com.miui.miwallpaper com.miui.packageinstaller com.miui.powerkeeper com.miui.securitycenter diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 477c39e3..d3a71f4b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -363,6 +363,7 @@ View Password Wi-Fi detail + Wallpaper zoom level Disable forced dark mode Do not invert some colors in dark mode Extended power menu diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index aca45176..22586a68 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -1209,6 +1209,17 @@ android:summary="@string/system_hideproxywarn_summ" android:defaultValue="false" /> + + Date: Sat, 21 Jan 2023 16:32:40 +0800 Subject: [PATCH 309/627] feat: customize mobile network type when mobile type is shown separately --- .../mikanoshi/customiuizer/MainModule.java | 5 +- .../mikanoshi/customiuizer/mods/System.java | 12 +- .../prefs/EditTextPreferenceEx.java | 60 ++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../prefs_system_statusbar_mobilesignal.xml | 298 +++++++++--------- 6 files changed, 229 insertions(+), 148 deletions(-) create mode 100644 app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 87b288d8..0adce562 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -264,7 +264,10 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_batteryindicator")) System.BatteryIndicatorHook(lpparam); if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationHook(lpparam); if (mPrefs.getBoolean("system_lockscreenshortcuts")) System.LockScreenShortcutHook(lpparam); - if (mPrefs.getBoolean("system_4gtolte")) System.Network4GtoLTEHook(lpparam); + if (mPrefs.getBoolean("system_4gtolte") + || (mPrefs.getBoolean("system_statusbar_mobiletype_single") && + !mPrefs.getString("system_statusbar_mobile_showname", "").equals("")) + ) System.MobileNetworkTypeHook(lpparam); boolean moveRight = mPrefs.getBoolean("system_statusbar_netspeed_atright") || mPrefs.getBoolean("system_statusbar_alarm_atright") || mPrefs.getBoolean("system_statusbar_sound_atright") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 067ad6df..17a079a0 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5098,14 +5098,20 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void Network4GtoLTEHook(LoadPackageParam lpparam) { + public static void MobileNetworkTypeHook(LoadPackageParam lpparam) { String MobileController = Helpers.isTPlus() ? "com.android.systemui.statusbar.connectivity.MobileSignalController" : "com.android.systemui.statusbar.policy.MobileSignalController"; Helpers.findAndHookMethod(MobileController, lpparam.classLoader, "getMobileTypeName", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { String net = (String)param.getResult(); - if ("4G".equals(net)) param.setResult("LTE"); - else if ("4G+".equals(net)) param.setResult("LTE+"); + if (MainModule.mPrefs.getBoolean("system_4gtolte")) { + if ("4G".equals(net)) param.setResult("LTE"); + else if ("4G+".equals(net)) param.setResult("LTE+"); + } + else { + String mobileType = MainModule.mPrefs.getString("system_statusbar_mobile_showname", ""); + param.setResult(mobileType); + } } }); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java new file mode 100644 index 00000000..623b2fef --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java @@ -0,0 +1,60 @@ +package name.mikanoshi.customiuizer.prefs; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; + +import androidx.preference.EditTextPreference; +import androidx.preference.PreferenceViewHolder; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import name.mikanoshi.customiuizer.R; +import name.mikanoshi.customiuizer.utils.Helpers; + +public class EditTextPreferenceEx extends EditTextPreference implements PreferenceState { + private final Resources res = getContext().getResources(); + + private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); + + private final boolean child; + private final boolean dynamic; + private boolean newmod = false; + private boolean unsupported = false; + + public EditTextPreferenceEx(Context context, AttributeSet attrs) { + super(context, attrs); + final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.CheckBoxPreferenceEx); + dynamic = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_dynamic, false); + child = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_child, false); + xmlAttrs.recycle(); + setIconSpaceReserved(false); + } + + public void getView(View finalView) { + TextView title = finalView.findViewById(android.R.id.title); + title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); + if (newmod) Helpers.applyNewMod(title); + + int hrzPadding = childpadding + (child ? childpadding : 0); + finalView.setPadding(hrzPadding, 0, childpadding, 0); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + getView(view.itemView); + } + + public void setUnsupported(boolean value) { + unsupported = value; + setEnabled(!value); + } + + @Override + public void markAsNew() { + newmod = true; + } + +} diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 76475c70..2e5078e0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -126,6 +126,7 @@ 隐藏移动网络类型 状态栏隐藏网络类型图标 4G显示LTE图标 + 自定义移动网络类型 不显示隐藏图标指示器 隐藏通知图标时不显示3点图标 网速分隔符 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3a71f4b..b8e3ad1f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -128,6 +128,7 @@ Hide WiFi network activity indicators Hide mobile network activity indicators Show LTE icon for 4G + Custom mobile network type No hidden icons indicator Do not show icon with 3 dots when notification icons are hidden Network speed separator diff --git a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml index 7930e575..dc3decca 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml @@ -1,145 +1,155 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + /> + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 700ad18e30d77afa757740f8b813ca42237318f7 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 21 Jan 2023 17:13:05 +0800 Subject: [PATCH 310/627] fix: time schedule when show seconds is enabled on status bar --- .../mikanoshi/customiuizer/mods/System.java | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 17a079a0..281d4673 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1164,12 +1164,16 @@ else if (align == 4) { } } - private static void initSecondTimer(Object clockController) { - boolean ccShowSeconds = MainModule.mPrefs.getBoolean("system_drawer_clockseconds"); + private static boolean getShowSeconds() { boolean sbShowSeconds = MainModule.mPrefs.getBoolean("system_statusbar_clock_show_seconds"); String customFormat = MainModule.mPrefs.getString("system_statusbar_clock_customformat", ""); boolean enableCustomFormat = MainModule.mPrefs.getBoolean("system_statusbar_clock_customformat_enable"); - boolean finalSbShowSeconds = (enableCustomFormat && customFormat.contains(":ss")) || (!enableCustomFormat && sbShowSeconds); + return (enableCustomFormat && customFormat.contains(":ss")) || (!enableCustomFormat && sbShowSeconds); + } + + private static void initSecondTimer(Object clockController) { + boolean ccShowSeconds = MainModule.mPrefs.getBoolean("system_drawer_clockseconds"); + boolean finalSbShowSeconds = getShowSeconds(); Context mContext = (Context) XposedHelpers.getObjectField(clockController, "mContext"); Timer scheduleTimer = (Timer) XposedHelpers.getAdditionalInstanceField(clockController, "scheduleTimer"); if (scheduleTimer != null) { @@ -1192,14 +1196,9 @@ public void run() { Iterator it = mClockListeners.iterator(); while (it.hasNext()) { Object clock = it.next(); - String clockName = (String) XposedHelpers.getAdditionalInstanceField(clock, "clockName"); - if (clock != null) { - if ("ccClock".equals(clockName) && ccShowSeconds) { - XposedHelpers.callMethod(clock, "onTimeChange"); - } - else if ("clock".equals(clockName) && finalSbShowSeconds) { - XposedHelpers.callMethod(clock, "onTimeChange"); - } + Object showSeconds = XposedHelpers.getAdditionalInstanceField(clock, "showSeconds"); + if (showSeconds != null) { + XposedHelpers.callMethod(clock, "onTimeChange"); } } } @@ -1230,6 +1229,23 @@ public void onReceive(Context context, Intent intent) { }; if (ccShowSeconds || statusbarClockTweak) { Helpers.hookAllConstructors("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, ScheduleHook); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiStatusBarClockController", lpparam.classLoader, "fireTimeChange", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object clockController = param.thisObject; + ArrayList mClockListeners = (ArrayList) XposedHelpers.getObjectField(clockController, "mClockListeners"); + Iterator it = mClockListeners.iterator(); + while (it.hasNext()) { + Object clock = it.next(); + Object showSeconds = XposedHelpers.getAdditionalInstanceField(clock, "showSeconds"); + if (showSeconds == null) { + XposedHelpers.callMethod(clock, "onTimeChange"); + } + } + param.setResult(null); + } + }); } if (statusbarClockTweak) { @@ -1251,9 +1267,13 @@ protected void after(MethodHookParam param) { int thisClockId = clock.getId(); if (clockId == thisClockId && statusbarClockTweak) { XposedHelpers.setAdditionalInstanceField(clock, "clockName", "clock"); + if (getShowSeconds()) { + XposedHelpers.setAdditionalInstanceField(clock, "showSeconds", true); + } } else if (bigClockId == thisClockId && ccShowSeconds) { XposedHelpers.setAdditionalInstanceField(clock, "clockName", "ccClock"); + XposedHelpers.setAdditionalInstanceField(clock, "showSeconds", true); } } }); From 822c802c594a88c1645101ff26e3b85403d421e0 Mon Sep 17 00:00:00 2001 From: MonwF Date: Sat, 21 Jan 2023 18:00:04 +0800 Subject: [PATCH 311/627] refactor: qs -> cc --- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/prefs_system.xml | 95 +++++++++++----------- app/src/main/res/xml/prefs_system_cat.xml | 2 +- 4 files changed, 56 insertions(+), 49 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2e5078e0..4052f9eb 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -481,6 +481,8 @@ 已选中活动 快速设置 控制中心 + 新控制中心 + 经典控制中心 行数 竖屏显示5行时会隐藏标签,横屏时则限制为3行。 列数 @@ -1135,7 +1137,7 @@ 剪切板隐私保护及模糊定位 点击左侧图标时切换手电筒 圆角矩形磁贴 - 开启控制中心样式切换 + 强制开启控制中心样式切换 禁用蓝牙临时关闭态 单击开关后自动收起 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b8e3ad1f..6a3152f1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -496,6 +496,8 @@ Selected activities Quick Settings Control Center + New control center + Legacy control center Number of rows Labels will be hidden for 5 rows in a portrait orientation. Number of rows is limited to 3 with hidden labels in a landscape orientation. Number of columns @@ -1175,7 +1177,7 @@ Enable AI clipboard and blur location Tap left shortcut to toggle flashlight Rounded rectangle tile - Enable CC style switch + Force Enable CC style switch Disable disconnect bluetooth until tomorrow Collapse after touch \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index 22586a68..bbe73a0f 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -685,7 +685,7 @@ + android:title="@string/system_mods_cc"> - - - - - - + + + + + android:title="@string/system_mods_cc_new" /> - - - - + + + + + + + + Date: Sat, 21 Jan 2023 18:02:59 +0800 Subject: [PATCH 312/627] bump new version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5b941d33..4f308461 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { minSdkVersion 31 //noinspection OldTargetApi,ExpiredTargetSdkVersion targetSdkVersion 33 - versionCode 51 - versionName "23.01.14" + versionCode 52 + versionName "23.01.21" resConfigs 'ru-rRU', 'zh-rCN', 'zh-rTW', 'pl-rPL' ndk { abiFilters "arm64-v8a" } } From 0736810d2929636b91570bf0af9c2fc78e425b3c Mon Sep 17 00:00:00 2001 From: MonwF Date: Sun, 22 Jan 2023 11:42:44 +0800 Subject: [PATCH 313/627] refaoctor: disable resource optimization and dual signal follow theme --- .../mikanoshi/customiuizer/mods/System.java | 47 +----------------- .../color_selector.xml | 0 .../statusbar_signal_1_0_dark_theme.png | Bin 0 -> 717 bytes .../drawable/statusbar_signal_1_0_theme.png | Bin 0 -> 696 bytes .../statusbar_signal_1_1_dark_theme.png | Bin 0 -> 922 bytes .../drawable/statusbar_signal_1_1_theme.png | Bin 0 -> 987 bytes .../statusbar_signal_1_2_dark_theme.png | Bin 0 -> 934 bytes .../drawable/statusbar_signal_1_2_theme.png | Bin 0 -> 1005 bytes .../statusbar_signal_1_3_dark_theme.png | Bin 0 -> 939 bytes .../drawable/statusbar_signal_1_3_theme.png | Bin 0 -> 1005 bytes .../statusbar_signal_1_4_dark_theme.png | Bin 0 -> 951 bytes .../drawable/statusbar_signal_1_4_theme.png | Bin 0 -> 1021 bytes .../statusbar_signal_1_5_dark_theme.png | Bin 0 -> 934 bytes .../drawable/statusbar_signal_1_5_theme.png | Bin 0 -> 965 bytes .../statusbar_signal_2_0_dark_theme.png | Bin 0 -> 621 bytes .../drawable/statusbar_signal_2_0_theme.png | Bin 0 -> 613 bytes .../statusbar_signal_2_1_dark_theme.png | Bin 0 -> 837 bytes .../drawable/statusbar_signal_2_1_theme.png | Bin 0 -> 860 bytes .../statusbar_signal_2_2_dark_theme.png | Bin 0 -> 868 bytes .../drawable/statusbar_signal_2_2_theme.png | Bin 0 -> 887 bytes .../statusbar_signal_2_3_dark_theme.png | Bin 0 -> 877 bytes .../drawable/statusbar_signal_2_3_theme.png | Bin 0 -> 920 bytes .../statusbar_signal_2_4_dark_theme.png | Bin 0 -> 876 bytes .../drawable/statusbar_signal_2_4_theme.png | Bin 0 -> 934 bytes .../statusbar_signal_2_5_dark_theme.png | Bin 0 -> 873 bytes .../drawable/statusbar_signal_2_5_theme.png | Bin 0 -> 868 bytes gradle.properties | 1 + 27 files changed, 3 insertions(+), 45 deletions(-) rename app/src/main/res/{color-night-v8 => color-night}/color_selector.xml (100%) create mode 100644 app/src/main/res/drawable/statusbar_signal_1_0_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_0_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_1_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_1_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_2_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_2_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_3_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_3_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_4_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_4_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_5_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_1_5_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_0_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_0_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_1_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_1_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_2_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_2_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_3_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_3_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_4_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_4_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_5_dark_theme.png create mode 100644 app/src/main/res/drawable/statusbar_signal_2_5_theme.png diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 281d4673..e9defa88 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8409,7 +8409,6 @@ public static void DualRowSignalHook(LoadPackageParam lpparam) { } HashMap dualSignalResMap = new HashMap(); - HashMap dualSignalId2NameMap = new HashMap(); String[] colorModeList = {"", "dark", "tint"}; // String[] iconStyles = {"", "thick", "theme"}; String selectedIconStyle = MainModule.mPrefs.getString("system_statusbar_dualsimin2rows_style", ""); @@ -8425,14 +8424,8 @@ protected void after(MethodHookParam param) throws Throwable { for (int slot = 1; slot <= 2; slot++) { for (int lvl = 0; lvl <= 5; lvl++) { for (String colorMode : colorModeList) { - String iconStyle = selectedIconStyle; - String dualIconResName = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!iconStyle.equals("") ? ("_" + iconStyle) : ""); - if (iconStyle.equals("theme")) { - int fakeResId = ResourceHooks.getFakeResId(dualIconResName); - dualSignalResMap.put(dualIconResName, fakeResId); - dualSignalId2NameMap.put(fakeResId, dualIconResName); - } - else { + if (!selectedIconStyle.equals("theme") || !colorMode.equals("tint") ) { + String dualIconResName = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!selectedIconStyle.equals("") ? ("_" + selectedIconStyle) : ""); int iconResId = modRes.getIdentifier(dualIconResName, "drawable", Helpers.modulePkg); dualSignalResMap.put(dualIconResName, MainModule.resHooks.addResource(dualIconResName, iconResId)); } @@ -8597,42 +8590,6 @@ protected void after(final MethodHookParam param) throws Throwable { } }); } - - if (selectedIconStyle.equals("theme")) { - Helpers.findAndHookMethod("android.content.res.AssetManager", lpparam.classLoader, "getResourceValue", int.class, int.class, TypedValue.class, boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - int resId = (int) param.args[0]; - String resName = dualSignalId2NameMap.get(resId); - if (resName != null) { - TypedValue tv = (TypedValue) param.args[2]; - tv.assetCookie = 17; - tv.type = 3; - tv.string = "res/drawable/" + resName + ".png"; - tv.resourceId = resId; - tv.changingConfigurations = 0; - tv.data = resId & 0x0000ffff; - param.setResult(true); - } - } - }); - Helpers.hookAllMethods("android.content.res.ResourcesImpl", lpparam.classLoader, "loadDrawableForCookie", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - int resId = (int) param.args[2]; - String resName = dualSignalId2NameMap.get(resId); - if (resName != null) { - Object dr; - Object mLookupStack = XposedHelpers.getObjectField(param.thisObject, "mLookupStack"); - Object stack = XposedHelpers.callMethod(mLookupStack, "get"); - XposedHelpers.callMethod(stack, "push", resId); - dr = XposedHelpers.callMethod(param.args[0], "loadOverlayDrawable", param.args[1], param.args[2]); - XposedHelpers.callMethod(stack, "pop"); - param.setResult(dr); - } - } - }); - } } public static void AddFiveGTileHook(LoadPackageParam lpparam) { diff --git a/app/src/main/res/color-night-v8/color_selector.xml b/app/src/main/res/color-night/color_selector.xml similarity index 100% rename from app/src/main/res/color-night-v8/color_selector.xml rename to app/src/main/res/color-night/color_selector.xml diff --git a/app/src/main/res/drawable/statusbar_signal_1_0_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_1_0_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..c0f3c7e95270977f224a168c55701e1aa5c37850 GIT binary patch literal 717 zcmV;;0y6!HP)k(QEoKs6V93oYDGG9TQizC*QeeNs zz{nuUz|5e@V40X)T;LcG;KP6ue7goz4Fs2UL1y7rhZS(8q!uRw=|4ammt0U(!oa{7 z17vfTmlS~589=s3QZ|@f17a5e9SCGk0I|~{>?L3|5cUqRnvfu8Ao~oE?U0VdPC{Zs z?F9kmWFrz?O#~=OttbJ}ZcYpgpfH7qBEkwG#w-TJ#taNhOAuoDix?Ozz5>N3AjFbp zGB9j!WnhrFg%DF&z`(%Y!oaZYd~#_~8PsYiAU@4_k~x`m5=S=oHvxOmKxq@jkD3#V zB&;X7u?CjMzRfPEV(r{Gt7c8+{@TljUmE=X4*=dlQ+;itfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00eVF zNmK|32nc)#WQYI&0TM|>K~#90?b)$P#6T2A;p4i9l@=Bjc8l--NFsJ3B6b#wSR`yQ zgms2Hj+4pxngo&wm!I6rgn%STk|b^3#eWyj$R0QVx4?CB?FhUAFZ20Xm(@$_(<5-t z6kKWt+|0+1-yXE9TUWR4D&4c0z?R;uRNAVGwh~x1Im!2++R(01$Qm4&hW3&@@Gzf0 z{dFO0X~}9sJ8CU~RU6t-YYD6yt!7v^Lp!QfVBHMus8%i6&Crg@eZ!(H)y>e3$_;Fo zmWs-4$zfV5DmSoUS}MwYSRn%|WMG91tdM~f$_*^%8}Do2^(VQ3y$A1E`}&jI-)x`2 z71Mq!-IE=GH{cog9(27VNs=TjyZq&N#aB8wRqxP?KOkzv*x2?hp6 z(M)IOfZ`x`CkBR!ImrnLk4}1?(@hgfNH}p;Ta&A(JgB3iCn#b6;R7cWP98Y3;AFzg z88I;rBm^EDZV;~7%@)GTGQHF>?O|BEXu;AYV(QETpyZV-O$EEN6_YGymI}F>eK%*UzUYuCe6)X-aF5Cw z^_?5prXAmRR&Pbp+dCGk(|n)(yLGxfUh2<(eujIF!L_-IAI}Gd8cVvPuOkD)#(wTU ziL5}rLb6AYF9SoB8UsT^3j@P1pisjL28L1t28LG&3=CE?7#PG0=Ijcz0qHGv@(kes zf*OvL4j})pr;B4q#hka-H}W+Zh_pUzPAn)cC@A>+cmB!7vyFETvWTZD2;~*$XGQpHu-YS&$!yVl%! ztr}~8{rg&R*+pd`JBlwD@8&#XD}@>&iukmAr4S?m8e6aVu_XPfA2)^;Mw= z2x+*fB*Js)+o`L+bZh3Wk5P{F$*i8aZ$raGtz}#Gu2H^u#-lRQebdZ|pEj{w1F{SG zyj>DHIdlXYRh2flTsxrizv6t`_48{Qd(Wk3#oKS5_hrBOkFD{G120|pPz7>41e|!r X8(HQcwPw4;Dv*GutDnm{r-UW|CWshx literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_1_1_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_1_1_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..19924fe8d2db82959d9c8aa5886ebf2a34f4bb1b GIT binary patch literal 922 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 b=X&x73~7*z;Zo{h00000NkvXXu0mjfDtWj2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_1_3_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_1_3_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..ba5e145c8e84ae969d967dc2920f91497206ac83 GIT binary patch literal 939 zcmV;c162HpP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZr1xZ9fRCt{2 z+P#VsQ4|2+FRLqyqJoMn3R)-@DuRN7g&>H9=v#<|g6R_fFy)&k?`aF2KkhpH?zDGlqs zZuOfpF%27-&BHDr!)~0y&aUxAyvD~SiWrrK?Z6f3(`Huj1@>;e3mKJD@~Ga|m=jGD zGAa$*I-s1|Mx|jJMw8dD?YNB#*wQh+gon6;?+w<|m!=xl!ULR7#7`=&L6;kHUg-XvQOiikY1rNY<&3o0hh>U}Wr~JniiTy1hGoiW*smHnRp!F)#Q1WB zxn((Z=da3X*wY$0FBMNl%Y4PFL~Opodza<3E6lHwlf7|GJqBLEJ={;k7jPXv6Y)h{ z!g52=`Tz0G6MU*Le~-1F z>9-XJtxQXC3pdj-wxT#lsRI>42q6R}=dWKOgb+dqA%qY@2qA>^@&{z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZrM@d9MRCt{2 z**$9%Q544U|5<~IA+n$;1O*X%4H(c$(aK)1h*~Px2!f5JjUU3wFCZ3zl}$>O5QX3e z@CA&RupluQL8ALuY?Miu*|~RTy}Oe=KiFo^Im4MVdxyI-;GA>LIp>_)er(VUq$J6J zotdxNX0{%4jFB0bq-o$Zuxm?b1$bd*OCiS@iGfL)0?u_w`2{>Rv(>U=HTu@oaGNTL zj{(O+4m2tQ+ta6-n+dG|kAa6~ z)=t$=uTtLh9|1QDV&~~>9PgxSr#DHKq@-iOjgqw6k`ATlr;4b7NxC9wPSTR3<&Dpx zq$iS&bSXVa`8}oqoQUaX5Q3Maq^or9HF+mK16+_aZDy^Uc<6;0`iB8Azp(psKcNG_ zt!nKIznFm??Nd&z#SAQDxeWc1s%krJT$AvDMe>0~@_|K)8QAvq|n1MYjiK|P_Dp14S6RhX#&{KmS_3}f5-Cb_W=``-rGRS%zlK_JLjBp&N=6tbIv*EoO8}O b=X&x73~7*z;Zo{h00000NkvXXu0mjfDtWj2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_1_4_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_1_4_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..0cfc3440963bc3e408231afd04aeb65151231cf5 GIT binary patch literal 951 zcmV;o14#UdP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZr5lKWrRCt{2 z*};nrVH^kW&$}!u95_gb18r%gmM90MovV&=Gl37cHj5?eQN4$e$VsFuWvK+zV8engb+dqA%y?pn(W5i{$=$Qw{fqDCVC~XQA}b}huVG|$9mjZ?nZj$lDw#M zSc_V?+C(G064;I|jj63y0$VkjyoYVZb)3Yyw*9ksfSdT)U_VRJRA4RK$BBaaI1b`$ zL;WmSQ$6Z8Fs0pz7ZE{^wJYj0^8Q5F+DAQhb4-@5=CH%BCtdeSfZ4`e%BaNWiI?# zhGWBAh51#+Bn38EW6U$ml+68s7X`J63djE6n5hc$tBgr{&GrQ6u%$z79(QqL;d9zK~(QeWddz8B2@j9u7JP=AM)1+{;qzQ`THDQs<2= Z_zT?qNMgm`>1qG~002ovPDHLkV1i=oqZz1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZrS4l)cRCt{2 z*}H2LQ547V?^&aQpa^0iL=eG8446g)MJo$!EuxkRHi}?lX<>>K`2(!{2gD*`VIc%; ze1zz~5N#qx79>6*NOXS|yCG|s$Gto2?2LOpu+5%x?w&cjGu)j4=bUrSIp^H}#|GU% znIsvot?R9pnXSdFF*E~{Gyxn3wr>ip058mJIb@xo7?`AS;8aG+FJRWpzUHmf=v!CS zHl7n70gi+$G%N$#(WjiD8Cc(p47!0(l171hz)3dx7O)7+nAyuR`l!XgB<%%W1EUGy zW55MT=gsW-zwV_jr{qnNhqZ1iFjYn)bs5-LpK=PT%fLeRi=`Y(Y1c4GTY%fZB(SS1 zv;sT??weVwtbTe`=0*Pja4jWvn)b%=R(b98rj(ztq{G0~oU|K~_LtF55m5t^bWzg0 zq-9B;IwNe4a&oRKtPX3d0n=oeG@n*lMu zu)Aa*&_3XLv39C2W?+Z7KrsEd=(z2iV!wdkbiq*^iKV r=bUrSIp>^n&N=6tbIv*ETu=T0Be9b|XaMgv00000NkvXXu0mjfFnqQs literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_1_5_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_1_5_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..1311b73d21779c89bfdb6ec0212dad8f2e127c38 GIT binary patch literal 934 zcmV;X16lluP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZr07*naRCt{2 z*}aPsK@~+j+d~Y&Nrm5JCtcgb@BcwNWQfvGu5T zyl>*;@@wd@4!7_XOMkTnPK_?L@pRqFLUp!ZI5@KG#!y3X!Ip3%~ZQt+^SMj;Rdz1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZrA4x<(RCt{2 z*}rQOaTv$(_t#2>UsPE`n}O z1s4Se!CyESD`E?dt$90C@DMKdO|Q8m=6S()NuKBK$%owK8xBGUA%qY@2>+in>;amf zwt%a^DWF|=YYkWgZlsjH4r8{Fq&~2>w`#lkNE1NaqjoC-Q@xOLye)$scm&Llck7wS zIoKowmV2Mhs@qy)kVdKdfiu8#;pHyy8hDga`qji7V-c7-4=ez!l9FfYiImdXpl2ER zOH!Qz?ol2Vz#MSCiFrmoFkm;ZGo$X%pa+5R2y7~|u945u*gZ_$4$K2PiZ282fhQ@Y z)uv{tqmjVW1Hg02FRev&E~WIdiFxX1>XN)m@B7dZ;BrH=)RO%TQ?~(Ufm!};@&r1- z!<5oWkM^S(r^u-px~#y|UBC-qUrEVz^>|9@Lyhx{#hx(tlDtWISg`)nf4lxTqc1nG z!<$qy_HqNu*$d_Fm&V#SY+Of51lFertWObGpC%zNH}hb*fi2an`BtO)#Odocc=r@y~jr zUaII#>J{~!x>8un>Pz)xMSn}Z^{0QSusZ5f^jyZq&N#aB8wRqxP?KOkzv*x2?hp6 z(M)IOfZ`x`CkBR!ImrnLk4}1?(@hgfNH}p;Ta&A(JgB3iCn#b6;R7cWP98Y3;AFzg z88I;rBm^EDZV;~7%@)GTGQHF>?O|BEXu;AYV(QETpyZV-O$EEN6_YGymI}F>eK%*UzUYuCe6)X-aF5Cw z^_?5prXAmRR&Pbp+dCGk(|n)(yLGxfUh2<(eujIF!L_-IAI}Gd8cVvPuOkD)#(wTU ziL5}rLb6AYF9SoB8UsT^3j@P1pisjL28L1t28LG&3=CE?7#PG0=Ijcz0qHGv@(kes zf*OvL4j_M%r;B4q#hka-_HrFEkZ^nWnE%m|=H}fM|F5g$xw_nu>9UYuVp|yhB0%cg z<|P;2Fa2OPp+UuS5-PgnB6e`6X#vx>1KTRDGs_nEp4WZ0`RWCSBDTJlhnK2u@P57c z;-B*cM-rc$x$`-4%ZB>;Wg&TAr+tdtVxTG(cJh!`WW>^p#OCk953Uy2b&HkBTN;0_ y5!<`Nu95ftjyZq&N#aB8wRqxP?KOkzv*x2?hp6 z(M)IOfZ`x`CkBR!ImrnLk4}1?(@hgfNH}p;Ta&A(JgB3iCn#b6;R7cWP98Y3;AFzg z88I;rBm^EDZV;~7%@)GTGQHF>?O|BEXu;AYV(QETpyZV-O$EEN6_YGymI}F>eK%*UzUYuCe6)X-aF5Cw z^_?5prXAmRR&Pbp+dCGk(|n)(yLGxfUh2<(eujIF!L_-IAI}Gd8cVvPuOkD)#(wTU ziL5}rLb6AYF9SoB8UsT^3j@P1pisjL28L1t28LG&3=CE?7#PG0=Ijcz0qHGv@(kes zf*OvL4j_M(r;B4q#hka-7V;f35MjMw-E=@vfJ5g0e_sw6rv3<{GZ`m@BBpaX758Ob zD%Z}_iemz5f`Jdpv1czB@Z45;uJT)D_sP=vPo_P&RT_Ig>EGS5yo3_JqCcOGW!l6` zofV(Gv+-i$(=+>@ci%dcRrl!2>g`kXv$&I&Y-knPHsO%iD&3qid(Tf97V%fa%Hl0Q tzyGPgv$D;XH--f%v5u>Z7vT1q#_c28G7mvv4FO#naZ>uvx5 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_2_1_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_2_1_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..32709930d350346a84b84fa2e0b59145863b6db3 GIT binary patch literal 837 zcmV-L1G@Z)P)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZqpGibPRCt{2 z*Go?VF%*X3cen*3D&7)tLE_5)|A*9&7$q8`5>OmqT(qMwGwrls;^upj*-U$S+EXqq zh=_=Yh=_=Yh=_=Yh=_=Yh=_=Yh=_>DUrGKUXSa|y13m*|n?R@VZULl$@f|zHx-VcE z7$04*0dNkq*52g{z6ahtu|435@`3^8zzr~~$$bGd3hy)E4Y&nXj@YKneMouDE8qcm z^yJZ0;){yd25?PvvA}G=5%A<_?*l{1#lq(A+IhJ)YzUlC{Q*gU z17M2TIIpS+xSR!yb?RvAVT$V00rnkjed@mr{Vm(DW7qWo;tJNP@8bN#hURhg3;F5r z<=8bou9N&y!6K<(kyNlqF$D`b+_}y{DdxQ7li@yqRvlHUa=7do|0AYgFE#C%r_a=>(e{LUGxFSHPx~1EhAn|-@9eCYgX;uywAiEkH=P0_{3rca%my{>1oJ1w6ncbv zQ42eE$L3y-pJQ$rz73sWu0U;@V?BNf+!1&^+vYBruvzGQ0wN+JA`j!vz`!V)>FgX(9OUlAz)&$KIU(WE zNzZe-X+jAJC(deXaut;ab#(LuCG0Jz=OjL!Zo|uLU>uG zmpZ0B3~LuHSh_?^o%yA`gUs}pfRIB64oEPk6i=Tn(r`o4VVg&g*^F4`BymPrjud}} zjh7YQs3w>SeB;|NYl1?$!f&1lZzuE}@pDRYe#^@EEJax;)|W-YbFBvB#XLVAo&^T2 z9ZH9|6p!h!9XZCsH_@f1G4T1tm`iJnv>#Ny|LAjRkC8povAgaELV~V5NlZAblq6o^ z`?*nkHcJ8P9M4&4n`R$iPq=j3yutp!@|ed;k5oU%-FTtTC_c$f{MR)j6cd&YBD_h+`9Uwd!o@&h}U+;9EEJu9+kbNMPUQk-~V3Uo$}jn k+X=U~yXVXV0^Pr?hdmo^SIhV217noI)78&qol`;+0Kds`RsaA1 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_2_2_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_2_2_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..ce69bb0fb35008641612b64a272b5fcd025dce70 GIT binary patch literal 868 zcmV-q1DpJbP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZqzDYzuRCt{2 z+s|s$P!tE?&yF1hs|+frE2(RjzK<&rU%;jMGU6i$u6zdtH=?3Qt%~@ER@>=xTqLdI zOmma8U_pK#WHCASTdKE+h=_=Yh=_=Yh=_=Yh=_=Y z<9Fg1<~%(&?-ai}<_<8N+qZ*p$NZtiH6qWEU<2I4ZJeLkKgA2&#gjt*3RW$i zFl^x!HVgSzaM|MPN>hBpYwQ-*zKU}e&v_SX_)wU8U!Q_K!2Lpe8#nOmfY=hQW4R^& zxvBv3M!2TD-j8_K5W9+th1@A#;(K8X`n_Cst0g|f&4$>DaEH?wf^K5#*7`@F3g&0Za{ZB z%w1|;kD9-)Pr)9x#3y*v5ZkD?k{|fl5c{OLDWxj*dLh29e8DF8TwGnP&mS9};*zQX zJvkR!!yP;>XP^o?|wD18;PE uJUh&@IP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZq(Md!>RCt{2 z*UM@YK^VpH|1pvY69qK^FQDkkh2TSpD|dntd=9t4m&w8h5Xn*yP2wHVXlCN@Ws!F1 zbf)XVgmK~dEvxEu)qFioe+_14W@ct)W@ct)W@ct)W@ct)W@ct)W_DJz=nW%c0Gw+L zO(cyAvjSE+!(&O4!u%4j+#Ui(lAlyn%uCnZvgwi zn^fT<;tFsRINzNDK1zC*Ir}YOozuVh5Aasfw^aVG;(|5B+Dv4=0QV*B^yKex`rpy^ zOVV~vb``jrIq!Q(dp-HP#UfNe>?6KjBzk4DZ@(g$7x9?m>X#0ApD0vJZbFmdhN z&0R~(t!J{zswr5>_34WNvRt$Row7!q)%* N002ovPDHLkV1jivf-?XB literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_2_3_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_2_3_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2312a73046afff3e04fdc0275848c6826018be GIT binary patch literal 877 zcmeAS@N?(olHy`uVBq!ia0vp^K0s{4!3HGHY>j!vz`!V)>FgX(9OUlAz)&$KIU(WE zNzZe-X+jAJC(deXaut;ab#(LuCG0Jz=OjL!Zo|uLU>uG zmpZ0B3~LuHSh_?^o%yA`gUs}pfRIB64oEPk6i=Tn(r`o4VVg&g*^F4`BymPrjud}} zjh7YQs3w>SeB;|NYl1?$!f&1lZzuE}@pDRYe#^@EEJax;)|W-YbFBvB#XLVAo&^T2 z9ZH9|6p!h!9XZCse;NLJ6)1g6Hhv+G`XnRHvgE>GUKAW zSg70Um%HwoDu=zFeC64^>UV3cwp*8WbzlcS!ngf-{&(9$6D#Fp?TXHSJU@$*cV0Mr zUh@00!ip?R#If1p0 zdR{$}dMEzrePaKr+i}O9|B4EcJr)}J+1hjcxtA-VTK=8bx+ts4Ui90)xb=HuLw8*K zlV6ctba>A>w|%PRE9CxcXWXappGgS_9_8<6VCfFssGW0t4ls%tJYD@<);T3K0RY@5 Bgi!zh literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_2_3_theme.png b/app/src/main/res/drawable/statusbar_signal_2_3_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..29211e740ccec5ed743757103c7800190429f7e1 GIT binary patch literal 920 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 IM6N<$f`D#~cmMzZ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_2_5_dark_theme.png b/app/src/main/res/drawable/statusbar_signal_2_5_dark_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..287a1a4a9fd2005001f1991400668d58b8760f7f GIT binary patch literal 873 zcmV-v1D5=WP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZq!%0LzRCt{2 z*FTR;Q5Xl{XLlt2Es8B98`(-Dp%n!!QThZ54L*Tr&`UH5g+ikhjVLG-5`{*iQIPDC z-5{1tghgf)cXo`;+;i{U71i%aPBAC%Z{Bmy&1B9YA|fIpA|fIpA|fIpA|fIpA|fIp zA|fLGm8t*SZyNL1Ha7PYi|Dt=@5UT@!|#F>EVb-EkJ+)$1H8ePmibP4xQ1o?7#nMN zfs+mS<5(Cja^rZ7qYe2h_&y=q$9>EcvitC0Si3R*4VM~vZ_3pP&Bn(Xj?`pl@V+7c z7CUP4XH0(B@o}@T_S+5FK28_%oAR!q=>XSjvZq>P2RKoaztbYSSXldq7WrF+{K#~3 z$;fPTNo~!pmOXZMoNwD>tND>G8y2!*on^y1%7*!&bLYv!r=J1JxOClDheg zJ?gZ{x2fsmhVtL?FC44MPT^@o{!yX#A$%=l`#4v~UsOKFt>R!IKhkScH1q`faoFEi z8>+W^0S^oLd)R}$!v(Gk$1?8Xyz1sK$wxfK0oAYK^H}~BF00OJb)KuvX>+Or_Imac zp5ZKB7V;yTxl3+WJ@~r5>H*r^1tTINBBJse#Rs&AQGLV200000NkvXXu0mjfE4O-< literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/statusbar_signal_2_5_theme.png b/app/src/main/res/drawable/statusbar_signal_2_5_theme.png new file mode 100644 index 0000000000000000000000000000000000000000..ea1beb01f4fdf4ab17bdac03bb5e78316d968506 GIT binary patch literal 868 zcmV-q1DpJbP)z1b7AFJgKR_IpTu@ZPz`z&-WOJ976oA+nK(!C15oW_71R`kRWFu`wWonkdDMoLSjSh1p(${BNAOr1SmvjF#FAz*Fl=vSV34?l5K~#ez`)h920ejIvX%oedniGs9tS7m#2A0RZ%`T{7?c6x4W=-b) z+RKMu8vOqc0Nz1UeQl%Tp8x;=1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g z0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy1am@3R0s$N2z&@+hyVZqzDYzuRCt{2 z*D*_$Q5eSY|1A+2I0QCC=+IP?wMs!wK~PN*4nol_rS}D7}okuBuz+KR@p~Mla+o}(q^UqEa`NmpO>^<>6axPuk;Tj4J-XC zN$HQLNz&uWW_y+@{kuf}sL&ph^gYqvFZ8D*Z6*5anX?$n9T{^yXJ!)p#lreop!oGA z_Baom=+W7UsyA6Q2|u#U0^rk*pIJ5FgPdp|1epY2m~ z*#rC5b7m#cmuA+0A3ge2pn9oo^xa9is`|xoAn8`4uib^dN;*^N@9pkU@L6)R z^^5Bp?Yv}~x;%~MfQP{Jfj_MSPa@)VqrU*$W&fRO?`iZjA~qWREO3XvKaG|mVyn?# u18x8(N0xuH^E7%M5! Date: Sun, 22 Jan 2023 12:17:32 +0800 Subject: [PATCH 314/627] fix: reduce tile hight when label is hidden --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index e9defa88..ccdcec3d 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2640,6 +2640,7 @@ private static void updateLabelsVisibility(Object mRecord, int mRows, int orient } private static void HideCCLabelsHook(ClassLoader pluginLoader) { + MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85f); Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); Helpers.hookAllMethods(QSController, "init", new MethodHook() { @Override @@ -8772,7 +8773,7 @@ protected void after(MethodHookParam param) throws Throwable { MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_control_center_tile_width", scaledTileWidthDim); MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "qs_control_tile_icon_bg_size", scaledTileWidthDim); MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_control_tile_icon_bg_size", scaledTileWidthDim); - MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85.0f); + MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85f); } } } From 96c93194eda3f19c5c40d68dd7213ec75db5eeec Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 24 Jan 2023 16:33:50 +0800 Subject: [PATCH 315/627] fix: disable apk signature verify --- .../mikanoshi/customiuizer/mods/System.java | 79 +++++++------------ 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index ccdcec3d..7e717ac5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -5718,9 +5718,20 @@ public static void DisableSystemIntegrityHook(LoadPackageParam lpparam) { public static void NoSignatureVerifyServiceHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapability", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapabilityRecover", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkSysAppCrack", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", new MethodHook() { + Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkSysAppCrack", XC_MethodReplacement.returnConstant(false)); + Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "compareSignatures", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object s1 = param.args[0]; + Object s2 = param.args[1]; + int ret = 0; + if (s1 == null || s2 == null) { + ret = -3; + } + param.setResult(ret); + } + }); + MethodHook compareHook = new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { Object s1 = param.args[0]; @@ -5738,12 +5749,21 @@ protected void before(MethodHookParam param) throws Throwable { } param.setResult(ret); } + }; + Helpers.hookAllMethodsSilently("miui.util.CertificateUtils", lpparam.classLoader, "compareSignatures", compareHook); + Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", compareHook); + + Class SignDetails = findClassIfExists("android.content.pm.SigningDetails", lpparam.classLoader); + Object signUnknown = XposedHelpers.getStaticObjectField(SignDetails, "UNKNOWN"); + Helpers.hookAllMethods(SignDetails, "checkCapability", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (param.thisObject == signUnknown || param.args[0] == signUnknown) param.setResult(false); + else param.setResult(true); + } }); - Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "matchSignaturesCompat", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "matchSignaturesRecover", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("miui.util.CertificateUtils", lpparam.classLoader, "compareSignatures", XC_MethodReplacement.returnConstant(true)); + if (Helpers.isTPlus()) { - Helpers.hookAllMethods("android.content.pm.SigningDetails", lpparam.classLoader, "checkCapability", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllConstructors("android.util.jar.StrictJarVerifier", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { @@ -5752,19 +5772,7 @@ protected void after(MethodHookParam param) throws Throwable { }); Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verifyMessageDigest", XC_MethodReplacement.returnConstant(true)); Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verify", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object pkgSetting = param.args[0]; - Object signDetails = XposedHelpers.callMethod(pkgSetting, "getSigningDetails"); - Object signatures = XposedHelpers.callMethod(signDetails, "getSignatures"); - if (signatures == null) { - param.setResult(false); - return; - } - param.setResult(true); - } - }); + Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", XC_MethodReplacement.returnConstant(false)); Helpers.hookAllMethods("com.android.server.pm.InstallPackageHelper", lpparam.classLoader, "doesSignatureMatchForPermissions", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { @@ -5778,37 +5786,6 @@ protected void before(MethodHookParam param) throws Throwable { } } - @SuppressWarnings("ResultOfMethodCallIgnored") - public static void NoSignatureVerifyMiuiHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethodSilently("com.android.packageinstaller.InstallAppProgress.a", lpparam.classLoader, "a", Boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - - Helpers.findAndHookMethodSilently("com.android.packageinstaller.InstallAppProgress.a", lpparam.classLoader, "onPostExecute", Boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - - Helpers.findAndHookMethodSilently("com.android.packageinstaller.IncrementInstallProgress.a", lpparam.classLoader, "a", Boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - - Helpers.findAndHookMethodSilently("com.android.packageinstaller.IncrementInstallProgress.a", lpparam.classLoader, "onPostExecute", Boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - } - public static void ScreenDimTimeHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.server.power.PowerManagerService", lpparam.classLoader, "readConfigurationLocked", new MethodHook() { @Override From bde8ae93f9ee3319eafe95984d3956bcd919d675 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 25 Jan 2023 12:49:15 +0800 Subject: [PATCH 316/627] refactor --- app/build.gradle | 5 +++++ .../main/java/name/mikanoshi/customiuizer/mods/System.java | 6 +++--- app/src/main/res/xml/prefs_controls.xml | 3 ++- build.gradle | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4f308461..58da1c3d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,11 @@ android { noCompress 'zip' } buildToolsVersion '33.0.0' +// gradle.projectsEvaluated { +// tasks.withType(JavaCompile) { +// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" +// } +// } // compileOptions { // sourceCompatibility JavaVersion.VERSION_1_8 // targetCompatibility JavaVersion.VERSION_1_8 diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 7e717ac5..3a3b8ed5 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2773,12 +2773,12 @@ protected void after(MethodHookParam param) throws Throwable { } public static void ExtendedPowerMenuHook(LoadPackageParam lpparam) { - final boolean[] isListened = {false}; Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isListened = false; @Override protected void after(MethodHookParam param) throws Throwable { - if (!isListened[0]) { - isListened[0] = true; + if (!isListened) { + isListened = true; Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); File powermenu = new File(mContext.getCacheDir(), "extended_power_menu"); if (powermenu == null) { diff --git a/app/src/main/res/xml/prefs_controls.xml b/app/src/main/res/xml/prefs_controls.xml index 108b37ab..d10a36c9 100644 --- a/app/src/main/res/xml/prefs_controls.xml +++ b/app/src/main/res/xml/prefs_controls.xml @@ -255,7 +255,8 @@ miuizer:minValue="0" miuizer:maxValue="50" miuizer:stepValue="1" - miuizer:format="%d dp" /> + miuizer:format="%d dp" + android:dependency="pref_key_controls_nonavbar" /> Date: Wed, 25 Jan 2023 12:53:01 +0800 Subject: [PATCH 317/627] sync at begin of second --- .../main/java/name/mikanoshi/customiuizer/mods/System.java | 2 ++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system_statusbar_clock.xml | 5 +++++ 4 files changed, 9 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 3a3b8ed5..82a2d624 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1182,6 +1182,8 @@ private static void initSecondTimer(Object clockController) { if (ccShowSeconds || finalSbShowSeconds) { final Handler mClockHandler = new Handler(mContext.getMainLooper()); long delay = 1000 - SystemClock.elapsedRealtime() % 1000; + boolean beginOfSecond = MainModule.mPrefs.getBoolean("system_statusbar_clock_seconds_sync_beginning"); + delay += beginOfSecond ? 950 : 50; Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4052f9eb..0d6397e1 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -84,6 +84,7 @@ 日历应用 点击通知抽屉上方的日期时打开所选应用 显示秒 + 在秒开始时同步 显示时段 24小时制 固定宽度以防相邻元素左右防抖 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a3152f1..657b85ce 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,6 +118,7 @@ Show year Fixed width to prevent horizontal jitter Horizontal alignment + Synchronization at the beginning of second Extra width Avoid to display an ellipsis Display seconds in the status bar clock diff --git a/app/src/main/res/xml/prefs_system_statusbar_clock.xml b/app/src/main/res/xml/prefs_system_statusbar_clock.xml index 17d81dd1..81d6c70c 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_clock.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_clock.xml @@ -75,6 +75,11 @@ android:title="@string/system_clockseconds_title" android:defaultValue="false" /> + + Date: Mon, 30 Jan 2023 13:35:17 +0800 Subject: [PATCH 318/627] fix(miui14): hide dismissview on notification panel --- .../name/mikanoshi/customiuizer/mods/System.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 82a2d624..fe8a7f53 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -2878,18 +2878,8 @@ public static void HideDismissViewHook(LoadPackageParam lpparam) { protected void before(MethodHookParam param) throws Throwable { View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); if (mDismissView != null) { - Object mKeyguardShowing = XposedHelpers.getObjectField(param.thisObject, "mKeyguardShowing"); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "currentKeyguard", mKeyguardShowing); - XposedHelpers.setObjectField(param.thisObject, "mKeyguardShowing", true); - } - } - - @Override - protected void after(MethodHookParam param) throws Throwable { - View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); - if (mDismissView != null) { - Object mKeyguardShowing = XposedHelpers.getAdditionalInstanceField(param.thisObject, "currentKeyguard"); - XposedHelpers.setObjectField(param.thisObject, "mKeyguardShowing", mKeyguardShowing); + mDismissView.setVisibility(View.GONE); + param.setResult(null); } } }); From 4e18b3693a6479b80103932602007ae396ff5a3e Mon Sep 17 00:00:00 2001 From: MonwF Date: Mon, 30 Jan 2023 13:58:12 +0800 Subject: [PATCH 319/627] feat: hide dual wifi icon --- .../main/java/name/mikanoshi/customiuizer/MainModule.java | 1 + .../main/java/name/mikanoshi/customiuizer/mods/System.java | 1 + app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/prefs_system_hideicons.xml | 5 +++++ 5 files changed, 9 insertions(+) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 0adce562..38dd3cd7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -347,6 +347,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { boolean hideIconsActive = mPrefs.getBoolean("system_statusbaricons_wifi") || + mPrefs.getBoolean("system_statusbaricons_dualwifi") || mPrefs.getBoolean("system_statusbaricons_alarm") || mPrefs.getBoolean("system_statusbaricons_profile") || mPrefs.getBoolean("system_statusbaricons_sound") || diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index fe8a7f53..78520a8e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -4089,6 +4089,7 @@ private static boolean checkSlot(String slotName) { "nfc".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nfc") || "location".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_gps") || "wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_wifi") || + "slave_wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_dualwifi") || "hotspot".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_hotspot") || "no_sim".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nosims") || "bluetooth_handsfree_battery".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_btbattery") || diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0d6397e1..9e27eb1e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -58,6 +58,7 @@ 通话:录音 HD图标 漫游 + 辅助 WLAN 电池条指示器 将电池电量显示为彩色条 限制可见性 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 657b85ce..a4bc8581 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,6 +52,7 @@ VoLTE VoWiFi Roaming + Dual Wi-Fi GPS VPN NFC diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index 1419ba48..0623750c 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -95,6 +95,11 @@ android:title="@string/array_global_toggle_wifi" android:defaultValue="false" /> + + Date: Mon, 30 Jan 2023 20:25:40 +0800 Subject: [PATCH 320/627] clean code --- app/src/main/java/name/mikanoshi/customiuizer/mods/System.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 78520a8e..030d1cf9 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -8721,9 +8721,6 @@ public static void SystemCCGridHook(LoadPackageParam lpparam) { if (cols > 4) { MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_columns", cols); } - if (rows != 4) { - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_min_rows", rows); - } Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { private boolean isHooked = false; From faa08dd86bc4b0732993a7ebfba97cbc03f0d55b Mon Sep 17 00:00:00 2001 From: MonwF Date: Tue, 31 Jan 2023 12:57:53 +0800 Subject: [PATCH 321/627] disable bluetooth restrict on miui13 --- .../main/java/name/mikanoshi/customiuizer/subs/System.java | 4 ---- app/src/main/res/xml/prefs_system.xml | 1 - 2 files changed, 5 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java index 1e30584a..1a0b0774 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System.java @@ -330,10 +330,6 @@ public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); - - if (Helpers.isTPlus()) { - findPreference("pref_key_system_cc_disable_bluetooth_restrict").setVisible(true); - } break; case "pref_key_system_cat_recents": findPreference("pref_key_system_hidefromrecents_apps").setOnPreferenceClickListener(openAppsEdit); diff --git a/app/src/main/res/xml/prefs_system.xml b/app/src/main/res/xml/prefs_system.xml index bbe73a0f..3f18f46e 100644 --- a/app/src/main/res/xml/prefs_system.xml +++ b/app/src/main/res/xml/prefs_system.xml @@ -723,7 +723,6 @@ Date: Tue, 31 Jan 2023 18:01:06 +0800 Subject: [PATCH 322/627] fix: swipe up gesture in launcher; show brightness percent; mute power sound; long press left button to toggle flashlight --- .../mikanoshi/customiuizer/mods/Launcher.java | 66 +-- .../mikanoshi/customiuizer/mods/System.java | 442 +++++------------- .../subs/System_LockScreenShortcuts.java | 1 - ...keyguard_bottom_flashlight_on_img_dark.xml | 32 -- ...eyguard_bottom_flashlight_on_img_light.xml | 32 -- app/src/main/res/values-pl-rPL/strings.xml | 5 - app/src/main/res/values-ru-rRU/strings.xml | 5 - app/src/main/res/values-zh-rCN/strings.xml | 9 +- app/src/main/res/values-zh-rTW/strings.xml | 7 +- app/src/main/res/values/strings.xml | 7 +- .../xml/prefs_system_lockscreenshortcuts.xml | 132 ++---- 11 files changed, 191 insertions(+), 547 deletions(-) delete mode 100644 app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_dark.xml delete mode 100644 app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_light.xml diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java index 458d4818..a52d699e 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java @@ -67,37 +67,9 @@ public class Launcher { -// private static GestureDetector mDetector; private static GestureDetector mDetectorHorizontal; - @SuppressWarnings("ResultOfMethodCallIgnored") public static void HomescreenSwipesHook(final LoadPackageParam lpparam) { -// // Detect vertical swipes -// Helpers.findAndHookMethod("com.miui.home.launcher.ForceTouchLayer", lpparam.classLoader, "onInterceptTouchEvent", MotionEvent.class, new MethodHook() { -// @Override -// protected void before(final MethodHookParam param) throws Throwable { -// Context helperContext = ((ViewGroup)param.thisObject).getContext(); -// -// if (helperContext == null) return; -// if (mDetector == null) mDetector = new GestureDetector(helperContext, new SwipeListener(helperContext)); -// -// MotionEvent ev = (MotionEvent)param.args[0]; -// if (ev == null) return; -// mDetector.onTouchEvent(ev); -// } -// }); - -// if (MainModule.pref_swipedown != 1) -// Helpers.findAndHookMethod("com.miui.launcher.utils.LauncherUtils", lpparam.classLoader, "expandStatusBar", Context.class, XC_MethodReplacement.DO_NOTHING); -// -// if (MainModule.pref_swipeup != 1) -// Helpers.findAndHookMethod("com.miui.home.launcher.DeviceConfig", lpparam.classLoader, "allowedSlidingUpToStartGolbalSearch", Context.class, new MethodHook() { -// @Override -// protected void before(final MethodHookParam param) throws Throwable { -// param.setResult(false); -// } -// }); - Helpers.findAndHookMethod("com.miui.home.launcher.Workspace", lpparam.classLoader, "onVerticalGesture", int.class, MotionEvent.class, new MethodHook() { @Override protected void before(final MethodHookParam param) throws Throwable { @@ -133,17 +105,18 @@ public void onChange(Uri uri) { try { String type = uri.getPathSegments().get(1); String key = uri.getPathSegments().get(2); - if (key.contains("pref_key_launcher_swipedown")) - switch (type) { - case "string": - MainModule.mPrefs.put(key, Helpers.getSharedStringPref(act, key, "")); - break; - case "integer": - MainModule.mPrefs.put(key, Helpers.getSharedIntPref(act, key, 1)); - break; - case "boolean": - MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(act, key, false)); - break; + if (key.contains("pref_key_launcher_swipedown")) { + switch (type) { + case "string": + MainModule.mPrefs.put(key, Helpers.getSharedStringPref(act, key, "")); + break; + case "integer": + MainModule.mPrefs.put(key, Helpers.getSharedIntPref(act, key, 1)); + break; + case "boolean": + MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(act, key, false)); + break; + } } } catch (Throwable t) { XposedBridge.log(t); @@ -160,6 +133,13 @@ protected void before(final MethodHookParam param) throws Throwable { } }); + Helpers.findAndHookMethodSilently("com.miui.home.launcher.uioverrides.AllAppsSwipeController", lpparam.classLoader, "canInterceptTouch", MotionEvent.class, new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + if (MainModule.mPrefs.getInt("launcher_swipeup_action", 1) > 1) param.setResult(false); + } + }); + // content_center, global_search, notification_bar Helpers.findAndHookMethodSilently("com.miui.home.launcher.allapps.LauncherMode", lpparam.classLoader, "getPullDownGesture", Context.class, new MethodHook() { @Override @@ -517,14 +497,6 @@ protected void after(final MethodHookParam param) throws Throwable { if (mHasLaunchedAppFromFolder) XposedHelpers.callMethod(param.thisObject, "closeFolder"); } }); - - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently("com.miui.home.launcher.common.CloseFolderStateMachine", lpparam.classLoader, "onPause", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - if (MainModule.mPrefs.getStringAsInt("launcher_closefolders", 1) == 3) param.setResult(null); - } - }); } @SuppressWarnings("ResultOfMethodCallIgnored") diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 030d1cf9..889f3e90 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -4505,27 +4505,15 @@ protected void after(MethodHookParam param) throws Throwable { Object img = param.getResult(); if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { Object thisObject = XposedHelpers.getSurroundingThis(param.thisObject); - Context mContext = (Context)XposedHelpers.getObjectField(thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(thisObject, "mContext"); boolean mDarkMode = XposedHelpers.getBooleanField(thisObject, "mDarkStyle"); - Drawable flashlightDrawable; - Object flashlightController = XposedHelpers.getObjectField(thisObject, "mFlashlightController"); - boolean isOn = (boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); - if (isOn) { - flashlightDrawable = Helpers.getModuleRes(mContext).getDrawable( - mDarkMode ? R.drawable.keyguard_bottom_flashlight_on_img_dark : R.drawable.keyguard_bottom_flashlight_on_img_light, - mContext.getTheme() - ); - } - else { - flashlightDrawable = Helpers.getModuleRes(mContext).getDrawable( - mDarkMode ? R.drawable.keyguard_bottom_flashlight_img_dark : R.drawable.keyguard_bottom_flashlight_img_light, - mContext.getTheme() - ); - } + Drawable flashlightDrawable = Helpers.getModuleRes(mContext).getDrawable( + mDarkMode ? R.drawable.keyguard_bottom_flashlight_img_dark : R.drawable.keyguard_bottom_flashlight_img_light, + mContext.getTheme() + ); XposedHelpers.setObjectField(img, "drawable", flashlightDrawable); - } - else if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) - XposedHelpers.setObjectField(img, "drawable", null); + } else if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) + XposedHelpers.setObjectField(img, "isVisible", false); } }); @@ -4534,14 +4522,14 @@ else if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) protected void after(MethodHookParam param) throws Throwable { Object img = param.getResult(); if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { - XposedHelpers.setObjectField(img, "drawable", null); + XposedHelpers.setObjectField(img, "isVisible", false); return; } boolean opt = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image"); if (!opt) return; Object thisObject = XposedHelpers.getSurroundingThis(param.thisObject); - Context mContext = (Context)XposedHelpers.getObjectField(thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(thisObject, "mContext"); boolean mDarkMode = XposedHelpers.getBooleanField(thisObject, "mDarkStyle"); XposedHelpers.setObjectField(img, "drawable", Helpers.getModuleRes(mContext).getDrawable( mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, @@ -4557,21 +4545,62 @@ protected void after(MethodHookParam param) throws Throwable { if (!opt) return; boolean isLeft = (boolean) param.args[0]; if (!isLeft) { - TextView mRightAffordanceViewTips = (TextView)XposedHelpers.getObjectField(param.thisObject, "mRightAffordanceViewTips"); - if (mRightAffordanceViewTips != null) mRightAffordanceViewTips.setText(Helpers.getModuleRes(mRightAffordanceViewTips.getContext()).getString(R.string.system_lockscreenshortcuts_right_image_hint)); + TextView mRightAffordanceViewTips = (TextView) XposedHelpers.getObjectField(param.thisObject, "mRightAffordanceViewTips"); + if (mRightAffordanceViewTips != null) + mRightAffordanceViewTips.setText(Helpers.getModuleRes(mRightAffordanceViewTips.getContext()).getString(R.string.system_lockscreenshortcuts_right_image_hint)); } } }); + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); + mLeftAffordanceView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); + boolean z = !(boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); + XposedHelpers.callMethod(flashlightController, "setFlashlight", z); + XposedHelpers.callMethod(param.thisObject, "updateLeftAffordanceIcon"); + return true; + } + }); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "updateLeftAffordanceIcon", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mLeftAffordanceView = XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); + Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); + boolean isOn = (boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); + XposedHelpers.callMethod(mLeftAffordanceView, "setCircleRadiusWithoutAnimation", isOn ? 66f : 0f); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onClick", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View view = (View) param.args[0]; + View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); + if (view == mLeftAffordanceView) { + param.setResult(null); + } + } + }); + } + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "launchCamera", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); if (GlobalActions.handleAction(mContext, "pref_key_system_lockscreenshortcuts_right", true)) { param.setResult(null); Object PanelInjector = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader)); Object panelController = XposedHelpers.getObjectField(PanelInjector, "mPanelViewController"); - final View mNotificationPanelView = (View)XposedHelpers.getObjectField(PanelInjector, "mPanelView"); + final View mNotificationPanelView = (View) XposedHelpers.getObjectField(PanelInjector, "mPanelView"); mNotificationPanelView.postDelayed(new Runnable() { @Override public void run() { @@ -4582,29 +4611,11 @@ public void run() { } }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onClick", View.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { - View view = (View) param.args[0]; - View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); - if (view == mLeftAffordanceView) { - Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); - boolean z = !(boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); - XposedHelpers.callMethod(flashlightController, "setFlashlight", z); - XposedHelpers.callMethod(param.thisObject, "updateLeftAffordanceIcon"); - param.setResult(null); - } - } - } - }); - Helpers.hookAllMethods("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "setDarkStyle", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image")) { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); boolean mDarkMode = XposedHelpers.getBooleanField(param.thisObject, "mDarkStyle"); XposedHelpers.callMethod(param.thisObject, "setPreviewImageDrawable", Helpers.getModuleRes(mContext).getDrawable(mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, mContext.getTheme())); } @@ -4614,10 +4625,10 @@ protected void after(MethodHookParam param) throws Throwable { Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "updatePreView", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - View mPreViewContainer = (View)XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); + View mPreViewContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); if ("active".equals(mPreViewContainer.getTag())) { XposedHelpers.setFloatField(param.thisObject, "mIconCircleAlpha", 0.0f); - ((View)param.thisObject).invalidate(); + ((View) param.thisObject).invalidate(); } } }); @@ -4625,21 +4636,21 @@ protected void before(MethodHookParam param) throws Throwable { Helpers.hookAllMethods("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "setPreviewImageDrawable", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); boolean mDarkMode = XposedHelpers.getBooleanField(param.thisObject, "mDarkStyle"); - ImageView mIconView = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mIconView"); + ImageView mIconView = (ImageView) XposedHelpers.getObjectField(param.thisObject, "mIconView"); if (mIconView != null) if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image")) mIconView.setImageDrawable(Helpers.getModuleRes(mContext).getDrawable(mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, mContext.getTheme())); else mIconView.setImageDrawable(mContext.getDrawable(mDarkMode ? mContext.getResources().getIdentifier("keyguard_bottom_camera_img_dark", "drawable", lpparam.packageName) : mContext.getResources().getIdentifier("keyguard_bottom_camera_img", "drawable", lpparam.packageName))); - View mPreView = (View)XposedHelpers.getObjectField(param.thisObject, "mPreView"); - View mPreViewContainer = (View)XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); - View mBackgroundView = (View)XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); - Paint mIconCircleStrokePaint = (Paint)XposedHelpers.getObjectField(param.thisObject, "mIconCircleStrokePaint"); - ViewOutlineProvider mPreViewOutlineProvider = (ViewOutlineProvider)XposedHelpers.getObjectField(param.thisObject, "mPreViewOutlineProvider"); + View mPreView = (View) XposedHelpers.getObjectField(param.thisObject, "mPreView"); + View mPreViewContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); + View mBackgroundView = (View) XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); + Paint mIconCircleStrokePaint = (Paint) XposedHelpers.getObjectField(param.thisObject, "mIconCircleStrokePaint"); + ViewOutlineProvider mPreViewOutlineProvider = (ViewOutlineProvider) XposedHelpers.getObjectField(param.thisObject, "mPreViewOutlineProvider"); boolean result = modifyCameraImage(mContext, mPreView, mDarkMode); if (result) param.setResult(null); if (mPreViewContainer != null) { @@ -4647,15 +4658,17 @@ protected void before(MethodHookParam param) throws Throwable { mPreViewContainer.setOutlineProvider(result ? null : mPreViewOutlineProvider); mPreViewContainer.setTag(result ? "active" : "inactive"); } - if (mBackgroundView != null) mBackgroundView.setBackgroundColor(result ? Color.TRANSPARENT : Color.BLACK); - if (mIconCircleStrokePaint != null) mIconCircleStrokePaint.setColor(result ? Color.TRANSPARENT : Color.WHITE); + if (mBackgroundView != null) + mBackgroundView.setBackgroundColor(result ? Color.TRANSPARENT : Color.BLACK); + if (mIconCircleStrokePaint != null) + mIconCircleStrokePaint.setColor(result ? Color.TRANSPARENT : Color.WHITE); } }); Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "handleMoveDistanceChanged", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - View mIconView = (View)XposedHelpers.getObjectField(param.thisObject, "mIconView"); + View mIconView = (View) XposedHelpers.getObjectField(param.thisObject, "mIconView"); if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { if (mIconView != null) mIconView.setVisibility(View.GONE); param.setResult(null); @@ -4668,7 +4681,7 @@ protected void before(MethodHookParam param) throws Throwable { protected void after(MethodHookParam param) throws Throwable { int action = MainModule.mPrefs.getInt("system_lockscreenshortcuts_right_action", 1); if (action <= 1) return; - AnimatorSet mAnimatorSet = (AnimatorSet)XposedHelpers.getObjectField(param.thisObject, "mAnimatorSet"); + AnimatorSet mAnimatorSet = (AnimatorSet) XposedHelpers.getObjectField(param.thisObject, "mAnimatorSet"); if (mAnimatorSet == null) return; param.setResult(null); mAnimatorSet.pause(); @@ -4676,13 +4689,14 @@ protected void after(MethodHookParam param) throws Throwable { mAnimatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); GlobalActions.handleAction(mContext, "pref_key_system_lockscreenshortcuts_right", true); Object mCallBack = XposedHelpers.getObjectField(param.thisObject, "mCallBack"); - if (mCallBack != null) XposedHelpers.callMethod(mCallBack, "onCompletedAnimationEnd"); + if (mCallBack != null) + XposedHelpers.callMethod(mCallBack, "onCompletedAnimationEnd"); XposedHelpers.setBooleanField(param.thisObject, "mIsPendingStartCamera", false); XposedHelpers.callMethod(param.thisObject, "dismiss"); - View mBackgroundView = (View)XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); + View mBackgroundView = (View) XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); if (mBackgroundView != null) mBackgroundView.setAlpha(1.0f); } }); @@ -4694,7 +4708,7 @@ public void onAnimationEnd(Animator animation) { @Override protected void after(final MethodHookParam param) throws Throwable { notificationPanelView = param.thisObject; - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { @Override public void onChange(Uri uri) { @@ -4721,35 +4735,9 @@ public void onChange(Uri uri) { } catch (Throwable t1) { try { XposedHelpers.callMethod(notificationPanelView, "setCameraImage"); - } catch (Throwable t2) {} + } catch (Throwable t2) { + } } - -// if (key.contains("pref_key_system_lockscreenshortcuts_left")) { -// Object leftView = null; -// try { -// leftView = XposedHelpers.getObjectField(XposedHelpers.getObjectField(notificationPanelView, "mKeyguardLeftView"), "mKeyguardMoveLeftView"); -// } catch (Throwable t) { -// XposedBridge.log(t); -// } -// -// if (leftView != null) try { -// XposedHelpers.callMethod(leftView, "reloadListItems"); -// } catch (Throwable t1) { -// try { -// XposedHelpers.callMethod(leftView, "updateShortcuts"); -// } catch (Throwable t2) { -// try { -// XposedHelpers.callMethod(leftView, "initKeyguardLeftItems"); -// } catch (Throwable t3) { -// try { -// XposedHelpers.callMethod(leftView, "initKeyguardLeftItemInfos"); -// } catch (Throwable t4) { -// XposedBridge.log(t4); -// } -// } -// } -// } -// } } catch (Throwable t) { XposedBridge.log(t); } @@ -4763,8 +4751,10 @@ public void onChange(Uri uri) { protected void before(MethodHookParam param) throws Throwable { int mCurrentScreen = XposedHelpers.getIntField(param.thisObject, "mCurrentScreen"); if (mCurrentScreen != 1) return; - if ((float)param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) param.args[0] = 0.0f; - else if ((float)param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) param.args[0] = 0.0f; + if ((float) param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) + param.args[0] = 0.0f; + else if ((float) param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) + param.args[0] = 0.0f; } }); @@ -4773,187 +4763,12 @@ protected void before(MethodHookParam param) throws Throwable { protected void before(MethodHookParam param) throws Throwable { int mCurrentScreen = XposedHelpers.getIntField(param.thisObject, "mCurrentScreen"); if (mCurrentScreen != 1) return; - if ((float)param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) param.setResult(null); - else if ((float)param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) param.setResult(null); + if ((float) param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) + param.setResult(null); + else if ((float) param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) + param.setResult(null); } }); - - View.OnClickListener mListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - int action = MainModule.mPrefs.getInt(v.getTag() + "_action", 1); - boolean skip = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_skiplock"); - if (!skip && (action == 8 || action == 9 || action == 20)) - XposedHelpers.callStaticMethod(findClass("com.android.systemui.SystemUICompat", lpparam.classLoader), "dismissKeyguardOnNextActivity"); - GlobalActions.handleAction(v.getContext(), "pref_key_" + v.getTag(), skip); - } - }; - - class LeftControlCenterHandler extends Handler { - - LeftControlCenterHandler(Looper looper) { - super(looper); - } - - public void handleMessage(Message msg) { - if (msg.what == 1) try { - ViewGroup leftView = (ViewGroup)msg.obj; - Context mContext = (Context)XposedHelpers.getObjectField(leftView, "mContext"); - int listResId = mContext.getResources().getIdentifier("keyguard_move_left", "id", lpparam.packageName); - ViewGroup oldList = leftView.findViewById(listResId); - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)oldList.getLayoutParams(); - ScrollView container = new ScrollView(oldList.getContext()); - container.setVerticalScrollBarEnabled(false); - ViewGroup parent = ((ViewGroup)oldList.getParent()); - LinearLayout leftList = new LinearLayout(oldList.getContext()); - parent.removeView(oldList); - leftList.setLayoutParams(new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT, ScrollView.LayoutParams.WRAP_CONTENT)); - leftList.setOrientation(LinearLayout.VERTICAL); - - try { - float density = mContext.getResources().getDisplayMetrics().density; - int align = MainModule.mPrefs.getStringAsInt("system_lockscreenshortcuts_left_align", 2); - int margin = Math.round(density * 40); - lp.topMargin = lp.bottomMargin; - if (lp.topMargin < margin) lp.topMargin = margin; - if (lp.bottomMargin < margin) lp.bottomMargin = margin; - boolean center = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_center"); - lp.leftMargin = Math.round((center ? 36.33f : 20) * density); - lp.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - if (align == 1) - lp.addRule(RelativeLayout.ALIGN_PARENT_TOP); - else - lp.removeRule(RelativeLayout.ALIGN_PARENT_TOP); - container.setLayoutParams(lp); - } catch (Throwable t) { - XposedBridge.log(t); - } - - container.addView(leftList); - container.setId(listResId); - parent.addView(container); - - LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - int layoutResId = mContext.getResources().getIdentifier("miui_keyguard_left_view_control_center_item", "layout", lpparam.packageName); - if (layoutResId == 0) layoutResId = mContext.getResources().getIdentifier("miui_keyguard_left_view_item", "layout", lpparam.packageName); - int imgResId = mContext.getResources().getIdentifier("keyguard_left_list_item_img", "id", lpparam.packageName); - int nameResId = mContext.getResources().getIdentifier("keyguard_left_list_item_name", "id", lpparam.packageName); - //int numberResId = mContext.getResources().getIdentifier("keyguard_left_list_item_number", "id", lpparam.packageName); - int margin = mContext.getResources().getDimensionPixelSize(mContext.getResources().getIdentifier("keyguard_move_left_item_margin", "dimen", lpparam.packageName)); - - String key = "system_lockscreenshortcuts_left"; - String itemStr = MainModule.mPrefs.getString(key, ""); - if (itemStr == null || itemStr.isEmpty()) return; - String[] itemArr = itemStr.trim().split("\\|"); - - int i = 0; - for (String uuid: itemArr) { - LinearLayout item = (LinearLayout)inflater.inflate(layoutResId, leftList, false); - item.setTag(key + "_" + uuid); - leftList.addView(item); - - ImageView img = item.findViewById(imgResId); - int size = (int)(32 * img.getResources().getDisplayMetrics().density); - ViewGroup.LayoutParams lp1 = img.getLayoutParams(); - lp1.width = size; - lp1.height = size; - img.setLayoutParams(lp1); - Drawable image = Helpers.getActionImage(mContext, "pref_key_" + key + "_" + uuid); - img.setImageDrawable(image != null ? image : mContext.getPackageManager().getApplicationIcon(Helpers.modulePkg)); - img.setBackgroundResource(0); - - TextView title = item.findViewById(nameResId); - title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); - title.setText(Helpers.getActionName(mContext, "pref_key_" + key + "_" + uuid)); - - LinearLayout.LayoutParams lp2 = (LinearLayout.LayoutParams)item.getLayoutParams(); - if (i > 0) lp2.topMargin = margin; - lp2.height = LinearLayout.LayoutParams.WRAP_CONTENT; - item.setLayoutParams(lp2); - - int padding = (int)(14 * img.getResources().getDisplayMetrics().density); - item.setPadding(padding, padding, padding, padding); - - i++; - item.setOnClickListener(mListener); - } - } catch (Throwable t) { - XposedBridge.log(t); - } - } - } - -// String leftViewCls = "com.android.keyguard.negative.MiuiKeyguardMoveLeftControlCenterView"; -// Helpers.findAndHookConstructor(leftViewCls, lpparam.classLoader, Context.class, AttributeSet.class, new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); -// Handler mHandler = new LeftControlCenterHandler(mContext.getMainLooper()); -// XposedHelpers.setAdditionalInstanceField(param.thisObject, "myHandler", mHandler); -// } -// }); -// -// Helpers.findAndHookMethodSilently(leftViewCls, lpparam.classLoader, "updateShortcuts", new MethodHook() { -// @Override -// protected void before(final MethodHookParam param) throws Throwable { -// param.setResult(null); -// initLeftView(param.thisObject); -// } -// }); -// Helpers.findAndHookMethod(leftViewCls, lpparam.classLoader, "onFinishInflate", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// View mSmartHomeLinearLayout = (View)XposedHelpers.getObjectField(param.thisObject, "mSmartHomeImageView"); -// View mRemoteCenterLinearLayout = (View)XposedHelpers.getObjectField(param.thisObject, "mRemoteCenterImageView"); -// final View.OnClickListener mListener = (View.OnClickListener)XposedHelpers.getObjectField(param.thisObject, "mClickListener"); -// View.OnClickListener mNewListener = new View.OnClickListener() { -// @Override -// public void onClick(View view) { -// if (!handleStockShortcut(view)) -// if (mListener != null) mListener.onClick(view); -// } -// }; -// mSmartHomeLinearLayout.setOnClickListener(mNewListener); -// mRemoteCenterLinearLayout.setOnClickListener(mNewListener); -// } -// }); - } - - private static boolean handleStockShortcut(View view) { - if (view == null) return false; - boolean skip = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_skiplock"); - if (!skip) return false; - Context context = view.getContext(); - int id = view.getId(); - try { - if (id == view.getResources().getIdentifier("keyguard_remote_controller_info", "id", context.getPackageName())) { - Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.duokan.phone.remotecontroller"); - if (intent == null) return false; - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_skiplock")) { - intent.putExtra("ShowCameraWhenLocked", true); - intent.putExtra("StartActivityWhenLocked", true); - } - context.startActivity(intent); - return true; - } else if (id == view.getResources().getIdentifier("keyguard_smarthome_info", "id", context.getPackageName())) { - Intent intent = new Intent(); - intent.setPackage("com.xiaomi.smarthome"); - intent.setData(Uri.parse("http://home.mi.com/main")); - intent.setAction("android.intent.action.VIEW"); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra("source", 11); - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_skiplock")) { - intent.putExtra("ShowCameraWhenLocked", true); - intent.putExtra("StartActivityWhenLocked", true); - } - context.startActivity(intent); - return true; - } - } catch (Throwable t) { - XposedBridge.log(t); - } - return false; } public static void LockScreenSecureLaunchHook() { @@ -5561,10 +5376,8 @@ private static void initPct(ViewGroup container, int source, Context context) { Resources res = context.getResources(); if (mPct == null) { mPct = new TextView(container.getContext()); - mPct.setTag("mirrorBrightnessPct"); mPct.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40); mPct.setGravity(Gravity.CENTER); - mPct.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL)); float density = res.getDisplayMetrics().density; FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); lp.topMargin = Math.round(MainModule.mPrefs.getInt("system_showpct_top", 26) * density); @@ -5602,40 +5415,44 @@ protected void after(final MethodHookParam param) throws Throwable { } }); -// Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStart", new MethodHook() { -// @Override -// protected void before(final MethodHookParam param) throws Throwable { -// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); -// Object mMirror = XposedHelpers.getObjectField(param.thisObject, "mControl"); -// Object controlCenterWindowViewController = XposedHelpers.getObjectField(mMirror, "controlCenterWindowViewController"); -// String ClsName = controlCenterWindowViewController.getClass().getName(); -// if (!ClsName.equals("ControlCenterWindowViewController")) { -// controlCenterWindowViewController = XposedHelpers.callMethod(controlCenterWindowViewController, "get"); -// } -// Object windowView = XposedHelpers.callMethod(controlCenterWindowViewController, "getView"); -// if (windowView == null) { -// Helpers.log("BrightnessPctHook", "mControlPanelContentView is null"); -// return; -// } -// initPct((ViewGroup) windowView, 1, mContext); -// mPct.setVisibility(View.VISIBLE); -// mPct.animate().alpha(1.0f).setDuration(300).start(); -// } -// }); -// -// Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStop", new MethodHook() { -// @Override -// protected void after(final MethodHookParam param) throws Throwable { -// if (mPct != null) mPct.setVisibility(View.GONE); -// } -// }); + Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStart", new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Object mMirror = XposedHelpers.getObjectField(param.thisObject, "mControl"); + Object controlCenterWindowViewController = XposedHelpers.getObjectField(mMirror, "controlCenterWindowViewController"); + String ClsName = controlCenterWindowViewController.getClass().getName(); + if (!ClsName.equals("ControlCenterWindowViewController")) { + controlCenterWindowViewController = XposedHelpers.callMethod(controlCenterWindowViewController, "get"); + } + Object windowView = XposedHelpers.callMethod(controlCenterWindowViewController, "getView"); + if (windowView == null) { + Helpers.log("BrightnessPctHook", "mControlPanelContentView is null"); + return; + } + initPct((ViewGroup) windowView, 2, mContext); + mPct.setVisibility(View.VISIBLE); + mPct.animate().alpha(1.0f).setDuration(300).start(); + } + }); + + Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStop", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + if (mPct != null) mPct.setVisibility(View.GONE); + } + }); final Class BrightnessUtils = XposedHelpers.findClassIfExists("com.android.systemui.controlcenter.policy.BrightnessUtils", lpparam.classLoader); Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onChanged", new MethodHook() { @Override @SuppressLint("SetTextI18n") protected void after(final MethodHookParam param) throws Throwable { - if (mPct == null || (int)mPct.getTag() != 1) return; + int pctTag = 0; + if (mPct != null) { + pctTag = (int) mPct.getTag(); + } + if (pctTag == 0) return; int currentLevel = (int)param.args[3]; if (BrightnessUtils != null) { int maxLevel = (int) XposedHelpers.getStaticObjectField(BrightnessUtils, "GAMMA_SPACE_MAX"); @@ -6301,19 +6118,6 @@ protected void before(final MethodHookParam param) throws Throwable { topMinimumBacklight = (float) XposedHelpers.getObjectField(mBrightnessController, "mMinimumBacklight"); topMaximumBacklight = (float) XposedHelpers.getObjectField(mBrightnessController, "mMaximumBacklight"); tapStartBrightness = (float) XposedHelpers.callMethod(mDisplayManager, "getBrightness", mDisplayId); - if (MainModule.mPrefs.getBoolean("system_showpct")) { - ViewGroup mStatusBarWindow; - if (isInControlCenter) { - mStatusBarWindow = (ViewGroup)param.thisObject; - } - else { - mStatusBarWindow = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mNotificationShadeWindowView"); - } - if (mStatusBarWindow == null) - Helpers.log("StatusBarGesturesHook", "mStatusBarWindow is null"); - else - initPct(mStatusBarWindow, 2, mContext); - } break; case MotionEvent.ACTION_POINTER_DOWN: tapStartPointers = event.getPointerCount(); @@ -6357,17 +6161,6 @@ protected void before(final MethodHookParam param) throws Throwable { float nextLevel = Math.min(topMaximumBacklight, Math.max(topMinimumBacklight, tapStartBrightness + (topMaximumBacklight - topMinimumBacklight) * ratio)); XposedHelpers.callMethod(mBrightnessController, "setBrightness", nextLevel); tapCurrentBrightness = nextLevel; - if (MainModule.mPrefs.getBoolean("system_showpct") && mPct != null) { - if (mPct.getVisibility() == View.GONE) { - mPct.setVisibility(View.VISIBLE); - mPct.animate().alpha(1.0f).setDuration(300).start(); - } - if ((int)mPct.getTag() == 2) { - int currentLevel = (int) XposedHelpers.callStaticMethod(BrightnessUtils, "convertLinearToGammaFloat", nextLevel, topMinimumBacklight, topMaximumBacklight); - int maxLevel = (int) XposedHelpers.getStaticObjectField(BrightnessUtils, "GAMMA_SPACE_MAX"); - mPct.setText(((currentLevel * 100) / maxLevel) + "%"); - } - } } else if (opt == 3) { tapCurrentBrightness = -1.0f; int sens = MainModule.mPrefs.getStringAsInt("system_statusbarcontrols_sens_vol", 2); @@ -6895,6 +6688,7 @@ public static void NoLowBatteryWarningHook(LoadPackageParam lpparam) { protected void before(MethodHookParam param) throws Throwable { String key = (String)param.args[1]; if ("low_battery_dialog_disabled".equals(key)) param.setResult(1); + else if ("power_sounds_enabled".equals(key)) param.setResult(0); } }; Helpers.hookAllMethods(Settings.System.class, "getIntForUser", settingHook); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_LockScreenShortcuts.java b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_LockScreenShortcuts.java index e1346be4..f6a0fa08 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/subs/System_LockScreenShortcuts.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/subs/System_LockScreenShortcuts.java @@ -11,7 +11,6 @@ public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); findPreference("pref_key_system_lockscreenshortcuts_right").setOnPreferenceClickListener(openLockScreenActions); - findPreference("pref_key_system_lockscreenshortcuts_left").setOnPreferenceClickListener(openSortableList); } } diff --git a/app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_dark.xml b/app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_dark.xml deleted file mode 100644 index 85b83250..00000000 --- a/app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_dark.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_light.xml b/app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_light.xml deleted file mode 100644 index 09c31d46..00000000 --- a/app/src/main/res/drawable/keyguard_bottom_flashlight_on_img_light.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 274fc291..5c486bba 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -275,12 +275,7 @@ Zastąp ikonę aparatu ikoną CustoMIUIzer Przeciągnij ikonę, aby wykonać niestandardową akcję Wyłącz gest przeciągnięcia palcem w prawo - Skróty w lewej części ekranu - Zarządzaj listą skrótów Wyrównanie w pionie - Wyśrodkuj poziomo - Nie wymagaj odblokowania - Dostęp do uruchomionych aplikacji można uzyskać, gdy urządzenie jest nadal zablokowane Wyłącz blokadę ekranu Niektóre urządzenia mogą nie działać bez odblokowania raz po uruchomieniu Selektywnie wyłącz blokadę ekranu (nie zmienia zabezpieczeń dla żadnych aplikacji i nie usuwa danych odcisków palców) diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 2349642d..7e1f5bc1 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -909,12 +909,7 @@ Заменить иконку камеры на иконку CustoMIUIzer Потяните иконку для запуска действия Отключить свайп вправо - Ярлыки на левом экране - Настройка списка ярлыков Выравнивание по вертикали - Горизонтально по центру - Не требовать разблокировки - Запущенные приложения будут доступны даже при заблокированном устройстве Отключить блокировку Некоторые устройства могут не работать без разблокировки один раз после перезагрузки Выборочно пропускает блокировку устройства (не влияет на безопасность приложений и не удаляет данные отпечатков пальцев) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9e27eb1e..d297e187 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -312,18 +312,13 @@ 某些应用中的身份验证需要访问证书,但如果在开机后跳过了PIN/密码/图案,其将保持锁定状态。当前选项添加允许解锁证书的启动器图标。 自定义动作 自定义快捷方式和滑动的动作 - 禁用向左滑动手势 + 禁用左滑手势 向左滑动作 更改右侧图标 用米客图标替换相机图标 拖动图标用以执行自定义动作 禁用右滑手势 - 左侧屏幕快捷方式 - 管理快捷方式列表 垂直对齐 - 水平居中 - 不需解锁 - 设备锁定时可以访问启动的应用 禁用屏幕锁 某些设备可能要开机后解锁一次才能工作 选择性禁用屏幕锁(不会更改任何应用的安全性,也不会移除指纹数据) @@ -1137,7 +1132,7 @@ 跳过开启特殊权限的倒计时 电池页面显示温度值 剪切板隐私保护及模糊定位 - 点击左侧图标时切换手电筒 + 长按左侧图标时切换手电筒 圆角矩形磁贴 强制开启控制中心样式切换 禁用蓝牙临时关闭态 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 59086da1..79f0c51c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -653,12 +653,7 @@ 忽略通話 停用亮度滑塊 垂直對齊 - 水平置中 禁用右滑手勢 - 設備鎖定時可以訪問啟動的應用 - 不需解鎖 - 管理快捷方式列表 - 左側螢幕快捷方式 拖動圖示用以執行自定義動作 用 CustoMIUIzer 圖示替換相機圖示 更改右側圖示 @@ -1021,7 +1016,7 @@ 僅電流 僅溫度 - 點選左側圖示時切換手電筒 + 長按左側圖示時切換手電筒 顯示內容 顯示電池溫度和電流 右側顯示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a4bc8581..12cc3c23 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -323,12 +323,7 @@ Replace camera icon with CustoMIUIzer icon Drag the icon to execute custom action Disable swipe right gesture - Left screen shortcuts - Manage shortcuts list Vertical alignment - Center horizontally - Do not require unlock - Launched apps could be accessed while device is still locked Disable screen lock Some devices might not work without unlocking once after boot Selectively disable screen lock (does not change security for any apps and does not remove fingerprint data) @@ -1177,7 +1172,7 @@ Skip permission intercept timer Show temperature in battery Enable AI clipboard and blur location - Tap left shortcut to toggle flashlight + Long click left shortcut to toggle flashlight Rounded rectangle tile Force Enable CC style switch Disable disconnect bluetooth until tomorrow diff --git a/app/src/main/res/xml/prefs_system_lockscreenshortcuts.xml b/app/src/main/res/xml/prefs_system_lockscreenshortcuts.xml index fa394f8e..ea8970c5 100644 --- a/app/src/main/res/xml/prefs_system_lockscreenshortcuts.xml +++ b/app/src/main/res/xml/prefs_system_lockscreenshortcuts.xml @@ -1,83 +1,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file From 708864eeb85c5d1e3f1e2961f13fc14958aac976 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 1 Feb 2023 11:52:37 +0800 Subject: [PATCH 323/627] miui 13 compatibility --- .../customiuizer/mods/GlobalActions.java | 15 ++++++++++++--- .../name/mikanoshi/customiuizer/mods/System.java | 10 +++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java index 2d71c6b4..c9b9c230 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java @@ -829,14 +829,23 @@ protected void before(MethodHookParam param) throws Throwable { } public static void setupForegroundMonitor(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.wm.DisplayPolicy", lpparam.classLoader, "updateSystemBarsLw", new MethodHook() { + String methodSystemuiChange = Helpers.isTPlus() ? "updateSystemBarAttributes" : "updateSystemUiVisibilityLw"; + Helpers.hookAllMethods("com.android.server.wm.DisplayPolicy", lpparam.classLoader, methodSystemuiChange, new MethodHook() { private String pkgName = null; private boolean fullScreen = false; @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); if (mContext != null) try { - String focusedApp = (String) XposedHelpers.getObjectField(param.thisObject, "mFocusedApp"); + String focusedApp; + if (Helpers.isTPlus()) { + focusedApp = (String) XposedHelpers.getObjectField(param.thisObject, "mFocusedApp"); + } + else { + Object mSystemUiControllingWindow = XposedHelpers.getObjectField(param.thisObject, "mSystemUiControllingWindow"); + WindowManager.LayoutParams mAttrs = (WindowManager.LayoutParams)XposedHelpers.getObjectField(mSystemUiControllingWindow, "mAttrs"); + focusedApp = mAttrs.packageName; + } boolean focusAppChanged = false; boolean fullscreenChanged = false; @@ -844,7 +853,7 @@ protected void after(MethodHookParam param) throws Throwable { pkgName = focusedApp; focusAppChanged = true; } - boolean isFullScreen = XposedHelpers.getBooleanField(param.thisObject, "mTopIsFullscreen"); + boolean isFullScreen = XposedHelpers.getBooleanField(param.thisObject, Helpers.isTPlus() ? "mTopIsFullscreen" : "mLastFocusIsFullscreen"); if (fullScreen != isFullScreen) { fullScreen = isFullScreen; fullscreenChanged = true; diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 889f3e90..9c48267c 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1892,12 +1892,12 @@ private static Bitmap processAlbumArt(Context context, Bitmap bitmap) { } public static void LockScreenAlbumArtHook(LoadPackageParam lpparam) { - Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.miui.systemui.util.MiuiThemeUtils", lpparam.classLoader); + Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader); Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); if (isDefaultLockScreenTheme) { Object mBlurRatioChangedListener = XposedHelpers.getObjectField(param.thisObject, "mBlurRatioChangedListener"); Object notificationShadeDepthController = XposedHelpers.getObjectField(param.thisObject, "notificationShadeDepthController"); @@ -1928,7 +1928,7 @@ public void onReceive(Context context, Intent intent) { MethodHook updateLockscreenHook = new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); if (!isDefaultLockScreenTheme) { return ; } @@ -1956,7 +1956,7 @@ protected void before(MethodHookParam param) throws Throwable { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); if (!isDefaultLockScreenTheme) { XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); @@ -1998,7 +1998,7 @@ protected void after(MethodHookParam param) throws Throwable { @Override protected void after(MethodHookParam param) throws Throwable { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultSysUiTheme"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); if (isDefaultLockScreenTheme) { From 3698304976cacb18e0040bf8c25ef220f1ea445f Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 1 Feb 2023 12:30:03 +0800 Subject: [PATCH 324/627] prefs support indent level --- .../prefs/CheckBoxPreferenceEx.java | 6 +- .../prefs/DropDownPreferenceEx.java | 8 +- .../prefs/EditTextPreferenceEx.java | 8 +- .../customiuizer/prefs/ListPreferenceEx.java | 6 +- .../customiuizer/prefs/PreferenceEx.java | 16 ++- .../customiuizer/prefs/SeekBarPreference.java | 40 +++--- app/src/main/res/values/attrs.xml | 118 +++++++++--------- app/src/main/res/xml/prefs_controls.xml | 12 +- app/src/main/res/xml/prefs_launcher.xml | 8 +- app/src/main/res/xml/prefs_system.xml | 51 ++++---- .../res/xml/prefs_system_batteryindicator.xml | 8 +- .../res/xml/prefs_system_detailednetspeed.xml | 2 +- .../main/res/xml/prefs_system_hideicons.xml | 2 +- .../res/xml/prefs_system_statusbar_clock.xml | 4 +- .../prefs_system_statusbar_mobilesignal.xml | 22 ++-- app/src/main/res/xml/prefs_various.xml | 2 +- .../res/xml/prefs_various_callreminder.xml | 2 +- .../res/xml/prefs_various_calluibright.xml | 4 +- 18 files changed, 159 insertions(+), 160 deletions(-) diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java index df0a6398..040393f1 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java @@ -18,7 +18,7 @@ public class CheckBoxPreferenceEx extends SwitchPreference implements Preference private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final boolean child; + private final int indentLevel; private final boolean dynamic; private boolean newmod = false; private boolean unsupported = false; @@ -27,7 +27,7 @@ public CheckBoxPreferenceEx(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.CheckBoxPreferenceEx); dynamic = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_dynamic, false); - child = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_child, false); + indentLevel = xmlAttrs.getInt(R.styleable.CheckBoxPreferenceEx_indentLevel, 0); xmlAttrs.recycle(); setIconSpaceReserved(false); } @@ -37,7 +37,7 @@ public void getView(View finalView) { title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - int hrzPadding = childpadding + (child ? childpadding : 0); + int hrzPadding = (indentLevel + 1) * childpadding; finalView.setPadding(hrzPadding, 0, childpadding, 0); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/DropDownPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/DropDownPreferenceEx.java index a7dbf16b..32873ab7 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/DropDownPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/DropDownPreferenceEx.java @@ -23,7 +23,7 @@ public class DropDownPreferenceEx extends DropDownPreference implements Preferen private final int secondary = res.getColor(R.color.preference_secondary_text, getContext().getTheme()); private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final boolean child; + private final int indentLevel; private final boolean dynamic; private boolean newmod = false; private boolean unsupported = false; @@ -32,8 +32,8 @@ public class DropDownPreferenceEx extends DropDownPreference implements Preferen public DropDownPreferenceEx(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.ListPreferenceEx); - child = xmlAttrs.getBoolean(R.styleable.DropDownPreferenceEx_child, false); - dynamic = xmlAttrs.getBoolean(R.styleable.DropDownPreferenceEx_child, false); + indentLevel = xmlAttrs.getInt(R.styleable.DropDownPreferenceEx_indentLevel, 0); + dynamic = xmlAttrs.getBoolean(R.styleable.DropDownPreferenceEx_dynamic, false); valueAsSummary = xmlAttrs.getBoolean(R.styleable.ListPreferenceEx_valueAsSummary, false); xmlAttrs.recycle(); setIconSpaceReserved(false); @@ -65,7 +65,7 @@ public void getView(View finalView) { title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - int hrzPadding = child ? childpadding : 0; + int hrzPadding = (indentLevel + 1) * childpadding; finalView.setPadding(hrzPadding, 0, childpadding, 0); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java index 623b2fef..8e7d3990 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/EditTextPreferenceEx.java @@ -18,7 +18,7 @@ public class EditTextPreferenceEx extends EditTextPreference implements Preferen private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final boolean child; + private final int indentLevel; private final boolean dynamic; private boolean newmod = false; private boolean unsupported = false; @@ -26,8 +26,8 @@ public class EditTextPreferenceEx extends EditTextPreference implements Preferen public EditTextPreferenceEx(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.CheckBoxPreferenceEx); - dynamic = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_dynamic, false); - child = xmlAttrs.getBoolean(R.styleable.CheckBoxPreferenceEx_child, false); + dynamic = xmlAttrs.getBoolean(R.styleable.PreferenceEx_dynamic, false); + indentLevel = xmlAttrs.getInt(R.styleable.PreferenceEx_indentLevel, 0); xmlAttrs.recycle(); setIconSpaceReserved(false); } @@ -37,7 +37,7 @@ public void getView(View finalView) { title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - int hrzPadding = childpadding + (child ? childpadding : 0); + int hrzPadding = (indentLevel + 1) * childpadding; finalView.setPadding(hrzPadding, 0, childpadding, 0); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java index 612c1a68..5180b452 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java @@ -22,7 +22,7 @@ public class ListPreferenceEx extends ListPreference implements PreferenceState private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); private final int secondary = res.getColor(R.color.preference_secondary_text, getContext().getTheme()); private final int disableColor = res.getColor(R.color.preference_primary_text_disable, getContext().getTheme()); - private final boolean child; + private final int indentLevel; private final boolean dynamic; private boolean newmod = false; private boolean unsupported = false; @@ -31,7 +31,7 @@ public class ListPreferenceEx extends ListPreference implements PreferenceState public ListPreferenceEx(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.ListPreferenceEx); - child = xmlAttrs.getBoolean(R.styleable.ListPreferenceEx_child, false); + indentLevel = xmlAttrs.getInt(R.styleable.ListPreferenceEx_indentLevel, 0); dynamic = xmlAttrs.getBoolean(R.styleable.ListPreferenceEx_dynamic, false); valueAsSummary = xmlAttrs.getBoolean(R.styleable.ListPreferenceEx_valueAsSummary, false); xmlAttrs.recycle(); @@ -65,7 +65,7 @@ public void getView(View finalView) { title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - int hrzPadding = childpadding + (child ? childpadding : 0); + int hrzPadding = (indentLevel + 1) * childpadding; finalView.setPadding(hrzPadding, 0, childpadding, 0); } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java index 4df091f5..4a3f61c6 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java @@ -24,13 +24,12 @@ public class PreferenceEx extends Preference implements PreferenceState { private final int disableColor = res.getColor(R.color.preference_primary_text_disable, getContext().getTheme()); private final int childpadding = res.getDimensionPixelSize(R.dimen.preference_item_child_padding); - private final boolean child; + private final int indentLevel; private final boolean dynamic; private final boolean warning; private final boolean countAsSummary; private final boolean longClickable; private String customSummary = null; - private boolean notice; private boolean newmod = false; private boolean unsupported = false; View.OnLongClickListener longPressListener; @@ -39,9 +38,8 @@ public PreferenceEx(Context context, AttributeSet attrs) { super(context, attrs); final TypedArray xmlAttrs = context.obtainStyledAttributes(attrs, R.styleable.PreferenceEx); dynamic = xmlAttrs.getBoolean(R.styleable.PreferenceEx_dynamic, false); - child = xmlAttrs.getBoolean(R.styleable.PreferenceEx_child, false); + indentLevel = xmlAttrs.getInt(R.styleable.PreferenceEx_indentLevel, 0); warning = xmlAttrs.getBoolean(R.styleable.PreferenceEx_warning, false); - notice = xmlAttrs.getBoolean(R.styleable.PreferenceEx_notice, false); countAsSummary = xmlAttrs.getBoolean(R.styleable.PreferenceEx_countAsSummary, false); longClickable = xmlAttrs.getBoolean(R.styleable.PreferenceEx_longClickable, false); xmlAttrs.recycle(); @@ -71,7 +69,7 @@ else if (countAsSummary) { title.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : ""))); if (newmod) Helpers.applyNewMod(title); - int hrzPadding = childpadding + (child ? childpadding : 0); + int hrzPadding = (indentLevel + 1) * childpadding; finalView.setPadding(hrzPadding, 0, childpadding, 0); if (longClickable) { finalView.setOnLongClickListener(new View.OnLongClickListener() { @@ -120,10 +118,10 @@ public void markAsNew() { newmod = true; } - public void setNotice(boolean value) { - notice = value; - setEnabled(!value); - } +// public void setNotice(boolean value) { +// notice = value; +// setEnabled(!value); +// } public void saveString(String val) { if (val != null) { persistString(val); diff --git a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java index 5d2d28db..7f367065 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java @@ -28,7 +28,7 @@ public class SeekBarPreference extends Preference implements PreferenceState { private int mMaxValue; private int mStepValue; private int mNegativeShift; - private final boolean child; + private final int indentLevel; private int mDisplayDividerValue; private boolean mUseDisplayDividerValue; @@ -56,20 +56,20 @@ public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) { mListener = null; if (attrs != null) { - TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.SeekBarPreference); - - child = a.getBoolean(R.styleable.SeekBarPreference_child, false); - dynamic = a.getBoolean(R.styleable.SeekBarPreference_dynamic, false); - mMinValue = a.getInt(R.styleable.SeekBarPreference_minValue, 0); - mMaxValue = a.getInt(R.styleable.SeekBarPreference_maxValue, 10); - mStepValue = a.getInt(R.styleable.SeekBarPreference_stepValue, 1); - mDefaultValue = a.getInt(R.styleable.SeekBarPreference_android_defaultValue, 0); - mNegativeShift = a.getInt(R.styleable.SeekBarPreference_negativeShift, 0); - mShowPlus = a.getBoolean(R.styleable.SeekBarPreference_showplus, false); - - if (a.hasValue(R.styleable.SeekBarPreference_displayDividerValue)) { + TypedArray xmlAttrs = getContext().obtainStyledAttributes(attrs, R.styleable.SeekBarPreference); + + indentLevel = xmlAttrs.getInt(R.styleable.SeekBarPreference_indentLevel, 0); + dynamic = xmlAttrs.getBoolean(R.styleable.SeekBarPreference_dynamic, false); + mMinValue = xmlAttrs.getInt(R.styleable.SeekBarPreference_minValue, 0); + mMaxValue = xmlAttrs.getInt(R.styleable.SeekBarPreference_maxValue, 10); + mStepValue = xmlAttrs.getInt(R.styleable.SeekBarPreference_stepValue, 1); + mDefaultValue = xmlAttrs.getInt(R.styleable.SeekBarPreference_android_defaultValue, 0); + mNegativeShift = xmlAttrs.getInt(R.styleable.SeekBarPreference_negativeShift, 0); + mShowPlus = xmlAttrs.getBoolean(R.styleable.SeekBarPreference_showplus, false); + + if (xmlAttrs.hasValue(R.styleable.SeekBarPreference_displayDividerValue)) { mUseDisplayDividerValue = true; - mDisplayDividerValue = a.getInt(R.styleable.SeekBarPreference_displayDividerValue, 1); + mDisplayDividerValue = xmlAttrs.getInt(R.styleable.SeekBarPreference_displayDividerValue, 1); } else { mUseDisplayDividerValue = false; mDisplayDividerValue = 1; @@ -85,13 +85,13 @@ else if (mDefaultValue > mMaxValue) if (mStepValue <= 0) mStepValue = 1; - mFormat = a.getString(R.styleable.SeekBarPreference_format); - mNote = a.getString(R.styleable.SeekBarPreference_note); - mOffText = a.getString(R.styleable.SeekBarPreference_offtext); + mFormat = xmlAttrs.getString(R.styleable.SeekBarPreference_format); + mNote = xmlAttrs.getString(R.styleable.SeekBarPreference_note); + mOffText = xmlAttrs.getString(R.styleable.SeekBarPreference_offtext); - a.recycle(); + xmlAttrs.recycle(); } else { - child = false; + indentLevel = 0; mMinValue = 0; mMaxValue = 10; mStepValue = 1; @@ -109,7 +109,7 @@ public void getView(View finalView) { mSeekBar.setAlpha(isEnabled() ? 1.0f : 0.75f); if (newmod) Helpers.applyNewMod(mTitle); - int hrzPadding = childpadding + (child ? childpadding : 0); + int hrzPadding = (indentLevel + 1) * childpadding; finalView.setPadding(hrzPadding, 0, childpadding, 0); } diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 30675524..d2a06dc3 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -1,60 +1,60 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_controls.xml b/app/src/main/res/xml/prefs_controls.xml index d10a36c9..ffd0ce8a 100644 --- a/app/src/main/res/xml/prefs_controls.xml +++ b/app/src/main/res/xml/prefs_controls.xml @@ -121,7 +121,7 @@ android:title="@string/controls_fingerprintsuccess_ignore_title" android:summary="@string/controls_fingerprintsuccess_ignore_summ" android:defaultValue="false" - miuizer:child="true" /> + miuizer:indentLevel="1" /> @@ -154,7 +154,7 @@ android:defaultValue="false" android:dependency="pref_key_controls_powerflash" miuizer:dynamic="true" - miuizer:child="true" /> + miuizer:indentLevel="1" /> @@ -174,13 +174,13 @@ android:title="@string/controls_volumecursor_reverse_title" android:defaultValue="false" android:dependency="pref_key_controls_volumecursor" - miuizer:child="true" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> @@ -312,7 +312,7 @@ android:title="@string/system_statusbarcolor_apps_title" android:key="pref_key_controls_fsg_horiz_apps" android:dependency="pref_key_controls_fsg_horiz" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:countAsSummary="true" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> @@ -122,7 +122,7 @@ android:title="@string/launcher_renameapps_list_title" android:dependency="pref_key_launcher_renameapps" miuizer:dynamic="true" - miuizer:child="true" /> + miuizer:indentLevel="1" /> @@ -292,7 +292,7 @@ android:title="@string/launcher_hideseekpoints_edit_title" android:defaultValue="false" android:dependency="pref_key_launcher_hideseekpoints" - miuizer:child="true" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> @@ -254,7 +254,7 @@ @@ -297,7 +297,7 @@ @@ -362,6 +362,7 @@ @@ -426,7 +427,7 @@ android:title="@string/system_statusbar_mobiletype_single_leftmargin_title" android:dependency="pref_key_system_statusbar_horizmargin" android:defaultValue="16" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:minValue="0" miuizer:maxValue="80" miuizer:stepValue="1" @@ -437,7 +438,7 @@ android:title="@string/system_statusbar_dualsimin2rows_rightmargin_title" android:dependency="pref_key_system_statusbar_horizmargin" android:defaultValue="16" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:minValue="0" miuizer:maxValue="30" miuizer:stepValue="1" @@ -462,7 +463,7 @@ android:title="@string/system_statusbarcolor_apps_title" android:key="pref_key_system_statusbarcolor_apps" android:dependency="pref_key_system_statusbarcolor" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:countAsSummary="true" /> @@ -648,7 +649,7 @@ + miuizer:indentLevel="1" /> @@ -846,7 +847,7 @@ android:title="@string/system_popupnotif_apps_title" android:key="pref_key_system_hidefromrecents_apps" android:dependency="pref_key_system_hidefromrecents" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:countAsSummary="true" /> + miuizer:indentLevel="1" /> @@ -1233,14 +1234,14 @@ android:key="pref_key_system_cleanshare_apps" android:dependency="pref_key_system_cleanshare" miuizer:dynamic="true" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:countAsSummary="true" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_system_hideicons.xml b/app/src/main/res/xml/prefs_system_hideicons.xml index 0623750c..eb870c46 100644 --- a/app/src/main/res/xml/prefs_system_hideicons.xml +++ b/app/src/main/res/xml/prefs_system_hideicons.xml @@ -52,7 +52,7 @@ miuizer:minValue="0" miuizer:maxValue="48" miuizer:stepValue="1" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:format="%d" /> diff --git a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml index dc3decca..e86b1690 100644 --- a/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml +++ b/app/src/main/res/xml/prefs_system_statusbar_mobilesignal.xml @@ -32,7 +32,7 @@ android:key="pref_key_system_statusbar_mobiletype_single_atleft" android:title="@string/system_statusbar_mobiletype_single_atleft_title" android:dependency="pref_key_system_statusbar_mobiletype_single" - miuizer:child="true" + miuizer:indentLevel="1" android:defaultValue="false" /> /> @@ -49,7 +49,7 @@ android:title="@string/launcher_titlefontsize_title" android:dependency="pref_key_system_statusbar_mobiletype_single" android:defaultValue="27" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:minValue="18" miuizer:maxValue="32" miuizer:stepValue="1" @@ -60,7 +60,7 @@ android:key="pref_key_system_statusbar_mobiletype_single_bold" android:title="@string/system_statusbar_mobiletype_single_bold_title" android:dependency="pref_key_system_statusbar_mobiletype_single" - miuizer:child="true" + miuizer:indentLevel="1" android:defaultValue="false" /> @@ -120,7 +120,7 @@ android:title="@string/launcher_iconscale_title" android:dependency="pref_key_system_statusbar_dualsimin2rows" android:defaultValue="10" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:minValue="6" miuizer:maxValue="16" miuizer:stepValue="1" @@ -133,7 +133,7 @@ android:title="@string/system_statusbar_mobiletype_single_leftmargin_title" android:dependency="pref_key_system_statusbar_dualsimin2rows" android:defaultValue="0" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:minValue="0" miuizer:maxValue="16" miuizer:stepValue="1" @@ -145,7 +145,7 @@ android:title="@string/system_statusbar_dualsimin2rows_rightmargin_title" android:dependency="pref_key_system_statusbar_dualsimin2rows" android:defaultValue="0" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:minValue="0" miuizer:maxValue="16" miuizer:stepValue="1" diff --git a/app/src/main/res/xml/prefs_various.xml b/app/src/main/res/xml/prefs_various.xml index 90d1b6fa..3d484e38 100644 --- a/app/src/main/res/xml/prefs_various.xml +++ b/app/src/main/res/xml/prefs_various.xml @@ -46,7 +46,7 @@ android:title="@string/system_popupnotif_apps_title" android:key="pref_key_various_alarmcompat_apps" android:dependency="pref_key_various_alarmcompat" - miuizer:child="true" + miuizer:indentLevel="1" miuizer:countAsSummary="true" /> + miuizer:indentLevel="1" /> diff --git a/app/src/main/res/xml/prefs_various_calluibright.xml b/app/src/main/res/xml/prefs_various_calluibright.xml index c7ee4e42..d84e6b46 100644 --- a/app/src/main/res/xml/prefs_various_calluibright.xml +++ b/app/src/main/res/xml/prefs_various_calluibright.xml @@ -41,13 +41,13 @@ android:key="pref_key_various_calluibright_night_start" android:title="@string/various_calluibright_night_start_title" android:dependency="pref_key_various_calluibright_night" - miuizer:child="true" /> + miuizer:indentLevel="1" /> + miuizer:indentLevel="1" /> From da9dc639c6d6d194c22b24f0717ecc78a9f9f897 Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 1 Feb 2023 13:24:33 +0800 Subject: [PATCH 325/627] split mods/system.java --- .../mikanoshi/customiuizer/MainModule.java | 82 +- .../mikanoshi/customiuizer/mods/System.java | 6561 +++++------------ .../mikanoshi/customiuizer/mods/SystemUI.java | 3209 ++++++++ 3 files changed, 4898 insertions(+), 4954 deletions(-) create mode 100644 app/src/main/java/name/mikanoshi/customiuizer/mods/SystemUI.java diff --git a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java index 38dd3cd7..d35aee1b 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/MainModule.java @@ -17,6 +17,7 @@ import name.mikanoshi.customiuizer.mods.Launcher; import name.mikanoshi.customiuizer.mods.PackagePermissions; import name.mikanoshi.customiuizer.mods.System; +import name.mikanoshi.customiuizer.mods.SystemUI; import name.mikanoshi.customiuizer.mods.Various; import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.Helpers.MethodHook; @@ -66,7 +67,7 @@ public void initZygote(StartupParam startParam) { if (mPrefs.getBoolean("system_nopassword")) System.NoPasswordHook(); if (mPrefs.getBoolean("system_statusbarcolor")) System.StatusBarBackgroundHook(); if (mPrefs.getBoolean("system_magnifier")) System.TextMagnifierHook(); - if (mPrefs.getBoolean("system_lockscreenshortcuts") || mPrefs.getInt("controls_powerdt_action", 1) > 1) System.LockScreenSecureLaunchHook(); + if (mPrefs.getBoolean("system_lockscreenshortcuts") || mPrefs.getInt("controls_powerdt_action", 1) > 1) SystemUI.LockScreenSecureLaunchHook(); if (mPrefs.getBoolean("system_notifmediaseekbar")) System.MediaNotificationSeekBarHook(); if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationBlockHook(); if (mPrefs.getBoolean("system_nooverscroll")) System.NoOverscrollHook(); @@ -191,30 +192,30 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("launcher_disable_wallpaperscale")) Launcher.DisableUnlockWallpaperScale(lpparam); } if (pkg.equals("com.android.systemui")) { - System.setupStatusBar(lpparam); + SystemUI.setupStatusBar(lpparam); GlobalActions.setupStatusBar(lpparam); if (mPrefs.getBoolean("system_screenshot_overlay")) { - System.TempHideOverlaySystemUIHook(lpparam); + SystemUI.TempHideOverlaySystemUIHook(lpparam); } if (mPrefs.getBoolean("system_fivegtile")) { - System.AddFiveGTileHook(lpparam); + SystemUI.AddFiveGTileHook(lpparam); } if (mPrefs.getBoolean("system_fw_splitscreen")) System.MultiWindowPlusHook(lpparam); - if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) System.QSGridRes(); - if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) System.QQSGridRes(); - if (mPrefs.getBoolean("system_volumetimer")) System.VolumeTimerValuesRes(lpparam); + if (mPrefs.getInt("system_qsgridcolumns", 2) > 2 || mPrefs.getInt("system_qsgridrows", 1) > 1) SystemUI.QSGridRes(); + if (mPrefs.getInt("system_qqsgridcolumns", 2) > 2) SystemUI.QQSGridRes(); + if (mPrefs.getBoolean("system_volumetimer")) SystemUI.VolumeTimerValuesRes(lpparam); // if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsRes(); if (mPrefs.getBoolean("system_networkindicator_wifi")) System.NetworkIndicatorWifi(lpparam); if (mPrefs.getInt("system_drawer_blur", 100) < 100) System.DrawerBlurRatioHook(lpparam); if (mPrefs.getInt("system_chargeanimtime", 20) < 20) System.ChargeAnimationHook(lpparam); if (mPrefs.getInt("system_betterpopups_delay", 0) > 0 && !mPrefs.getBoolean("system_betterpopups_nohide")) System.BetterPopupsHideDelayHook(lpparam); - if (mPrefs.getInt("system_netspeedinterval", 4) != 4) System.NetSpeedIntervalHook(lpparam); - if (mPrefs.getInt("system_qsgridrows", 1) > 1 || mPrefs.getBoolean("system_qsnolabels")) System.QSGridLabelsHook(lpparam); + if (mPrefs.getInt("system_netspeedinterval", 4) != 4) SystemUI.NetSpeedIntervalHook(lpparam); + if (mPrefs.getInt("system_qsgridrows", 1) > 1 || mPrefs.getBoolean("system_qsnolabels")) SystemUI.QSGridLabelsHook(lpparam); if (mPrefs.getInt("system_lstimeout", 9) > 9) System.LockScreenTimeoutHook(lpparam); if (mPrefs.getInt("controls_fsg_coverage", 60) != 60) Controls.BackGestureAreaHeightHook(lpparam, true); if (mPrefs.getInt("controls_fsg_width", 100) > 100) Controls.BackGestureAreaWidthHook(lpparam, true); @@ -233,8 +234,8 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_drawer_clockseconds") ) System.StatusBarClockTweakHook(lpparam); if (mPrefs.getBoolean("system_noscreenlock_act")) System.NoScreenLockHook(lpparam); - if (mPrefs.getBoolean("system_detailednetspeed")) System.DetailedNetSpeedHook(lpparam); - if (mPrefs.getBoolean("system_albumartonlock")) System.LockScreenAlbumArtHook(lpparam); + if (mPrefs.getBoolean("system_detailednetspeed")) SystemUI.DetailedNetSpeedHook(lpparam); + if (mPrefs.getBoolean("system_albumartonlock")) SystemUI.LockScreenAlbumArtHook(lpparam); if (mPrefs.getBoolean("system_popupnotif")) System.PopupNotificationsHook(lpparam); if (mPrefs.getStringAsInt("system_expandheadups", 1) > 1) System.ExpandHeadsUpHook(lpparam); if (mPrefs.getBoolean("system_betterpopups_nohide")) System.BetterPopupsNoHideHook(lpparam); @@ -244,13 +245,10 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_notifafterunlock")) System.ShowNotificationsAfterUnlockHook(lpparam); if (mPrefs.getBoolean("system_notifrowmenu")) System.NotificationRowMenuHook(lpparam); if (mPrefs.getBoolean("system_compactnotif")) System.CompactNotificationsHook(lpparam); - if (mPrefs.getBoolean("system_removedismiss")) System.HideDismissViewHook(lpparam); + if (mPrefs.getBoolean("system_removedismiss")) SystemUI.HideDismissViewHook(lpparam); if (mPrefs.getBoolean("controls_nonavbar")) Controls.HideNavBarHook(lpparam); if (mPrefs.getBoolean("controls_imebackalticon")) Controls.ImeBackAltIconHook(lpparam); if (mPrefs.getBoolean("system_visualizer")) System.AudioVisualizerHook(lpparam); - if (mPrefs.getBoolean("system_separatevolume") && mPrefs.getBoolean("system_separatevolume_slider")) { - System.NotificationVolumeDialogRes(); - } if (mPrefs.getBoolean("system_nosilentvibrate") || mPrefs.getBoolean("system_qs_force_systemfonts") || mPrefs.getBoolean("system_qsnolabels") @@ -259,11 +257,11 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || (mPrefs.getInt("system_volumedialogdelay_collapsed", 0) > 0 || mPrefs.getInt("system_volumedialogdelay_expanded", 0) > 0) || (mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || mPrefs.getInt("system_volumeblur_expanded", 0) > 0) ) { - System.MIUIVolumeDialogHook(lpparam); + SystemUI.MIUIVolumeDialogHook(lpparam); } - if (mPrefs.getBoolean("system_batteryindicator")) System.BatteryIndicatorHook(lpparam); + if (mPrefs.getBoolean("system_batteryindicator")) SystemUI.BatteryIndicatorHook(lpparam); if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationHook(lpparam); - if (mPrefs.getBoolean("system_lockscreenshortcuts")) System.LockScreenShortcutHook(lpparam); + if (mPrefs.getBoolean("system_lockscreenshortcuts")) SystemUI.LockScreenShortcutHook(lpparam); if (mPrefs.getBoolean("system_4gtolte") || (mPrefs.getBoolean("system_statusbar_mobiletype_single") && !mPrefs.getString("system_statusbar_mobile_showname", "").equals("")) @@ -279,14 +277,14 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft") || mPrefs.getBoolean("system_statusbaricons_swap_wifi_mobile") ) { - System.StatusBarIconsPositionAdjustHook(lpparam, moveRight); + SystemUI.StatusBarIconsPositionAdjustHook(lpparam, moveRight); } if (mPrefs.getBoolean("system_statusbar_clock_atright") && !mPrefs.getBoolean("system_statusbar_dualrows")) { - System.StatusBarClockAtRightHook(lpparam); + SystemUI.StatusBarClockAtRightHook(lpparam); } - if (mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) System.DisplayBatteryDetailHook(lpparam); - if (mPrefs.getBoolean("system_statusbar_topmargin") && mPrefs.getBoolean("system_statusbar_topmargin_unset_lockscreen")) System.LockScreenTopMarginHook(lpparam); - if (mPrefs.getBoolean("system_statusbar_horizmargin")) System.HorizMarginHook(lpparam); + if (mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) SystemUI.DisplayBatteryDetailHook(lpparam); + if (mPrefs.getBoolean("system_statusbar_topmargin") && mPrefs.getBoolean("system_statusbar_topmargin_unset_lockscreen")) SystemUI.LockScreenTopMarginHook(lpparam); + if (mPrefs.getBoolean("system_statusbar_horizmargin")) SystemUI.HorizMarginHook(lpparam); if (mPrefs.getBoolean("system_showpct")) System.BrightnessPctHook(lpparam); if (mPrefs.getBoolean("system_hidelsstatusbar")) System.HideLockScreenStatusBarHook(lpparam); if (mPrefs.getBoolean("system_hidelsclock")) System.HideLockScreenClockHook(lpparam); @@ -295,12 +293,12 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_allownotifonkeyguard")) System.AllowAllKeyguardHook(lpparam); if (mPrefs.getBoolean("system_allownotiffloat")) System.AllowAllFloatHook(lpparam); if (mPrefs.getBoolean("system_hideqs")) System.HideQSHook(lpparam); - if (mPrefs.getBoolean("system_lsalarm")) System.LockScreenAlaramHook(lpparam); - if (mPrefs.getBoolean("system_statusbarcontrols")) System.StatusBarGesturesHook(lpparam); - if (mPrefs.getBoolean("system_nonetspeedseparator")) System.NoNetworkSpeedSeparatorHook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_clock")) System.HideIconsClockHook(lpparam); - if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideNetworkSpeedUnitHook(lpparam); - if (mPrefs.getBoolean("system_detailednetspeed_low") && !mPrefs.getBoolean("system_detailednetspeed")) System.HideLowNetworkSpeedHook(lpparam); + if (mPrefs.getBoolean("system_lsalarm")) System.LockScreenAlarmHook(lpparam); + if (mPrefs.getBoolean("system_statusbarcontrols")) SystemUI.StatusBarGesturesHook(lpparam); + if (mPrefs.getBoolean("system_nonetspeedseparator")) SystemUI.NoNetworkSpeedSeparatorHook(lpparam); + if (mPrefs.getBoolean("system_statusbaricons_clock")) SystemUI.HideIconsClockHook(lpparam); + if (mPrefs.getBoolean("system_detailednetspeed_secunit") && !mPrefs.getBoolean("system_detailednetspeed")) SystemUI.HideNetworkSpeedUnitHook(lpparam); + if (mPrefs.getBoolean("system_detailednetspeed_low") && !mPrefs.getBoolean("system_detailednetspeed")) SystemUI.HideLowNetworkSpeedHook(lpparam); if ( mPrefs.getInt("system_netspeed_fontsize", 13) > 13 || mPrefs.getInt("system_netspeed_verticaloffset", 8) != 8 @@ -308,14 +306,14 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_detailednetspeed") || mPrefs.getBoolean("system_netspeed_bold") ) { - System.NetSpeedStyleHook(lpparam); + SystemUI.NetSpeedStyleHook(lpparam); } // if (mPrefs.getBoolean("system_snoozedmanager")) System.MoreSnoozeOptionsHook(lpparam); if (mPrefs.getBoolean("system_taptounlock")) System.TapToUnlockHook(lpparam); if (mPrefs.getBoolean("system_nosos")) System.NoSOSHook(lpparam); if (mPrefs.getBoolean("system_morenotif")) System.MoreNotificationsHook(lpparam); if (mPrefs.getBoolean("system_charginginfo")) System.ChargingInfoHook(lpparam); - if (mPrefs.getBoolean("system_secureqs")) System.SecureQSTilesHook(lpparam); + if (mPrefs.getBoolean("system_secureqs")) SystemUI.SecureQSTilesHook(lpparam); if (mPrefs.getBoolean("system_mutevisiblenotif")) System.MuteVisibleNotificationsHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery1")) System.HideIconsBattery1Hook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_battery3") || mPrefs.getBoolean("system_statusbaricons_battery2") || mPrefs.getBoolean("system_statusbaricons_battery4")) System.HideIconsBattery2Hook(lpparam); @@ -325,12 +323,12 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { || mPrefs.getBoolean("system_statusbaricons_sim2") || mPrefs.getBoolean("system_statusbaricons_roaming") || mPrefs.getBoolean("system_statusbaricons_volte") - ) System.HideIconsSignalHook(lpparam); - if (mPrefs.getBoolean("system_statusbaricons_vowifi")) System.HideIconsVoWiFiHook(lpparam); + ) SystemUI.HideIconsSignalHook(lpparam); + if (mPrefs.getBoolean("system_statusbaricons_vowifi")) SystemUI.HideIconsVoWiFiHook(lpparam); if (!mPrefs.getBoolean("system_statusbaricons_alarm") && mPrefs.getInt("system_statusbaricons_alarmn", 0) > 0) System.HideIconsSelectiveAlarmHook(lpparam); if (!mPrefs.getString("system_shortcut_app", "").equals("") || !mPrefs.getString("system_calendar_app", "").equals("") - || !mPrefs.getString("system_clock_app", "").equals("")) System.ReplaceShortcutAppHook(lpparam); + || !mPrefs.getString("system_clock_app", "").equals("")) SystemUI.ReplaceShortcutAppHook(lpparam); if (mPrefs.getStringAsInt("system_qshaptics", 1) > 1) System.QSHapticHook(lpparam); if (mPrefs.getBoolean("system_qs_hideoperator")) System.HideCCOperatorHook(lpparam); if (mPrefs.getBoolean("system_cc_disable_bluetooth_restrict")) System.DisableBluetoothRestrictHook(lpparam); @@ -343,7 +341,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { System.HideNetworkIndicatorHook(lpparam); } if (mPrefs.getStringAsInt("system_statusbaricons_bluetooth", 1) > 1) System.HideIconsBluetoothHook(lpparam); - if (mPrefs.getBoolean("system_epm")) System.ExtendedPowerMenuHook(lpparam); + if (mPrefs.getBoolean("system_epm")) SystemUI.ExtendedPowerMenuHook(lpparam); boolean hideIconsActive = mPrefs.getBoolean("system_statusbaricons_wifi") || @@ -363,7 +361,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { mPrefs.getBoolean("system_statusbaricons_gps") || mPrefs.getBoolean("system_statusbaricons_btbattery") || mPrefs.getBoolean("system_statusbaricons_volte"); - if (hideIconsActive) System.HideIconsHook(lpparam); + if (hideIconsActive) SystemUI.HideIconsHook(lpparam); if (mPrefs.getInt("system_messagingstylelines", 0) > 0) System.MessagingStyleLinesHook(lpparam); if (mPrefs.getBoolean("system_betterpopups_allowfloat")) System.BetterPopupsAllowFloatHook(lpparam); @@ -372,17 +370,17 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("system_notifchannelsettings")) System.NotificationChannelSettingsHook(lpparam); if (mPrefs.getStringAsInt("system_maxsbicons", 0) != 0) System.MaxNotificationIconsHook(lpparam); if (mPrefs.getBoolean("system_statusbar_mobiletype_single")) { - System.MobileTypeSingleHook(lpparam); + SystemUI.MobileTypeSingleHook(lpparam); } if (mPrefs.getBoolean("system_statusbar_dualsimin2rows")) { - System.DualRowSignalHook(lpparam); + SystemUI.DualRowSignalHook(lpparam); } if (mPrefs.getBoolean("system_statusbar_dualrows")) { - System.DualRowStatusbarHook(lpparam); + SystemUI.DualRowStatusbarHook(lpparam); } - if (mPrefs.getInt("system_ccgridcolumns", 4) > 4 || mPrefs.getInt("system_ccgridrows", 4) != 4) System.SystemCCGridHook(lpparam); + if (mPrefs.getInt("system_ccgridcolumns", 4) > 4 || mPrefs.getInt("system_ccgridrows", 4) != 4) SystemUI.SystemCCGridHook(lpparam); if (mPrefs.getBoolean("system_cc_tile_roundedrect")) { - System.CCTileCornerHook(lpparam); + SystemUI.CCTileCornerHook(lpparam); } } @@ -412,7 +410,7 @@ public void handleLoadPackage(final LoadPackageParam lpparam) { if (mPrefs.getBoolean("various_enable_sc_ai_clipboard_location")) Various.UnlockClipboardAndLocationHook(lpparam); if (mPrefs.getBoolean("system_statusbaricons_privacy")) System.HideIconsPrivacyHook(lpparam); if (mPrefs.getBoolean("system_hidelowbatwarn")) { - System.NoLowBatteryWarningHook(lpparam); + System.NoLowBatteryWarningHook(); } } diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java index 9c48267c..f0c9f191 100644 --- a/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/System.java @@ -1,15 +1,11 @@ package name.mikanoshi.customiuizer.mods; import static java.lang.System.currentTimeMillis; -import static java.lang.System.nanoTime; import static de.robv.android.xposed.XposedHelpers.findClass; import static de.robv.android.xposed.XposedHelpers.findClassIfExists; import static de.robv.android.xposed.XposedHelpers.findMethodExactIfExists; import static name.mikanoshi.customiuizer.mods.GlobalActions.ACTION_PREFIX; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.Activity; @@ -22,20 +18,17 @@ import android.app.NotificationChannel; import android.app.PendingIntent; import android.app.TaskStackBuilder; -import android.app.WallpaperColors; import android.app.WallpaperManager; import android.appwidget.AppWidgetProviderInfo; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Configuration; @@ -43,12 +36,7 @@ import android.content.res.TypedArray; import android.database.ContentObserver; import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Matrix; -import android.graphics.Paint; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -64,23 +52,17 @@ import android.media.SoundPool; import android.media.session.MediaController; import android.media.session.PlaybackState; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; import android.net.NetworkInfo; -import android.net.TrafficStats; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.BadParcelableException; import android.os.BatteryManager; import android.os.Binder; -import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.Parcelable; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.SystemClock; @@ -97,22 +79,17 @@ import android.text.style.TypefaceSpan; import android.util.ArrayMap; import android.util.AttributeSet; -import android.util.DisplayMetrics; import android.util.Pair; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TypedValue; -import android.view.Display; import android.view.Gravity; import android.view.KeyEvent; -import android.view.LayoutInflater; import android.view.MotionEvent; -import android.view.SurfaceControl; import android.view.SurfaceView; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.view.ViewOutlineProvider; import android.view.Window; import android.view.WindowManager; import android.view.animation.AlphaAnimation; @@ -121,15 +98,11 @@ import android.widget.AbsListView; import android.widget.Button; import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Magnifier; -import android.widget.RelativeLayout; import android.widget.RemoteViews; -import android.widget.ScrollView; import android.widget.SeekBar; -import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; @@ -137,35 +110,24 @@ import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; -import java.net.NetworkInterface; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Properties; import java.util.Set; import java.util.TimeZone; import java.util.Timer; @@ -181,15 +143,12 @@ import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; import de.robv.android.xposed.callbacks.XCallback; -import miui.telephony.TelephonyManager; import name.mikanoshi.customiuizer.MainModule; import name.mikanoshi.customiuizer.R; import name.mikanoshi.customiuizer.utils.AudioVisualizer; -import name.mikanoshi.customiuizer.utils.BatteryIndicator; import name.mikanoshi.customiuizer.utils.Helpers; import name.mikanoshi.customiuizer.utils.Helpers.MethodHook; import name.mikanoshi.customiuizer.utils.Helpers.MimeType; -import name.mikanoshi.customiuizer.utils.ResourceHooks; import name.mikanoshi.customiuizer.utils.SoundData; public class System { @@ -849,17 +808,6 @@ public boolean onTouch(View v, MotionEvent event) { }); } - private static int notifVolumeOnResId; - private static int notifVolumeOffResId; - public static void NotificationVolumeDialogRes() { - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_content_width_expanded", R.dimen.miui_volume_content_width_expanded); - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_ringer_layout_width_expanded", R.dimen.miui_volume_ringer_layout_width_expanded); - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_column_width_expanded", R.dimen.miui_volume_column_width_expanded); - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_column_margin_horizontal_expanded", R.dimen.miui_volume_column_margin_horizontal_expanded); - notifVolumeOnResId = MainModule.resHooks.addResource("ic_miui_volume_notification", R.drawable.ic_miui_volume_notification); - notifVolumeOffResId = MainModule.resHooks.addResource("ic_miui_volume_notification_mute", R.drawable.ic_miui_volume_notification_mute); - } - private static int callsResId; public static void NotificationVolumeSettingsRes() { callsResId = MainModule.resHooks.addResource("ring_volume_option_newtitle", R.string.calls); @@ -888,7 +836,7 @@ protected void before(MethodHookParam param) throws Throwable { Object mContentResolver = XposedHelpers.getObjectField(XposedHelpers.getSurroundingThis(param.thisObject), "mContentResolver"); SparseIntArray mIndexMap = (SparseIntArray)XposedHelpers.getObjectField(param.thisObject, "mIndexMap"); for (Integer deviceType : remainingDevices) { - int device = deviceType.intValue(); + int device = deviceType; String name = (String)XposedHelpers.callMethod(param.thisObject, "getSettingNameForDevice", device); int index = (int)XposedHelpers.callStaticMethod(Settings.System.class, "getIntForUser", mContentResolver, name, device == DEVICE_OUT_DEFAULT ? DEFAULT_STREAM_VOLUME[mStreamType] : -1, -2); if (index != -1) { @@ -913,64 +861,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - private static ClassLoader pluginLoader = null; - - public static void MIUIVolumeDialogHook(LoadPackageParam lpparam) { - String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; - Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { - isHooked = true; - if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); - } - Class MiuiVolumeDialogImpl = XposedHelpers.findClassIfExists("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", pluginLoader); - if (MainModule.mPrefs.getBoolean("system_separatevolume") && MainModule.mPrefs.getBoolean("system_separatevolume_slider")) { - Helpers.hookAllMethods(MiuiVolumeDialogImpl, "addColumn", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args.length != 4) return; - int streamType = (int) param.args[0]; - if (streamType == 4) { - XposedHelpers.callMethod(param.thisObject, "addColumn", 5, notifVolumeOnResId, notifVolumeOffResId, true, false); - } - } - }); - } - if (MainModule.mPrefs.getBoolean("system_nosilentvibrate")) { - Helpers.hookAllMethods(MiuiVolumeDialogImpl, "vibrateH", XC_MethodReplacement.DO_NOTHING); - } - if (MainModule.mPrefs.getInt("system_volumedialogdelay_collapsed", 0) > 0 || MainModule.mPrefs.getInt("system_volumedialogdelay_expanded", 0) > 0) { - VolumeDialogAutohideDelayHook(pluginLoader); - } - if (MainModule.mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || MainModule.mPrefs.getInt("system_volumeblur_expanded", 0) > 0) { - BlurVolumeDialogBackgroundHook(pluginLoader); - } - if (MainModule.mPrefs.getBoolean("system_volumebar_blur_mtk")) { - BlurMTKVolumeBarHook(pluginLoader); - } - if (MainModule.mPrefs.getBoolean("system_qs_force_systemfonts")) { - Helpers.findAndHookMethod("miui.systemui.util.SystemUIResourcesHelperImpl", pluginLoader, "getBoolean", String.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String key = (String) param.args[0]; - if (key.equals("header_big_time_use_system_font")) { - param.setResult(Boolean.TRUE); - } - } - }); - } - if (MainModule.mPrefs.getBoolean("system_qsnolabels")) { - HideCCLabelsHook(pluginLoader); - } - } - } - }); - } - public static void NotificationVolumeSettingsHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.settings.MiuiSoundSettings", lpparam.classLoader, "onCreate", Bundle.class, new MethodHook() { @Override @@ -1706,310 +1596,6 @@ public void onChange(Uri uri) { }); } - private static long measureTime = 0; - private static long txBytesTotal = 0; - private static long rxBytesTotal = 0; - private static long txSpeed = 0; - private static long rxSpeed = 0; - - private static Pair getTrafficBytes(Object thisObject) { - long tx = -1L; - long rx = -1L; - - try { - for (Enumeration list = NetworkInterface.getNetworkInterfaces(); list.hasMoreElements();) { - NetworkInterface iface = list.nextElement(); - if (iface.isUp() && !iface.isVirtual() && !iface.isLoopback() && !iface.isPointToPoint() && !"".equals(iface.getName())) { - tx += (long)XposedHelpers.callStaticMethod(TrafficStats.class, "getTxBytes", iface.getName()); - rx += (long)XposedHelpers.callStaticMethod(TrafficStats.class, "getRxBytes", iface.getName()); - } - } - } catch (Throwable t) { - XposedBridge.log(t); - tx = TrafficStats.getTotalTxBytes(); - rx = TrafficStats.getTotalRxBytes(); - } - - return new Pair(tx, rx); - } - - @SuppressLint("DefaultLocale") - private static String humanReadableByteCount(Context ctx, long bytes) { - try { - Resources modRes = Helpers.getModuleRes(ctx); - boolean hideSecUnit = MainModule.mPrefs.getBoolean("system_detailednetspeed_secunit"); - String unitSuffix = modRes.getString(R.string.Bs); - if (hideSecUnit) { - unitSuffix = ""; - } - if (bytes < 1024) return bytes + " " + (hideSecUnit ? "B" : unitSuffix); - int exp = (int) (Math.log(bytes) / Math.log(1024)); - char pre = modRes.getString(R.string.speedunits).charAt(exp-1); - DecimalFormat df = new DecimalFormat("0.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); - df.setMinimumFractionDigits(0); - df.setMaximumFractionDigits(1); - return df.format(bytes / Math.pow(1024, exp)) + " " + String.format("%s" + unitSuffix, pre); - } catch (Throwable t) { - XposedBridge.log(t); - return ""; - } - } - - public static void NetSpeedIntervalHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "postUpdateNetworkSpeedDelay", long.class, new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - long originInterval = (long) param.args[0]; - if (originInterval == 4000L) { - long newInterval = MainModule.mPrefs.getInt("system_netspeedinterval", 4) * 1000; - param.args[0] = newInterval; - } - } - }); - } - - public static void DetailedNetSpeedHook(LoadPackageParam lpparam) { - Class nscCls = XposedHelpers.findClassIfExists("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader); - if (nscCls == null) { - Helpers.log("DetailedNetSpeedHook", "No NetworkSpeed view or controller"); - return; - } - - Helpers.findAndHookMethod(nscCls, "getTotalByte", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Pair bytes = getTrafficBytes(param.thisObject); - txBytesTotal = bytes.first; - rxBytesTotal = bytes.second; - measureTime = nanoTime(); - } - }); - - Helpers.findAndHookMethod(nscCls, "updateNetworkSpeed", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - boolean isConnected = false; - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - ConnectivityManager mConnectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - Network nw = mConnectivityManager.getActiveNetwork(); - if (nw != null) { - NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(nw); - if (capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))) { - isConnected = true; - } - } - if (isConnected) { - long nanoTime = nanoTime(); - long newTime = nanoTime - measureTime; - measureTime = nanoTime; - if (newTime == 0) newTime = Math.round(4 * Math.pow(10, 9)); - Pair bytes = getTrafficBytes(param.thisObject); - long newTxBytes = bytes.first; - long newRxBytes = bytes.second; - long newTxBytesFixed = newTxBytes - txBytesTotal; - long newRxBytesFixed = newRxBytes - rxBytesTotal; - if (newTxBytesFixed < 0 || txBytesTotal == 0) newTxBytesFixed = 0; - if (newRxBytesFixed < 0 || rxBytesTotal == 0) newRxBytesFixed = 0; - txSpeed = Math.round(newTxBytesFixed / (newTime / Math.pow(10, 9))); - rxSpeed = Math.round(newRxBytesFixed / (newTime / Math.pow(10, 9))); - txBytesTotal = newTxBytes; - rxBytesTotal = newRxBytes; - } else { - txSpeed = 0; - rxSpeed = 0; - } - } - }); - - Helpers.findAndHookMethod(nscCls, "updateText", String.class, new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean hideLow = MainModule.mPrefs.getBoolean("system_detailednetspeed_low"); - int lowLevel = MainModule.mPrefs.getInt("system_detailednetspeed_lowlevel", 1) * 1024; - int icons = Integer.parseInt(MainModule.mPrefs.getString("system_detailednetspeed_icon", "2")); - - String txarrow = ""; - String rxarrow = ""; - if (icons == 2) { - txarrow = txSpeed < lowLevel ? "△" : "▲"; - rxarrow = rxSpeed < lowLevel ? "▽" : "▼"; - } else if (icons == 3) { - txarrow = txSpeed < lowLevel ? " ☖" : " ☗"; - rxarrow = rxSpeed < lowLevel ? " ⛉" : " ⛊"; - } - - String tx = hideLow && txSpeed < lowLevel ? "" : humanReadableByteCount(mContext, txSpeed) + txarrow; - String rx = hideLow && rxSpeed < lowLevel ? "" : humanReadableByteCount(mContext, rxSpeed) + rxarrow; - param.args[0] = tx + "\n" + rx; - } - }); - } - - private static Bitmap processAlbumArt(Context context, Bitmap bitmap) { - if (context == null || bitmap == null) return bitmap; - int rescale = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_albumartonlock_scale", "1")); - boolean grayscale = Helpers.getSharedBoolPref(context, "pref_key_system_albumartonlock_gray", false); - if (rescale == 1 && !grayscale) return bitmap; - - Paint paint = new Paint(); - Matrix transformation = new Matrix(); - int width = 0; - int height = 0; - - if (grayscale) { - width = bitmap.getWidth(); - height = bitmap.getHeight(); - - ColorMatrix matrix = new ColorMatrix(); - matrix.setSaturation(0); - paint.setColorFilter(new ColorMatrixColorFilter(matrix)); - } - - if (rescale != 1) { - Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - Point point = new Point(); - display.getRealSize(point); - width = point.x; - height = point.y; - - float originalWidth = bitmap.getWidth(); - float originalHeight = bitmap.getHeight(); - float scale = rescale == 2 ? Math.min(width / originalWidth, height / originalHeight) : Math.max(width / originalWidth, height / originalHeight); - float xTranslation = (width - originalWidth * scale) / 2.0f; - float yTranslation = (height - originalHeight * scale) / 2.0f; - - transformation.postTranslate(xTranslation, yTranslation); - transformation.preScale(scale, scale); - - paint.setFilterBitmap(true); - } - - Bitmap processed = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(processed); - canvas.drawBitmap(bitmap, transformation, paint); - return processed; - } - - public static void LockScreenAlbumArtHook(LoadPackageParam lpparam) { - Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader); - - Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); - if (isDefaultLockScreenTheme) { - Object mBlurRatioChangedListener = XposedHelpers.getObjectField(param.thisObject, "mBlurRatioChangedListener"); - Object notificationShadeDepthController = XposedHelpers.getObjectField(param.thisObject, "notificationShadeDepthController"); - XposedHelpers.callMethod(notificationShadeDepthController, "removeListener", mBlurRatioChangedListener); - View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); - view.setAlpha(1.0f); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); - view.getContext().registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) return; - if (action.equals(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART")) { - try { - XposedHelpers.callMethod(param.thisObject, "updateThemeBackground"); - } - catch (Throwable e) { - XposedHelpers.callMethod(param.thisObject, "updateThemeBackgroundVisibility"); - } - } - } - }, intentFilter); - } - } - }); - MethodHook updateLockscreenHook = new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); - if (!isDefaultLockScreenTheme) { - return ; - } - View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); - boolean isOnShade = (boolean) XposedHelpers.callMethod(param.thisObject, "isOnShade"); - if (isOnShade) { - view.setVisibility(View.GONE); - } - else { - Object mAlbumArt = XposedHelpers.getAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt"); - if (mAlbumArt != null) { - view.setBackground(new BitmapDrawable(view.getContext().getResources(), (Bitmap) mAlbumArt)); - } - view.setVisibility(mAlbumArt != null ? View.VISIBLE : View.GONE); - } - param.setResult(null); - } - }; - Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackground", updateLockscreenHook); - - if (Helpers.isTPlus()) { - Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackgroundVisibility", updateLockscreenHook); - } - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMediaManager", lpparam.classLoader, "updateMediaMetaData", boolean.class, boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); - if (!isDefaultLockScreenTheme) { - XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); - XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); - return; - } - MediaMetadata mMediaMetadata = (MediaMetadata)XposedHelpers.getObjectField(param.thisObject, "mMediaMetadata"); - Bitmap art = null; - if (mMediaMetadata != null) { - art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART); - if (art == null) art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); - if (art == null) art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON); - } - Bitmap mAlbumArt = (Bitmap)XposedHelpers.getAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource"); - try { - if (art == null && mAlbumArt == null) return; - if (art != null && art.sameAs(mAlbumArt)) return; - } catch (Throwable ignore) {} - XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", art); - - int blur = Helpers.getSharedIntPref(mContext, "pref_key_system_albumartonlock_blur", 0); - Bitmap blurArt = processAlbumArt(mContext, art != null && blur > 0 ? Helpers.fastBlur(art, blur + 1) : art); - XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", blurArt); - - Intent updateAlbumWallpaper = new Intent(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); - updateAlbumWallpaper.setPackage("com.android.systemui"); - mContext.sendBroadcast(updateAlbumWallpaper); - - if (blurArt != null) { - Intent updateFakeWallpaper = new Intent("miui.intent.action.LOCK_WALLPAPER_CHANGED"); - updateFakeWallpaper.setPackage("com.android.systemui"); - WallpaperColors fromBitmap = WallpaperColors.fromBitmap(blurArt); - boolean isWallpaperColorLight = (fromBitmap.getColorHints() & 1) == 1; - updateFakeWallpaper.putExtra("is_wallpaper_color_light", isWallpaperColorLight); - mContext.sendBroadcast(updateFakeWallpaper); - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMediaManager", lpparam.classLoader, "clearCurrentMediaNotification", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); - XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); - XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); - if (isDefaultLockScreenTheme) { - Intent updateAlbumWallpaper = new Intent(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); - updateAlbumWallpaper.setPackage("com.android.systemui"); - mContext.sendBroadcast(updateAlbumWallpaper); - } - } - }); - } - public static void BetterPopupsHideDelaySysHook() { Helpers.findAndHookMethod(MiuiNotification.class, "getFloatTime", XC_MethodReplacement.returnConstant(0)); } @@ -2070,7 +1656,6 @@ protected void before(final MethodHookParam param) throws Throwable { public static void BetterPopupsSwipeDownHook(LoadPackageParam lpparam) { Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.HeadsUpTouchHelper", lpparam.classLoader, "onInterceptTouchEvent", MotionEvent.class, new MethodHook() { @Override - @SuppressWarnings("ConstantConditions") protected void after(final MethodHookParam param) throws Throwable { MotionEvent me = (MotionEvent)param.args[0]; if (me.getActionMasked() == MotionEvent.ACTION_DOWN) { @@ -2583,126 +2168,6 @@ protected void before(final MethodHookParam param) throws Throwable { }); } - public static void QQSGridRes() { - int cols = MainModule.mPrefs.getInt("system_qqsgridcolumns", 2); - int colsResId = R.integer.quick_quick_settings_num_rows_5; - switch (cols) { - case 3: colsResId = R.integer.quick_quick_settings_num_rows_3; break; - case 4: colsResId = R.integer.quick_quick_settings_num_rows_4; break; - case 5: colsResId = R.integer.quick_quick_settings_num_rows_5; break; - case 6: colsResId = R.integer.quick_quick_settings_num_rows_6; break; - case 7: colsResId = R.integer.quick_quick_settings_num_rows_7; break; - } - MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_qqs_count", colsResId); - } - - public static void QSGridRes() { - int cols = MainModule.mPrefs.getInt("system_qsgridcolumns", 2); - int rows = MainModule.mPrefs.getInt("system_qsgridrows", 1); - int colsRes = R.integer.quick_settings_num_columns_3; - int rowsRes = R.integer.quick_settings_num_rows_4; - - switch (cols) { - case 3: colsRes = R.integer.quick_settings_num_columns_3; break; - case 4: colsRes = R.integer.quick_settings_num_columns_4; break; - case 5: colsRes = R.integer.quick_settings_num_columns_5; break; - case 6: colsRes = R.integer.quick_settings_num_columns_6; break; - case 7: colsRes = R.integer.quick_settings_num_columns_7; break; - } - - switch (rows) { - case 2: rowsRes = R.integer.quick_settings_num_rows_2; break; - case 3: rowsRes = R.integer.quick_settings_num_rows_3; break; - case 4: rowsRes = R.integer.quick_settings_num_rows_4; break; - case 5: rowsRes = R.integer.quick_settings_num_rows_5; break; - } - - if (cols > 2) MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_num_columns", colsRes); - if (rows > 1) MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_num_rows", rowsRes); - } - - private static void updateLabelsVisibility(Object mRecord, int mRows, int orientation) { - if (mRecord == null) return; - Object tileView = XposedHelpers.getObjectField(mRecord, "tileView"); - if (tileView != null) { - ViewGroup mLabelContainer = null; - try { - mLabelContainer = (ViewGroup)XposedHelpers.getObjectField(tileView, "mLabelContainer"); - } - catch (Throwable ignore) {} - - if (mLabelContainer != null) { - mLabelContainer.setVisibility( - MainModule.mPrefs.getBoolean("system_qsnolabels") || - orientation == Configuration.ORIENTATION_PORTRAIT && mRows >= 5 || - orientation == Configuration.ORIENTATION_LANDSCAPE && mRows >= 3 ? View.GONE : View.VISIBLE - ); - } - } - } - - private static void HideCCLabelsHook(ClassLoader pluginLoader) { - MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85f); - Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); - Helpers.hookAllMethods(QSController, "init", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args.length != 1) return; - View mLabelContainer = (View)XposedHelpers.getObjectField(param.thisObject, "labelContainer"); - if (mLabelContainer != null) { - mLabelContainer.setVisibility(View.GONE); - } - } - }); - } - - public static void QSGridLabelsHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.qs.MiuiTileLayout", lpparam.classLoader, "addTile", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - updateLabelsVisibility(param.args[0], XposedHelpers.getIntField(param.thisObject, "mRows"), ((ViewGroup)param.thisObject).getResources().getConfiguration().orientation); - } - }); - - Helpers.hookAllMethods("com.android.systemui.qs.MiuiPagedTileLayout", lpparam.classLoader, "addTile", new MethodHook() { - @Override - @SuppressWarnings("unchecked") - protected void before(MethodHookParam param) throws Throwable { - ArrayList mPages = (ArrayList)XposedHelpers.getObjectField(param.thisObject, "mPages"); - if (mPages == null) return; - int mRows = 0; - if (mPages.size() > 0) mRows = XposedHelpers.getIntField(mPages.get(0), "mRows"); - updateLabelsVisibility(param.args[0], mRows, ((ViewGroup)param.thisObject).getResources().getConfiguration().orientation); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.qs.MiuiTileLayout", lpparam.classLoader, "updateResources", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - if (MainModule.mPrefs.getInt("system_qsgridrows", 1) != 2) return; - if (!(boolean)param.getResult()) return; - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) return; - XposedHelpers.setIntField(param.thisObject, "mCellHeight", Math.round(XposedHelpers.getIntField(param.thisObject, "mCellHeight") / 1.5f)); - ((ViewGroup)param.thisObject).requestLayout(); - } - }); - - if (MainModule.mPrefs.getInt("system_qsgridrows", 1) == 4) - Helpers.findAndHookMethod("com.android.systemui.qs.tileimpl.MiuiQSTileView", lpparam.classLoader, "createLabel", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - ViewGroup mLabelContainer = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mLabelContainer"); - if (mLabelContainer != null) mLabelContainer.setPadding( - mLabelContainer.getPaddingLeft(), - Math.round(mLabelContainer.getResources().getDisplayMetrics().density * 2), - mLabelContainer.getPaddingRight(), - mLabelContainer.getPaddingBottom() - ); - } - }); - } - public static void NoDuckingHook(LoadPackageParam lpparam) { //Helpers.hookAllMethods("com.android.server.audio.PlaybackActivityMonitor", lpparam.classLoader, "duckPlayers", XC_MethodReplacement.returnConstant(true)); //Helpers.hookAllMethods("com.android.server.audio.PlaybackActivityMonitor$DuckingManager", lpparam.classLoader, "addDuck", XC_MethodReplacement.DO_NOTHING); @@ -2774,174 +2239,6 @@ protected void after(MethodHookParam param) throws Throwable { }); } - public static void ExtendedPowerMenuHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - private boolean isListened = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - if (!isListened) { - isListened = true; - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - File powermenu = new File(mContext.getCacheDir(), "extended_power_menu"); - if (powermenu == null) { - Helpers.log("ExtendedPowerMenuHook", "No writable path found!"); - return; - } - if (powermenu.exists()) powermenu.delete(); - - InputStream inputStream; - FileOutputStream outputStream; - byte[] fileBytes; - Resources resources = Helpers.getModuleRes(mContext); - inputStream = resources.openRawResource(resources.getIdentifier("extended_power_menu", "raw", Helpers.modulePkg)); - fileBytes = new byte[inputStream.available()]; - inputStream.read(fileBytes); - outputStream = new FileOutputStream(powermenu); - outputStream.write(fileBytes); - outputStream.close(); - inputStream.close(); - - if (!powermenu.exists()) { - Helpers.log("ExtendedPowerMenuHook", "MAML file not found in cache"); - } - else { - Helpers.findAndHookConstructor("com.miui.maml.util.ZipResourceLoader", lpparam.classLoader, String.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String res = (String) param.args[0]; - if ("/system/media/theme/default/powermenu".equals(res)) { - param.args[0] = powermenu.getPath(); - } - } - }); - } - } - } - }); - Helpers.findAndHookMethod("com.miui.maml.ScreenElementRoot", lpparam.classLoader, "issueExternCommand", String.class, Double.class, String.class, new MethodHook() { - @Override - @SuppressLint("MissingPermission") - protected void before(MethodHookParam param) throws Throwable { - String cmd = (String)param.args[0]; - Object scrContext = XposedHelpers.getObjectField(param.thisObject, "mContext"); - Context mContext = (Context)XposedHelpers.getObjectField(scrContext, "mContext"); - PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); - Object mService = XposedHelpers.getObjectField(pm, "mService"); - Object mSystemExternCommandListener = XposedHelpers.getObjectField(param.thisObject, "mSystemExternCommandListener"); - - boolean custom = false; - if ("recovery".equals(cmd)) { - XposedHelpers.callMethod(mService, "reboot", false, "recovery", false); - custom = true; - } else if ("bootloader".equals(cmd)) { - XposedHelpers.callMethod(mService, "reboot", false, "bootloader", false); - custom = true; - } else if ("softreboot".equals(cmd)) { - mContext.sendBroadcast(new Intent(ACTION_PREFIX + "FastReboot")); - custom = true; - } else if ("killsysui".equals(cmd)) { - mContext.sendBroadcast(new Intent(ACTION_PREFIX + "RestartSystemUI")); - custom = true; - } else if ("killlauncher".equals(cmd)) { - ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_HOME); - ResolveInfo launcherInfo = mContext.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); - if (launcherInfo != null) { - String pkgName = launcherInfo.activityInfo.packageName; - if (pkgName != null) XposedHelpers.callMethod(am, "forceStopPackage", pkgName); - } - custom = true; - } - - if (custom) { - if (mSystemExternCommandListener != null) XposedHelpers.callMethod(mSystemExternCommandListener, "onCommand", param.args[0], param.args[1], param.args[2]); - param.setResult(null); - } - } - }); - - Helpers.findAndHookMethod("com.android.systemui.plugins.PluginEnablerImpl", lpparam.classLoader, "isEnabled", ComponentName.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - ComponentName componentName = (ComponentName) param.args[0]; - if (componentName.getClassName().contains("GlobalActions")) { - param.setResult(false); - } - } - }); - } - - public static void HideDismissViewHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateDismissView", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); - if (mDismissView != null) { - mDismissView.setVisibility(View.GONE); - param.setResult(null); - } - } - }); - } - - public static void ReplaceShortcutAppHook(LoadPackageParam lpparam) { - MethodHook openAppHook = new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Context mContext = AndroidAppHelper.currentApplication(); - int user = 0; - String pkgAppName = ""; - if (param.method.getName().equals("startCalendarApp")) { - user = Helpers.getSharedIntPref(mContext, "pref_key_system_calendar_app_user", 0); - pkgAppName = Helpers.getSharedStringPref(mContext, "pref_key_system_calendar_app", ""); - } - else if (param.method.getName().equals("startClockApp")) { - user = Helpers.getSharedIntPref(mContext, "pref_key_system_clock_app_user", 0); - pkgAppName = Helpers.getSharedStringPref(mContext, "pref_key_system_clock_app", ""); - } - else if (param.method.getName().equals("startSettingsApp")) { - user = Helpers.getSharedIntPref(mContext, "pref_key_system_shortcut_app_user", 0); - pkgAppName = Helpers.getSharedStringPref(mContext, "pref_key_system_shortcut_app", ""); - } - if (pkgAppName != null && !pkgAppName.equals("")) { - String[] pkgAppArray = pkgAppName.split("\\|"); - if (pkgAppArray.length < 2) return; - - ComponentName name = new ComponentName(pkgAppArray[0], pkgAppArray[1]); - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - intent.setComponent(name); - if (user != 0) { - try { - Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); - String StatusbarClsForDep = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfaces" : "com.android.systemui.statusbar.phone.StatusBar"; - Object mStatusBar = XposedHelpers.callStaticMethod(Dependency, "get", findClass(StatusbarClsForDep, lpparam.classLoader)); - XposedHelpers.callMethod(mStatusBar, "collapsePanels"); - XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user)); - } catch (Throwable t) { - XposedBridge.log(t); - } - } else { - Object activiyStarter = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", mContext.getClassLoader()), "get", findClass("com.android.systemui.plugins.ActivityStarter", mContext.getClassLoader())); - XposedHelpers.callMethod(activiyStarter, "startActivity", intent, true); - } - param.setResult(null); - } - } - }; - if (!MainModule.mPrefs.getString("system_shortcut_app", "").equals("")) { - Helpers.findAndHookMethod("com.miui.systemui.util.CommonUtil", lpparam.classLoader, "startSettingsApp", openAppHook); - } - if (!MainModule.mPrefs.getString("system_calendar_app", "").equals("")) { - Helpers.findAndHookMethod("com.miui.systemui.util.CommonUtil", lpparam.classLoader, "startCalendarApp", Context.class, openAppHook); - } - if (!MainModule.mPrefs.getString("system_clock_app", "").equals("")) { - Helpers.findAndHookMethod("com.miui.systemui.util.CommonUtil", lpparam.classLoader, "startClockApp", openAppHook); - } - } - private static final int NOCOLOR = 0x01010101; private static int actionBarColor = NOCOLOR; @@ -3491,59 +2788,6 @@ protected void after(MethodHookParam param) throws Throwable { Helpers.hookAllMethods(ActQueryService, lpparam.classLoader, "queryIntentActivitiesInternal", hook); } - public static void VolumeTimerValuesRes(LoadPackageParam lpparam) { - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "array", "miui_volume_timer_segments", R.array.miui_volume_timer_segments); - - String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; - Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { - isHooked = true; - if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); - } - Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeTimerDrawableHelper", pluginLoader, "initTimerString", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - String[] mTimeSegmentTitle = new String[11]; - int timerOffId = mContext.getResources().getIdentifier("timer_off", "string", "miui.systemui.plugin"); - int minuteId = mContext.getResources().getIdentifier("timer_30_minutes", "string", "miui.systemui.plugin"); - int hourId = mContext.getResources().getIdentifier("timer_1_hour", "string", "miui.systemui.plugin"); - mTimeSegmentTitle[0] = mContext.getResources().getString(timerOffId); - mTimeSegmentTitle[1] = mContext.getResources().getString(minuteId, 30); - mTimeSegmentTitle[2] = mContext.getResources().getString(hourId, 1); - mTimeSegmentTitle[3] = mContext.getResources().getString(hourId, 2); - mTimeSegmentTitle[4] = mContext.getResources().getString(hourId, 3); - mTimeSegmentTitle[5] = mContext.getResources().getString(hourId, 4); - mTimeSegmentTitle[6] = mContext.getResources().getString(hourId, 5); - mTimeSegmentTitle[7] = mContext.getResources().getString(hourId, 6); - mTimeSegmentTitle[8] = mContext.getResources().getString(hourId, 8); - mTimeSegmentTitle[9] = mContext.getResources().getString(hourId, 10); - mTimeSegmentTitle[10] = mContext.getResources().getString(hourId, 12); - XposedHelpers.setObjectField(param.thisObject, "mTimeSegmentTitle", mTimeSegmentTitle); - } - }); - Helpers.findAndHookMethod("com.android.systemui.miui.volume.TimerItem", pluginLoader, "getTimePos", int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object timer = XposedHelpers.getObjectField(param.thisObject, "mTimerTime"); - float halfTimerWidth = ((int) XposedHelpers.callMethod(timer, "getWidth")) / 2.0f; - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - float seekWidth = mContext.getResources().getDimension(mContext.getResources().getIdentifier("miui_volume_timer_seelbar_width", "dimen", "miui.systemui.plugin")); - int marginLeft = mContext.getResources().getDimensionPixelSize(mContext.getResources().getIdentifier("miui_volume_timer_seekbar_margin_left", "dimen", "miui.systemui.plugin")); - int seg = (int) XposedHelpers.getObjectField(param.thisObject, "mDeterminedSegment"); - param.setResult(seekWidth / 10 * seg + marginLeft - halfTimerWidth); - } - }); - } - } - }); - } - public static void AppLockHook(LoadPackageParam lpparam) { Helpers.hookAllMethods("com.miui.server.SecurityManagerService", lpparam.classLoader, "removeAccessControlPassLocked", new MethodHook() { @Override @@ -4032,173 +3276,6 @@ protected void before(MethodHookParam param) throws Throwable { }); } - public static void HideIconsClockHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showClock", boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - XposedHelpers.callMethod(param.thisObject, "hideClockInternal", 8, false); - XposedHelpers.callMethod(param.thisObject, "hideNetworkSpeedSplitter", 8, false); - param.setResult(null); - } - }); - } - - public static void HideIconsVoWiFiHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethodSilently("com.android.systemui.MiuiOperatorCustomizedPolicy$MiuiOperatorConfig", lpparam.classLoader, "getHideVowifi", XC_MethodReplacement.returnConstant(true)); - } - - public static void HideIconsSignalHook(LoadPackageParam lpparam) { - MethodHook beforeUpdate = new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Object mobileIconState = param.args[0]; - if (MainModule.mPrefs.getBoolean("system_statusbaricons_signal")) { - XposedHelpers.setObjectField(mobileIconState, "visible", false); - return; - } - int subId = (int) XposedHelpers.getObjectField(mobileIconState, "subId"); - if ((MainModule.mPrefs.getBoolean("system_statusbaricons_sim1") && subId == 1) - || (MainModule.mPrefs.getBoolean("system_statusbaricons_sim2") && subId == 2) - ) { - XposedHelpers.setObjectField(mobileIconState, "visible", false); - return; - } - if (MainModule.mPrefs.getBoolean("system_statusbaricons_roaming")) { - XposedHelpers.setObjectField(mobileIconState, "roaming", false); - } - if (MainModule.mPrefs.getBoolean("system_statusbaricons_volte")) { - XposedHelpers.setObjectField(mobileIconState, "volte", false); - XposedHelpers.setObjectField(mobileIconState, "speechHd", false); - } - } - }; - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", beforeUpdate); - } - - private static boolean checkSlot(String slotName) { - try { - return "headset".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_headset") || - "volume".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_sound") || - "zen".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_dnd") || - "volume".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_mute") || - "speakerphone".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_speaker") || - "call_record".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_record") || - "alarm_clock".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_alarm") || - "managed_profile".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_profile") || - "vpn".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_vpn") || - "nfc".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nfc") || - "location".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_gps") || - "wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_wifi") || - "slave_wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_dualwifi") || - "hotspot".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_hotspot") || - "no_sim".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nosims") || - "bluetooth_handsfree_battery".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_btbattery") || - "hd".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_volte"); - } catch (Throwable t) { - XposedBridge.log(t); - return false; - } - } - - public static void HideIconsHook(LoadPackageParam lpparam) { - MethodHook iconHook = new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String iconType = (String)param.args[0]; - if (checkSlot(iconType)) { - param.args[1] = false; - } - } - }; - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, iconHook); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, iconHook); - } - - public static void BatteryIndicatorHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "createAndAddWindows", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - ViewGroup mStatusBarWindow; - if (Helpers.isTPlus()) { - Object sbWindowController = XposedHelpers.getObjectField(param.thisObject, "mStatusBarWindowController"); - mStatusBarWindow = (ViewGroup) XposedHelpers.getObjectField(sbWindowController, "mStatusBarWindowView"); - } - else { - mStatusBarWindow = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mPhoneStatusBarWindow"); - } - - BatteryIndicator indicator = new BatteryIndicator(mContext); - View panel = mStatusBarWindow.findViewById(mContext.getResources().getIdentifier("notification_panel", "id", lpparam.packageName)); - mStatusBarWindow.addView(indicator, panel != null ? mStatusBarWindow.indexOfChild(panel) + 1 : Math.max(mStatusBarWindow.getChildCount() - 1, 2)); - indicator.setAdjustViewBounds(false); - indicator.init(param.thisObject); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mBatteryIndicator", indicator); - Object mNotificationIconAreaController = XposedHelpers.getObjectField(param.thisObject, "mNotificationIconAreaController"); - XposedHelpers.setAdditionalInstanceField(mNotificationIconAreaController, "mBatteryIndicator", indicator); - Object mBatteryController = XposedHelpers.getObjectField(param.thisObject, "mBatteryController"); - XposedHelpers.setAdditionalInstanceField(mBatteryController, "mBatteryIndicator", indicator); - XposedHelpers.callMethod(mBatteryController, "fireBatteryLevelChanged"); - XposedHelpers.callMethod(mBatteryController, "firePowerSaveChanged"); - } - }); - - Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "setPanelExpanded", boolean.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onExpandingChanged(!isKeyguardShowing && (boolean)param.args[0]); - } - }); - - Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "setQsExpanded", boolean.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); - if (!isKeyguardShowing) return; - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onExpandingChanged((boolean)param.args[0]); - } - }); - - Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "updateIsKeyguard", boolean.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onKeyguardStateChanged(isKeyguardShowing); - } - }); - - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationIconAreaController", lpparam.classLoader, "onDarkChanged", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onDarkModeChanged((float)param.args[1], (int)param.args[2]); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiBatteryControllerImpl", lpparam.classLoader, "fireBatteryLevelChanged", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - int mLevel = XposedHelpers.getIntField(param.thisObject, "mLevel"); - boolean mCharging = XposedHelpers.getBooleanField(param.thisObject, "mCharging"); - boolean mCharged = XposedHelpers.getBooleanField(param.thisObject, "mCharged"); - if (indicator != null) indicator.onBatteryLevelChanged(mLevel, mCharging, mCharged); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BatteryControllerImpl", lpparam.classLoader, "firePowerSaveChanged", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); - if (indicator != null) indicator.onPowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mPowerSave")); - } - }); - } - private static boolean obtainMagnifierShowCoordinates(Object mEditor, int type, final MotionEvent event, final PointF showPosInView) { TextView mTextView = (TextView)XposedHelpers.getObjectField(mEditor, "mTextView"); final int offset; @@ -4413,2522 +3490,725 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl }); } - private static boolean modifyCameraImage(Context mContext, View mKeyguardRightView, boolean mDarkMode) { - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { - restoreCameraImage(mKeyguardRightView); - return false; - } + private static Handler stateHandler; - final String key = "pref_key_system_lockscreenshortcuts_right"; + public static class StateRunnable implements Runnable { + Context context; + MediaController controller; - int action = Helpers.getSharedIntPref(mContext, key + "_action", 1); - if (action <= 1) { - restoreCameraImage(mKeyguardRightView); - return false; + StateRunnable(Context ctx, MediaController ctrl) { + context = ctx; + controller = ctrl; } - String str = Helpers.getActionName(mContext, key); - if (str == null) { - restoreCameraImage(mKeyguardRightView); - return false; + @Override + public void run() { + try { + if (stateHandler != null) stateHandler.postDelayed(this, 1000); + } catch (Throwable t) { + XposedBridge.log(t); + } } + } - Drawable icon = Helpers.getActionImage(mContext, key); - mKeyguardRightView.setBackgroundColor(Color.TRANSPARENT); - mKeyguardRightView.setForeground(icon); - mKeyguardRightView.setForegroundGravity(Gravity.CENTER); - - float density = mContext.getResources().getDisplayMetrics().density; - int size = Math.round(mContext.getResources().getConfiguration().smallestScreenWidthDp * density); - - Bitmap bmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bmp); - Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setShadowLayer(2 * density, 0, 0, mDarkMode ? Color.argb(90, 255, 255, 255) : Color.argb(90, 0, 0, 0)); - paint.setTextSize(20 * density); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(density); - paint.setColor(mDarkMode ? Color.WHITE : Color.BLACK); - paint.setAlpha(90); - - Rect bounds = new Rect(); - paint.getTextBounds(str, 0, str.length(), bounds); - float x = size / 2f - bounds.width() / 2f; - float y = size / 2f + bounds.height() / 2f + (icon == null ? 0 : icon.getIntrinsicHeight() / 2f + 30 * density); - canvas.drawText(str, x, y, paint); - paint.setStyle(Paint.Style.FILL); -// paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); - paint.clearShadowLayer(); - paint.setColor(mDarkMode ? Color.BLACK : Color.WHITE); - paint.setAlpha(mDarkMode ? 160 : 230); - canvas.drawText(str, x, y, paint); - - BitmapDrawable bmpDrawable = new BitmapDrawable(mContext.getResources(), bmp); - if (mKeyguardRightView instanceof ImageView) { - ((ImageView)mKeyguardRightView).setScaleType(ImageView.ScaleType.CENTER); - ((ImageView)mKeyguardRightView).setImageDrawable(bmpDrawable); - } else { - bmpDrawable.setGravity(Gravity.CENTER); - mKeyguardRightView.setBackground(bmpDrawable); + public static class SeekBarReceiver extends BroadcastReceiver { + View parent; + TextView posDur; + SeekBar seekBar; + + SeekBarReceiver(View view, SeekBar sBar, TextView pos) { + parent = view; + posDur = pos; + seekBar = sBar; } - return true; + @Override + public void onReceive(Context context, Intent intent) {} } - private static void restoreCameraImage(View mKeyguardRightView) { - mKeyguardRightView.setBackgroundColor(Color.BLACK); - mKeyguardRightView.setForeground(null); - if (mKeyguardRightView instanceof ImageView) - ((ImageView)mKeyguardRightView).setScaleType(ImageView.ScaleType.FIT_END); - } + public static class MediaControllerReceiver extends BroadcastReceiver { + MediaController.TransportControls transportControls; + + MediaControllerReceiver(MediaController.TransportControls transport) { + transportControls = transport; + } - private static void initLeftView(final Object thisObject) { - Context mContext = (Context)XposedHelpers.getObjectField(thisObject, "mContext"); - try { XposedHelpers.setObjectField(thisObject, "mMiWalletCardNum", new TextView(mContext)); } catch (Throwable ignore) {} - try { XposedHelpers.setObjectField(thisObject, "mRemoteControllerNum", new TextView(mContext)); } catch (Throwable ignore) {} - try { XposedHelpers.setObjectField(thisObject, "mSmartHomeNum", new TextView(mContext)); } catch (Throwable ignore) {} + @Override + public void onReceive(Context context, Intent intent) {} + } - Handler mHandler = (Handler)XposedHelpers.getAdditionalInstanceField(thisObject, "myHandler"); - mHandler.removeMessages(1); - Message msg = new Message(); - msg.what = 1; - msg.obj = thisObject; - mHandler.sendMessageDelayed(msg, 1000); + private static void sendSeekBarUpdate(Context mContext, MediaController controller) { + try { + if (mContext == null) return; + String pkgName = (String)XposedHelpers.callMethod(controller, "getPackageName"); + Intent intent = new Intent(ACTION_PREFIX + "UpdateMediaPosition:" + pkgName); + MediaMetadata medaData = controller.getMetadata(); + if (medaData == null) return; + intent.putExtra(MediaMetadata.METADATA_KEY_DURATION, medaData.getLong(MediaMetadata.METADATA_KEY_DURATION)); + intent.putExtra("android.media.metadata.POSITION", controller.getPlaybackState().getPosition()); + mContext.sendBroadcast(intent); + } catch (Throwable t) { + XposedBridge.log(t); + } } - private static Object notificationPanelView = null; - public static void LockScreenShortcutHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView$MiuiDefaultLeftButton", lpparam.classLoader, "getIcon", new MethodHook() { + public static void MediaNotificationSeekBarHook() { + MethodHook hook = new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Object img = param.getResult(); - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { - Object thisObject = XposedHelpers.getSurroundingThis(param.thisObject); - Context mContext = (Context) XposedHelpers.getObjectField(thisObject, "mContext"); - boolean mDarkMode = XposedHelpers.getBooleanField(thisObject, "mDarkStyle"); - Drawable flashlightDrawable = Helpers.getModuleRes(mContext).getDrawable( - mDarkMode ? R.drawable.keyguard_bottom_flashlight_img_dark : R.drawable.keyguard_bottom_flashlight_img_light, - mContext.getTheme() - ); - XposedHelpers.setObjectField(img, "drawable", flashlightDrawable); - } else if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) - XposedHelpers.setObjectField(img, "isVisible", false); + stateHandler = new Handler(); + MediaController mController = (MediaController)XposedHelpers.callMethod(param.thisObject, "getController"); + MediaController.TransportControls mTransportControls = (MediaController.TransportControls)XposedHelpers.getObjectField(mController, "mTransportControls"); + MediaControllerReceiver mSeekToReceiver = new MediaControllerReceiver(mTransportControls) { + @Override + public void onReceive(Context context, Intent intent) { + if (transportControls == null) return; + long position = intent.getLongExtra("android.media.metadata.POSITION", 0L); + transportControls.seekTo(position); + } + }; + StateRunnable mStateRunnable = new StateRunnable((Context)param.args[0], mController) { + @Override + public void run() { + if (context != null && controller != null) try { + sendSeekBarUpdate(context, controller); + PlaybackState state = controller.getPlaybackState(); + if (state != null && state.getState() != PlaybackState.STATE_PLAYING) return; + } catch (Throwable t) { + XposedBridge.log(t); + } + super.run(); + } + }; + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSeekToReceiver", mSeekToReceiver); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mStateRunnable", mStateRunnable); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mContext", param.args[0]); } - }); + }; - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView$MiuiDefaultRightButton", lpparam.classLoader, "getIcon", new MethodHook() { + Helpers.findAndHookConstructor("android.media.session.MediaSession", null, Context.class, String.class, Bundle.class, hook); + Helpers.findAndHookMethod("android.media.session.MediaSession", null, "setActive", boolean.class, new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - Object img = param.getResult(); - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { - XposedHelpers.setObjectField(img, "isVisible", false); - return; - } + protected void before(MethodHookParam param) throws Throwable { + boolean mActive = XposedHelpers.getBooleanField(param.thisObject, "mActive"); + boolean newActive = (boolean)param.args[0]; + if (mActive == newActive) return; + + Context mContext = (Context)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mContext"); + if (mContext == null) return; - boolean opt = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image"); - if (!opt) return; - Object thisObject = XposedHelpers.getSurroundingThis(param.thisObject); - Context mContext = (Context) XposedHelpers.getObjectField(thisObject, "mContext"); - boolean mDarkMode = XposedHelpers.getBooleanField(thisObject, "mDarkStyle"); - XposedHelpers.setObjectField(img, "drawable", Helpers.getModuleRes(mContext).getDrawable( - mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, - mContext.getTheme() - )); + MediaControllerReceiver mSeekToReceiver = (MediaControllerReceiver)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSeekToReceiver"); + if (newActive) + mContext.registerReceiver(mSeekToReceiver, new IntentFilter(ACTION_PREFIX + "SeekToMediaPosition:" + mContext.getPackageName())); + else + mContext.unregisterReceiver(mSeekToReceiver); } }); - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "initTipsView", new MethodHook() { + Helpers.findAndHookMethod("android.media.session.MediaSession", null, "setPlaybackState", PlaybackState.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - boolean opt = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image"); - if (!opt) return; - boolean isLeft = (boolean) param.args[0]; - if (!isLeft) { - TextView mRightAffordanceViewTips = (TextView) XposedHelpers.getObjectField(param.thisObject, "mRightAffordanceViewTips"); - if (mRightAffordanceViewTips != null) - mRightAffordanceViewTips.setText(Helpers.getModuleRes(mRightAffordanceViewTips.getContext()).getString(R.string.system_lockscreenshortcuts_right_image_hint)); - } - } - }); - - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onFinishInflate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); - mLeftAffordanceView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); - boolean z = !(boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); - XposedHelpers.callMethod(flashlightController, "setFlashlight", z); - XposedHelpers.callMethod(param.thisObject, "updateLeftAffordanceIcon"); - return true; - } - }); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "updateLeftAffordanceIcon", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mLeftAffordanceView = XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); - Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); - boolean isOn = (boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); - XposedHelpers.callMethod(mLeftAffordanceView, "setCircleRadiusWithoutAnimation", isOn ? 66f : 0f); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onClick", View.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - View view = (View) param.args[0]; - View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); - if (view == mLeftAffordanceView) { - param.setResult(null); - } - } - }); - } + Context mContext = (Context)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mContext"); + if (mContext == null) return; + MediaController mController = (MediaController)XposedHelpers.callMethod(param.thisObject, "getController"); + if (mController == null) return; + StateRunnable mStateRunnable = (StateRunnable)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mStateRunnable"); + if (mStateRunnable == null) return; - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "launchCamera", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (GlobalActions.handleAction(mContext, "pref_key_system_lockscreenshortcuts_right", true)) { - param.setResult(null); - Object PanelInjector = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader)); - Object panelController = XposedHelpers.getObjectField(PanelInjector, "mPanelViewController"); - final View mNotificationPanelView = (View) XposedHelpers.getObjectField(PanelInjector, "mPanelView"); - mNotificationPanelView.postDelayed(new Runnable() { - @Override - public void run() { - XposedHelpers.callMethod(panelController, "resetViews", false); - } - }, 500); - } + stateHandler.removeCallbacks(mStateRunnable); + if (((PlaybackState)param.args[0]).getState() == PlaybackState.STATE_PLAYING) + stateHandler.postDelayed(mStateRunnable, 100); + else + sendSeekBarUpdate(mContext, mController); } }); + } - Helpers.hookAllMethods("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "setDarkStyle", new MethodHook() { + public static void MobileNetworkTypeHook(LoadPackageParam lpparam) { + String MobileController = Helpers.isTPlus() ? "com.android.systemui.statusbar.connectivity.MobileSignalController" : "com.android.systemui.statusbar.policy.MobileSignalController"; + Helpers.findAndHookMethod(MobileController, lpparam.classLoader, "getMobileTypeName", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image")) { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean mDarkMode = XposedHelpers.getBooleanField(param.thisObject, "mDarkStyle"); - XposedHelpers.callMethod(param.thisObject, "setPreviewImageDrawable", Helpers.getModuleRes(mContext).getDrawable(mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, mContext.getTheme())); + String net = (String)param.getResult(); + if (MainModule.mPrefs.getBoolean("system_4gtolte")) { + if ("4G".equals(net)) param.setResult("LTE"); + else if ("4G+".equals(net)) param.setResult("LTE+"); + } + else { + String mobileType = MainModule.mPrefs.getString("system_statusbar_mobile_showname", ""); + param.setResult(mobileType); } } }); + } - Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "updatePreView", new MethodHook() { + @SuppressLint("StaticFieldLeak") + private static TextView mPct = null; + private static void initPct(ViewGroup container, int source, Context context) { + Resources res = context.getResources(); + if (mPct == null) { + mPct = new TextView(container.getContext()); + mPct.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40); + mPct.setGravity(Gravity.CENTER); + float density = res.getDisplayMetrics().density; + FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); + lp.topMargin = Math.round(MainModule.mPrefs.getInt("system_showpct_top", 26) * density); + lp.gravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP; + mPct.setPadding(Math.round(20 * density), Math.round(10 * density), Math.round(18 * density), Math.round(12 * density)); + mPct.setLayoutParams(lp); + container.addView(mPct); + } + mPct.setTag(source); + int panelResId = res.getIdentifier("panel_round_corner_bg", "drawable", "com.android.systemui"); + mPct.setBackground(res.getDrawable(panelResId, context.getTheme())); + mPct.setAlpha(0.0f); + mPct.setVisibility(View.GONE); + } + + public static void BrightnessPctHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "showMirror", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - View mPreViewContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); - if ("active".equals(mPreViewContainer.getTag())) { - XposedHelpers.setFloatField(param.thisObject, "mIconCircleAlpha", 0.0f); - ((View) param.thisObject).invalidate(); + protected void after(final MethodHookParam param) throws Throwable { + ViewGroup mStatusBarWindow = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mStatusBarWindow"); + if (mStatusBarWindow == null) { + Helpers.log("BrightnessPctHook", "mStatusBarWindow is null"); + return; } + initPct(mStatusBarWindow, 1, mStatusBarWindow.getContext()); + mPct.setVisibility(View.VISIBLE); + mPct.animate().alpha(1.0f).setDuration(300).start(); } }); - Helpers.hookAllMethods("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "setPreviewImageDrawable", new MethodHook() { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "hideMirror", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - - boolean mDarkMode = XposedHelpers.getBooleanField(param.thisObject, "mDarkStyle"); - ImageView mIconView = (ImageView) XposedHelpers.getObjectField(param.thisObject, "mIconView"); - if (mIconView != null) - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image")) - mIconView.setImageDrawable(Helpers.getModuleRes(mContext).getDrawable(mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, mContext.getTheme())); - else - mIconView.setImageDrawable(mContext.getDrawable(mDarkMode ? mContext.getResources().getIdentifier("keyguard_bottom_camera_img_dark", "drawable", lpparam.packageName) : mContext.getResources().getIdentifier("keyguard_bottom_camera_img", "drawable", lpparam.packageName))); - - View mPreView = (View) XposedHelpers.getObjectField(param.thisObject, "mPreView"); - View mPreViewContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); - View mBackgroundView = (View) XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); - Paint mIconCircleStrokePaint = (Paint) XposedHelpers.getObjectField(param.thisObject, "mIconCircleStrokePaint"); - ViewOutlineProvider mPreViewOutlineProvider = (ViewOutlineProvider) XposedHelpers.getObjectField(param.thisObject, "mPreViewOutlineProvider"); - boolean result = modifyCameraImage(mContext, mPreView, mDarkMode); - if (result) param.setResult(null); - if (mPreViewContainer != null) { - mPreViewContainer.setBackgroundColor(result ? Color.TRANSPARENT : Color.BLACK); - mPreViewContainer.setOutlineProvider(result ? null : mPreViewOutlineProvider); - mPreViewContainer.setTag(result ? "active" : "inactive"); - } - if (mBackgroundView != null) - mBackgroundView.setBackgroundColor(result ? Color.TRANSPARENT : Color.BLACK); - if (mIconCircleStrokePaint != null) - mIconCircleStrokePaint.setColor(result ? Color.TRANSPARENT : Color.WHITE); + protected void after(final MethodHookParam param) throws Throwable { + if (mPct != null) mPct.setVisibility(View.GONE); } }); - Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "handleMoveDistanceChanged", new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStart", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - View mIconView = (View) XposedHelpers.getObjectField(param.thisObject, "mIconView"); - if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { - if (mIconView != null) mIconView.setVisibility(View.GONE); - param.setResult(null); - } else if (mIconView != null) mIconView.setVisibility(View.VISIBLE); + protected void before(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Object mMirror = XposedHelpers.getObjectField(param.thisObject, "mControl"); + Object controlCenterWindowViewController = XposedHelpers.getObjectField(mMirror, "controlCenterWindowViewController"); + String ClsName = controlCenterWindowViewController.getClass().getName(); + if (!ClsName.equals("ControlCenterWindowViewController")) { + controlCenterWindowViewController = XposedHelpers.callMethod(controlCenterWindowViewController, "get"); + } + Object windowView = XposedHelpers.callMethod(controlCenterWindowViewController, "getView"); + if (windowView == null) { + Helpers.log("BrightnessPctHook", "mControlPanelContentView is null"); + return; + } + initPct((ViewGroup) windowView, 2, mContext); + mPct.setVisibility(View.VISIBLE); + mPct.animate().alpha(1.0f).setDuration(300).start(); } }); - Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "startFullScreenAnim", new MethodHook() { + Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStop", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - int action = MainModule.mPrefs.getInt("system_lockscreenshortcuts_right_action", 1); - if (action <= 1) return; - AnimatorSet mAnimatorSet = (AnimatorSet) XposedHelpers.getObjectField(param.thisObject, "mAnimatorSet"); - if (mAnimatorSet == null) return; - param.setResult(null); - mAnimatorSet.pause(); - mAnimatorSet.removeAllListeners(); - mAnimatorSet.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - GlobalActions.handleAction(mContext, "pref_key_system_lockscreenshortcuts_right", true); - Object mCallBack = XposedHelpers.getObjectField(param.thisObject, "mCallBack"); - if (mCallBack != null) - XposedHelpers.callMethod(mCallBack, "onCompletedAnimationEnd"); - XposedHelpers.setBooleanField(param.thisObject, "mIsPendingStartCamera", false); - XposedHelpers.callMethod(param.thisObject, "dismiss"); - View mBackgroundView = (View) XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); - if (mBackgroundView != null) mBackgroundView.setAlpha(1.0f); - } - }); - mAnimatorSet.resume(); + protected void after(final MethodHookParam param) throws Throwable { + if (mPct != null) mPct.setVisibility(View.GONE); } }); - Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, new MethodHook() { + final Class BrightnessUtils = XposedHelpers.findClassIfExists("com.android.systemui.controlcenter.policy.BrightnessUtils", lpparam.classLoader); + Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onChanged", new MethodHook() { @Override + @SuppressLint("SetTextI18n") protected void after(final MethodHookParam param) throws Throwable { - notificationPanelView = param.thisObject; - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { - @Override - public void onChange(Uri uri) { - try { - String type = uri.getPathSegments().get(1); - String key = uri.getPathSegments().get(2); - if (!key.contains("pref_key_system_lockscreenshortcuts")) return; + int pctTag = 0; + if (mPct != null) { + pctTag = (int) mPct.getTag(); + } + if (pctTag == 0) return; + int currentLevel = (int)param.args[3]; + if (BrightnessUtils != null) { + int maxLevel = (int) XposedHelpers.getStaticObjectField(BrightnessUtils, "GAMMA_SPACE_MAX"); + mPct.setText(((currentLevel * 100) / maxLevel) + "%"); + } + } + }); + } - switch (type) { - case "string": - MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "")); - break; - case "integer": - MainModule.mPrefs.put(key, Helpers.getSharedIntPref(mContext, key, 1)); - break; - case "boolean": - MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(mContext, key, false)); - break; - } + public static void HideProximityWarningHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.server.policy.MiuiScreenOnProximityLock", lpparam.classLoader, "showHint", XC_MethodReplacement.DO_NOTHING); + Helpers.findAndHookMethod("com.android.server.policy.MiuiScreenOnProximityLock", lpparam.classLoader, "prepareHintWindow", XC_MethodReplacement.DO_NOTHING); + } - if (key.contains("pref_key_system_lockscreenshortcuts_right")) - try { - XposedHelpers.callMethod(notificationPanelView, "setCameraImage", false); - } catch (Throwable t1) { - try { - XposedHelpers.callMethod(notificationPanelView, "setCameraImage"); - } catch (Throwable t2) { - } - } - } catch (Throwable t) { - XposedBridge.log(t); - } + public static void HideLockScreenClockHook(LoadPackageParam lpparam) { + if (!Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.keyguard.clock.KeyguardClockContainer", lpparam.classLoader, "updateClock", float.class, int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = 0.0f; + } + }); + Helpers.hookAllMethods("com.android.keyguard.KeyguardVisibilityHelper", lpparam.classLoader, "setViewVisibility", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object KeyguardClockInjector = XposedHelpers.callStaticMethod(findClassIfExists("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.keyguard.injector.KeyguardClockInjector", lpparam.classLoader)); + View mKeyguardClockView = (View)XposedHelpers.callMethod(KeyguardClockInjector, "getView"); + if (mKeyguardClockView == null) { + Helpers.log("HideLockScreenClockHook", "mKeyguardClockView is null"); + return; } - }; + mKeyguardClockView.animate().cancel(); + XposedHelpers.setBooleanField(param.thisObject, "mKeyguardViewVisibilityAnimating", false); + mKeyguardClockView.setAlpha(0.0f); + mKeyguardClockView.setVisibility(View.INVISIBLE); + } + }); + } + else { + MethodHook hideClockHook = new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + View mClockFrame = (View) XposedHelpers.getObjectField(param.thisObject, "mClockFrame"); + mClockFrame.setVisibility(View.INVISIBLE); + mClockFrame = (View) XposedHelpers.getObjectField(param.thisObject, "mLargeClockFrame"); + mClockFrame.setVisibility(View.INVISIBLE); + } + }; + Helpers.hookAllMethods("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader, "setClockPlugin", hideClockHook); + Helpers.findAndHookMethod("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader, "updateClockViews", boolean.class, boolean.class, hideClockHook); + } + } + + public static void FirstVolumePressHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.server.audio.AudioService$VolumeController", lpparam.classLoader, "suppressAdjustment", int.class, int.class, boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + int streamType = (int)param.args[0]; + if (streamType != AudioManager.STREAM_MUSIC) return; + boolean isMuteAdjust = (boolean)param.args[2]; + if (isMuteAdjust) return; + Object mController = XposedHelpers.getObjectField(param.thisObject, "mController"); + if (mController == null) return; + param.setResult(false); } }); + } + + public static void DisableSystemIntegrityHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("android.util.apk.ApkSignatureVerifier", lpparam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class, XC_MethodReplacement.returnConstant(1)); + } - Helpers.findAndHookMethod("com.android.keyguard.KeyguardMoveHelper", lpparam.classLoader, "setTranslation", float.class, boolean.class, boolean.class, boolean.class, boolean.class, new MethodHook() { + public static void NoSignatureVerifyServiceHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapability", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapabilityRecover", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkSysAppCrack", XC_MethodReplacement.returnConstant(false)); + Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "compareSignatures", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - int mCurrentScreen = XposedHelpers.getIntField(param.thisObject, "mCurrentScreen"); - if (mCurrentScreen != 1) return; - if ((float) param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) - param.args[0] = 0.0f; - else if ((float) param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) - param.args[0] = 0.0f; + Object s1 = param.args[0]; + Object s2 = param.args[1]; + int ret = 0; + if (s1 == null || s2 == null) { + ret = -3; + } + param.setResult(ret); } }); + MethodHook compareHook = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object s1 = param.args[0]; + Object s2 = param.args[1]; + int ret = 0; + if (s1 == null) { + if (s2 == null) { + ret = 1; + } + else { + ret = -1; + } + } else if (s2 == null) { + ret = -2; + } + param.setResult(ret); + } + }; + Helpers.hookAllMethodsSilently("miui.util.CertificateUtils", lpparam.classLoader, "compareSignatures", compareHook); + Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", compareHook); - Helpers.findAndHookMethod("com.android.keyguard.KeyguardMoveHelper", lpparam.classLoader, "fling", float.class, boolean.class, boolean.class, new MethodHook() { + Class SignDetails = findClassIfExists("android.content.pm.SigningDetails", lpparam.classLoader); + Object signUnknown = XposedHelpers.getStaticObjectField(SignDetails, "UNKNOWN"); + Helpers.hookAllMethods(SignDetails, "checkCapability", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - int mCurrentScreen = XposedHelpers.getIntField(param.thisObject, "mCurrentScreen"); - if (mCurrentScreen != 1) return; - if ((float) param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) - param.setResult(null); - else if ((float) param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) - param.setResult(null); + if (param.thisObject == signUnknown || param.args[0] == signUnknown) param.setResult(false); + else param.setResult(true); } }); + + if (Helpers.isTPlus()) { + Helpers.hookAllConstructors("android.util.jar.StrictJarVerifier", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "signatureSchemeRollbackProtectionsEnforced", false); + } + }); + Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verifyMessageDigest", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verify", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", XC_MethodReplacement.returnConstant(false)); + Helpers.hookAllMethods("com.android.server.pm.InstallPackageHelper", lpparam.classLoader, "doesSignatureMatchForPermissions", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String packageName = (String) XposedHelpers.callMethod(param.args[1], "getPackageName"); + String sourcePackageName = (String) param.args[0]; + if (sourcePackageName.equals(packageName)) { + param.setResult(true); + } + } + }); + } } - public static void LockScreenSecureLaunchHook() { - Helpers.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new MethodHook() { - @SuppressWarnings("ConstantConditions") + public static void ScreenDimTimeHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.server.power.PowerManagerService", lpparam.classLoader, "readConfigurationLocked", new MethodHook() { + @Override protected void after(MethodHookParam param) throws Throwable { - Activity act = (Activity)param.thisObject; - if (act == null) return; - Intent intent = act.getIntent(); - if (intent == null) return; - boolean mFromSecureKeyguard = intent.getBooleanExtra("StartActivityWhenLocked", false); - boolean mStartedFromLockScreen = false; - try { - mStartedFromLockScreen = (boolean)XposedHelpers.getAdditionalInstanceField(act.getApplication(), "wasStartedFromLockScreen"); - } catch (Throwable ignore) {} - if (mFromSecureKeyguard || mStartedFromLockScreen) { - XposedHelpers.setAdditionalInstanceField(act.getApplication(), "wasStartedFromLockScreen", true); - act.setShowWhenLocked(true); - act.setInheritShowWhenLocked(true); - } + float opt = MainModule.mPrefs.getInt("system_dimtime", 0) / 100f; + XposedHelpers.setIntField(param.thisObject, "mMaximumScreenDimDurationConfig", 600000); + XposedHelpers.setFloatField(param.thisObject, "mMaximumScreenDimRatioConfig", opt); +// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); +// int minScreenOffTimeout = mContext.getResources().getInteger(mContext.getResources().getIdentifier("config_minimumScreenOffTimeout", "integer", "android")); } }); - } - - private static Handler stateHandler; - - public static class StateRunnable implements Runnable { - Context context; - MediaController controller; - StateRunnable(Context ctx, MediaController ctrl) { - context = ctx; - controller = ctrl; - } - - @Override - public void run() { - try { - if (stateHandler != null) stateHandler.postDelayed(this, 1000); - } catch (Throwable t) { - XposedBridge.log(t); +// Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "getScreenOffTimeoutLocked", new MethodHook() { +// @Override +// protected void after(MethodHookParam param) throws Throwable { +// //XposedBridge.log("getScreenOffTimeoutLocked (mSleepTimeoutSetting): " + param.args[0]); +// //XposedBridge.log("mMaximumScreenOffTimeoutFromDeviceAdmin: " + XposedHelpers.getLongField(param.thisObject, "mMaximumScreenOffTimeoutFromDeviceAdmin")); +// XposedBridge.log("mUserActivityTimeoutOverrideFromWindowManager: " + XposedHelpers.getLongField(param.thisObject, "mUserActivityTimeoutOverrideFromWindowManager")); +// } +// }); +// +// Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "updateUserActivitySummaryLocked", new MethodHook() { +// @Override +// protected void after(MethodHookParam param) throws Throwable { +// if ((int)param.args[1] == 1) return; +// XposedBridge.log("updateUserActivitySummaryLocked: " + param.args[0] + ", " + param.args[1]); +// } +// }); + } + + public static void NoOverscrollHook() { + Helpers.findAndHookMethod("android.widget.AbsListView", null, "initAbsListView", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + ((AbsListView)param.thisObject).setOverScrollMode(View.OVER_SCROLL_NEVER); } - } + }); } - public static class SeekBarReceiver extends BroadcastReceiver { - View parent; - TextView posDur; - SeekBar seekBar; + public static void NoOverscrollAppHook(LoadPackageParam lpparam) { + MethodHook hookParam = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = false; + } + }; - SeekBarReceiver(View view, SeekBar sBar, TextView pos) { - parent = view; - posDur = pos; - seekBar = sBar; + Class sblCls = findClassIfExists("miuix.springback.view.SpringBackLayout", lpparam.classLoader); + if (sblCls != null) { + Helpers.hookAllConstructors(sblCls, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + try { + XposedHelpers.callMethod(param.thisObject, "setSpringBackEnable", false); + } catch (Throwable t) { + try { XposedHelpers.setBooleanField(param.thisObject, "mSpringBackEnable", false); } catch (Throwable ignore) {} + } + } + }); + //noinspection ResultOfMethodCallIgnored + Helpers.findAndHookMethodSilently(sblCls, "setSpringBackEnable", boolean.class, hookParam); } - @Override - public void onReceive(Context context, Intent intent) {} + Class rrvCls = findClassIfExists("androidx.recyclerview.widget.RemixRecyclerView", lpparam.classLoader); + if (rrvCls != null) { + Helpers.hookAllConstructors(rrvCls, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + ((View)param.thisObject).setOverScrollMode(View.OVER_SCROLL_NEVER); + try { + XposedHelpers.callMethod(param.thisObject, "setSpringEnabled", false); + } catch (Throwable t) { + try { XposedHelpers.setBooleanField(param.thisObject, "mSpringEnabled", false); } catch (Throwable ignore) {} + } + } + }); + //noinspection ResultOfMethodCallIgnored + Helpers.findAndHookMethodSilently(rrvCls, "setSpringEnabled", boolean.class, hookParam); + } } - public static class MediaControllerReceiver extends BroadcastReceiver { - MediaController.TransportControls transportControls; - - MediaControllerReceiver(MediaController.TransportControls transport) { - transportControls = transport; - } + public static void RemoveSecureHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.server.wm.WindowState", lpparam.classLoader, "isSecureLocked", XC_MethodReplacement.returnConstant(false)); + } - @Override - public void onReceive(Context context, Intent intent) {} + public static void RemoveActStartConfirmHook(LoadPackageParam lpparam) { + Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkAllowStartActivity", XC_MethodReplacement.returnConstant(true)); } - private static void sendSeekBarUpdate(Context mContext, MediaController controller) { - try { - if (mContext == null) return; - String pkgName = (String)XposedHelpers.callMethod(controller, "getPackageName"); - Intent intent = new Intent(ACTION_PREFIX + "UpdateMediaPosition:" + pkgName); - MediaMetadata medaData = controller.getMetadata(); - if (medaData == null) return; - intent.putExtra(MediaMetadata.METADATA_KEY_DURATION, medaData.getLong(MediaMetadata.METADATA_KEY_DURATION)); - intent.putExtra("android.media.metadata.POSITION", controller.getPlaybackState().getPosition()); - mContext.sendBroadcast(intent); - } catch (Throwable t) { - XposedBridge.log(t); - } + public static void AllowAllKeyguardHook(LoadPackageParam lpparam) { + //noinspection ResultOfMethodCallIgnored + Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.notification.MiuiNotificationCompat", lpparam.classLoader, "isEnableKeyguard", Notification.class, XC_MethodReplacement.returnConstant(true)); } - public static void MediaNotificationSeekBarHook() { - MethodHook hook = new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - stateHandler = new Handler(); - MediaController mController = (MediaController)XposedHelpers.callMethod(param.thisObject, "getController"); - MediaController.TransportControls mTransportControls = (MediaController.TransportControls)XposedHelpers.getObjectField(mController, "mTransportControls"); - MediaControllerReceiver mSeekToReceiver = new MediaControllerReceiver(mTransportControls) { - @Override - public void onReceive(Context context, Intent intent) { - if (transportControls == null) return; - long position = intent.getLongExtra("android.media.metadata.POSITION", 0L); - transportControls.seekTo(position); - } - }; - StateRunnable mStateRunnable = new StateRunnable((Context)param.args[0], mController) { - @Override - public void run() { - if (context != null && controller != null) try { - sendSeekBarUpdate(context, controller); - PlaybackState state = controller.getPlaybackState(); - if (state != null && state.getState() != PlaybackState.STATE_PLAYING) return; - } catch (Throwable t) { - XposedBridge.log(t); - } - super.run(); - } - }; - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSeekToReceiver", mSeekToReceiver); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mStateRunnable", mStateRunnable); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mContext", param.args[0]); + public static void AllowAllKeyguardSysHook() { + Helpers.findAndHookMethod(MiuiNotification.class, "setEnableKeyguard", boolean.class, new MethodHook() { + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = true; } - }; + }); - Helpers.findAndHookConstructor("android.media.session.MediaSession", null, Context.class, String.class, Bundle.class, hook); - Helpers.findAndHookMethod("android.media.session.MediaSession", null, "setActive", boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - boolean mActive = XposedHelpers.getBooleanField(param.thisObject, "mActive"); - boolean newActive = (boolean)param.args[0]; - if (mActive == newActive) return; + Helpers.findAndHookMethod(MiuiNotification.class, "isEnableKeyguard", XC_MethodReplacement.returnConstant(true)); + } - Context mContext = (Context)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mContext"); - if (mContext == null) return; + public static void AllowAllFloatHook(LoadPackageParam lpparam) { + //noinspection ResultOfMethodCallIgnored + Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.notification.MiuiNotificationCompat", lpparam.classLoader, "isEnableFloat", Notification.class, XC_MethodReplacement.returnConstant(true)); + } - MediaControllerReceiver mSeekToReceiver = (MediaControllerReceiver)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSeekToReceiver"); - if (newActive) - mContext.registerReceiver(mSeekToReceiver, new IntentFilter(ACTION_PREFIX + "SeekToMediaPosition:" + mContext.getPackageName())); - else - mContext.unregisterReceiver(mSeekToReceiver); + public static void AllowAllFloatSysHook() { + Helpers.findAndHookMethod(MiuiNotification.class, "setEnableFloat", boolean.class, new MethodHook() { + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = true; } }); - Helpers.findAndHookMethod("android.media.session.MediaSession", null, "setPlaybackState", PlaybackState.class, new MethodHook() { + Helpers.findAndHookMethod(MiuiNotification.class, "isEnableFloat", XC_MethodReplacement.returnConstant(true)); + } + + public static void AllowDirectReplyHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "setLockScreenAllowRemoteInput", boolean.class, new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mContext"); - if (mContext == null) return; - MediaController mController = (MediaController)XposedHelpers.callMethod(param.thisObject, "getController"); - if (mController == null) return; - StateRunnable mStateRunnable = (StateRunnable)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mStateRunnable"); - if (mStateRunnable == null) return; + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = true; + } + }); + } - stateHandler.removeCallbacks(mStateRunnable); - if (((PlaybackState)param.args[0]).getState() == PlaybackState.STATE_PLAYING) - stateHandler.postDelayed(mStateRunnable, 100); - else - sendSeekBarUpdate(mContext, mController); + public static void HideQSHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "onStateChanged", int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object mNotificationPanel = XposedHelpers.getObjectField(param.thisObject, "mQSContainer"); + if ((int)param.args[0] == 1) { + XposedHelpers.callMethod(mNotificationPanel, "setShowQSPanel", false); + } else { + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + XposedHelpers.callMethod(mNotificationPanel, "setShowQSPanel", true); + } + }, 300); + } } }); } - public static void MobileNetworkTypeHook(LoadPackageParam lpparam) { - String MobileController = Helpers.isTPlus() ? "com.android.systemui.statusbar.connectivity.MobileSignalController" : "com.android.systemui.statusbar.policy.MobileSignalController"; - Helpers.findAndHookMethod(MobileController, lpparam.classLoader, "getMobileTypeName", int.class, new MethodHook() { + public static void LockScreenTimeoutHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarWindowManager", lpparam.classLoader, "applyUserActivityTimeout", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - String net = (String)param.getResult(); - if (MainModule.mPrefs.getBoolean("system_4gtolte")) { - if ("4G".equals(net)) param.setResult("LTE"); - else if ("4G+".equals(net)) param.setResult("LTE+"); - } - else { - String mobileType = MainModule.mPrefs.getString("system_statusbar_mobile_showname", ""); - param.setResult(mobileType); - } + Object mLpChanged = XposedHelpers.getObjectField(param.thisObject, "mLpChanged"); + if (mLpChanged == null) return; + long userActivityTimeout = XposedHelpers.getLongField(mLpChanged, "userActivityTimeout"); + if (userActivityTimeout > 0) + XposedHelpers.setLongField(mLpChanged, "userActivityTimeout", MainModule.mPrefs.getInt("system_lstimeout", 9) * 1000L); } }); } - private static TextView createBatteryDetailView(Context mContext, LinearLayout.LayoutParams lp) { - TextView batteryView = (TextView) LayoutInflater.from(mContext).inflate(statusbarTextIconLayoutResId, null); - XposedHelpers.setObjectField(batteryView, "mVisibilityByDisableInfo", 0); - XposedHelpers.setObjectField(batteryView, "mVisibleByController", true); - XposedHelpers.setObjectField(batteryView, "mShown", true); - XposedHelpers.setAdditionalInstanceField(batteryView, "mCustomSlot", "battery_detail"); - Resources res = mContext.getResources(); - int styleId = res.getIdentifier("TextAppearance.StatusBar.Clock", "style", "com.android.systemui"); - batteryView.setTextAppearance(styleId); - float fontSize = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_fontsize", 16) * 0.5f; - int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); - if (opt == 1 && MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_singlerow")) { - batteryView.setLineSpacing(0, fontSize > 8.5f ? 0.85f : 0.9f); - batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - } - batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize); - if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_bold")) { - batteryView.setTypeface(Typeface.DEFAULT_BOLD); - } - int leftMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_leftmargin", 8); - leftMargin = (int)TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - leftMargin * 0.5f, - res.getDisplayMetrics() - ); - int rightMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_rightmargin", 8); - rightMargin = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - rightMargin * 0.5f, - res.getDisplayMetrics() - ); - batteryView.setPaddingRelative(leftMargin, 0, rightMargin, 0); + private static final SimpleDateFormat formatter = new SimpleDateFormat("H:m", Locale.ENGLISH); + public static void MuffledVibrationHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.server.vibrator.VibratorManagerService", lpparam.classLoader, "systemReady", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Handler mHandler = new Handler(mContext.getMainLooper()); + new Helpers.SharedPrefObserver(mContext, mHandler) { + @Override + public void onChange(Uri uri) { + try { + String key = uri.getPathSegments().get(2); + if (key.contains("pref_key_system_vibration_amp_")) MainModule.mPrefs.put(key, Helpers.getSharedIntPref(mContext, key, 100)); + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }; + } + }); - int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_verticaloffset", 8); - if (verticalOffset != 8) { - float marginTop = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - (verticalOffset - 8) * 0.5f, - res.getDisplayMetrics() - ); - lp.topMargin = (int) (marginTop); - } - batteryView.setLayoutParams(lp); - return batteryView; - } - static final ArrayList mBatteryDetailViews = new ArrayList(); - - private static void updateTempAndCurrent(Class ChargeUtilsClass) { - Handler handler = new Handler(Looper.getMainLooper()); - Runnable refreshRunner = new Runnable() { - @Override - public void run() { - String batteryInfo = ""; - FileInputStream fis = null; - Properties props = null; - boolean showInfo = true; - if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_incharge") && ChargeUtilsClass != null) { - Object batteryStatus = Helpers.getStaticObjectFieldSilently(ChargeUtilsClass, "sBatteryStatus"); - if (batteryStatus == null) { - showInfo = false; - } - else { - showInfo = (boolean) XposedHelpers.callMethod(batteryStatus, "isCharging"); - } - } - if (showInfo) { - try { - fis = new FileInputStream("/sys/class/power_supply/battery/uevent"); - props = new Properties(); - props.load(fis); - } - catch (Throwable ign) {} - finally { - try { - fis.close(); - } - catch (Throwable ign) {} - } - if (props != null) { - int tempVal = Integer.parseInt(props.getProperty("POWER_SUPPLY_TEMP")); - int currVal = -1 * Math.round(Integer.parseInt(props.getProperty("POWER_SUPPLY_CURRENT_NOW")) / 1000); - if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_positive")) { - currVal = Math.abs(currVal); - } - int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); - String simpleTempVal = tempVal % 10 == 0 ? (tempVal / 10 + "") : (tempVal / 10f + ""); - if (opt == 1) { - String splitChar = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_singlerow") - ? " " : "\n"; - batteryInfo = simpleTempVal + "℃" + splitChar + currVal + "mA"; - if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_reverseorder")) { - batteryInfo = currVal + "mA" + splitChar + simpleTempVal + "℃"; - } - } - else if (opt == 2) { - batteryInfo = simpleTempVal + "℃"; - } - else { - batteryInfo = currVal + "mA"; - } - } - } - for (TextView tv:mBatteryDetailViews) { - XposedHelpers.callMethod(tv, "setBlocked", !showInfo); - XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); - } - handler.postDelayed(this, 1500); - } - }; - handler.post(refreshRunner); - } - private static int statusbarTextIconLayoutResId = 0; - public static void setupStatusBar(LoadPackageParam lpparam) { - statusbarTextIconLayoutResId = MainModule.resHooks.addResource("statusbar_text_icon", R.layout.statusbar_text_icon); - if (MainModule.mPrefs.getBoolean("system_statusbar_topmargin")) { - int topMargin = MainModule.mPrefs.getInt("system_statusbar_topmargin_val", 1); - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", topMargin); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_horizmargin")) { - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); - } - if (MainModule.mPrefs.getBoolean("system_cc_enable_style_switch")) { - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "integer", "force_use_control_panel", 0); - } - if (MainModule.mPrefs.getBoolean("system_qs_force_systemfonts")) { - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "bool", "header_big_time_use_system_font", true); - } - } - public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { - Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); - Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); - Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); - Class StatusBarIconHolder = XposedHelpers.findClass("com.android.systemui.statusbar.phone.StatusBarIconHolder", lpparam.classLoader); - boolean atRight = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright"); - if (atRight && !MainModule.mPrefs.getBoolean("system_statusbar_dualrows")) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - Object iconController = XposedHelpers.getObjectField(param.thisObject, "mStatusBarIconController"); - int slotIndex = (int) XposedHelpers.callMethod(iconController, "getSlotIndex", "battery_detail"); - Object iconHolder = XposedHelpers.callMethod(iconController, "getIcon", slotIndex, 0); - if (iconHolder == null) { - iconHolder = XposedHelpers.newInstance(StatusBarIconHolder); - XposedHelpers.setObjectField(iconHolder, "mType", 91); - XposedHelpers.callMethod(iconController, "setIcon", slotIndex, iconHolder); - } - if (!isHooked) { - isHooked = true; - updateTempAndCurrent(ChargeUtilsClass); - } - } - }); + Helpers.hookAllMethods("com.android.server.VibratorService", lpparam.classLoader, "doVibratorOn", new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + float ratio_ringer = MainModule.mPrefs.getInt("system_vibration_amp_ringer", 100) / 100f; + float ratio_notif = MainModule.mPrefs.getInt("system_vibration_amp_notif", 100) / 100f; + float ratio_other = MainModule.mPrefs.getInt("system_vibration_amp_other", 100) / 100f; - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarIconController$IconManager", lpparam.classLoader, "addHolder", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args.length != 4) return; - Object iconHolder = param.args[3]; - int type = (int) XposedHelpers.callMethod(iconHolder, "getType"); - if (type == 91) { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) XposedHelpers.callMethod(param.thisObject, "onCreateLayoutParams"); - TextView batteryView = createBatteryDetailView(mContext, lp); - int i = (int) param.args[0]; - ViewGroup mGroup = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mGroup"); - mGroup.addView(batteryView, i); - mBatteryDetailViews.add(batteryView); - param.setResult(batteryView); - } - } - }); - Class NetworkSpeedViewClass = XposedHelpers.findClass("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader); - Helpers.findAndHookMethod(NetworkSpeedViewClass, "getSlot", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object customSlot = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomSlot"); - if (customSlot != null) { - param.setResult(customSlot); - } - } - }); - } - else if (!atRight) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getContext"); - TextView mSplitter = (TextView) XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedSplitter"); - ViewGroup batteryViewContainer = (ViewGroup) mSplitter.getParent(); - int bvIndex = batteryViewContainer.indexOfChild(mSplitter); - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSplitter.getLayoutParams(); - TextView batteryView = createBatteryDetailView(mContext, lp); - batteryViewContainer.addView(batteryView, bvIndex + 1); - mBatteryDetailViews.add(batteryView); - Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); - XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mBatteryView", batteryView); - if (!isHooked) { - isHooked = true; - updateTempAndCurrent(ChargeUtilsClass); - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showClock", boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); - if (bv != null) { - XposedHelpers.callMethod(bv, "setVisibilityByController", true); - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "hideClockInternal", int.class, boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); - if (bv != null) { - XposedHelpers.callMethod(bv, "setVisibilityByController", false); - } + boolean isRingtone = false; + boolean isNotification = false; + Object mCurrentVibration = XposedHelpers.getObjectField(param.thisObject, "mCurrentVibration"); + if (mCurrentVibration != null) try { + isRingtone = (boolean)XposedHelpers.callMethod(mCurrentVibration, "isRingtone"); + isNotification = (boolean)XposedHelpers.callMethod(mCurrentVibration, "isNotification"); + } catch (Throwable t) { + int mUsageHint = XposedHelpers.getIntField(mCurrentVibration, "mUsageHint"); + isRingtone = mUsageHint == 6; + isNotification = mUsageHint == 5 || mUsageHint == 7 || mUsageHint == 8 || mUsageHint == 9; } - }); - } - } - public static void StatusBarIconsPositionAdjustHook(LoadPackageParam lpparam, boolean moveRight) { - boolean swapWifiSignal = MainModule.mPrefs.getBoolean("system_statusbaricons_swap_wifi_mobile"); - boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); - String[] signalIcons; - if (!swapWifiSignal) { - signalIcons = new String[]{"no_sim", "mobile", "demo_mobile", "airplane", "hotspot", "slave_wifi", "wifi", "demo_wifi"}; - } - else { - signalIcons = new String[]{"hotspot", "slave_wifi", "wifi", "demo_wifi", "no_sim", "mobile", "demo_mobile", "airplane"}; - } - ArrayList signalRelatedIcons = new ArrayList(Arrays.asList(signalIcons)); - if (moveRight) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String slot = (String) param.args[0]; - if (("alarm_clock".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) - || ("volume".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) - || ("zen".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) - || ("nfc".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) - || ("headset".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) - ) { - param.args[1] = false; - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - private boolean isHooked = false; + float ratio; + if (isRingtone) ratio = ratio_ringer; + else if (isNotification) ratio = ratio_notif; + else ratio = ratio_other; + if (ratio == 1.0f) return; - @Override - protected void after(MethodHookParam param) throws Throwable { - if (!isHooked) { - isHooked = true; - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - Class MiuiEndIconManager = findClass("com.android.systemui.statusbar.phone.MiuiEndIconManager", lpparam.classLoader); - Object blockList = Helpers.getStaticObjectFieldSilently(MiuiEndIconManager, "RIGHT_BLOCK_LIST"); - ArrayList rightBlockList; - Resources res = mContext.getResources(); - if (blockList != null) { - rightBlockList = (ArrayList) blockList; - } - else { - int blockResId = res.getIdentifier("config_drip_right_block_statusBarIcons", "array", lpparam.packageName); - rightBlockList = new ArrayList(Arrays.asList(res.getStringArray(blockResId))); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright")) { - rightBlockList.remove("network_speed"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) { - rightBlockList.remove("alarm_clock"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) { - rightBlockList.remove("volume"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) { - rightBlockList.remove("zen"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_btbattery_atright")) { - rightBlockList.remove("bluetooth_handsfree_battery"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) { - rightBlockList.remove("nfc"); - } - if (MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) { - rightBlockList.remove("headset"); - } - if (blockList != null) { - XposedHelpers.setStaticObjectField(MiuiEndIconManager, "RIGHT_BLOCK_LIST", rightBlockList); - } - else { - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "array", "config_drip_right_block_statusBarIcons", rightBlockList.toArray(new String[0])); - } - } - } - }); - } - ArrayList dripLeftIcons = new ArrayList(); - if (swapWifiSignal || moveSignalLeft) { - Helpers.findAndHookConstructor("com.android.systemui.statusbar.phone.StatusBarIconList", lpparam.classLoader, String[].class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - boolean isRightController = "StatusBarIconControllerImpl".equals(param.thisObject.getClass().getSimpleName()); - ArrayList allStatusIcons = new ArrayList(Arrays.asList((String[]) param.args[0])); - if (isRightController) { - int startIndex = allStatusIcons.indexOf("no_sim"); - int endIndex = allStatusIcons.indexOf("demo_wifi") + 1; - List removedIcons = allStatusIcons.subList(startIndex, endIndex); - removedIcons.clear(); - if (!moveSignalLeft) { - startIndex = allStatusIcons.indexOf("ethernet"); - allStatusIcons.addAll(startIndex + 1, signalRelatedIcons); - } - param.args[0] = allStatusIcons.toArray(new String[0]); - } - else if (moveSignalLeft) { - dripLeftIcons.addAll(allStatusIcons); - allStatusIcons.addAll(0, signalRelatedIcons); - param.args[0] = allStatusIcons.toArray(new String[0]); - } - } - }); - } + String key = "system_vibration_amp_period"; + int start_hour = MainModule.mPrefs.getInt(key + "_start_hour", 0); + int start_minute = MainModule.mPrefs.getInt(key + "_start_minute", 0); + int end_hour = MainModule.mPrefs.getInt(key + "_end_hour", 0); + int end_minute = MainModule.mPrefs.getInt(key + "_end_minute", 0); - if (moveSignalLeft) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiStatusBarSignalPolicy", lpparam.classLoader, "initMiuiSlot", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); - XposedHelpers.setObjectField(param.thisObject, "mIconController", dripLeftController); - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); - Object mDripIconManager = XposedHelpers.getObjectField(param.thisObject, "mDripLeftDarkIconManager"); - ArrayList blockList = new ArrayList(); - int mCurrentStatusBarType = (int) XposedHelpers.getAdditionalInstanceField(dripLeftController, "mCurrentStatusBarType"); - if (mCurrentStatusBarType != 1) { - blockList.addAll(dripLeftIcons); - } - XposedHelpers.callMethod(mDripIconManager, "setBlockList", blockList); - XposedHelpers.callMethod(dripLeftController, "refreshIconGroup", mDripIconManager); - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "setStatusBarType", int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - int mCurrentStatusBarType = XposedHelpers.getIntField(param.thisObject, "mCurrentStatusBarType"); - Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); - XposedHelpers.setAdditionalInstanceField(dripLeftController, "mCurrentStatusBarType", mCurrentStatusBarType); - } - }); - } + formatter.setTimeZone(TimeZone.getDefault()); + Date start = formatter.parse(start_hour + ":" + start_minute); + Date end = formatter.parse(end_hour + ":" + end_minute); + Date now = formatter.parse(formatter.format(new Date())); - boolean netspeedRight = MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright"); - if (moveSignalLeft || netspeedRight) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); - if (mCurrentStatusBarType == 1) { - if (netspeedRight) { - Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); - XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); - } - } - else { - boolean dualRows = MainModule.mPrefs.getBoolean("system_statusbar_dualrows"); - if (moveSignalLeft && !dualRows) { - View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); - mDripStatusBarLeftStatusIconArea.setVisibility(View.VISIBLE); - } - } - } - }); - } + boolean insidePeriod = start.before(end) ? now.after(start) && now.before(end) : now.before(end) || now.after(start); + if (!insidePeriod) return; - if (netspeedRight) { - Helpers.hookAllMethods("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "setDripNetworkSpeedView", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = null; - } - }); - } + boolean mSupportsAmplitudeControl = false; + try { + mSupportsAmplitudeControl = XposedHelpers.getBooleanField(param.thisObject, "mSupportsAmplitudeControl"); + } catch (Throwable ignored) {} + + if (mSupportsAmplitudeControl) + param.args[1] = Math.round(((int)param.args[1] == -1 ? XposedHelpers.getIntField(param.thisObject, "mDefaultVibrationAmplitude") : (int)param.args[1]) * ratio); + else + param.args[0] = Math.max(3, (long)Math.round((long)param.args[0] * ratio)); + } + }); + +// if (Helpers.isNougat()) +// Helpers.hookAllMethods("com.android.server.VibratorService", lpparam.classLoader, "vibratePattern", new MethodHook() { +// @Override +// protected void before(final MethodHookParam param) throws Throwable { +// +// } +// }); } - public static void StatusBarClockAtRightHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + public static void ResizableWidgetsHook() { + Helpers.findAndHookMethod("android.appwidget.AppWidgetHostView", null, "getAppWidgetInfo", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - FrameLayout sbView = (FrameLayout) param.thisObject; - Context mContext = sbView.getContext(); - Resources res = mContext.getResources(); - TextView mClockView = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMiuiClock"); - ((ViewGroup)mClockView.getParent()).removeView(mClockView); - int contentId = res.getIdentifier("status_bar_contents", "id", lpparam.packageName); - LinearLayout mContentsContainer = sbView.findViewById(contentId); - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); - mContentsContainer.addView(mClockView, lp); + AppWidgetProviderInfo widgetInfo = (AppWidgetProviderInfo)param.getResult(); + if (widgetInfo == null) return; + widgetInfo.resizeMode = AppWidgetProviderInfo.RESIZE_VERTICAL | AppWidgetProviderInfo.RESIZE_HORIZONTAL; + widgetInfo.minHeight = 0; + widgetInfo.minWidth = 0; + widgetInfo.minResizeHeight = 0; + widgetInfo.minResizeWidth = 0; + param.setResult(widgetInfo); } }); - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { + Helpers.findAndHookMethod("android.appwidget.AppWidgetManager", null, "getAppWidgetInfo", int.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); - if (mCurrentStatusBarType == 0) { - View mSystemIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mSystemIconArea"); - LinearLayout.LayoutParams mSystemIconAreaLp = (LinearLayout.LayoutParams) mSystemIconArea.getLayoutParams(); - mSystemIconAreaLp.width = 0; - mSystemIconAreaLp.weight = 1.0f; - } + AppWidgetProviderInfo widgetInfo = (AppWidgetProviderInfo)param.getResult(); + if (widgetInfo == null) return; + widgetInfo.resizeMode = AppWidgetProviderInfo.RESIZE_VERTICAL | AppWidgetProviderInfo.RESIZE_HORIZONTAL; + widgetInfo.minHeight = 0; + widgetInfo.minWidth = 0; + widgetInfo.minResizeHeight = 0; + widgetInfo.minResizeWidth = 0; + param.setResult(widgetInfo); } }); } - @SuppressLint("StaticFieldLeak") - private static TextView mPct = null; - private static void initPct(ViewGroup container, int source, Context context) { - Resources res = context.getResources(); - if (mPct == null) { - mPct = new TextView(container.getContext()); - mPct.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40); - mPct.setGravity(Gravity.CENTER); - float density = res.getDisplayMetrics().density; - FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); - lp.topMargin = Math.round(MainModule.mPrefs.getInt("system_showpct_top", 26) * density); - lp.gravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP; - mPct.setPadding(Math.round(20 * density), Math.round(10 * density), Math.round(18 * density), Math.round(12 * density)); - mPct.setLayoutParams(lp); - container.addView(mPct); - } - mPct.setTag(source); - int panelResId = res.getIdentifier("panel_round_corner_bg", "drawable", "com.android.systemui"); - mPct.setBackground(res.getDrawable(panelResId, context.getTheme())); - mPct.setAlpha(0.0f); - mPct.setVisibility(View.GONE); - } - - public static void BrightnessPctHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "showMirror", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - ViewGroup mStatusBarWindow = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mStatusBarWindow"); - if (mStatusBarWindow == null) { - Helpers.log("BrightnessPctHook", "mStatusBarWindow is null"); - return; - } - initPct(mStatusBarWindow, 1, mStatusBarWindow.getContext()); - mPct.setVisibility(View.VISIBLE); - mPct.animate().alpha(1.0f).setDuration(300).start(); + private static void hookUpdateTime(Object thisObject, boolean isSingle) { + try { + TextView mCurrentDate = null; + TextView mCurrentDateLarge = null; + if (isSingle) { + try { mCurrentDate = (TextView)XposedHelpers.getObjectField(thisObject, "mCurrentDate"); } catch (Throwable ignore) {} + try { mCurrentDateLarge = (TextView)XposedHelpers.getObjectField(thisObject, "mCurrentDateLarge"); } catch (Throwable ignore) {} } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BrightnessMirrorController", lpparam.classLoader, "hideMirror", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - if (mPct != null) mPct.setVisibility(View.GONE); + else { + try { mCurrentDate = (TextView)XposedHelpers.getObjectField(thisObject, "mLocalDate"); } catch (Throwable ignore) {} } - }); + if (mCurrentDate == null && mCurrentDateLarge == null) return; + Context mContext = mCurrentDate != null ? mCurrentDate.getContext() : mCurrentDateLarge.getContext(); - Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStart", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Object mMirror = XposedHelpers.getObjectField(param.thisObject, "mControl"); - Object controlCenterWindowViewController = XposedHelpers.getObjectField(mMirror, "controlCenterWindowViewController"); - String ClsName = controlCenterWindowViewController.getClass().getName(); - if (!ClsName.equals("ControlCenterWindowViewController")) { - controlCenterWindowViewController = XposedHelpers.callMethod(controlCenterWindowViewController, "get"); - } - Object windowView = XposedHelpers.callMethod(controlCenterWindowViewController, "getView"); - if (windowView == null) { - Helpers.log("BrightnessPctHook", "mControlPanelContentView is null"); - return; - } - initPct((ViewGroup) windowView, 2, mContext); - mPct.setVisibility(View.VISIBLE); - mPct.animate().alpha(1.0f).setDuration(300).start(); - } - }); - - Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onStop", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - if (mPct != null) mPct.setVisibility(View.GONE); - } - }); - - final Class BrightnessUtils = XposedHelpers.findClassIfExists("com.android.systemui.controlcenter.policy.BrightnessUtils", lpparam.classLoader); - Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.MiuiBrightnessController", lpparam.classLoader, "onChanged", new MethodHook() { - @Override - @SuppressLint("SetTextI18n") - protected void after(final MethodHookParam param) throws Throwable { - int pctTag = 0; - if (mPct != null) { - pctTag = (int) mPct.getTag(); - } - if (pctTag == 0) return; - int currentLevel = (int)param.args[3]; - if (BrightnessUtils != null) { - int maxLevel = (int) XposedHelpers.getStaticObjectField(BrightnessUtils, "GAMMA_SPACE_MAX"); - mPct.setText(((currentLevel * 100) / maxLevel) + "%"); - } - } - }); - } - - public static void HideProximityWarningHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.policy.MiuiScreenOnProximityLock", lpparam.classLoader, "showHint", XC_MethodReplacement.DO_NOTHING); - Helpers.findAndHookMethod("com.android.server.policy.MiuiScreenOnProximityLock", lpparam.classLoader, "prepareHintWindow", XC_MethodReplacement.DO_NOTHING); - } - - public static void HideLockScreenClockHook(LoadPackageParam lpparam) { - if (!Helpers.isTPlus()) { - Helpers.findAndHookMethod("com.android.keyguard.clock.KeyguardClockContainer", lpparam.classLoader, "updateClock", float.class, int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = 0.0f; - } - }); - Helpers.hookAllMethods("com.android.keyguard.KeyguardVisibilityHelper", lpparam.classLoader, "setViewVisibility", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object KeyguardClockInjector = XposedHelpers.callStaticMethod(findClassIfExists("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.keyguard.injector.KeyguardClockInjector", lpparam.classLoader)); - View mKeyguardClockView = (View)XposedHelpers.callMethod(KeyguardClockInjector, "getView"); - if (mKeyguardClockView == null) { - Helpers.log("HideLockScreenClockHook", "mKeyguardClockView is null"); - return; - } - mKeyguardClockView.animate().cancel(); - XposedHelpers.setBooleanField(param.thisObject, "mKeyguardViewVisibilityAnimating", false); - mKeyguardClockView.setAlpha(0.0f); - mKeyguardClockView.setVisibility(View.INVISIBLE); - } - }); - } - else { - MethodHook hideClockHook = new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - View mClockFrame = (View) XposedHelpers.getObjectField(param.thisObject, "mClockFrame"); - mClockFrame.setVisibility(4); - mClockFrame = (View) XposedHelpers.getObjectField(param.thisObject, "mLargeClockFrame"); - mClockFrame.setVisibility(4); - } - }; - Helpers.hookAllMethods("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader, "setClockPlugin", hideClockHook); - Helpers.findAndHookMethod("com.android.keyguard.KeyguardClockSwitch", lpparam.classLoader, "updateClockViews", boolean.class, boolean.class, hideClockHook); - } - } - - public static void FirstVolumePressHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.audio.AudioService$VolumeController", lpparam.classLoader, "suppressAdjustment", int.class, int.class, boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - int streamType = (int)param.args[0]; - if (streamType != AudioManager.STREAM_MUSIC) return; - boolean isMuteAdjust = (boolean)param.args[2]; - if (isMuteAdjust) return; - Object mController = XposedHelpers.getObjectField(param.thisObject, "mController"); - if (mController == null) return; - param.setResult(false); - } - }); - } - - public static void DisableSystemIntegrityHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("android.util.apk.ApkSignatureVerifier", lpparam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class, XC_MethodReplacement.returnConstant(1)); - } - - public static void NoSignatureVerifyServiceHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapability", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("android.content.pm.PackageParser.SigningDetails", lpparam.classLoader, "checkCapabilityRecover", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkSysAppCrack", XC_MethodReplacement.returnConstant(false)); - Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "compareSignatures", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object s1 = param.args[0]; - Object s2 = param.args[1]; - int ret = 0; - if (s1 == null || s2 == null) { - ret = -3; - } - param.setResult(ret); - } - }); - MethodHook compareHook = new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object s1 = param.args[0]; - Object s2 = param.args[1]; - int ret = 0; - if (s1 == null) { - if (s2 == null) { - ret = 1; - } - else { - ret = -1; - } - } else if (s2 == null) { - ret = -2; - } - param.setResult(ret); - } - }; - Helpers.hookAllMethodsSilently("miui.util.CertificateUtils", lpparam.classLoader, "compareSignatures", compareHook); - Helpers.hookAllMethodsSilently("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "compareSignatures", compareHook); - - Class SignDetails = findClassIfExists("android.content.pm.SigningDetails", lpparam.classLoader); - Object signUnknown = XposedHelpers.getStaticObjectField(SignDetails, "UNKNOWN"); - Helpers.hookAllMethods(SignDetails, "checkCapability", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.thisObject == signUnknown || param.args[0] == signUnknown) param.setResult(false); - else param.setResult(true); - } - }); - - if (Helpers.isTPlus()) { - Helpers.hookAllConstructors("android.util.jar.StrictJarVerifier", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setObjectField(param.thisObject, "signatureSchemeRollbackProtectionsEnforced", false); - } - }); - Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verifyMessageDigest", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("android.util.jar.StrictJarVerifier", lpparam.classLoader, "verify", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("com.android.server.pm.PackageManagerServiceUtils", lpparam.classLoader, "verifySignatures", XC_MethodReplacement.returnConstant(false)); - Helpers.hookAllMethods("com.android.server.pm.InstallPackageHelper", lpparam.classLoader, "doesSignatureMatchForPermissions", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String packageName = (String) XposedHelpers.callMethod(param.args[1], "getPackageName"); - String sourcePackageName = (String) param.args[0]; - if (sourcePackageName.equals(packageName)) { - param.setResult(true); - } - } - }); - } - } - - public static void ScreenDimTimeHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.power.PowerManagerService", lpparam.classLoader, "readConfigurationLocked", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - float opt = MainModule.mPrefs.getInt("system_dimtime", 0) / 100f; - XposedHelpers.setIntField(param.thisObject, "mMaximumScreenDimDurationConfig", 600000); - XposedHelpers.setFloatField(param.thisObject, "mMaximumScreenDimRatioConfig", opt); -// Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); -// int minScreenOffTimeout = mContext.getResources().getInteger(mContext.getResources().getIdentifier("config_minimumScreenOffTimeout", "integer", "android")); - } - }); - -// Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "getScreenOffTimeoutLocked", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// //XposedBridge.log("getScreenOffTimeoutLocked (mSleepTimeoutSetting): " + param.args[0]); -// //XposedBridge.log("mMaximumScreenOffTimeoutFromDeviceAdmin: " + XposedHelpers.getLongField(param.thisObject, "mMaximumScreenOffTimeoutFromDeviceAdmin")); -// XposedBridge.log("mUserActivityTimeoutOverrideFromWindowManager: " + XposedHelpers.getLongField(param.thisObject, "mUserActivityTimeoutOverrideFromWindowManager")); -// } -// }); -// -// Helpers.hookAllMethods("com.android.server.power.PowerManagerService", lpparam.classLoader, "updateUserActivitySummaryLocked", new MethodHook() { -// @Override -// protected void after(MethodHookParam param) throws Throwable { -// if ((int)param.args[1] == 1) return; -// XposedBridge.log("updateUserActivitySummaryLocked: " + param.args[0] + ", " + param.args[1]); -// } -// }); - } - - public static void NoOverscrollHook() { - Helpers.findAndHookMethod("android.widget.AbsListView", null, "initAbsListView", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - ((AbsListView)param.thisObject).setOverScrollMode(View.OVER_SCROLL_NEVER); - } - }); - } - - public static void NoOverscrollAppHook(LoadPackageParam lpparam) { - MethodHook hookParam = new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = false; - } - }; - - Class sblCls = findClassIfExists("miuix.springback.view.SpringBackLayout", lpparam.classLoader); - if (sblCls != null) { - Helpers.hookAllConstructors(sblCls, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - try { - XposedHelpers.callMethod(param.thisObject, "setSpringBackEnable", false); - } catch (Throwable t) { - try { XposedHelpers.setBooleanField(param.thisObject, "mSpringBackEnable", false); } catch (Throwable ignore) {} - } - } - }); - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently(sblCls, "setSpringBackEnable", boolean.class, hookParam); - } - - Class rrvCls = findClassIfExists("androidx.recyclerview.widget.RemixRecyclerView", lpparam.classLoader); - if (rrvCls != null) { - Helpers.hookAllConstructors(rrvCls, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - ((View)param.thisObject).setOverScrollMode(View.OVER_SCROLL_NEVER); - try { - XposedHelpers.callMethod(param.thisObject, "setSpringEnabled", false); - } catch (Throwable t) { - try { XposedHelpers.setBooleanField(param.thisObject, "mSpringEnabled", false); } catch (Throwable ignore) {} - } - } - }); - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently(rrvCls, "setSpringEnabled", boolean.class, hookParam); - } - } - - private static float blurCollapsed = 0.0f; - private static float blurExpanded = 0.0f; - - public static void BlurVolumeDialogBackgroundHook(ClassLoader classLoader) { - MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_collapsed", 0f); - MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_expanded", 0f); - - Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "updateDialogWindowH", boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - boolean mExpanded = XposedHelpers.getBooleanField(param.thisObject, "mExpanded"); - float blurRatio = blurCollapsed; - boolean isVisible = (boolean) param.args[0]; - if (mExpanded && !isVisible) { - blurRatio = blurExpanded; - } - if (!mExpanded && blurCollapsed > 0.001f) { - Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); - mWindow.clearFlags(8); - } - if (mExpanded) { - XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurRatio, 0); - } - } - }); - Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "showH", int.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - if (blurCollapsed > 0.001f) { - Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); - mWindow.clearFlags(8); - XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurCollapsed, 0); - } - } - }); - Helpers.hookAllMethods("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "initDialog", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Handler mHandler = new Handler(mContext.getMainLooper()); - - blurCollapsed = MainModule.mPrefs.getInt("system_volumeblur_collapsed", 0) / 100f; - blurExpanded = MainModule.mPrefs.getInt("system_volumeblur_expanded", 0) / 100f; - new Helpers.SharedPrefObserver(mContext, mHandler) { - @Override - public void onChange(Uri uri) { - try { - String key = uri.getPathSegments().get(2); - if (key.equals("pref_key_system_volumeblur_collapsed")) blurCollapsed = Helpers.getSharedIntPref(mContext, key, 0) / 100f; - if (key.equals("pref_key_system_volumeblur_expanded")) blurExpanded = Helpers.getSharedIntPref(mContext, key, 0) / 100f; - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; - } - }); - } - - public static void BlurMTKVolumeBarHook(ClassLoader classLoader) { - Helpers.findAndHookMethod("com.android.systemui.miui.volume.Util", classLoader, "isSupportBlurS", XC_MethodReplacement.returnConstant(true)); - } - - public static void RemoveSecureHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.wm.WindowState", lpparam.classLoader, "isSecureLocked", XC_MethodReplacement.returnConstant(false)); - } - - public static void RemoveActStartConfirmHook(LoadPackageParam lpparam) { - Helpers.hookAllMethodsSilently("com.miui.server.SecurityManagerService", lpparam.classLoader, "checkAllowStartActivity", XC_MethodReplacement.returnConstant(true)); - } - - public static void AllowAllKeyguardHook(LoadPackageParam lpparam) { - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.notification.MiuiNotificationCompat", lpparam.classLoader, "isEnableKeyguard", Notification.class, XC_MethodReplacement.returnConstant(true)); - } - - public static void AllowAllKeyguardSysHook() { - Helpers.findAndHookMethod(MiuiNotification.class, "setEnableKeyguard", boolean.class, new MethodHook() { - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - - Helpers.findAndHookMethod(MiuiNotification.class, "isEnableKeyguard", XC_MethodReplacement.returnConstant(true)); - } - - public static void AllowAllFloatHook(LoadPackageParam lpparam) { - //noinspection ResultOfMethodCallIgnored - Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.notification.MiuiNotificationCompat", lpparam.classLoader, "isEnableFloat", Notification.class, XC_MethodReplacement.returnConstant(true)); - } - - public static void AllowAllFloatSysHook() { - Helpers.findAndHookMethod(MiuiNotification.class, "setEnableFloat", boolean.class, new MethodHook() { - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - - Helpers.findAndHookMethod(MiuiNotification.class, "isEnableFloat", XC_MethodReplacement.returnConstant(true)); - } - - public static void AllowDirectReplyHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "setLockScreenAllowRemoteInput", boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.args[0] = true; - } - }); - } - - public static void HideQSHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "onStateChanged", int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object mNotificationPanel = XposedHelpers.getObjectField(param.thisObject, "mQSContainer"); - if ((int)param.args[0] == 1) { - XposedHelpers.callMethod(mNotificationPanel, "setShowQSPanel", false); - } else { - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - XposedHelpers.callMethod(mNotificationPanel, "setShowQSPanel", true); - } - }, 300); - } - } - }); - } - - public static void LockScreenTimeoutHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarWindowManager", lpparam.classLoader, "applyUserActivityTimeout", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mLpChanged = XposedHelpers.getObjectField(param.thisObject, "mLpChanged"); - if (mLpChanged == null) return; - long userActivityTimeout = XposedHelpers.getLongField(mLpChanged, "userActivityTimeout"); - if (userActivityTimeout > 0) - XposedHelpers.setLongField(mLpChanged, "userActivityTimeout", MainModule.mPrefs.getInt("system_lstimeout", 9) * 1000L); - } - }); - } - - private static final SimpleDateFormat formatter = new SimpleDateFormat("H:m", Locale.ENGLISH); - public static void MuffledVibrationHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.vibrator.VibratorManagerService", lpparam.classLoader, "systemReady", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Handler mHandler = new Handler(mContext.getMainLooper()); - new Helpers.SharedPrefObserver(mContext, mHandler) { - @Override - public void onChange(Uri uri) { - try { - String key = uri.getPathSegments().get(2); - if (key.contains("pref_key_system_vibration_amp_")) MainModule.mPrefs.put(key, Helpers.getSharedIntPref(mContext, key, 100)); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; - } - }); - - Helpers.hookAllMethods("com.android.server.VibratorService", lpparam.classLoader, "doVibratorOn", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - float ratio_ringer = MainModule.mPrefs.getInt("system_vibration_amp_ringer", 100) / 100f; - float ratio_notif = MainModule.mPrefs.getInt("system_vibration_amp_notif", 100) / 100f; - float ratio_other = MainModule.mPrefs.getInt("system_vibration_amp_other", 100) / 100f; - - boolean isRingtone = false; - boolean isNotification = false; - Object mCurrentVibration = XposedHelpers.getObjectField(param.thisObject, "mCurrentVibration"); - if (mCurrentVibration != null) try { - isRingtone = (boolean)XposedHelpers.callMethod(mCurrentVibration, "isRingtone"); - isNotification = (boolean)XposedHelpers.callMethod(mCurrentVibration, "isNotification"); - } catch (Throwable t) { - int mUsageHint = XposedHelpers.getIntField(mCurrentVibration, "mUsageHint"); - isRingtone = mUsageHint == 6; - isNotification = mUsageHint == 5 || mUsageHint == 7 || mUsageHint == 8 || mUsageHint == 9; - } - - float ratio; - if (isRingtone) ratio = ratio_ringer; - else if (isNotification) ratio = ratio_notif; - else ratio = ratio_other; - if (ratio == 1.0f) return; - - String key = "system_vibration_amp_period"; - int start_hour = MainModule.mPrefs.getInt(key + "_start_hour", 0); - int start_minute = MainModule.mPrefs.getInt(key + "_start_minute", 0); - int end_hour = MainModule.mPrefs.getInt(key + "_end_hour", 0); - int end_minute = MainModule.mPrefs.getInt(key + "_end_minute", 0); - - formatter.setTimeZone(TimeZone.getDefault()); - Date start = formatter.parse(start_hour + ":" + start_minute); - Date end = formatter.parse(end_hour + ":" + end_minute); - Date now = formatter.parse(formatter.format(new Date())); - - boolean insidePeriod = start.before(end) ? now.after(start) && now.before(end) : now.before(end) || now.after(start); - if (!insidePeriod) return; - - boolean mSupportsAmplitudeControl = false; - try { - mSupportsAmplitudeControl = XposedHelpers.getBooleanField(param.thisObject, "mSupportsAmplitudeControl"); - } catch (Throwable ignored) {} - - if (mSupportsAmplitudeControl) - param.args[1] = Math.round(((int)param.args[1] == -1 ? XposedHelpers.getIntField(param.thisObject, "mDefaultVibrationAmplitude") : (int)param.args[1]) * ratio); - else - param.args[0] = Math.max(3, (long)Math.round((long)param.args[0] * ratio)); - } - }); - -// if (Helpers.isNougat()) -// Helpers.hookAllMethods("com.android.server.VibratorService", lpparam.classLoader, "vibratePattern", new MethodHook() { -// @Override -// protected void before(final MethodHookParam param) throws Throwable { -// -// } -// }); - } - - public static void ResizableWidgetsHook() { - Helpers.findAndHookMethod("android.appwidget.AppWidgetHostView", null, "getAppWidgetInfo", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - AppWidgetProviderInfo widgetInfo = (AppWidgetProviderInfo)param.getResult(); - if (widgetInfo == null) return; - widgetInfo.resizeMode = AppWidgetProviderInfo.RESIZE_BOTH; - widgetInfo.minHeight = 0; - widgetInfo.minWidth = 0; - widgetInfo.minResizeHeight = 0; - widgetInfo.minResizeWidth = 0; - param.setResult(widgetInfo); - } - }); - - Helpers.findAndHookMethod("android.appwidget.AppWidgetManager", null, "getAppWidgetInfo", int.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - AppWidgetProviderInfo widgetInfo = (AppWidgetProviderInfo)param.getResult(); - if (widgetInfo == null) return; - widgetInfo.resizeMode = AppWidgetProviderInfo.RESIZE_BOTH; - widgetInfo.minHeight = 0; - widgetInfo.minWidth = 0; - widgetInfo.minResizeHeight = 0; - widgetInfo.minResizeWidth = 0; - param.setResult(widgetInfo); - } - }); - } - - @SuppressWarnings("ConstantConditions") - private static void hookUpdateTime(Object thisObject, boolean isSingle) { - try { - TextView mCurrentDate = null; - TextView mCurrentDateLarge = null; - if (isSingle) { - try { mCurrentDate = (TextView)XposedHelpers.getObjectField(thisObject, "mCurrentDate"); } catch (Throwable ignore) {} - try { mCurrentDateLarge = (TextView)XposedHelpers.getObjectField(thisObject, "mCurrentDateLarge"); } catch (Throwable ignore) {} - } - else { - try { mCurrentDate = (TextView)XposedHelpers.getObjectField(thisObject, "mLocalDate"); } catch (Throwable ignore) {} - } - if (mCurrentDate == null && mCurrentDateLarge == null) return; - Context mContext = mCurrentDate != null ? mCurrentDate.getContext() : mCurrentDateLarge.getContext(); - - long timestamp = Helpers.getNextMIUIAlarmTime(mContext); - if (timestamp == 0 && MainModule.mPrefs.getBoolean("system_lsalarm_all")) - timestamp = Helpers.getNextStockAlarmTime(mContext); - if (timestamp == 0) return; - - StringBuilder alarmStr = new StringBuilder(); - alarmStr.append("\n").append(Helpers.getModuleRes(mContext).getString(R.string.system_statusbaricons_alarm_title)).append(" "); - int format = MainModule.mPrefs.getStringAsInt("system_lsalarm_format", 1); - if (format == 1 || format == 3) { - SimpleDateFormat dateFormat = new SimpleDateFormat(DateFormat.getBestDateTimePattern(Locale.getDefault(), DateFormat.is24HourFormat(mContext) ? "EHmm" : "EHmma"), Locale.getDefault()); - dateFormat.setTimeZone(TimeZone.getDefault()); - Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - calendar.setTimeInMillis(timestamp); - alarmStr.append(dateFormat.format(calendar.getTime())); - } - if (format == 2 || format == 3) { - StringBuilder timeStr = new StringBuilder(DateUtils.getRelativeTimeSpanString(timestamp, currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE)); - timeStr.setCharAt(0, Character.toLowerCase(timeStr.charAt(0))); - alarmStr.append(format == 3 ? " (" + timeStr + ")" : timeStr); - } - if (mCurrentDate != null) { - mCurrentDate.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT); - mCurrentDate.setLineSpacing(0, 1.5f); - mCurrentDate.append(alarmStr); - if (isSingle) { - int pos = Settings.System.getInt(mContext.getContentResolver(), "selected_keyguard_clock_position", 0); - if (pos != 2 && pos != 4) mCurrentDate.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); - } - } - if (mCurrentDateLarge != null) { - int resId = mCurrentDateLarge.getResources().getIdentifier("miui_clock_date_text_size", "dimen", "com.android.systemui"); - int fontSize = resId == 0 ? Math.round(mCurrentDateLarge.getResources().getDisplayMetrics().density * 14.0f) : mCurrentDateLarge.getResources().getDimensionPixelSize(resId); - alarmStr.insert(1, "\n\n "); - SpannableString span = new SpannableString(alarmStr); - span.setSpan(new AbsoluteSizeSpan(fontSize, false), 0, alarmStr.length(), 0); - span.setSpan(new TypefaceSpan("sans-serif"), 0, alarmStr.length(), 0); - mCurrentDateLarge.append(span); - } - } catch (Throwable t) { - XposedBridge.log(t); - } - } - - public static void LockScreenAlaramHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.keyguard.KeyguardUpdateMonitor", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { - @Override - public void onChange(Uri uri) { - try { - String key = uri.getPathSegments().get(2); - if ("pref_key_system_lsalarm_all".equals(key)) MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(mContext, key, false)); - if ("pref_key_system_lsalarm_format".equals(key)) MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "1")); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; - } - }); - - Helpers.findAndHookMethod("com.android.keyguard.clock.MiuiKeyguardSingleClock", lpparam.classLoader, "updateTime", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mMiuiBaseClock = XposedHelpers.getObjectField(param.thisObject, "mMiuiBaseClock"); - if (mMiuiBaseClock != null) hookUpdateTime(mMiuiBaseClock, true); - } - }); - Helpers.findAndHookMethod("com.android.keyguard.clock.MiuiKeyguardDualClock", lpparam.classLoader, "updateTime", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mMiuiDualClock = XposedHelpers.getObjectField(param.thisObject, "mMiuiDualClock"); - if (mMiuiDualClock != null) hookUpdateTime(mMiuiDualClock, false); - } - }); - } - - private static boolean isSlidingStart = false; - private static boolean isSliding = false; - private static float tapStartX = 0; - private static float tapStartY = 0; - private static float tapStartPointers = 0; - private static float tapStartBrightness = 0; - private static float tapCurrentBrightness = 0; - private static float topMinimumBacklight = 0.0f; - private static float topMaximumBacklight = 1.0f; - private static float currentTouchX = 0; - private static long currentTouchTime = 0; - - public static void StatusBarGesturesHook(LoadPackageParam lpparam) { - - Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { - @Override - public void onChange(Uri uri) { - try { - String key = uri.getPathSegments().get(2); - if ("pref_key_system_statusbarcontrols_single".equals(key) || "pref_key_system_statusbarcontrols_dual".equals(key)) - MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "1")); - else if ("pref_key_system_statusbarcontrols_sens_bright".equals(key) || "pref_key_system_statusbarcontrols_sens_vol".equals(key)) - MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "2")); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; - } - }); - - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "setExpandedHeightInternal", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - float mExpandedFraction = (float) XposedHelpers.callMethod(param.thisObject, "getExpandedFraction"); - if (mExpandedFraction > 0.33f) { - currentTouchTime = 0; - currentTouchX = 0; - } - } - }); - - final Class BrightnessUtils = XposedHelpers.findClassIfExists("com.android.systemui.controlcenter.policy.BrightnessUtils", lpparam.classLoader); - - MethodHook hook = new MethodHook() { - Object mBrightnessController = null; - private int sbHeight = 0; - @Override - @SuppressLint("SetTextI18n") - protected void before(final MethodHookParam param) throws Throwable { - String clsName = param.thisObject.getClass().getSimpleName(); - boolean isInControlCenter = "ControlPanelWindowView".equals(clsName) || "ControlCenterWindowViewImpl".equals(clsName); - if (Helpers.isTPlus() && isInControlCenter) { - if (param.args.length == 2 && (boolean) param.args[1]) { - return ; - } - Object statusBarStateController = XposedHelpers.getObjectField(param.thisObject, "statusBarStateController"); - int state = (int) XposedHelpers.callMethod(statusBarStateController, "getState"); - if (state == 1 || state == 2) { - return; - } - } - Context mContext = isInControlCenter ? ((View)param.thisObject).getContext() : (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Resources res = mContext.getResources(); - if (sbHeight == 0) { - sbHeight = res.getDimensionPixelSize(res.getIdentifier("status_bar_height", "dimen", "android")); - } - MotionEvent event = (MotionEvent)param.args[0]; - switch (event.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - tapStartX = event.getX(); - tapStartY = event.getY(); - isSlidingStart = isInControlCenter ? tapStartY <= sbHeight : !XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); - tapStartPointers = 1; - if (mBrightnessController == null) { - Object mControlCenterController; - if (Helpers.isTPlus() && isInControlCenter) { - mControlCenterController = XposedHelpers.getObjectField(param.thisObject, "controlCenterController"); - } - else { - mControlCenterController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); - } - mBrightnessController = XposedHelpers.callMethod(XposedHelpers.getObjectField(mControlCenterController, "brightnessController"), "get"); - } - Object mDisplayManager = XposedHelpers.getObjectField(mBrightnessController, "mDisplayManager"); - int mDisplayId = mContext.getDisplay().getDisplayId(); - topMinimumBacklight = (float) XposedHelpers.getObjectField(mBrightnessController, "mMinimumBacklight"); - topMaximumBacklight = (float) XposedHelpers.getObjectField(mBrightnessController, "mMaximumBacklight"); - tapStartBrightness = (float) XposedHelpers.callMethod(mDisplayManager, "getBrightness", mDisplayId); - break; - case MotionEvent.ACTION_POINTER_DOWN: - tapStartPointers = event.getPointerCount(); - break; - case MotionEvent.ACTION_UP: - long lastTouchTime = currentTouchTime; - float lastTouchX = currentTouchX; - currentTouchTime = currentTimeMillis(); - currentTouchX = event.getX(); - if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100F) { - currentTouchTime = 0L; - currentTouchX = 0F; - GlobalActions.handleAction(mContext, "pref_key_system_statusbarcontrols_dt"); - } - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_CANCEL: - isSlidingStart = false; - isSliding = false; - if (mPct != null) { - mPct.setVisibility(View.GONE); - int opt = MainModule.mPrefs.getStringAsInt(tapStartPointers == 2 ? "system_statusbarcontrols_dual" : "system_statusbarcontrols_single", 1); - if (tapCurrentBrightness > -0.5f && opt == 2) { - mDisplayManager = XposedHelpers.getObjectField(mBrightnessController, "mDisplayManager"); - XposedHelpers.callMethod(mDisplayManager, "setBrightness", mContext.getDisplay().getDisplayId(), tapCurrentBrightness); - } - } - break; - case MotionEvent.ACTION_MOVE: - if (!isSlidingStart) return; - DisplayMetrics metrics = res.getDisplayMetrics(); - if (event.getY() - tapStartY > sbHeight) return; - float delta = event.getX() - tapStartX; - if (delta == 0) return; - if (!isSliding && Math.abs(delta) > metrics.widthPixels / 10f) isSliding = true; - if (!isSliding) return; - int opt = MainModule.mPrefs.getStringAsInt(tapStartPointers == 2 ? "system_statusbarcontrols_dual" : "system_statusbarcontrols_single", 1); - if (opt == 2) { - int sens = MainModule.mPrefs.getStringAsInt("system_statusbarcontrols_sens_bright", 2); - float ratio = delta / metrics.widthPixels; - ratio = (sens == 1 ? 0.66f : (sens == 3 ? 1.66f : 1.0f)) * ratio * 0.618f; - float nextLevel = Math.min(topMaximumBacklight, Math.max(topMinimumBacklight, tapStartBrightness + (topMaximumBacklight - topMinimumBacklight) * ratio)); - XposedHelpers.callMethod(mBrightnessController, "setBrightness", nextLevel); - tapCurrentBrightness = nextLevel; - } else if (opt == 3) { - tapCurrentBrightness = -1.0f; - int sens = MainModule.mPrefs.getStringAsInt("system_statusbarcontrols_sens_vol", 2); - if (Math.abs(delta) < metrics.widthPixels / ((sens == 1 ? 0.66f : (sens == 3 ? 1.66f : 1.0f)) * 20 * metrics.density)) return; - tapStartX = event.getX(); - AudioManager audioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); - audioManager.adjustVolume(delta > 0 ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, 1 << 12 /* FLAG_FROM_KEY */ | AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_ALLOW_RINGER_MODES | AudioManager.FLAG_VIBRATE); - } - break; - } - } - }; - String eventMethod = Helpers.isTPlus() ? "onTouchEvent" : "interceptTouchEvent"; - Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, eventMethod, MotionEvent.class, hook); - if (Helpers.isTPlus()) { - String pluginLoaderClass = "com.android.systemui.shared.plugins.PluginInstance$Factory"; - Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { - isHooked = true; - if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); - } - Helpers.findAndHookMethod("miui.systemui.controlcenter.windowview.ControlCenterWindowViewImpl", pluginLoader, "handleMotionEvent", MotionEvent.class, boolean.class, hook); - } - } - }); - } - else { - Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.ControlPanelWindowView", lpparam.classLoader, "onTouchEvent", MotionEvent.class, hook); - } - } - - public static void ScreenshotConfigHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("android.content.ContentResolver", lpparam.classLoader, "update", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args.length != 4) return; - ContentValues contentValues = (ContentValues) param.args[1]; - String displayName = contentValues.getAsString("_display_name"); - if (displayName != null && displayName.contains("Screenshot")) { - Context context = Helpers.findContext(); - int format = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_format", "2")); - String ext = format <= 2 ? ".jpg" : (format == 3 ? ".png" : ".webp"); - - displayName = displayName.replace(".png", "").replace(".jpg", "").replace(".webp", "") + ext; - contentValues.put("_display_name", displayName); - } - } - }); - Helpers.findAndHookMethod("android.content.ContentResolver", lpparam.classLoader, "insert", Uri.class, ContentValues.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Uri imgUri = (Uri) param.args[0]; - ContentValues contentValues = (ContentValues) param.args[1]; - String displayName = contentValues.getAsString("_display_name"); - if (MediaStore.Images.Media.EXTERNAL_CONTENT_URI.equals(imgUri) && displayName != null && displayName.contains("Screenshot")) { - Context context = Helpers.findContext(); - int folder = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_path", "1")); - String dir = Helpers.getSharedStringPref(context, "pref_key_system_screenshot_mypath", ""); - int format = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_format", "2")); - String ext = format <= 2 ? ".jpg" : (format == 3 ? ".png" : ".webp"); - - File mScreenshotDir; - displayName = displayName.replace(".png", "").replace(".jpg", "").replace(".webp", "") + ext; - if (folder > 1) { - if (folder == 4 && !TextUtils.isEmpty(dir)) - mScreenshotDir = new File(dir); - else - mScreenshotDir = new File(Environment.getExternalStoragePublicDirectory(folder == 2 ? Environment.DIRECTORY_PICTURES : Environment.DIRECTORY_DCIM), "Screenshots"); - if (!mScreenshotDir.exists()) mScreenshotDir.mkdirs(); - String relativePath = mScreenshotDir.getPath().replace(Environment.getExternalStorageDirectory().getPath() + File.separator, ""); - contentValues.put("relative_path", relativePath); - if (contentValues.getAsString("_data") != null) { - contentValues.put("_data", mScreenshotDir.getPath() + "/" + displayName); - } - } - contentValues.put("_display_name", displayName); - } - } - }); - - Helpers.hookAllMethods("android.graphics.Bitmap", lpparam.classLoader, "compress", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Context context = Helpers.findContext(); - int quality = (int) param.args[1]; - if (quality != 100 || (param.args[2] instanceof ByteArrayOutputStream)) return; - int format = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_format", "2")); - quality = Helpers.getSharedIntPref(context, "pref_key_system_screenshot_quality", 100); - if (format == 3) { - quality = 100; - } - Bitmap.CompressFormat compress = format <= 2 ? Bitmap.CompressFormat.JPEG : (format == 3 ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.WEBP); - param.args[0] = compress; - param.args[1] = quality; - } - }); - } - - public static void NoNetworkSpeedSeparatorHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.views.NetworkSpeedSplitter", lpparam.classLoader, "updateVisibility", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - XposedHelpers.setObjectField(param.thisObject, "mNetworkSpeedVisibility", View.GONE); - } - }); - } - - public static void HideNetworkSpeedUnitHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "formatSpeed", Context.class, long.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - String speedText = (String) param.getResult(); - param.setResult(speedText.replaceFirst("B?[/']s", "")); - } - }); - } - - public static void HideLowNetworkSpeedHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "formatSpeed", Context.class, long.class, new MethodHook(100) { - @Override - protected void before(MethodHookParam param) throws Throwable { - int lowLevel = MainModule.mPrefs.getInt("system_detailednetspeed_lowlevel", 1) * 1024; - long speedVal = (long) param.args[1]; - if (speedVal < lowLevel) { - param.setResult(""); - } - } - }); - } - - public static void NetSpeedStyleHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - TextView meter = (TextView)param.thisObject; - if (meter == null) return; - if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { - int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 13); - if (MainModule.mPrefs.getBoolean("system_detailednetspeed")) { - if (fontSize > 20) fontSize = 16; - } - else { - if (fontSize < 20) fontSize = 27; - } - if (fontSize != 13) { - meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); - } - if (MainModule.mPrefs.getBoolean("system_netspeed_bold")) { - meter.setTypeface(Typeface.DEFAULT_BOLD); - } - - int horizMargin = 0; - if (MainModule.mPrefs.getBoolean("system_fixmeter")) { - horizMargin = Math.round(meter.getResources().getDisplayMetrics().density * 4); - } - int topMargin = 0; - int verticalOffset = MainModule.mPrefs.getInt("system_netspeed_verticaloffset", 8); - if (verticalOffset != 8) { - float marginTop = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - (verticalOffset - 8) * 0.5f, - meter.getResources().getDisplayMetrics() - ); - topMargin = (int) (marginTop); - } - meter.setPaddingRelative(horizMargin, topMargin, horizMargin, 0); - - if (MainModule.mPrefs.getBoolean("system_detailednetspeed")) { - float spacing = 0.9f; - meter.setSingleLine(false); - meter.setLines(2); - meter.setMaxLines(2); - if (fontSize > 8.5f) { - spacing = 0.85f; - } - meter.setLineSpacing(0, spacing); - } - } - } - }); - } - - public static void ToastTimeHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.server.notification.NotificationManagerService", lpparam.classLoader, "showNextToastLocked", new MethodHook() { - @Override - @SuppressWarnings("unchecked") - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.callMethod(param.thisObject, "getContext"); - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); - ArrayList mToastQueue = (ArrayList)XposedHelpers.getObjectField(param.thisObject, "mToastQueue"); - if (mContext == null || mHandler == null || mToastQueue == null || mToastQueue.size() == 0) return; - int mod = (Helpers.getSharedIntPref(mContext, "pref_key_system_toasttime", 0) - 4) * 1000; - for (Object record: mToastQueue) - if (record != null && mHandler.hasMessages(2, record)) { - mHandler.removeCallbacksAndMessages(record); - int duration = XposedHelpers.getIntField(record, "duration"); - int delay = Math.max(1000, (duration == 1 ? 3500 : 2000) + mod); - mHandler.sendMessageDelayed(Message.obtain(mHandler, 2, record), delay); - } - } - }); - - Helpers.findAndHookMethod("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "systemReady", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); - - new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_toasttime", 0) { - @Override - public void onChange(String name, int defValue) { - MainModule.mPrefs.put(name, Helpers.getSharedIntPref(mContext, name, defValue)); - } - }; - } - }); - - String windowClass = "com.android.server.wm.DisplayPolicy"; - Helpers.hookAllMethods(windowClass, lpparam.classLoader, "adjustWindowParamsLw", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object lp = param.args.length == 1 ? param.args[0] : param.args[1]; - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mPrevHideTimeout", XposedHelpers.getLongField(lp, "hideTimeoutMilliseconds")); - } - - @Override - protected void after(MethodHookParam param) throws Throwable { - Object lp = param.args.length == 1 ? param.args[0] : param.args[1]; - long mPrevHideTimeout = (long)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mPrevHideTimeout"); - long mHideTimeout = XposedHelpers.getLongField(lp, "hideTimeoutMilliseconds"); - if (mPrevHideTimeout == -1 || mHideTimeout == -1) return; - - long dur = 0; - if (mPrevHideTimeout == 1000 || mPrevHideTimeout == 4000 || mPrevHideTimeout == 5000 || mPrevHideTimeout == 7000 || mPrevHideTimeout != mHideTimeout) - dur = Math.max(1000, 3500 + (MainModule.mPrefs.getInt("system_toasttime", 0) - 4) * 1000); - if (dur != 0) XposedHelpers.setLongField(lp, "hideTimeoutMilliseconds", dur); - } - }); - } - - public static void ClearAllTasksHook(LoadPackageParam lpparam) { - String wpuClass = "com.android.server.wm.WindowProcessUtils"; - Helpers.hookAllMethods(wpuClass, lpparam.classLoader, "getPerceptibleRecentAppList", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - param.setResult(null); - } - }); - } - - private static int hours3ResId; - private static int hours4ResId; - private static int hours5ResId; - private static int hours6ResId; - private static int hours8ResId; - private static int hours10ResId; - private static int hours12ResId; - private static int foreverResId; - public static void MoreSnoozeOptionsRes() { - hours3ResId = MainModule.resHooks.addResource("time_3h", R.string.time_3h); - hours4ResId = MainModule.resHooks.addResource("time_4h", R.string.time_4h); - hours5ResId = MainModule.resHooks.addResource("time_5h", R.string.time_5h); - hours6ResId = MainModule.resHooks.addResource("time_6h", R.string.time_6h); - hours8ResId = MainModule.resHooks.addResource("time_8h", R.string.time_8h); - hours10ResId = MainModule.resHooks.addResource("time_10h", R.string.time_10h); - hours12ResId = MainModule.resHooks.addResource("time_12h", R.string.time_12h); - foreverResId = MainModule.resHooks.addResource("time_forever", R.string.time_forever); - } - - public static void MoreSnoozeOptionsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationSnooze", lpparam.classLoader, "getDefaultSnoozeOptions", new MethodHook() { - @Override - @SuppressWarnings("unchecked") - protected void after(MethodHookParam param) throws Throwable { - ArrayList options = (ArrayList)param.getResult(); - if (options == null) return; - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours3ResId, 180)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours4ResId, 240)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours5ResId, 300)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours6ResId, 360)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours8ResId, 480)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours10ResId, 600)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", hours12ResId, 720)); - options.add(XposedHelpers.callMethod(param.thisObject, "createOption", foreverResId, 1024)); - } - }); - - Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationSnooze", lpparam.classLoader, "createOptionViews", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - LinearLayout mSnoozeOptionContainer = (LinearLayout)XposedHelpers.getObjectField(param.thisObject, "mSnoozeOptionContainer"); - ViewGroup parent = ((ViewGroup)mSnoozeOptionContainer.getParent()); - if (parent.getClass() == ScrollView.class) return; - parent.removeView(mSnoozeOptionContainer); - HorizontalScrollView scrollView = new HorizontalScrollView(mSnoozeOptionContainer.getContext()); - scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); - scrollView.setVerticalScrollBarEnabled(false); - scrollView.setHorizontalScrollBarEnabled(false); - scrollView.addView(mSnoozeOptionContainer); - parent.addView(scrollView); - ViewGroup.LayoutParams lp1 = scrollView.getLayoutParams(); - lp1.width = ViewGroup.LayoutParams.MATCH_PARENT; - lp1.height = ViewGroup.LayoutParams.WRAP_CONTENT; - scrollView.setLayoutParams(lp1); - ViewGroup.MarginLayoutParams lp2 = (ViewGroup.MarginLayoutParams)mSnoozeOptionContainer.getLayoutParams(); - lp2.setMarginStart(0); - lp2.width = ViewGroup.LayoutParams.MATCH_PARENT; - lp2.height = ViewGroup.LayoutParams.WRAP_CONTENT; - mSnoozeOptionContainer.setLayoutParams(lp2); - } - }); - } - - public static void MoreSnoozeOptionsServiceHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.notification.SnoozeHelper", lpparam.classLoader, "scheduleRepost", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if ((long)param.args[3] == 1024 * 60000) param.setResult(null); - } - @Override - @SuppressWarnings("unchecked") - protected void after(MethodHookParam param) throws Throwable { - if ((long)param.args[3] == 1024 * 60000) return; - ArrayMap mSnoozedNotificationDelays = (ArrayMap)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSnoozedNotificationDelays"); - if (mSnoozedNotificationDelays == null) mSnoozedNotificationDelays = new ArrayMap(); - mSnoozedNotificationDelays.put((String)param.args[1], currentTimeMillis() + (long)param.args[3]); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSnoozedNotificationDelays", mSnoozedNotificationDelays); - } - }); - - Helpers.findAndHookMethod("com.android.server.notification.SnoozeHelper", lpparam.classLoader, "repost", String.class, int.class, new MethodHook() { - @Override - @SuppressWarnings({"unchecked", "SuspiciousMethodCalls"}) - protected void after(MethodHookParam param) throws Throwable { - ArrayMap mSnoozedNotificationDelays = (ArrayMap)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSnoozedNotificationDelays"); - if (mSnoozedNotificationDelays != null) mSnoozedNotificationDelays.remove(param.args[0]); - } - }); - - Helpers.hookAllConstructors("com.android.server.notification.SnoozeHelper", lpparam.classLoader, new MethodHook() { - @Override - @SuppressWarnings("unchecked") - protected void after(MethodHookParam param) throws Throwable { - IntentFilter filter = new IntentFilter(); - filter.addAction(ACTION_PREFIX + "GetSnoozedNotifications"); - filter.addAction(ACTION_PREFIX + "UnsnoozeNotification"); - filter.addAction(ACTION_PREFIX + "CancelNotification"); - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - ArrayMap>> mSnoozedNotifications = (ArrayMap>>)XposedHelpers.getObjectField(param.thisObject, "mSnoozedNotifications"); - ArrayMap mSnoozedNotificationDelays = (ArrayMap)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSnoozedNotificationDelays"); - - if (action.equals(ACTION_PREFIX + "CancelNotification")) try { - ArrayMap> packages = mSnoozedNotifications.get(intent.getIntExtra("user", 0)); - if (packages == null) return; - ArrayMap notificatios = packages.get(intent.getStringExtra("package")); - if (notificatios == null) return; - if (notificatios.containsKey(intent.getStringExtra("key"))) - XposedHelpers.setBooleanField(notificatios.get(intent.getStringExtra("key")), "isCanceled", intent.getBooleanExtra("canceled", false)); - return; - } catch (Throwable t) { - XposedBridge.log(t); - } - - if (action.equals(ACTION_PREFIX + "UnsnoozeNotification")) try { - XposedHelpers.callMethod(param.thisObject, "repost", intent.getStringExtra("key"), intent.getIntExtra("user", 0)); - } catch (Throwable t) { - XposedBridge.log(t); - } - - try { - Bundle notifications = new Bundle(); - int user; - String pkg; - for (int i = 0; i < mSnoozedNotifications.size(); i++ ) { - user = mSnoozedNotifications.keyAt(i); - ArrayMap> mSnoozedNotification = mSnoozedNotifications.get(mSnoozedNotifications.keyAt(i)); - for (int j = 0; j < mSnoozedNotification.size(); j++ ) { - pkg = mSnoozedNotification.keyAt(j); - ArrayMap mSnoozed = mSnoozedNotification.get(mSnoozedNotification.keyAt(j)); - for (int k = 0; k < mSnoozed.size(); k++) { - String key = mSnoozed.keyAt(k); - Bundle notif = new Bundle(); - notif.putInt("user", user); - notif.putString("package", pkg); - notif.putString("key", key); - Object record = mSnoozed.get(key); - notif.putBoolean("canceled", XposedHelpers.getBooleanField(record, "isCanceled")); - notif.putLong("created", XposedHelpers.getLongField(record, "mCreationTimeMs")); - notif.putLong("updated", XposedHelpers.getLongField(record, "mUpdateTimeMs")); - if (mSnoozedNotificationDelays != null && mSnoozedNotificationDelays.get(key) != null) - notif.putLong("reposted", mSnoozedNotificationDelays.get(key)); - Object sbn = XposedHelpers.getObjectField(record, "sbn"); - Notification notification = (Notification)XposedHelpers.getObjectField(sbn, "notification"); - if (notification != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - notif.putString("channel", notification.getChannelId()); - notif.putInt("color", notification.color); - if (notification.getLargeIcon() != null) - notif.putParcelable("icon", notification.getLargeIcon()); - if (notification.extras != null) { - notif.putString("title", notification.extras.getCharSequence(Notification.EXTRA_TITLE).toString()); - CharSequence text = notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT, null); - if (text == null || "" == text) text = notification.extras.getCharSequence(Notification.EXTRA_TEXT, null); - if (text != null && "" != text) { - String[] lines = text.toString().split("\\n"); - notif.putString("text", lines[0] + (lines.length == 1 ? "" : "...")); - } - Parcelable[] messages = notification.extras.getParcelableArray(Notification.EXTRA_MESSAGES); - if (messages != null) notif.putInt("messages", messages.length); - } - } - notifications.putBundle(mSnoozed.keyAt(k), notif); - } - } - } - Intent snoozedIntent = new Intent(GlobalActions.EVENT_PREFIX + "UpdateSnoozedNotifications"); - snoozedIntent.setPackage(Helpers.modulePkg); - snoozedIntent.putExtras(notifications); - mContext.sendBroadcast(snoozedIntent); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }, filter); - } - }); - } - - public static void InactiveBrightnessSliderHook(LoadPackageParam lpparam) { - MethodHook hook = new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - int opt = MainModule.mPrefs.getStringAsInt("system_inactivebrightness", 1); - if (opt == 2) { - SeekBar mSlider = (SeekBar)XposedHelpers.getObjectField(param.thisObject, "mSlider"); - if (mSlider != null) - mSlider.setOnTouchListener(new View.OnTouchListener(){ - @Override - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); - } else if (opt == 3) try { - View sliderView = (View)param.thisObject; - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)sliderView.getLayoutParams(); - lp.height = 0; - lp.topMargin = Math.round(2 * sliderView.getResources().getDisplayMetrics().density); - lp.bottomMargin = 0; - sliderView.setLayoutParams(lp); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; - Helpers.findAndHookMethod("com.android.systemui.settings.brightness.BrightnessSliderView", lpparam.classLoader, "onFinishInflate", hook); -// Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.widget.QCToggleSliderView", lpparam.classLoader, "onAttachedToWindow", hook); - } - - private static final float[] startPos = new float[2]; - private static void processLSEvent(MethodHookParam param) { - MotionEvent event = (MotionEvent)param.args[0]; - if (event.getPointerCount() > 1) return; - int action = event.getActionMasked(); - if (action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_UP) return; - - ViewGroup mKeyguardBottomArea = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mBottomAreaView"); - if (mKeyguardBottomArea == null) return; - ViewGroup mIndicationArea = (ViewGroup)XposedHelpers.getObjectField(mKeyguardBottomArea, "mIndicationArea"); - if (!Helpers.isReallyVisible(mIndicationArea)) return; - - int[] coord = new int[2]; - mIndicationArea.getLocationOnScreen(coord); - Rect rect = new Rect(coord[0], coord[1], coord[0] + mIndicationArea.getWidth(), coord[1] + mIndicationArea.getHeight()); - if (!rect.contains((int)event.getX(), (int)event.getY())) return; - - if (action == MotionEvent.ACTION_DOWN) { - startPos[0] = event.getX(); - startPos[1] = event.getY(); - } else if (action == MotionEvent.ACTION_UP) try { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - int slop = ViewConfiguration.get(mContext).getScaledTouchSlop(); - if (Math.abs(event.getX() - startPos[0]) > slop || Math.abs(event.getY() - startPos[1]) > slop) return; - Object mPanelViewController = XposedHelpers.getObjectField(param.thisObject, "mPanelViewController"); - Object statusBarKeyguardViewManager = XposedHelpers.getObjectField(mPanelViewController, "statusBarKeyguardViewManager"); - - XposedHelpers.callMethod(statusBarKeyguardViewManager, "showGenericBouncer", true); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - - public static void TapToUnlockHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader, "onTouchEvent", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - processLSEvent(param); - } - }); - - Helpers.hookAllMethods("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader, "onInterceptTouchEvent", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - processLSEvent(param); - } - }); - } - - public static void NoSafeVolumeWarningRes() { - MainModule.resHooks.setObjectReplacement("android", "bool", "config_safe_media_volume_enabled", false); - MainModule.resHooks.setObjectReplacement("android", "bool", "config_safe_media_disable_on_volume_up", false); - } - - public static void NoLowBatteryWarningHook(LoadPackageParam lpparam) { - MethodHook settingHook = new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - String key = (String)param.args[1]; - if ("low_battery_dialog_disabled".equals(key)) param.setResult(1); - else if ("power_sounds_enabled".equals(key)) param.setResult(0); - } - }; - Helpers.hookAllMethods(Settings.System.class, "getIntForUser", settingHook); - Helpers.hookAllMethods(Settings.System.class, "getInt", settingHook); - } - - public static void TempHideOverlaySystemUIHook(LoadPackageParam lpparam) { - - Helpers.hookAllMethods("com.android.wm.shell.pip.PipTaskOrganizer", lpparam.classLoader, "onTaskAppeared", new MethodHook() { - private boolean isActListened = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (!isActListened) { - isActListened = true; - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction("miui.intent.TAKE_SCREENSHOT"); - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) return; - if (action.equals("miui.intent.TAKE_SCREENSHOT")) { - boolean state = intent.getBooleanExtra("IsFinished", true); - Object mState; - if (Helpers.isTPlus()) { - mState = XposedHelpers.getObjectField(param.thisObject, "mPipTransitionState"); - } - else { - mState = XposedHelpers.getObjectField(param.thisObject, "mState"); - } - boolean isPip = (boolean) XposedHelpers.callMethod(mState, "isInPip"); - if (isPip) { - Object mSurfaceControlTransactionFactory = XposedHelpers.getObjectField(param.thisObject, "mSurfaceControlTransactionFactory"); - SurfaceControl.Transaction transaction = (SurfaceControl.Transaction) XposedHelpers.callMethod(mSurfaceControlTransactionFactory, "getTransaction"); - SurfaceControl mLeash = (SurfaceControl) XposedHelpers.getObjectField(param.thisObject, "mLeash"); - transaction.setVisibility(mLeash, state); - transaction.apply(); - } - } - } - }, intentFilter); - } - } - }); - } - public static void TempHideOverlayAppHook(LoadPackageParam lpparam) { - final boolean[] isListened = {false}; - final ArrayList mViews = new ArrayList<>(); - MethodHook addViewHook = new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - if (param.args[0] == null || !(param.args[1] instanceof WindowManager.LayoutParams) || param.getThrowable() != null) return; - WindowManager.LayoutParams params = (WindowManager.LayoutParams)param.args[1]; - if (params.type != WindowManager.LayoutParams.TYPE_PHONE - && params.type != WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY - && params.type != WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY) return; - View view = (View)param.args[0]; - Context mContext = view.getContext(); - mViews.add(view); - - if (!isListened[0]) { - isListened[0] = true; - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction("miui.intent.TAKE_SCREENSHOT"); - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) return; - if (action.equals("miui.intent.TAKE_SCREENSHOT")) { - boolean state = intent.getBooleanExtra("IsFinished", true); - for (int size = mViews.size() - 1; size >= 0; size--) { - View vs = mViews.get(size); - if (vs != null) { - if (state) { - if (vs.getVisibility() != View.VISIBLE && XposedHelpers.getAdditionalInstanceField(vs, "mSavedVisibility") != null) { - XposedHelpers.removeAdditionalInstanceField(vs, "mSavedVisibility"); - vs.setVisibility(View.VISIBLE); - } - } - else { - if (vs.getVisibility() == View.VISIBLE) { - vs.setVisibility(View.INVISIBLE); - XposedHelpers.setAdditionalInstanceField(vs, "mSavedVisibility", true); - } - } - } - } - } - } - }, intentFilter); - } - } - }; - MethodHook removeViewHook = new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - mViews.remove(param.args[0]); - } - }; - Helpers.hookAllMethods("android.view.WindowManagerGlobal", lpparam.classLoader, "addView", addViewHook); - Helpers.hookAllMethods("android.view.WindowManagerGlobal", lpparam.classLoader, "removeView", removeViewHook); - } - - public static void GalleryScreenshotPathHook(LoadPackageParam lpparam) { - Class MIUIStorageConstants = findClass("com.miui.gallery.storage.constants.MIUIStorageConstants", lpparam.classLoader); - int folder = MainModule.mPrefs.getStringAsInt("system_gallery_screenshots_path", 1); - String ssPath = ""; - if (folder == 2) { - ssPath = Environment.DIRECTORY_PICTURES + File.separator + "Screenshots"; - } - else if (folder == 3) { - ssPath = Environment.DIRECTORY_DCIM + File.separator + "Screenshots"; - } - if (folder > 1) { - XposedHelpers.setStaticObjectField(MIUIStorageConstants, "DIRECTORY_SCREENSHOT_PATH", ssPath); - } - } - - public static void ScreenshotFloatTimeHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.miui.screenshot.GlobalScreenshot", lpparam.classLoader, "startGotoThumbnailAnimation", Runnable.class, new MethodHook() { - @Override - @SuppressWarnings("ConstantConditions") - protected void after(MethodHookParam param) throws Throwable { - boolean mIsShowLongScreenShotGuide = false; - try { - mIsShowLongScreenShotGuide = XposedHelpers.getBooleanField(param.thisObject, "mIsShowLongScreenShotGuide"); - } catch (Throwable ignore) {} - if (mIsShowLongScreenShotGuide) return; - int opt = MainModule.mPrefs.getInt("system_screenshot_floattime", 0); - if (opt <= 0) return; - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); - Runnable mQuitThumbnailRunnable = (Runnable)XposedHelpers.getObjectField(param.thisObject, "mQuitThumbnailRunnable"); - mHandler.removeCallbacks(mQuitThumbnailRunnable); - mHandler.postDelayed(mQuitThumbnailRunnable, opt * 1000L); - } - }); - } - - public static void ScrambleAppLockPINHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.miui.applicationlock.widget.MiuiNumericInputView", lpparam.classLoader, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - LinearLayout keys = (LinearLayout)param.thisObject; - ArrayList mRandomViews = new ArrayList(); - View bottom0 = null; View bottom2 = null; - for (int row = 0; row <= 3; row++) { - ViewGroup cols = (ViewGroup)keys.getChildAt(row); - for (int col = 0; col <= 2; col++) { - if (row == 3) - if (col == 0) { - bottom0 = cols.getChildAt(col); - continue; - } else if (col == 2) { - bottom2 = cols.getChildAt(col); - continue; - } - mRandomViews.add(cols.getChildAt(col)); - } - cols.removeAllViews(); - } - - Collections.shuffle(mRandomViews); + long timestamp = Helpers.getNextMIUIAlarmTime(mContext); + if (timestamp == 0 && MainModule.mPrefs.getBoolean("system_lsalarm_all")) + timestamp = Helpers.getNextStockAlarmTime(mContext); + if (timestamp == 0) return; - int cnt = 0; - for (int row = 0; row <= 3; row++) - for (int col = 0; col <= 2; col++) { - ViewGroup cols = (ViewGroup)keys.getChildAt(row); - if (row == 3) - if (col == 0) { - cols.addView(bottom0); - continue; - } else if (col == 2) { - cols.addView(bottom2); - continue; - } - cols.addView(mRandomViews.get(cnt)); - cnt++; - } + StringBuilder alarmStr = new StringBuilder(); + alarmStr.append("\n").append(Helpers.getModuleRes(mContext).getString(R.string.system_statusbaricons_alarm_title)).append(" "); + int format = MainModule.mPrefs.getStringAsInt("system_lsalarm_format", 1); + if (format == 1 || format == 3) { + SimpleDateFormat dateFormat = new SimpleDateFormat(DateFormat.getBestDateTimePattern(Locale.getDefault(), DateFormat.is24HourFormat(mContext) ? "EHmm" : "EHmma"), Locale.getDefault()); + dateFormat.setTimeZone(TimeZone.getDefault()); + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.setTimeInMillis(timestamp); + alarmStr.append(dateFormat.format(calendar.getTime())); } - }); - } - - public static void ChargingInfoServiceHook(LoadPackageParam lpparam) { - if (!Helpers.hookAllMethodsSilently("com.android.server.BatteryService$BatteryPropertiesRegistrar", lpparam.classLoader, "getProperty", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - int req = (int)param.args[0]; - if (req < 1000) return; - long value = Long.MIN_VALUE; - if (req == 1001) - value = XposedHelpers.getIntField(XposedHelpers.getSurroundingThis(param.thisObject), "mLastBatteryVoltage"); - else if (req == 1002) - value = XposedHelpers.getIntField(XposedHelpers.getSurroundingThis(param.thisObject), "mLastBatteryTemperature"); - else if (req == 1003) - value = XposedHelpers.getIntField(XposedHelpers.getSurroundingThis(param.thisObject), "mLastBatteryHealth"); - XposedHelpers.callMethod(param.args[1], "setLong", value); - param.setResult(0); + if (format == 2 || format == 3) { + StringBuilder timeStr = new StringBuilder(DateUtils.getRelativeTimeSpanString(timestamp, currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE)); + timeStr.setCharAt(0, Character.toLowerCase(timeStr.charAt(0))); + alarmStr.append(format == 3 ? " (" + timeStr + ")" : timeStr); } - })) Helpers.findAndHookMethod("com.android.server.BatteryService", lpparam.classLoader, "processValuesLocked", boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - try { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - ContentResolver provider = mContext.getContentResolver(); - Settings.Global.putInt(provider, Helpers.modulePkg + ".battery.voltage", XposedHelpers.getIntField(param.thisObject, "mLastBatteryVoltage")); - Settings.Global.putInt(provider, Helpers.modulePkg + ".battery.temperature", XposedHelpers.getIntField(param.thisObject, "mLastBatteryTemperature")); - Settings.Global.putInt(provider, Helpers.modulePkg + ".battery.health", XposedHelpers.getIntField(param.thisObject, "mLastBatteryHealth")); - } catch (Throwable ignore) {} + if (mCurrentDate != null) { + mCurrentDate.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT); + mCurrentDate.setLineSpacing(0, 1.5f); + mCurrentDate.append(alarmStr); + if (isSingle) { + int pos = Settings.System.getInt(mContext.getContentResolver(), "selected_keyguard_clock_position", 0); + if (pos != 2 && pos != 4) mCurrentDate.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + } } - }); + if (mCurrentDateLarge != null) { + int resId = mCurrentDateLarge.getResources().getIdentifier("miui_clock_date_text_size", "dimen", "com.android.systemui"); + int fontSize = resId == 0 ? Math.round(mCurrentDateLarge.getResources().getDisplayMetrics().density * 14.0f) : mCurrentDateLarge.getResources().getDimensionPixelSize(resId); + alarmStr.insert(1, "\n\n "); + SpannableString span = new SpannableString(alarmStr); + span.setSpan(new AbsoluteSizeSpan(fontSize, false), 0, alarmStr.length(), 0); + span.setSpan(new TypefaceSpan("sans-serif"), 0, alarmStr.length(), 0); + mCurrentDateLarge.append(span); + } + } catch (Throwable t) { + XposedBridge.log(t); + } } - public static void ChargingInfoHook(LoadPackageParam lpparam) { + public static void LockScreenAlarmHook(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.android.keyguard.KeyguardUpdateMonitor", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)param.args[0]; - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); - - new Helpers.SharedPrefObserver(mContext, mHandler) { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { @Override public void onChange(Uri uri) { try { - String type = uri.getPathSegments().get(1); String key = uri.getPathSegments().get(2); - if (!key.contains("pref_key_system_charginginfo_")) return; - - switch (type) { - case "string": - MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "")); - break; - case "integer": - MainModule.mPrefs.put(key, Helpers.getSharedIntPref(mContext, key, 1)); - break; - case "boolean": - MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(mContext, key, false)); - break; - } + if ("pref_key_system_lsalarm_all".equals(key)) MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(mContext, key, false)); + if ("pref_key_system_lsalarm_format".equals(key)) MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "1")); } catch (Throwable t) { XposedBridge.log(t); } @@ -6937,1932 +4217,1389 @@ public void onChange(Uri uri) { } }); - Helpers.hookAllMethods("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader, "getChargingHintText", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Context context = (Context)param.args[0]; - int charge = (int)param.args[2]; - String hint = (String)param.getResult(); - String PROVIDER_POWER_CENTER = (String)XposedHelpers.getStaticObjectField(findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader), "PROVIDER_POWER_CENTER"); - - Bundle bundle = null; - try { - bundle = context.getContentResolver().call(Uri.parse(PROVIDER_POWER_CENTER), "getBatteryCurrent", null, null); - } catch (Exception ignore) {} - - if (bundle != null && charge < 100) { - boolean showCurr = MainModule.mPrefs.getBoolean("system_charginginfo_current"); - boolean showVolt = MainModule.mPrefs.getBoolean("system_charginginfo_voltage"); - boolean showWatt = MainModule.mPrefs.getBoolean("system_charginginfo_wattage"); - boolean showTemp = MainModule.mPrefs.getBoolean("system_charginginfo_temp"); - - ArrayList values = new ArrayList<>(); - BatteryManager btrMgr = (BatteryManager)context.getSystemService(Context.BATTERY_SERVICE); - int currVal = Math.abs(bundle.getInt("current_now")); - long voltVal = btrMgr.getLongProperty(1001); - if (voltVal == Long.MIN_VALUE) voltVal = Settings.Global.getInt(context.getContentResolver(), Helpers.modulePkg + ".battery.voltage", 0); - if (voltVal == Long.MIN_VALUE) voltVal = 0; - long tempVal = btrMgr.getLongProperty(1002); - if (tempVal == Long.MIN_VALUE) tempVal = Settings.Global.getInt(context.getContentResolver(), Helpers.modulePkg + ".battery.temperature", 0); - if (tempVal == Long.MIN_VALUE) tempVal = 0; - - if (showCurr) values.add(currVal + " mA"); - if (showVolt) values.add(String.format(Locale.getDefault(), "%.1f", voltVal / 1000f) + " V"); - if (showWatt) values.add(String.format(Locale.getDefault(), "%.1f", voltVal / 1000f * currVal / 1000f) + " W"); - if (showTemp) values.add(Math.round(tempVal / 10f) + " ℃"); - if (values.size() == 0) return; - String info = TextUtils.join(" · ", values); - - int opt = MainModule.mPrefs.getStringAsInt("system_charginginfo_view", 1); - if (opt == 1) - param.setResult(hint + "\n" + info); - else if (opt == 2) - param.setResult(hint + " · " + info); - else if (opt == 3) - param.setResult(info + " · " + hint); - } - } - }); - - Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.KeyguardIndicationTextView", lpparam.classLoader, new MethodHook() { + Helpers.findAndHookMethod("com.android.keyguard.clock.MiuiKeyguardSingleClock", lpparam.classLoader, "updateTime", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - int opt = MainModule.mPrefs.getStringAsInt("system_charginginfo_view", 1); - if (opt != 1) return; - TextView indicator = (TextView)param.thisObject; - if (indicator != null) indicator.setSingleLine(false); + Object mMiuiBaseClock = XposedHelpers.getObjectField(param.thisObject, "mMiuiBaseClock"); + if (mMiuiBaseClock != null) hookUpdateTime(mMiuiBaseClock, true); } }); - } - - public static void NoSOSHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.keyguard.EmergencyButton", lpparam.classLoader, "updateEmergencyCallButton", new MethodHook() { + Helpers.findAndHookMethod("com.android.keyguard.clock.MiuiKeyguardDualClock", lpparam.classLoader, "updateTime", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Button mSOS = (Button)param.thisObject; - if (mSOS.getVisibility() == View.VISIBLE) { - mSOS.setVisibility(View.INVISIBLE); - } + Object mMiuiDualClock = XposedHelpers.getObjectField(param.thisObject, "mMiuiDualClock"); + if (mMiuiDualClock != null) hookUpdateTime(mMiuiDualClock, false); } }); } - public static void NoDarkForceHook(LoadPackageParam lpparam) { - MethodHook hook = new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - ContentResolver contentResolver = ((Context)XposedHelpers.callMethod(param.thisObject, "getContext")).getContentResolver(); - XposedHelpers.callStaticMethod(Settings.System.class, "putIntForUser", contentResolver, "smart_dark_enable", 0, XposedHelpers.callStaticMethod(UserHandle.class, "getCallingUserId")); - XposedHelpers.callStaticMethod(XposedHelpers.findClassIfExists("android.os.SystemProperties", lpparam.classLoader), "set", "debug.hwui.force_dark", "false"); - } - }; - Helpers.findAndHookMethodSilently("com.android.server.UiModeManagerService", lpparam.classLoader, "setForceDark", Context.class, hook); - Helpers.findAndHookMethod("com.miui.server.SecurityManagerService", lpparam.classLoader, "getAppDarkModeForUser", String.class, int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.setResult(false); - } - }); - Helpers.findAndHookMethod("com.android.server.DarkModeAppSettingsInfo", lpparam.classLoader, "getOverrideEnableValue", new MethodHook() { + public static void ScreenshotConfigHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("android.content.ContentResolver", lpparam.classLoader, "update", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - param.setResult(2); - } - }); - } + if (param.args.length != 4) return; + ContentValues contentValues = (ContentValues) param.args[1]; + String displayName = contentValues.getAsString("_display_name"); + if (displayName != null && displayName.contains("Screenshot")) { + Context context = Helpers.findContext(); + int format = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_format", "2")); + String ext = format <= 2 ? ".jpg" : (format == 3 ? ".png" : ".webp"); - public static void MaxNotificationIconsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.NotificationIconContainer", lpparam.classLoader, "miuiShowNotificationIcons", boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - boolean isShow = (boolean) param.args[0]; - if (isShow) { - int opt = MainModule.mPrefs.getStringAsInt("system_maxsbicons", 0); - opt = opt == -1 ? 999 : opt; - XposedHelpers.setObjectField(param.thisObject, "MAX_DOTS", 3); - XposedHelpers.setObjectField(param.thisObject, "MAX_STATIC_ICONS", opt); - String fieldLockVisible = Helpers.isTPlus() ? "MAX_ICONS_ON_LOCKSCREEN" : "MAX_VISIBLE_ICONS_ON_LOCK"; - XposedHelpers.setObjectField(param.thisObject, fieldLockVisible, opt); - XposedHelpers.callMethod(param.thisObject, "updateState"); - param.setResult(null); + displayName = displayName.replace(".png", "").replace(".jpg", "").replace(".webp", "") + ext; + contentValues.put("_display_name", displayName); } } }); - } - - public static void MoreNotificationsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.policy.NotificationCountLimitPolicy", lpparam.classLoader, "checkNotificationCountLimit", String.class, new MethodHook() { + Helpers.findAndHookMethod("android.content.ContentResolver", lpparam.classLoader, "insert", Uri.class, ContentValues.class, new MethodHook() { @Override - @SuppressWarnings({"unchecked", "SynchronizationOnLocalVariableOrMethodParameter"}) protected void before(MethodHookParam param) throws Throwable { - String pkgName = (String) param.args[0]; - Collection mNotifications = (Collection) XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mEntryManager"), "getAllNotifs"); - List list = (List) mNotifications.stream().filter(new Predicate() { - @Override - public final boolean test(Object obj) { - String notifyPkgName = (String) XposedHelpers.callMethod(XposedHelpers.callMethod(obj, "getSbn"), "getPackageName"); - return pkgName.equals(notifyPkgName); - } - }).collect(Collectors.toList()); - if (list.size() < 24) param.setResult(null); - } - }); - } + Uri imgUri = (Uri) param.args[0]; + ContentValues contentValues = (ContentValues) param.args[1]; + String displayName = contentValues.getAsString("_display_name"); + if (MediaStore.Images.Media.EXTERNAL_CONTENT_URI.equals(imgUri) && displayName != null && displayName.contains("Screenshot")) { + Context context = Helpers.findContext(); + int folder = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_path", "1")); + String dir = Helpers.getSharedStringPref(context, "pref_key_system_screenshot_mypath", ""); + int format = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_format", "2")); + String ext = format <= 2 ? ".jpg" : (format == 3 ? ".png" : ".webp"); - public static void NoMediaMuteInDNDHook() { - Helpers.hookAllMethods("android.media.AudioServiceInjector", null, "handleZenModeChangedForMusic", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if ((int)param.args[2] == 1 || (int)param.args[3] == 1) param.setResult(null); + File mScreenshotDir; + displayName = displayName.replace(".png", "").replace(".jpg", "").replace(".webp", "") + ext; + if (folder > 1) { + if (folder == 4 && !TextUtils.isEmpty(dir)) + mScreenshotDir = new File(dir); + else + mScreenshotDir = new File(Environment.getExternalStoragePublicDirectory(folder == 2 ? Environment.DIRECTORY_PICTURES : Environment.DIRECTORY_DCIM), "Screenshots"); + if (!mScreenshotDir.exists()) mScreenshotDir.mkdirs(); + String relativePath = mScreenshotDir.getPath().replace(Environment.getExternalStorageDirectory().getPath() + File.separator, ""); + contentValues.put("relative_path", relativePath); + if (contentValues.getAsString("_data") != null) { + contentValues.put("_data", mScreenshotDir.getPath() + "/" + displayName); + } + } + contentValues.put("_display_name", displayName); + } } }); - } - public static void VolumeDialogAutohideDelayHook(ClassLoader classLoader) { - Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "computeTimeoutH", new MethodHook() { + Helpers.hookAllMethods("android.graphics.Bitmap", lpparam.classLoader, "compress", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - boolean mHovering = XposedHelpers.getBooleanField(param.thisObject, "mHovering"); - if (mHovering) { - param.setResult(16000); - return; - } - boolean mSafetyWarning; - try { - mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mIsSafetyShowing"); - } - catch (Throwable e) { - mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mSafetyWarning"); - } - if (mSafetyWarning) { - int opt = MainModule.mPrefs.getInt("system_volumedialogdelay_expanded", 0); - param.setResult(opt > 0 ? opt : 5000); - return; + Context context = Helpers.findContext(); + int quality = (int) param.args[1]; + if (quality != 100 || (param.args[2] instanceof ByteArrayOutputStream)) return; + int format = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_screenshot_format", "2")); + quality = Helpers.getSharedIntPref(context, "pref_key_system_screenshot_quality", 100); + if (format == 3) { + quality = 100; } - boolean mExpanded = XposedHelpers.getBooleanField(param.thisObject, "mExpanded"); - int opt = MainModule.mPrefs.getInt(mExpanded ? "system_volumedialogdelay_expanded" : "system_volumedialogdelay_collapsed", 0); - if (opt > 0) param.setResult(opt); - } - }); - } - - public static ArrayList mLastPlayedSounds = new ArrayList(); - - public static void AudioSilencerServiceHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "init", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - IntentFilter filter = new IntentFilter(); - filter.addAction(ACTION_PREFIX + "SavePlayedSound"); - filter.addAction(ACTION_PREFIX + "FetchPlayedSounds"); - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - mContext.registerReceiver(new BroadcastReceiver() { - public void onReceive(final Context context, Intent intent) { - String action = intent.getAction(); - if (action != null) try { - if (action.equals(ACTION_PREFIX + "SavePlayedSound")) { - SoundData data = intent.getParcelableExtra("data"); - mLastPlayedSounds.add(0, data); - if (mLastPlayedSounds.size() > 10) - mLastPlayedSounds = new ArrayList(mLastPlayedSounds.subList(0, 10)); - } else if (action.equals(ACTION_PREFIX + "FetchPlayedSounds")) { - Intent soundsIntent = new Intent(GlobalActions.EVENT_PREFIX + "FetchPlayedSoundsData"); - soundsIntent.putParcelableArrayListExtra("sounds", mLastPlayedSounds); - soundsIntent.setPackage(Helpers.modulePkg); - mContext.sendBroadcast(soundsIntent); - } - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }, filter); + Bitmap.CompressFormat compress = format <= 2 ? Bitmap.CompressFormat.JPEG : (format == 3 ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.WEBP); + param.args[0] = compress; + param.args[1] = quality; } }); } - public static void SavePlayedSound(Context context, SoundData data) { - Intent saveSoundIntent = new Intent(ACTION_PREFIX + "SavePlayedSound"); - saveSoundIntent.putExtra("data", data); - saveSoundIntent.setPackage("android"); - context.sendBroadcast(saveSoundIntent); - } - - @SuppressWarnings({"unchecked"}) - public static void AudioSilencerHook() { - Helpers.hookAllConstructors(SoundPool.class, new MethodHook() { + public static void ToastTimeHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.server.notification.NotificationManagerService", lpparam.classLoader, "showNextToastLocked", new MethodHook() { @Override + @SuppressWarnings("unchecked") protected void after(MethodHookParam param) throws Throwable { - if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData") == null) { - SparseArray mSourceSoundData = new SparseArray(); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSourceSoundData", mSourceSoundData); - } + Context mContext = (Context)XposedHelpers.callMethod(param.thisObject, "getContext"); + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); + ArrayList mToastQueue = (ArrayList)XposedHelpers.getObjectField(param.thisObject, "mToastQueue"); + if (mContext == null || mHandler == null || mToastQueue == null || mToastQueue.size() == 0) return; + int mod = (Helpers.getSharedIntPref(mContext, "pref_key_system_toasttime", 0) - 4) * 1000; + for (Object record: mToastQueue) + if (record != null && mHandler.hasMessages(2, record)) { + mHandler.removeCallbacksAndMessages(record); + int duration = XposedHelpers.getIntField(record, "duration"); + int delay = Math.max(1000, (duration == 1 ? 3500 : 2000) + mod); + mHandler.sendMessageDelayed(Message.obtain(mHandler, 2, record), delay); + } } }); - Helpers.hookAllMethods(SoundPool.class, "load", new MethodHook() { + Helpers.findAndHookMethod("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "systemReady", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - SparseArray mSourceSoundData = (SparseArray)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData"); - Context callerContext = Helpers.findContext(); - if (callerContext == null) return; - String caller = callerContext.getPackageName(); - if (param.args[0] instanceof Context) { - Context mContext = (Context)param.args[0]; - mSourceSoundData.put((int)param.getResult(), new SoundData(caller, "resource", mContext.getResources().getResourceName((int)param.args[1]))); - } else if (param.args[0] instanceof String) { - mSourceSoundData.put((int)param.getResult(), new SoundData(caller, "file", (String)param.args[0])); - } + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); + + new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_toasttime", 0) { + @Override + public void onChange(String name, int defValue) { + MainModule.mPrefs.put(name, Helpers.getSharedIntPref(mContext, name, defValue)); + } + }; } }); - Helpers.hookAllMethods(SoundPool.class, "play", new MethodHook() { + String windowClass = "com.android.server.wm.DisplayPolicy"; + Helpers.hookAllMethods(windowClass, lpparam.classLoader, "adjustWindowParamsLw", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - SparseArray mSourceSoundData = (SparseArray)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData"); - if (mSourceSoundData != null) { - Context mContext = Helpers.findContext(); - if (mContext == null) return; - SoundData data = mSourceSoundData.get((Integer)param.args[0]); - SavePlayedSound(mContext, data); - Set silencedSounds = Helpers.getSharedStringSetPref(mContext, "pref_key_system_audiosilencer_sounds"); - if (silencedSounds.contains(data.toPref())) param.setResult(null); - } + Object lp = param.args.length == 1 ? param.args[0] : param.args[1]; + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mPrevHideTimeout", XposedHelpers.getLongField(lp, "hideTimeoutMilliseconds")); } - }); - Helpers.hookAllMethods(MediaPlayer.class, "setDataSource", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - if (Modifier.isPrivate(param.method.getModifiers())) return; - Context callerContext = Helpers.findContext(); - if (callerContext == null) return; - String caller = callerContext.getPackageName(); - SoundData soundData = null; - if (param.args.length > 1 && param.args[0] instanceof Context && param.args[1] instanceof Uri) - soundData = new SoundData(caller, "uri", ((Uri)param.args[1]).getPath()); - else if (param.args[0] instanceof String) - soundData = new SoundData(caller, "file", (String)param.args[0]); - if (soundData != null) - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSourceSoundData", soundData); + protected void after(MethodHookParam param) throws Throwable { + Object lp = param.args.length == 1 ? param.args[0] : param.args[1]; + long mPrevHideTimeout = (long)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mPrevHideTimeout"); + long mHideTimeout = XposedHelpers.getLongField(lp, "hideTimeoutMilliseconds"); + if (mPrevHideTimeout == -1 || mHideTimeout == -1) return; + + long dur = 0; + if (mPrevHideTimeout == 1000 || mPrevHideTimeout == 4000 || mPrevHideTimeout == 5000 || mPrevHideTimeout == 7000 || mPrevHideTimeout != mHideTimeout) + dur = Math.max(1000, 3500 + (MainModule.mPrefs.getInt("system_toasttime", 0) - 4) * 1000); + if (dur != 0) XposedHelpers.setLongField(lp, "hideTimeoutMilliseconds", dur); } }); + } - Helpers.hookAllMethods(MediaPlayer.class, "start", new MethodHook() { + public static void ClearAllTasksHook(LoadPackageParam lpparam) { + String wpuClass = "com.android.server.wm.WindowProcessUtils"; + Helpers.hookAllMethods(wpuClass, lpparam.classLoader, "getPerceptibleRecentAppList", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - SoundData mSourceSoundData = (SoundData)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData"); - if (mSourceSoundData != null) { - Context mContext = Helpers.findContext(); - if (mContext == null) return; - SavePlayedSound(mContext, mSourceSoundData); - Set silencedSounds = Helpers.getSharedStringSetPref(mContext, "pref_key_system_audiosilencer_sounds"); - if (silencedSounds.contains(mSourceSoundData.toPref())) param.setResult(null); - } + protected void after(MethodHookParam param) throws Throwable { + param.setResult(null); } }); } - public static void BetterPopupsAllowFloatHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.notification.policy.AppMiniWindowManager", lpparam.classLoader, new MethodHook() { + public static void InactiveBrightnessSliderHook(LoadPackageParam lpparam) { + MethodHook hook = new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "context"); - Handler mHandler = new Handler(Looper.getMainLooper()); + int opt = MainModule.mPrefs.getStringAsInt("system_inactivebrightness", 1); + if (opt == 2) { + SeekBar mSlider = (SeekBar)XposedHelpers.getObjectField(param.thisObject, "mSlider"); + if (mSlider != null) + mSlider.setOnTouchListener(new View.OnTouchListener(){ + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + } else if (opt == 3) try { + View sliderView = (View)param.thisObject; + ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)sliderView.getLayoutParams(); + lp.height = 0; + lp.topMargin = Math.round(2 * sliderView.getResources().getDisplayMetrics().density); + lp.bottomMargin = 0; + sliderView.setLayoutParams(lp); + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }; + Helpers.findAndHookMethod("com.android.systemui.settings.brightness.BrightnessSliderView", lpparam.classLoader, "onFinishInflate", hook); +// Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.widget.QCToggleSliderView", lpparam.classLoader, "onAttachedToWindow", hook); + } - new Helpers.SharedPrefObserver(mContext, mHandler) { - @Override - public void onChange(Uri uri) { - try { - String key = uri.getPathSegments().get(2); - if (key.contains("pref_key_system_betterpopups_allowfloat_apps")) - MainModule.mPrefs.put(key, Helpers.getSharedStringSetPref(mContext, key)); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; + private static final float[] startPos = new float[2]; + private static void processLSEvent(MethodHookParam param) { + MotionEvent event = (MotionEvent)param.args[0]; + if (event.getPointerCount() > 1) return; + int action = event.getActionMasked(); + if (action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_UP) return; + + ViewGroup mKeyguardBottomArea = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mBottomAreaView"); + if (mKeyguardBottomArea == null) return; + ViewGroup mIndicationArea = (ViewGroup)XposedHelpers.getObjectField(mKeyguardBottomArea, "mIndicationArea"); + if (!Helpers.isReallyVisible(mIndicationArea)) return; + + int[] coord = new int[2]; + mIndicationArea.getLocationOnScreen(coord); + Rect rect = new Rect(coord[0], coord[1], coord[0] + mIndicationArea.getWidth(), coord[1] + mIndicationArea.getHeight()); + if (!rect.contains((int)event.getX(), (int)event.getY())) return; + + if (action == MotionEvent.ACTION_DOWN) { + startPos[0] = event.getX(); + startPos[1] = event.getY(); + } else if (action == MotionEvent.ACTION_UP) try { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + int slop = ViewConfiguration.get(mContext).getScaledTouchSlop(); + if (Math.abs(event.getX() - startPos[0]) > slop || Math.abs(event.getY() - startPos[1]) > slop) return; + Object mPanelViewController = XposedHelpers.getObjectField(param.thisObject, "mPanelViewController"); + Object statusBarKeyguardViewManager = XposedHelpers.getObjectField(mPanelViewController, "statusBarKeyguardViewManager"); + + XposedHelpers.callMethod(statusBarKeyguardViewManager, "showGenericBouncer", true); + } catch (Throwable t) { + XposedBridge.log(t); + } + } + + public static void TapToUnlockHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader, "onTouchEvent", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + processLSEvent(param); } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.NotificationSettingsManager", lpparam.classLoader, "canSlide", String.class, new MethodHook() { + Helpers.hookAllMethods("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader, "onInterceptTouchEvent", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - String pkgName = (String) param.args[0]; - Set selectedApps = MainModule.mPrefs.getStringSet("system_betterpopups_allowfloat_apps"); - Set selectedAppsBlack = MainModule.mPrefs.getStringSet("system_betterpopups_allowfloat_apps_black"); - if (selectedApps.contains(pkgName)) param.setResult(true); - else if (selectedAppsBlack.contains(pkgName)) param.setResult(false); + processLSEvent(param); } }); + } - Helpers.hookAllMethods("com.android.systemui.statusbar.notification.policy.MiniWindowPolicy", lpparam.classLoader, "canSlidePackage", new MethodHook() { + public static void NoSafeVolumeWarningRes() { + MainModule.resHooks.setObjectReplacement("android", "bool", "config_safe_media_volume_enabled", false); + MainModule.resHooks.setObjectReplacement("android", "bool", "config_safe_media_disable_on_volume_up", false); + } + + public static void NoLowBatteryWarningHook() { + MethodHook settingHook = new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - param.setResult(true); + String key = (String)param.args[1]; + if ("low_battery_dialog_disabled".equals(key)) param.setResult(1); + else if ("power_sounds_enabled".equals(key)) param.setResult(0); } - }); + }; + Helpers.hookAllMethods(Settings.System.class, "getIntForUser", settingHook); + Helpers.hookAllMethods(Settings.System.class, "getInt", settingHook); } - public static void NoFloatingWindowBlacklistHook(LoadPackageParam lpparam) { - MainModule.resHooks.setResReplacement("android", "array", "freeform_black_list", R.array.miui_resize_black_list); - MainModule.resHooks.setResReplacement("com.miui.rom", "array", "freeform_black_list", R.array.miui_resize_black_list); - MethodHook clearHook = new MethodHook() { + public static void TempHideOverlayAppHook(LoadPackageParam lpparam) { + final boolean[] isListened = {false}; + final ArrayList mViews = new ArrayList<>(); + MethodHook addViewHook = new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - List blackList = (List)param.getResult(); - if (blackList != null) blackList.clear(); - param.setResult(blackList); + protected void after(final MethodHookParam param) throws Throwable { + if (param.args[0] == null || !(param.args[1] instanceof WindowManager.LayoutParams) || param.getThrowable() != null) return; + WindowManager.LayoutParams params = (WindowManager.LayoutParams)param.args[1]; + if (params.type != WindowManager.LayoutParams.TYPE_PHONE + && params.type != WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY + && params.type != WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY) return; + View view = (View)param.args[0]; + Context mContext = view.getContext(); + mViews.add(view); + + if (!isListened[0]) { + isListened[0] = true; + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction("miui.intent.TAKE_SCREENSHOT"); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) return; + if (action.equals("miui.intent.TAKE_SCREENSHOT")) { + boolean state = intent.getBooleanExtra("IsFinished", true); + for (int size = mViews.size() - 1; size >= 0; size--) { + View vs = mViews.get(size); + if (vs != null) { + if (state) { + if (vs.getVisibility() != View.VISIBLE && XposedHelpers.getAdditionalInstanceField(vs, "mSavedVisibility") != null) { + XposedHelpers.removeAdditionalInstanceField(vs, "mSavedVisibility"); + vs.setVisibility(View.VISIBLE); + } + } + else { + if (vs.getVisibility() == View.VISIBLE) { + vs.setVisibility(View.INVISIBLE); + XposedHelpers.setAdditionalInstanceField(vs, "mSavedVisibility", true); + } + } + } + } + } + } + }, intentFilter); + } } }; - Helpers.hookAllMethods("android.util.MiuiMultiWindowAdapter", lpparam.classLoader, "getFreeformBlackList", clearHook); - Helpers.hookAllMethods("android.util.MiuiMultiWindowAdapter", lpparam.classLoader, "getFreeformBlackListFromCloud", clearHook); - Helpers.hookAllMethods("android.util.MiuiMultiWindowAdapter", lpparam.classLoader, "setFreeformBlackList", new MethodHook() { + MethodHook removeViewHook = new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - List blackList = new ArrayList(); - blackList.add("ab.cd.xyz"); - param.args[0] = blackList; + protected void before(final MethodHookParam param) throws Throwable { + mViews.remove(param.args[0]); } - }); - Helpers.findAndHookMethod("android.util.MiuiMultiWindowUtils", lpparam.classLoader, "isForceResizeable", XC_MethodReplacement.returnConstant(true)); - Helpers.findAndHookMethod("android.util.MiuiMultiWindowUtils", lpparam.classLoader, "supportFreeform", XC_MethodReplacement.returnConstant(true)); - if (Helpers.isTPlus()) { - Helpers.findAndHookMethod("com.android.server.wm.MiuiFreeformServicesUtils", lpparam.classLoader, "supportsFreeform", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - param.setResult(true); - } - }); - } - } - - public static ConcurrentHashMap> fwApps = new ConcurrentHashMap>(); - - public static String getTaskPackageName(Object thisObject, int taskId) { - return getTaskPackageName(thisObject, taskId, false, null); - } - - public static String getTaskPackageName(Object thisObject, int taskId, ActivityOptions options) { - return getTaskPackageName(thisObject, taskId, options != null, options); - } - - public static String getTaskPackageName(Object thisObject, int taskId, boolean withOptions, ActivityOptions options) { - Object mRootWindowContainer = XposedHelpers.getObjectField(thisObject, "mRootWindowContainer"); - if (mRootWindowContainer == null) return null; - Object task = withOptions ? - XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 2, options, true) : - XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 0); - if (task == null) return null; - Intent intent = (Intent)XposedHelpers.getObjectField(task, "intent"); - return intent == null ? null : intent.getComponent().getPackageName(); - } - - public static String serializeFwApps() { - StringBuilder data = new StringBuilder(); - for (Map.Entry> entry: fwApps.entrySet()) { - Pair val = entry.getValue(); - data.append(entry.getKey()); - data.append(":"); - data.append(val.first); - data.append(":"); - data.append(val.second == null ? "-" : val.second.flattenToString()); - data.append("|"); - } - return data.toString().replaceFirst("\\|$", ""); + }; + Helpers.hookAllMethods("android.view.WindowManagerGlobal", lpparam.classLoader, "addView", addViewHook); + Helpers.hookAllMethods("android.view.WindowManagerGlobal", lpparam.classLoader, "removeView", removeViewHook); } - public static void unserializeFwApps(String data) { - fwApps.clear(); - if (data == null || "".equals(data)) return; - String[] dataArr = data.split("\\|"); - for (String appData: dataArr) { - if ("".equals(appData)) continue; - String[] appDataArr = appData.split(":"); - fwApps.put(appDataArr[0], new Pair(Float.parseFloat(appDataArr[1]), "-".equals(appDataArr[2]) ? null : Rect.unflattenFromString(appDataArr[2]))); + public static void GalleryScreenshotPathHook(LoadPackageParam lpparam) { + Class MIUIStorageConstants = findClass("com.miui.gallery.storage.constants.MIUIStorageConstants", lpparam.classLoader); + int folder = MainModule.mPrefs.getStringAsInt("system_gallery_screenshots_path", 1); + String ssPath = ""; + if (folder == 2) { + ssPath = Environment.DIRECTORY_PICTURES + File.separator + "Screenshots"; } - } - - public static void storeFwAppsInSetting(Context context) { - Settings.Global.putString(context.getContentResolver(), Helpers.modulePkg + ".fw.apps", serializeFwApps()); - } - - public static void restoreFwAppsInSetting(Context context) { - unserializeFwApps(Settings.Global.getString(context.getContentResolver(), Helpers.modulePkg + ".fw.apps")); - } - private static ActivityOptions patchActivityOptions(Context mContext, ActivityOptions options, String pkgName, Class MiuiMultiWindowUtils) { - if (options == null) options = ActivityOptions.makeBasic(); - XposedHelpers.callMethod(options, "setLaunchWindowingMode", 5); - XposedHelpers.callMethod(options, "setMiuiConfigFlag", 2); - - Float scale; - Rect rect; - Pair values = fwApps.get(pkgName); - if (values == null || values.first == 0f || values.second == null) { - scale = 0.7f; - rect = (Rect)XposedHelpers.callStaticMethod(MiuiMultiWindowUtils, "getFreeformRect", mContext); - } else { - scale = values.first; - rect = values.second; + else if (folder == 3) { + ssPath = Environment.DIRECTORY_DCIM + File.separator + "Screenshots"; } - options.setLaunchBounds(rect); - try { - Object injector = XposedHelpers.callMethod(options, "getActivityOptionsInjector"); - XposedHelpers.callMethod(injector, "setFreeformScale", scale); - } catch (Throwable ignore) { - XposedBridge.log(ignore); + if (folder > 1) { + XposedHelpers.setStaticObjectField(MIUIStorageConstants, "DIRECTORY_SCREENSHOT_PATH", ssPath); } - return options; } - public static void StickyFloatingWindowsHook(LoadPackageParam lpparam) { - final List fwBlackList = new ArrayList(); - fwBlackList.add("com.miui.securitycenter"); - fwBlackList.add("com.miui.home"); - fwBlackList.add("com.android.camera"); - Class MiuiMultiWindowUtils = findClass("android.util.MiuiMultiWindowUtils", lpparam.classLoader); - Helpers.hookAllMethods("com.android.server.wm.ActivityStarterInjector", lpparam.classLoader, "modifyLaunchActivityOptionIfNeed", new MethodHook() { + public static void ScreenshotFloatTimeHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.miui.screenshot.GlobalScreenshot", lpparam.classLoader, "startGotoThumbnailAnimation", Runnable.class, new MethodHook() { @Override + @SuppressWarnings("ConstantConditions") protected void after(MethodHookParam param) throws Throwable { - if (param.args.length != 8) return; - Intent intent = (Intent)param.args[5]; - if (intent == null || intent.getComponent() == null) return; - ActivityOptions options = (ActivityOptions)param.getResult(); - int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); - String pkgName = intent.getComponent().getPackageName(); - if (fwBlackList.contains(pkgName)) return; - Context mContext; + boolean mIsShowLongScreenShotGuide = false; try { - mContext = (Context)XposedHelpers.getObjectField(param.args[0], "mContext"); - } catch (Throwable ignore) { - mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.args[0], "mService"), "mContext"); - } - if (windowingMode != 5 && fwApps.containsKey(pkgName)) { - try { - if (MiuiMultiWindowUtils == null) { - Helpers.log("StickyFloatingWindowsHook", "Cannot find MiuiMultiWindowUtils class"); - return; - } - options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); - param.setResult(options); - } catch (Throwable t) { - Helpers.log(t); - } - } - else if (windowingMode == 5 && !fwApps.containsKey(pkgName)) { - fwApps.put(pkgName, new Pair(0f, null)); - storeFwAppsInSetting(mContext); - } + mIsShowLongScreenShotGuide = XposedHelpers.getBooleanField(param.thisObject, "mIsShowLongScreenShotGuide"); + } catch (Throwable ignore) {} + if (mIsShowLongScreenShotGuide) return; + int opt = MainModule.mPrefs.getInt("system_screenshot_floattime", 0); + if (opt <= 0) return; + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); + Runnable mQuitThumbnailRunnable = (Runnable)XposedHelpers.getObjectField(param.thisObject, "mQuitThumbnailRunnable"); + mHandler.removeCallbacks(mQuitThumbnailRunnable); + mHandler.postDelayed(mQuitThumbnailRunnable, opt * 1000L); } }); + } - Helpers.hookAllMethods("com.android.server.wm.ActivityTaskSupervisor", lpparam.classLoader, "startActivityFromRecents", new MethodHook() { + public static void ScrambleAppLockPINHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.miui.applicationlock.widget.MiuiNumericInputView", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Object safeOptions = param.args[3]; - ActivityOptions options = (ActivityOptions)XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject); - if (Helpers.isTPlus()) { - if (options != null) { - Object windowToken = XposedHelpers.callMethod(options, "getLaunchRootTask"); - if (windowToken != null) return; - } - } - String pkgName = (String) XposedHelpers.getAdditionalInstanceField(param.thisObject, "startPackageName"); - XposedHelpers.removeAdditionalInstanceField(param.thisObject, "startPackageName"); - if (fwBlackList.contains(pkgName)) return; - int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); - if (windowingMode == 5 && pkgName != null) { - fwApps.put(pkgName, new Pair(0f, null)); - Context mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext"); - storeFwAppsInSetting(mContext); - } - } - @Override - protected void before(MethodHookParam param) throws Throwable { - Object safeOptions = param.args[3]; - ActivityOptions options = (ActivityOptions)XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject); - if (Helpers.isTPlus()) { - if (options != null) { - Object windowToken = XposedHelpers.callMethod(options, "getLaunchRootTask"); - if (windowToken != null) return; - } - } - String pkgName = getTaskPackageName(param.thisObject, (int)param.args[2], options); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "startPackageName", pkgName); - if (!fwBlackList.contains(pkgName)) { - int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); - if (windowingMode != 5 && fwApps.containsKey(pkgName)) { - Object mService = XposedHelpers.getObjectField(param.thisObject, "mService"); - Context mContext = (Context)XposedHelpers.getObjectField(mService, "mContext"); - options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); - XposedHelpers.setObjectField(safeOptions, "mOriginalOptions", options); - param.args[3] = safeOptions; - Intent intent = new Intent(ACTION_PREFIX + "dismissRecentsWhenFreeWindowOpen"); - intent.putExtra("package", pkgName); - mContext.sendBroadcast(intent); + LinearLayout keys = (LinearLayout)param.thisObject; + ArrayList mRandomViews = new ArrayList(); + View bottom0 = null; View bottom2 = null; + for (int row = 0; row <= 3; row++) { + ViewGroup cols = (ViewGroup)keys.getChildAt(row); + for (int col = 0; col <= 2; col++) { + if (row == 3) + if (col == 0) { + bottom0 = cols.getChildAt(col); + continue; + } else if (col == 2) { + bottom2 = cols.getChildAt(col); + continue; + } + mRandomViews.add(cols.getChildAt(col)); } + cols.removeAllViews(); } - } - }); - Helpers.findAndHookMethod("com.android.server.wm.MiuiFreeFormGestureController$FreeFormReceiver", lpparam.classLoader, "onReceive", new Object[]{Context.class, Intent.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Intent intent = (Intent) param.args[1]; - String action = intent.getAction(); - if (action == "miui.intent.action_launch_fullscreen_from_freeform") { - Object parentThis = XposedHelpers.getSurroundingThis(param.thisObject); - XposedHelpers.setAdditionalInstanceField(parentThis, "skipFreeFormStateClear", true); - } - } - }}); + Collections.shuffle(mRandomViews); - Helpers.hookAllMethods("com.android.server.wm.MiuiFreeFormGestureController", lpparam.classLoader, "notifyFullScreenWidnowModeStart", new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - if (param.args.length != 3) return; - String pkgName = (String)XposedHelpers.callMethod(param.args[1], "getStackPackageName"); - Object skipClear = XposedHelpers.getAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear"); - boolean skipFreeFormStateClear = false; - if (skipClear != null) { - skipFreeFormStateClear = (boolean) skipClear; - } - if (!skipFreeFormStateClear) { - if (fwBlackList.contains(pkgName)) return; - if (fwApps.remove(pkgName) != null) { - storeFwAppsInSetting((Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext")); + int cnt = 0; + for (int row = 0; row <= 3; row++) + for (int col = 0; col <= 2; col++) { + ViewGroup cols = (ViewGroup)keys.getChildAt(row); + if (row == 3) + if (col == 0) { + cols.addView(bottom0); + continue; + } else if (col == 2) { + cols.addView(bottom2); + continue; + } + cols.addView(mRandomViews.get(cnt)); + cnt++; } - } - else { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear", false); - } } }); + } - Helpers.hookAllMethods("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "launchSmallFreeFormWindow", new MethodHook() { + public static void ChargingInfoServiceHook(LoadPackageParam lpparam) { + if (!Helpers.hookAllMethodsSilently("com.android.server.BatteryService$BatteryPropertiesRegistrar", lpparam.classLoader, "getProperty", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int req = (int)param.args[0]; + if (req < 1000) return; + long value = Long.MIN_VALUE; + if (req == 1001) + value = XposedHelpers.getIntField(XposedHelpers.getSurroundingThis(param.thisObject), "mLastBatteryVoltage"); + else if (req == 1002) + value = XposedHelpers.getIntField(XposedHelpers.getSurroundingThis(param.thisObject), "mLastBatteryTemperature"); + else if (req == 1003) + value = XposedHelpers.getIntField(XposedHelpers.getSurroundingThis(param.thisObject), "mLastBatteryHealth"); + XposedHelpers.callMethod(param.args[1], "setLong", value); + param.setResult(0); + } + })) Helpers.findAndHookMethod("com.android.server.BatteryService", lpparam.classLoader, "processValuesLocked", boolean.class, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Object taskId = XposedHelpers.getObjectField(param.args[0], "taskId"); - Object mMiuiFreeFormManagerService = XposedHelpers.getObjectField(param.thisObject, "mMiuiFreeFormManagerService"); - Object miuiFreeFormActivityStack = XposedHelpers.callMethod(mMiuiFreeFormManagerService, "getMiuiFreeFormActivityStack", taskId); - String pkgName = (String) XposedHelpers.callMethod(miuiFreeFormActivityStack, "getStackPackageName"); - if (fwBlackList.contains(pkgName)) return; - if (!fwApps.containsKey(pkgName)) { - fwApps.put(pkgName, new Pair(0f, null)); + try { Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - storeFwAppsInSetting(mContext); - } + ContentResolver provider = mContext.getContentResolver(); + Settings.Global.putInt(provider, Helpers.modulePkg + ".battery.voltage", XposedHelpers.getIntField(param.thisObject, "mLastBatteryVoltage")); + Settings.Global.putInt(provider, Helpers.modulePkg + ".battery.temperature", XposedHelpers.getIntField(param.thisObject, "mLastBatteryTemperature")); + Settings.Global.putInt(provider, Helpers.modulePkg + ".battery.health", XposedHelpers.getIntField(param.thisObject, "mLastBatteryHealth")); + } catch (Throwable ignore) {} } }); + } - Helpers.findAndHookMethod("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "onSystemReady", new MethodHook() { + public static void ChargingInfoHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.keyguard.KeyguardUpdateMonitor", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - restoreFwAppsInSetting(mContext); - Class MiuiMultiWindowAdapter = findClass("android.util.MiuiMultiWindowAdapter", lpparam.classLoader); - List blackList = (List) XposedHelpers.getStaticObjectField(MiuiMultiWindowAdapter, "FREEFORM_BLACK_LIST"); - blackList.clear(); - mContext.registerReceiver(new BroadcastReceiver() { + Context mContext = (Context)param.args[0]; + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); + + new Helpers.SharedPrefObserver(mContext, mHandler) { @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == "miui.intent.action_launch_fullscreen_from_freeform") { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear", true); + public void onChange(Uri uri) { + try { + String type = uri.getPathSegments().get(1); + String key = uri.getPathSegments().get(2); + if (!key.contains("pref_key_system_charginginfo_")) return; + + switch (type) { + case "string": + MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "")); + break; + case "integer": + MainModule.mPrefs.put(key, Helpers.getSharedIntPref(mContext, key, 1)); + break; + case "boolean": + MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(mContext, key, false)); + break; + } + } catch (Throwable t) { + XposedBridge.log(t); } } - }, new IntentFilter("miui.intent.action_launch_fullscreen_from_freeform")); + }; } }); - Helpers.hookAllMethods("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "resizeTask", new MethodHook() { + Helpers.hookAllMethods("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader, "getChargingHintText", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - String pkgName = getTaskPackageName(param.thisObject, (int)param.args[0]); - if (pkgName != null) { - Object skipClear = XposedHelpers.getAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear"); - boolean skipFreeFormStateClear = false; - if (skipClear != null) { - skipFreeFormStateClear = (boolean) skipClear; - } - if (skipFreeFormStateClear) { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear", false); - } - else { - if (fwBlackList.contains(pkgName)) return; - Object mMiuiFreeFormManagerService = XposedHelpers.getObjectField(param.thisObject, "mMiuiFreeFormManagerService"); - Object miuiFreeFormActivityStack = XposedHelpers.callMethod(mMiuiFreeFormManagerService, "getMiuiFreeFormActivityStack", param.args[0]); - if (fwApps.containsKey(pkgName)) { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - float sScale = (float) XposedHelpers.callMethod(miuiFreeFormActivityStack, "getFreeFormScale"); - fwApps.put(pkgName, new Pair(sScale, new Rect((Rect)param.args[1]))); - storeFwAppsInSetting(mContext); - } - } + protected void after(MethodHookParam param) throws Throwable { + Context context = (Context)param.args[0]; + int charge = (int)param.args[2]; + String hint = (String)param.getResult(); + String PROVIDER_POWER_CENTER = (String)XposedHelpers.getStaticObjectField(findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader), "PROVIDER_POWER_CENTER"); + + Bundle bundle = null; + try { + bundle = context.getContentResolver().call(Uri.parse(PROVIDER_POWER_CENTER), "getBatteryCurrent", null, null); + } catch (Exception ignore) {} + + if (bundle != null && charge < 100) { + boolean showCurr = MainModule.mPrefs.getBoolean("system_charginginfo_current"); + boolean showVolt = MainModule.mPrefs.getBoolean("system_charginginfo_voltage"); + boolean showWatt = MainModule.mPrefs.getBoolean("system_charginginfo_wattage"); + boolean showTemp = MainModule.mPrefs.getBoolean("system_charginginfo_temp"); + + ArrayList values = new ArrayList<>(); + BatteryManager btrMgr = (BatteryManager)context.getSystemService(Context.BATTERY_SERVICE); + int currVal = Math.abs(bundle.getInt("current_now")); + long voltVal = btrMgr.getLongProperty(1001); + if (voltVal == Long.MIN_VALUE) voltVal = Settings.Global.getInt(context.getContentResolver(), Helpers.modulePkg + ".battery.voltage", 0); + if (voltVal == Long.MIN_VALUE) voltVal = 0; + long tempVal = btrMgr.getLongProperty(1002); + if (tempVal == Long.MIN_VALUE) tempVal = Settings.Global.getInt(context.getContentResolver(), Helpers.modulePkg + ".battery.temperature", 0); + if (tempVal == Long.MIN_VALUE) tempVal = 0; + + if (showCurr) values.add(currVal + " mA"); + if (showVolt) values.add(String.format(Locale.getDefault(), "%.1f", voltVal / 1000f) + " V"); + if (showWatt) values.add(String.format(Locale.getDefault(), "%.1f", voltVal / 1000f * currVal / 1000f) + " W"); + if (showTemp) values.add(Math.round(tempVal / 10f) + " ℃"); + if (values.size() == 0) return; + String info = TextUtils.join(" · ", values); + + int opt = MainModule.mPrefs.getStringAsInt("system_charginginfo_view", 1); + if (opt == 1) + param.setResult(hint + "\n" + info); + else if (opt == 2) + param.setResult(hint + " · " + info); + else if (opt == 3) + param.setResult(info + " · " + hint); } } }); - } - public static void MessagingStyleLinesSysHook() { - Helpers.findAndHookMethod("android.app.Notification.MessagingStyle", null, "makeMessagingView", boolean.class, boolean.class, new MethodHook() { + Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.KeyguardIndicationTextView", lpparam.classLoader, new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - if ((boolean)param.args[0] && (boolean)param.args[1]) return; - RemoteViews remote = (RemoteViews)param.getResult(); - Context mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mBuilder"), "mContext"); - remote.setInt(mContext.getResources().getIdentifier("notification_messaging", "id", "android"), "setMaxDisplayedLines", MainModule.mPrefs.getInt("system_messagingstylelines", Integer.MAX_VALUE)); + int opt = MainModule.mPrefs.getStringAsInt("system_charginginfo_view", 1); + if (opt != 1) return; + TextView indicator = (TextView)param.thisObject; + if (indicator != null) indicator.setSingleLine(false); } }); } - public static void MessagingStyleLinesHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.android.systemui.statusbar.notification.NotificationMessagingTemplateViewWrapper", lpparam.classLoader, new MethodHook() { + public static void NoSOSHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.keyguard.EmergencyButton", lpparam.classLoader, "updateEmergencyCallButton", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Object mMessagingLinearLayout = XposedHelpers.getObjectField(param.thisObject, "mMessagingLinearLayout"); - int mMaxDisplayedLines = XposedHelpers.getIntField(mMessagingLinearLayout, "mMaxDisplayedLines"); - if (mMaxDisplayedLines == Integer.MAX_VALUE) XposedHelpers.callMethod(mMessagingLinearLayout, "setMaxDisplayedLines", MainModule.mPrefs.getInt("system_messagingstylelines", Integer.MAX_VALUE)); + Button mSOS = (Button)param.thisObject; + if (mSOS.getVisibility() == View.VISIBLE) { + mSOS.setVisibility(View.INVISIBLE); + } } }); } - public static void MultiWindowPlusHook(LoadPackageParam lpparam) { - if (lpparam.packageName.equals("com.miui.home")) { - Helpers.findAndHookMethodSilently("com.android.systemui.shared.recents.model.Task", lpparam.classLoader, "isSupportSplit", XC_MethodReplacement.returnConstant(true)); - Helpers.hookAllMethods("com.miui.home.recents.views.RecentMenuView", lpparam.classLoader, "onMessageEvent", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - ImageView mMenuItemMultiWindow = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mMenuItemMultiWindow"); - ImageView mMenuItemSmallWindow = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mMenuItemSmallWindow"); - mMenuItemMultiWindow.setEnabled(true); - mMenuItemMultiWindow.setImageAlpha(255); - mMenuItemSmallWindow.setEnabled(true); - mMenuItemSmallWindow.setImageAlpha(255); - } - }, 200); - } - }); - } - else if (lpparam.packageName.equals("android")) { - MainModule.resHooks.setResReplacement("android", "array", "miui_resize_black_list", R.array.miui_resize_black_list); - MainModule.resHooks.setResReplacement("com.miui.rom", "array", "miui_resize_black_list", R.array.miui_resize_black_list); - Class AtmClass = XposedHelpers.findClassIfExists("com.android.server.wm.ActivityTaskManagerServiceImpl", lpparam.classLoader); - if (AtmClass != null) { - Helpers.findAndHookMethod(AtmClass, "updateResizeBlackList", Context.class, XC_MethodReplacement.DO_NOTHING); - Helpers.findAndHookMethod(AtmClass, "getSplitScreenBlackListFromXml", XC_MethodReplacement.DO_NOTHING); - Helpers.hookAllMethods(AtmClass, "inResizeBlackList", XC_MethodReplacement.returnConstant(false)); + public static void NoDarkForceHook(LoadPackageParam lpparam) { + MethodHook hook = new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + ContentResolver contentResolver = ((Context)XposedHelpers.callMethod(param.thisObject, "getContext")).getContentResolver(); + XposedHelpers.callStaticMethod(Settings.System.class, "putIntForUser", contentResolver, "smart_dark_enable", 0, XposedHelpers.callStaticMethod(UserHandle.class, "getCallingUserId")); + XposedHelpers.callStaticMethod(XposedHelpers.findClassIfExists("android.os.SystemProperties", lpparam.classLoader), "set", "debug.hwui.force_dark", "false"); } - } -// else { -// Class AtmClass = XposedHelpers.findClassIfExists("android.app.ActivityTaskManager", lpparam.classLoader); -// if (AtmClass != null) { -// Helpers.hookAllMethods(AtmClass, "supportsSplitScreen", XC_MethodReplacement.returnConstant(true)); -// } -// } - } - - public static void SecureControlCenterHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethodSilently("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader, "supportExpandableStatusbarUnderKeyguard", XC_MethodReplacement.returnConstant(false)); - Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader, "onContentChanged", new MethodHook() { + }; + Helpers.findAndHookMethodSilently("com.android.server.UiModeManagerService", lpparam.classLoader, "setForceDark", Context.class, hook); + Helpers.findAndHookMethod("com.miui.server.SecurityManagerService", lpparam.classLoader, "getAppDarkModeForUser", String.class, int.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - String key = (String) param.args[0]; - if ("expandable_under_lock_screen".equals(key)) { - param.args[1] = "0"; - } + param.setResult(false); } }); - } - - public static void MinimalNotificationViewHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateNotification", new MethodHook() { + Helpers.findAndHookMethod("com.android.server.DarkModeAppSettingsInfo", lpparam.classLoader, "getOverrideEnableValue", new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - if (param.args.length != 3) return; - Object expandableRow = XposedHelpers.getObjectField(param.args[0], "row"); - Object mNotificationData = XposedHelpers.getObjectField(param.thisObject, "mNotificationData"); - boolean newLowPriority = (boolean)XposedHelpers.callMethod(mNotificationData, "isAmbient", XposedHelpers.callMethod(param.args[1], "getKey")) && !(boolean)XposedHelpers.callMethod(XposedHelpers.callMethod(param.args[1], "getNotification"), "isGroupSummary"); - boolean hasEntry = XposedHelpers.callMethod(mNotificationData, "get", XposedHelpers.getObjectField(param.args[0], "key")) != null; - boolean isLowPriority = (boolean)XposedHelpers.callMethod(expandableRow, "isLowPriority"); - XposedHelpers.callMethod(expandableRow, "setIsLowPriority", newLowPriority); - boolean hasLowPriorityChanged = hasEntry && isLowPriority != newLowPriority; - XposedHelpers.callMethod(expandableRow, "setLowPriorityStateUpdated", hasLowPriorityChanged); - XposedHelpers.callMethod(expandableRow, "updateNotification", param.args[0]); + protected void before(MethodHookParam param) throws Throwable { + param.setResult(2); } }); } - public static void NotificationChannelSettingsHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow", lpparam.classLoader, "onClickInfoItem", new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Context mContext = (Context)param.args[0]; - Object entry = XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mParent"), "getEntry"); - String id = (String)XposedHelpers.callMethod(XposedHelpers.callMethod(entry, "getChannel"), "getId"); - if ("miscellaneous".equals(id)) return; - Object notification = XposedHelpers.callMethod(entry, "getSbn"); - Class nuCls = findClassIfExists("com.android.systemui.miui.statusbar.notification.NotificationUtil", lpparam.classLoader); - if (nuCls != null) { - boolean isHybrid = (boolean)XposedHelpers.callStaticMethod(nuCls, "isHybrid", notification); - if (isHybrid) return; - } - String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); - int user = (int)XposedHelpers.callMethod(notification, "getAppUid"); - - Bundle bundle = new Bundle(); - bundle.putString("android.provider.extra.CHANNEL_ID", id); - bundle.putString("package", pkgName); - bundle.putInt("uid", user); - bundle.putString("miui.targetPkg", pkgName); - Intent intent = new Intent("android.intent.action.MAIN"); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(":android:show_fragment", "com.android.settings.notification.ChannelNotificationSettings"); - intent.putExtra(":android:show_fragment_args", bundle); - intent.setClassName("com.android.settings", "com.android.settings.SubSettings"); - try { - XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, android.os.Process.myUserHandle()); + public static void MaxNotificationIconsHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.NotificationIconContainer", lpparam.classLoader, "miuiShowNotificationIcons", boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean isShow = (boolean) param.args[0]; + if (isShow) { + int opt = MainModule.mPrefs.getStringAsInt("system_maxsbicons", 0); + opt = opt == -1 ? 999 : opt; + XposedHelpers.setObjectField(param.thisObject, "MAX_DOTS", 3); + XposedHelpers.setObjectField(param.thisObject, "MAX_STATIC_ICONS", opt); + String fieldLockVisible = Helpers.isTPlus() ? "MAX_ICONS_ON_LOCKSCREEN" : "MAX_VISIBLE_ICONS_ON_LOCK"; + XposedHelpers.setObjectField(param.thisObject, fieldLockVisible, opt); + XposedHelpers.callMethod(param.thisObject, "updateState"); param.setResult(null); - Object ModalController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", mContext.getClassLoader()), "get", findClass("com.android.systemui.statusbar.notification.modal.ModalController", mContext.getClassLoader())); - XposedHelpers.callMethod(ModalController, "animExitModelCollapsePanels"); - } catch (Throwable ignore) { - Helpers.log(ignore); } } }); } - public static void SkipAppLockHook(LoadPackageParam lpparam) { - Helpers.hookAllConstructors("com.miui.server.AccessController", lpparam.classLoader, new MethodHook() { + public static void MoreNotificationsHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.policy.NotificationCountLimitPolicy", lpparam.classLoader, "checkNotificationCountLimit", String.class, new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mWorkHandler"); - - new Helpers.SharedPrefObserver(mContext, mHandler) { - @Override - public void onChange(Uri uri) { - try { - String type = uri.getPathSegments().get(1); - String key = uri.getPathSegments().get(2); - if (key.contains("pref_key_system_applock_skip_activities") && "string".equals(type)) - MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "")); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }; + protected void before(MethodHookParam param) throws Throwable { + String pkgName = (String) param.args[0]; + Collection mNotifications = (Collection) XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mEntryManager"), "getAllNotifs"); + List list = (List) mNotifications.stream().filter(new Predicate() { + @Override + public boolean test(Object obj) { + String notifyPkgName = (String) XposedHelpers.callMethod(XposedHelpers.callMethod(obj, "getSbn"), "getPackageName"); + return pkgName.equals(notifyPkgName); + } + }).collect(Collectors.toList()); + if (list.size() < 24) param.setResult(null); } }); + } - Helpers.hookAllMethods("com.miui.server.AccessController", lpparam.classLoader, "skipActivity", new MethodHook() { + public static void NoMediaMuteInDNDHook() { + Helpers.hookAllMethods("android.media.AudioServiceInjector", null, "handleZenModeChangedForMusic", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - Intent intent = (Intent)param.args[0]; - if (intent == null || intent.getComponent() == null) return; - String pkgName = intent.getComponent().getPackageName(); - String actName = intent.getComponent().getClassName(); - String key = "system_applock_skip_activities"; - String itemStr = MainModule.mPrefs.getString(key, ""); - if (itemStr == null || itemStr.isEmpty()) return; - String[] itemArr = itemStr.trim().split("\\|"); - for (String uuid: itemArr) { - String pkgAct = MainModule.mPrefs.getString(key + "_" + uuid + "_activity", ""); - if (pkgAct.equals(pkgName + "|" + actName)) param.setResult(true); - } + protected void before(MethodHookParam param) throws Throwable { + if ((int)param.args[2] == 1 || (int)param.args[3] == 1) param.setResult(null); } }); } - private static final List securedTiles = new ArrayList(); - - public static void SecureQSTilesHook(LoadPackageParam lpparam) { - Class tileHostCls = XposedHelpers.findClassIfExists("com.android.systemui.qs.QSTileHost", lpparam.classLoader); + public static ArrayList mLastPlayedSounds = new ArrayList(); - MethodHook hook = new MethodHook() { + public static void AudioSilencerServiceHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.server.policy.PhoneWindowManager", lpparam.classLoader, "init", new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { + protected void after(MethodHookParam param) throws Throwable { + IntentFilter filter = new IntentFilter(); + filter.addAction(ACTION_PREFIX + "SavePlayedSound"); + filter.addAction(ACTION_PREFIX + "FetchPlayedSounds"); Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - BroadcastReceiver mAfterUnlockReceiver = new BroadcastReceiver() { - @Override - @SuppressWarnings("unchecked") - public void onReceive(Context context, Intent intent) { - try { - String tileName = intent.getStringExtra("tileName"); - boolean expandAfter = intent.getBooleanExtra("expandAfter", false); - boolean usingCenter = intent.getBooleanExtra("usingCenter", false); - if ("edit".equals(tileName) || expandAfter) { - Intent expandIntent = new Intent(ACTION_PREFIX + "ExpandSettings"); - expandIntent.putExtra("forceExpand", true); - context.sendBroadcast(expandIntent); - } - LinkedHashMap mTiles = (LinkedHashMap)XposedHelpers.getObjectField(param.thisObject, "mTiles"); - Object tile = mTiles.get(tileName); - if (tile == null) { - if (usingCenter) { - Object mController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.systemui.miui.statusbar.policy.ControlPanelController", lpparam.classLoader)); - Object mControlCenter = XposedHelpers.getObjectField(mController, "mControlCenter"); - Object mControlPanelContentView = XposedHelpers.getObjectField(mControlCenter, "mControlPanelContentView"); - Object mControlCenterPanel = XposedHelpers.callMethod(mControlPanelContentView, "getControlCenterPanel"); - Object mBigTile = null; - if ("bt".equals(tileName)) mBigTile = XposedHelpers.getObjectField(mControlCenterPanel, "mBigTile1"); - else if ("cell".equals(tileName)) mBigTile = XposedHelpers.getObjectField(mControlCenterPanel, "mBigTile2"); - else if ("wifi".equals(tileName)) mBigTile = XposedHelpers.getObjectField(mControlCenterPanel, "mBigTile3"); - if (mBigTile != null) tile = XposedHelpers.getObjectField(mBigTile, "mQSTile"); - if (tile == null) return; - } - return; + mContext.registerReceiver(new BroadcastReceiver() { + public void onReceive(final Context context, Intent intent) { + String action = intent.getAction(); + if (action != null) try { + if (action.equals(ACTION_PREFIX + "SavePlayedSound")) { + SoundData data = intent.getParcelableExtra("data"); + mLastPlayedSounds.add(0, data); + if (mLastPlayedSounds.size() > 10) + mLastPlayedSounds = new ArrayList(mLastPlayedSounds.subList(0, 10)); + } else if (action.equals(ACTION_PREFIX + "FetchPlayedSounds")) { + Intent soundsIntent = new Intent(GlobalActions.EVENT_PREFIX + "FetchPlayedSoundsData"); + soundsIntent.putParcelableArrayListExtra("sounds", mLastPlayedSounds); + soundsIntent.setPackage(Helpers.modulePkg); + mContext.sendBroadcast(soundsIntent); } - XposedHelpers.setAdditionalInstanceField(tile, "mCalledAfterUnlock", true); - Method clickHandler = XposedHelpers.findMethodExact(tile.getClass(), "handleClick", View.class); - clickHandler.invoke(tile, new Object[]{ null }); } catch (Throwable t) { XposedBridge.log(t); } } - }; - mContext.registerReceiver(mAfterUnlockReceiver, new IntentFilter(ACTION_PREFIX + "HandleQSTileClick")); + }, filter); } - }; + }); + } - Helpers.hookAllConstructors(tileHostCls, hook); + public static void SavePlayedSound(Context context, SoundData data) { + Intent saveSoundIntent = new Intent(ACTION_PREFIX + "SavePlayedSound"); + saveSoundIntent.putExtra("data", data); + saveSoundIntent.setPackage("android"); + context.sendBroadcast(saveSoundIntent); + } - String FactoryImpl = Helpers.isTPlus() ? "com.android.systemui.qs.tileimpl.MiuiQSFactory" : "com.android.systemui.qs.tileimpl.QSFactoryImpl"; - Helpers.findAndHookMethod(FactoryImpl, lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { + @SuppressWarnings({"unchecked"}) + public static void AudioSilencerHook() { + Helpers.hookAllConstructors(SoundPool.class, new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - Object tile = param.getResult(); - if (tile == null) return; - String tileClass = tile.getClass().getCanonicalName(); - final String tileName = (String)param.args[0]; - String name = tileName; - if (name.startsWith("intent(")) name = "intent"; - else if (name.startsWith("custom(")) name = "custom"; - final HashSet secureTitles = new HashSet(); - if (MainModule.mPrefs.getBoolean("system_secureqs_wifi")) secureTitles.add("wifi"); - if (MainModule.mPrefs.getBoolean("system_secureqs_bt")) secureTitles.add("bt"); - if (MainModule.mPrefs.getBoolean("system_secureqs_mobiledata")) secureTitles.add("cell"); - if (MainModule.mPrefs.getBoolean("system_secureqs_airplane")) secureTitles.add("airplane"); - if (MainModule.mPrefs.getBoolean("system_secureqs_location")) secureTitles.add("gps"); - if (MainModule.mPrefs.getBoolean("system_secureqs_hotspot")) secureTitles.add("hotspot"); - if (MainModule.mPrefs.getBoolean("system_secureqs_nfc")) secureTitles.add("nfc"); - if (MainModule.mPrefs.getBoolean("system_secureqs_sync")) secureTitles.add("sync"); - if (MainModule.mPrefs.getBoolean("system_secureqs_edit")) secureTitles.add("edit"); - if (MainModule.mPrefs.getBoolean("system_secureqs_custom")) { - secureTitles.add("intent"); - secureTitles.add("custom"); + protected void after(MethodHookParam param) throws Throwable { + if (XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData") == null) { + SparseArray mSourceSoundData = new SparseArray(); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSourceSoundData", mSourceSoundData); } - if (secureTitles.contains(name) && !securedTiles.contains(tileClass)) { - MethodHook hook = new MethodHook(10) { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Boolean mCalledAfterUnlock = (Boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCalledAfterUnlock"); - if (mCalledAfterUnlock != null && mCalledAfterUnlock) { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCalledAfterUnlock", false); - return; - } - Boolean isScreenLockDisabled = (Boolean)XposedHelpers.getAdditionalStaticField(findClass("com.android.systemui.keyguard.KeyguardViewMediator", lpparam.classLoader), "isScreenLockDisabled"); - isScreenLockDisabled = isScreenLockDisabled != null && isScreenLockDisabled; - if (isScreenLockDisabled) return; - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - KeyguardManager kgMgr = (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE); - if (!kgMgr.isKeyguardLocked() || !kgMgr.isKeyguardSecure()) return; - Handler mHandler = new Handler(mContext.getMainLooper()); - mHandler.post(new Runnable() { - @Override - public void run() { - try { - Class DependencyClass = findClass("com.android.systemui.Dependency", lpparam.classLoader); - String StatusbarClsForDep = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfaces" : "com.android.systemui.statusbar.phone.StatusBar"; - Object mStatusBar = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists(StatusbarClsForDep, lpparam.classLoader)); - boolean usingControlCenter; - Object mController = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); - usingControlCenter = (boolean)XposedHelpers.callMethod(mController, "isUseControlCenter"); - if (usingControlCenter) XposedHelpers.callMethod(mController, "collapseControlCenter", true); - boolean keepOpened = MainModule.mPrefs.getBoolean("system_secureqs_keepopened"); - final boolean usingCenter = usingControlCenter; - final boolean expandAfter = usingControlCenter && keepOpened; -// if (!usingControlCenter && keepOpened) -// XposedHelpers.callMethod(XposedHelpers.getObjectField(mStatusBar, "mStatusBarStateController"), "setLeaveOpenOnKeyguardHide", true); - XposedHelpers.callMethod(mStatusBar, "postQSRunnableDismissingKeyguard", !keepOpened, new Runnable() { - public void run() { - Intent intent = new Intent(ACTION_PREFIX + "HandleQSTileClick"); - intent.putExtra("tileName", tileName); - intent.putExtra("expandAfter", expandAfter); - intent.putExtra("usingCenter", usingCenter); - mContext.sendBroadcast(intent); - } - }); - } catch (Throwable t) { - XposedBridge.log(t); - } - } - }); - param.setResult(null); - } - }; - Helpers.findAndHookMethod(tileClass, lpparam.classLoader, "handleClick", View.class, hook); - Helpers.hookAllMethodsSilently(tileClass, lpparam.classLoader, "handleSecondaryClick", hook); - securedTiles.add(tileClass); + } + }); + + Helpers.hookAllMethods(SoundPool.class, "load", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + SparseArray mSourceSoundData = (SparseArray)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData"); + Context callerContext = Helpers.findContext(); + if (callerContext == null) return; + String caller = callerContext.getPackageName(); + if (param.args[0] instanceof Context) { + Context mContext = (Context)param.args[0]; + mSourceSoundData.put((int)param.getResult(), new SoundData(caller, "resource", mContext.getResources().getResourceName((int)param.args[1]))); + } else if (param.args[0] instanceof String) { + mSourceSoundData.put((int)param.getResult(), new SoundData(caller, "file", (String)param.args[0])); } } }); - } - public static void HideLockScreenHintHook(LoadPackageParam lpparam) { - MethodHook hook = new MethodHook() { + Helpers.hookAllMethods(SoundPool.class, "play", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - XposedHelpers.setObjectField(param.thisObject, "mUpArrowIndication", null); + SparseArray mSourceSoundData = (SparseArray)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData"); + if (mSourceSoundData != null) { + Context mContext = Helpers.findContext(); + if (mContext == null) return; + SoundData data = mSourceSoundData.get((Integer)param.args[0]); + SavePlayedSound(mContext, data); + Set silencedSounds = Helpers.getSharedStringSetPref(mContext, "pref_key_system_audiosilencer_sounds"); + if (silencedSounds.contains(data.toPref())) param.setResult(null); + } } - }; - if (Helpers.isTPlus()) { - Helpers.findAndHookMethod("com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController", lpparam.classLoader, "hasIndicationsExceptResting", XC_MethodReplacement.returnConstant(true)); - } - else { - Helpers.findAndHookMethod("com.android.systemui.statusbar.KeyguardIndicationController", lpparam.classLoader, "updateIndication", boolean.class, boolean.class, hook); - } - } + }); - public static void HideLockScreenStatusBarHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { + Helpers.hookAllMethods(MediaPlayer.class, "setDataSource", new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - View mKeyguardStatusBar = (View) XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mNotificationPanelViewController"), "mKeyguardStatusBar"); - mKeyguardStatusBar.setTranslationY(-999f); + protected void before(MethodHookParam param) throws Throwable { + if (Modifier.isPrivate(param.method.getModifiers())) return; + Context callerContext = Helpers.findContext(); + if (callerContext == null) return; + String caller = callerContext.getPackageName(); + SoundData soundData = null; + if (param.args.length > 1 && param.args[0] instanceof Context && param.args[1] instanceof Uri) + soundData = new SoundData(caller, "uri", ((Uri)param.args[1]).getPath()); + else if (param.args[0] instanceof String) + soundData = new SoundData(caller, "file", (String)param.args[0]); + if (soundData != null) + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mSourceSoundData", soundData); + } + }); + + Helpers.hookAllMethods(MediaPlayer.class, "start", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + SoundData mSourceSoundData = (SoundData)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData"); + if (mSourceSoundData != null) { + Context mContext = Helpers.findContext(); + if (mContext == null) return; + SavePlayedSound(mContext, mSourceSoundData); + Set silencedSounds = Helpers.getSharedStringSetPref(mContext, "pref_key_system_audiosilencer_sounds"); + if (silencedSounds.contains(mSourceSoundData.toPref())) param.setResult(null); + } } }); } - public static void MuteVisibleNotificationsHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.media.NotificationPlayer$CreationAndCompletionThread", lpparam.classLoader, "run", new MethodHook() { + public static void BetterPopupsAllowFloatHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.systemui.statusbar.notification.policy.AppMiniWindowManager", lpparam.classLoader, new MethodHook() { @Override - @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") - protected void before(final MethodHookParam param) throws Throwable { - Object mCmd = XposedHelpers.getObjectField(param.thisObject, "mCmd"); - if (mCmd == null) return; - int code = XposedHelpers.getIntField(mCmd, "code"); - if (code != 1) return; - AudioAttributes attributes = (AudioAttributes)XposedHelpers.getObjectField(mCmd, "attributes"); - if (attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION || attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE || attributes.getUsage() == AudioAttributes.USAGE_UNKNOWN) - if (attributes.getContentType() == AudioAttributes.CONTENT_TYPE_SONIFICATION || attributes.getContentType() == AudioAttributes.CONTENT_TYPE_UNKNOWN) { - Context context = (Context)XposedHelpers.getObjectField(mCmd, "context"); - PowerManager powerMgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - if (powerMgr.isInteractive()) { - Thread thread = (Thread)param.thisObject; - synchronized (thread) { thread.notify(); } - param.setResult(null); + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "context"); + Handler mHandler = new Handler(Looper.getMainLooper()); + + new Helpers.SharedPrefObserver(mContext, mHandler) { + @Override + public void onChange(Uri uri) { + try { + String key = uri.getPathSegments().get(2); + if (key.contains("pref_key_system_betterpopups_allowfloat_apps")) + MainModule.mPrefs.put(key, Helpers.getSharedStringSetPref(mContext, key)); + } catch (Throwable t) { + XposedBridge.log(t); } } + }; + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.NotificationSettingsManager", lpparam.classLoader, "canSlide", String.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + String pkgName = (String) param.args[0]; + Set selectedApps = MainModule.mPrefs.getStringSet("system_betterpopups_allowfloat_apps"); + Set selectedAppsBlack = MainModule.mPrefs.getStringSet("system_betterpopups_allowfloat_apps_black"); + if (selectedApps.contains(pkgName)) param.setResult(true); + else if (selectedAppsBlack.contains(pkgName)) param.setResult(false); + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.notification.policy.MiniWindowPolicy", lpparam.classLoader, "canSlidePackage", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.setResult(true); } }); } - public static void NetworkIndicatorWifi(LoadPackageParam lpparam) { - MethodHook hideWifiActivity = new MethodHook() { + public static void NoFloatingWindowBlacklistHook(LoadPackageParam lpparam) { + MainModule.resHooks.setResReplacement("android", "array", "freeform_black_list", R.array.miui_resize_black_list); + MainModule.resHooks.setResReplacement("com.miui.rom", "array", "freeform_black_list", R.array.miui_resize_black_list); + MethodHook clearHook = new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - Object mWifiActivityView = XposedHelpers.getObjectField(param.thisObject, "mWifiActivityView"); - XposedHelpers.callMethod(mWifiActivityView, "setVisibility", 4); + protected void after(MethodHookParam param) throws Throwable { + List blackList = (List)param.getResult(); + if (blackList != null) blackList.clear(); + param.setResult(blackList); } }; - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarWifiView", lpparam.classLoader, "applyWifiState", hideWifiActivity); - } - - public static void SetLockscreenWallpaperHook(LoadPackageParam lpparam) { - Helpers.hookAllMethods("com.android.server.wallpaper.WallpaperManagerService", lpparam.classLoader, "setWallpaper", new MethodHook() { + Helpers.hookAllMethods("android.util.MiuiMultiWindowAdapter", lpparam.classLoader, "getFreeformBlackList", clearHook); + Helpers.hookAllMethods("android.util.MiuiMultiWindowAdapter", lpparam.classLoader, "getFreeformBlackListFromCloud", clearHook); + Helpers.hookAllMethods("android.util.MiuiMultiWindowAdapter", lpparam.classLoader, "setFreeformBlackList", new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - if (param.getThrowable() != null || param.getResult() == null || (int)param.args[5] == 1 || "com.android.thememanager".equals(param.args[1])) return; + protected void before(MethodHookParam param) throws Throwable { + List blackList = new ArrayList(); + blackList.add("ab.cd.xyz"); + param.args[0] = blackList; + } + }); + Helpers.findAndHookMethod("android.util.MiuiMultiWindowUtils", lpparam.classLoader, "isForceResizeable", XC_MethodReplacement.returnConstant(true)); + Helpers.findAndHookMethod("android.util.MiuiMultiWindowUtils", lpparam.classLoader, "supportFreeform", XC_MethodReplacement.returnConstant(true)); + if (Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.server.wm.MiuiFreeformServicesUtils", lpparam.classLoader, "supportsFreeform", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.setResult(true); + } + }); + } + } - Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); - if (mContext == null) return; + public static ConcurrentHashMap> fwApps = new ConcurrentHashMap>(); - int handleIncomingUser = 0; - try { - handleIncomingUser = (int)XposedHelpers.callStaticMethod(ActivityManager.class, "handleIncomingUser", Binder.getCallingPid(), Binder.getCallingUid(), param.args[7], false, true, "changing wallpaper", null); - } catch (Throwable ignore) {} - Object wallpaperData = XposedHelpers.callMethod(param.thisObject, "getWallpaperSafeLocked", handleIncomingUser, param.args[5]); - File wallpaper = (File)XposedHelpers.getObjectField(wallpaperData, "wallpaperFile"); + public static String getTaskPackageName(Object thisObject, int taskId) { + return getTaskPackageName(thisObject, taskId, false, null); + } - new Handler(mContext.getMainLooper()).postDelayed(new Runnable() { - @Override - public void run() { - if (!wallpaper.exists()) return; + public static String getTaskPackageName(Object thisObject, int taskId, ActivityOptions options) { + return getTaskPackageName(thisObject, taskId, options != null, options); + } - String lockWallpaperPath = "/data/system/theme/thirdparty_lock_wallpaper"; - Helpers.copyFile(wallpaper.getAbsolutePath(), lockWallpaperPath); - Class ThemeUtils = XposedHelpers.findClass("miui.content.res.ThemeNativeUtils", lpparam.classLoader); - XposedHelpers.callStaticMethod(ThemeUtils, "updateFilePermissionWithThemeContext", lockWallpaperPath); - JSONObject data = new JSONObject(); - JSONObject ex = new JSONObject(); - try { - File lockWallpaper = new File(lockWallpaperPath); - ex - .put("link_type", "0") - .put("title_size", "26") - .put("item_id", "wallpaper1") - .put("title_color", "#ffffffff") - .put("index_in_album", "1") - .put("tag_list", "CustoMIUIzer,mod") - .put("content_color", "#ffffffff") - .put("total_of_album", "1") - .put("img_level", "0") - .put("album_id", "1") - .put("title_customized", "0") - .put("lks_entry_text", "Some wallpaper"); + public static String getTaskPackageName(Object thisObject, int taskId, boolean withOptions, ActivityOptions options) { + Object mRootWindowContainer = XposedHelpers.getObjectField(thisObject, "mRootWindowContainer"); + if (mRootWindowContainer == null) return null; + Object task = withOptions ? + XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 2, options, true) : + XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 0); + if (task == null) return null; + Intent intent = (Intent)XposedHelpers.getObjectField(task, "intent"); + return intent == null ? null : intent.getComponent().getPackageName(); + } - data - .put("authority", "name.mikanoshi.customiuizer.mods.set_lockscreen_wallpaper") - .put("content", "Wallpaper set by some app") - .put("contentColorValue", 0) - .put("cp", "CustoMIUIzer") - .put("cpColorValue", 0) - .put("definition", -1) - .put("ex", ex.toString()) - .put("fromColorValue", 0) - .put("hasAcc", false) - .put("indexInAlbum", -1) - .put("isAd", false) - .put("isCustom", false) - .put("isFd", false) - .put("isFrontCover", false) - .put("key", "wallpaper1") - .put("like", false) - .put("linkType", 0) - .put("noApply", false) - .put("noDislike", false) - .put("noSave", false) - .put("noShare", false) - .put("pos", 0) - .put("supportLike", true) - .put("title", "Some wallpaper") - .put("titleColorValue", 0) - .put("titleTextSize", -1) - .put("totalOfAlbum", -1) - .put("wallpaperUri", lockWallpaper.toURI()); - } catch (Throwable t) { - XposedBridge.log(t); - } + public static String serializeFwApps() { + StringBuilder data = new StringBuilder(); + for (Map.Entry> entry: fwApps.entrySet()) { + Pair val = entry.getValue(); + data.append(entry.getKey()); + data.append(":"); + data.append(val.first); + data.append(":"); + data.append(val.second == null ? "-" : val.second.flattenToString()); + data.append("|"); + } + return data.toString().replaceFirst("\\|$", ""); + } - Intent setIntent = new Intent("com.miui.miwallpaper.UPDATE_LOCKSCREEN_WALLPAPER"); - setIntent.putExtra("wallpaperInfo", data.toString()); - setIntent.putExtra("apply", true); - mContext.sendBroadcast(setIntent); - } - }, 1800); - } - }); + public static void unserializeFwApps(String data) { + fwApps.clear(); + if (data == null || "".equals(data)) return; + String[] dataArr = data.split("\\|"); + for (String appData: dataArr) { + if ("".equals(appData)) continue; + String[] appDataArr = appData.split(":"); + fwApps.put(appDataArr[0], new Pair(Float.parseFloat(appDataArr[1]), "-".equals(appDataArr[2]) ? null : Rect.unflattenFromString(appDataArr[2]))); + } + } + public static void storeFwAppsInSetting(Context context) { + Settings.Global.putString(context.getContentResolver(), Helpers.modulePkg + ".fw.apps", serializeFwApps()); + } + public static void restoreFwAppsInSetting(Context context) { + unserializeFwApps(Settings.Global.getString(context.getContentResolver(), Helpers.modulePkg + ".fw.apps")); } + private static ActivityOptions patchActivityOptions(Context mContext, ActivityOptions options, String pkgName, Class MiuiMultiWindowUtils) { + if (options == null) options = ActivityOptions.makeBasic(); + XposedHelpers.callMethod(options, "setLaunchWindowingMode", 5); + XposedHelpers.callMethod(options, "setMiuiConfigFlag", 2); - public static void BetterPopupsCenteredHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.HeadsUpManager", lpparam.classLoader, "getHeadsUpTopMargin", Context.class, new MethodHook() { - @Override - protected void after(final MethodHookParam param) throws Throwable { - Context context = (Context)param.args[0]; - Resources res = context.getResources(); - int maxPopupHeight = res.getDimensionPixelSize(res.getIdentifier("notification_max_heads_up_height", "dimen", "com.android.systemui")); - if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) maxPopupHeight /= 3; - param.setResult(Math.round(context.getResources().getDisplayMetrics().heightPixels / 2.0f - maxPopupHeight / 2.0f)); - } - }); + Float scale; + Rect rect; + Pair values = fwApps.get(pkgName); + if (values == null || values.first == 0f || values.second == null) { + scale = 0.7f; + rect = (Rect)XposedHelpers.callStaticMethod(MiuiMultiWindowUtils, "getFreeformRect", mContext); + } else { + scale = values.first; + rect = values.second; + } + options.setLaunchBounds(rect); + try { + Object injector = XposedHelpers.callMethod(options, "getActivityOptionsInjector"); + XposedHelpers.callMethod(injector, "setFreeformScale", scale); + } catch (Throwable ignore) { + XposedBridge.log(ignore); + } + return options; } - public static void HorizMarginHook(LoadPackageParam lpparam) { - MethodHook horizHook = new MethodHook() { + public static void StickyFloatingWindowsHook(LoadPackageParam lpparam) { + final List fwBlackList = new ArrayList(); + fwBlackList.add("com.miui.securitycenter"); + fwBlackList.add("com.miui.home"); + fwBlackList.add("com.android.camera"); + Class MiuiMultiWindowUtils = findClass("android.util.MiuiMultiWindowUtils", lpparam.classLoader); + Helpers.hookAllMethods("com.android.server.wm.ActivityStarterInjector", lpparam.classLoader, "modifyLaunchActivityOptionIfNeed", new MethodHook() { @Override - protected void before(final MethodHookParam param) throws Throwable { - Context context; - if (param.method.getName().equals("paddingNeededForCutoutAndRoundedCorner")) { - context = Helpers.findContext(); + protected void after(MethodHookParam param) throws Throwable { + if (param.args.length != 8) return; + Intent intent = (Intent)param.args[5]; + if (intent == null || intent.getComponent() == null) return; + ActivityOptions options = (ActivityOptions)param.getResult(); + int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); + String pkgName = intent.getComponent().getPackageName(); + if (fwBlackList.contains(pkgName)) return; + Context mContext; + try { + mContext = (Context)XposedHelpers.getObjectField(param.args[0], "mContext"); + } catch (Throwable ignore) { + mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.args[0], "mService"), "mContext"); } - else { - context = (Context) XposedHelpers.getObjectField(param.thisObject, "context"); + if (windowingMode != 5 && fwApps.containsKey(pkgName)) { + try { + if (MiuiMultiWindowUtils == null) { + Helpers.log("StickyFloatingWindowsHook", "Cannot find MiuiMultiWindowUtils class"); + return; + } + options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); + param.setResult(options); + } catch (Throwable t) { + Helpers.log(t); + } + } + else if (windowingMode == 5 && !fwApps.containsKey(pkgName)) { + fwApps.put(pkgName, new Pair(0f, null)); + storeFwAppsInSetting(mContext); } - int leftMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_left", 16); - float marginLeft = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - leftMargin, - context.getResources().getDisplayMetrics() - ); - leftMargin = (int) marginLeft; - int rightMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_right", 16); - float marginRight = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - rightMargin, - context.getResources().getDisplayMetrics() - ); - rightMargin = (int) marginRight; - param.setResult(new Pair(Integer.valueOf(leftMargin), Integer.valueOf(rightMargin))); } - }; - String StatusBarWindowViewCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.window.StatusBarWindowView" : "com.android.systemui.statusbar.phone.StatusBarWindowView"; - Helpers.hookAllMethods(StatusBarWindowViewCls, lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", horizHook); - if (Helpers.isTPlus()) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider", lpparam.classLoader, "getStatusBarContentInsetsForCurrentRotation", horizHook); - } - } + }); - public static void LockScreenTopMarginHook(LoadPackageParam lpparam) { - final int[] statusBarPaddingTop = new int[1]; - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + Helpers.hookAllMethods("com.android.server.wm.ActivityTaskSupervisor", lpparam.classLoader, "startActivityFromRecents", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - int dimenResId = mContext.getResources().getIdentifier("status_bar_padding_top", "dimen", lpparam.packageName); - statusBarPaddingTop[0] = mContext.getResources().getDimensionPixelSize(dimenResId); + Object safeOptions = param.args[3]; + ActivityOptions options = (ActivityOptions)XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject); + if (Helpers.isTPlus()) { + if (options != null) { + Object windowToken = XposedHelpers.callMethod(options, "getLaunchRootTask"); + if (windowToken != null) return; + } + } + String pkgName = (String) XposedHelpers.getAdditionalInstanceField(param.thisObject, "startPackageName"); + XposedHelpers.removeAdditionalInstanceField(param.thisObject, "startPackageName"); + if (fwBlackList.contains(pkgName)) return; + int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); + if (windowingMode == 5 && pkgName != null) { + fwApps.put(pkgName, new Pair(0f, null)); + Context mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext"); + storeFwAppsInSetting(mContext); + } } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - View view = (View) param.args[0]; - if (view != null) { - view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); - param.setResult(null); + Object safeOptions = param.args[3]; + ActivityOptions options = (ActivityOptions)XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject); + if (Helpers.isTPlus()) { + if (options != null) { + Object windowToken = XposedHelpers.callMethod(options, "getLaunchRootTask"); + if (windowToken != null) return; + } + } + String pkgName = getTaskPackageName(param.thisObject, (int)param.args[2], options); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "startPackageName", pkgName); + if (!fwBlackList.contains(pkgName)) { + int windowingMode = options == null ? -1 : (int)XposedHelpers.callMethod(options, "getLaunchWindowingMode"); + if (windowingMode != 5 && fwApps.containsKey(pkgName)) { + Object mService = XposedHelpers.getObjectField(param.thisObject, "mService"); + Context mContext = (Context)XposedHelpers.getObjectField(mService, "mContext"); + options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils); + XposedHelpers.setObjectField(safeOptions, "mOriginalOptions", options); + param.args[3] = safeOptions; + Intent intent = new Intent(ACTION_PREFIX + "dismissRecentsWhenFreeWindowOpen"); + intent.putExtra("package", pkgName); + mContext.sendBroadcast(intent); + } } } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); - } - }); - } - - - public static void MobileTypeSingleHook(LoadPackageParam lpparam) { - MethodHook showSingleMobileType = new MethodHook(MethodHook.PRIORITY_HIGHEST) { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Object mobileIconState = param.args[0]; - XposedHelpers.setObjectField(mobileIconState, "showMobileDataTypeSingle", true); - XposedHelpers.setObjectField(mobileIconState, "fiveGDrawableId", 0); - } - }; - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", showSingleMobileType); - MethodHook afterUpdate = new MethodHook() { + Helpers.findAndHookMethod("com.android.server.wm.MiuiFreeFormGestureController$FreeFormReceiver", lpparam.classLoader, "onReceive", new Object[]{Context.class, Intent.class, new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - Object mMobileLeftContainer = XposedHelpers.getObjectField(param.thisObject, "mMobileLeftContainer"); - XposedHelpers.callMethod(mMobileLeftContainer, "setVisibility", 8); + protected void before(MethodHookParam param) throws Throwable { + Intent intent = (Intent) param.args[1]; + String action = intent.getAction(); + if ("miui.intent.action_launch_fullscreen_from_freeform".equals(action)) { + Object parentThis = XposedHelpers.getSurroundingThis(param.thisObject); + XposedHelpers.setAdditionalInstanceField(parentThis, "skipFreeFormStateClear", true); + } } - }; - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", afterUpdate); + }}); - Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "init", new MethodHook() { + Helpers.hookAllMethods("com.android.server.wm.MiuiFreeFormGestureController", lpparam.classLoader, "notifyFullScreenWidnowModeStart", new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - Resources res = mContext.getResources(); - LinearLayout mMobileGroup = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mMobileGroup"); - TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); - if (!MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single_atleft")) { - mMobileGroup.removeView(mMobileTypeSingle); - mMobileGroup.addView(mMobileTypeSingle); - } - ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) mMobileTypeSingle.getLayoutParams(); - int leftMargin = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_leftmargin", 4); - float marginLeft = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - leftMargin * 0.5f, - res.getDisplayMetrics() - ); - mlp.leftMargin = (int) marginLeft; - int rightMargin = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_rightmargin", 0); - if (rightMargin > 0) { - float marginRight = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - rightMargin * 0.5f, - res.getDisplayMetrics() - ); - mlp.rightMargin = (int) marginRight; + protected void before(MethodHookParam param) throws Throwable { + if (param.args.length != 3) return; + String pkgName = (String)XposedHelpers.callMethod(param.args[1], "getStackPackageName"); + Object skipClear = XposedHelpers.getAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear"); + boolean skipFreeFormStateClear = false; + if (skipClear != null) { + skipFreeFormStateClear = (boolean) skipClear; } - int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_verticaloffset", 8); - if (verticalOffset != 8) { - float marginTop = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - (verticalOffset - 8) * 0.5f, - res.getDisplayMetrics() - ); - mlp.topMargin = (int) marginTop; + if (!skipFreeFormStateClear) { + if (fwBlackList.contains(pkgName)) return; + if (fwApps.remove(pkgName) != null) { + storeFwAppsInSetting((Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext")); + } } - mMobileTypeSingle.setLayoutParams(mlp); - int fontSize = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_fontsize", 27); - mMobileTypeSingle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); - if (MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single_bold")) { - mMobileTypeSingle.setTypeface(Typeface.DEFAULT_BOLD); + else { + XposedHelpers.setAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear", false); } } }); - } - public static void DualRowSignalHook(LoadPackageParam lpparam) { - boolean mobileTypeSingle = MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single"); - if (!mobileTypeSingle) { - MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_type_half_to_top_distance", 3); - MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_left_inout_over_strength", 0); - MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_type_middle_to_strength_start", -0.4f); - } - - HashMap dualSignalResMap = new HashMap(); - String[] colorModeList = {"", "dark", "tint"}; -// String[] iconStyles = {"", "thick", "theme"}; - String selectedIconStyle = MainModule.mPrefs.getString("system_statusbar_dualsimin2rows_style", ""); + Helpers.hookAllMethods("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "launchSmallFreeFormWindow", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object taskId = XposedHelpers.getObjectField(param.args[0], "taskId"); + Object mMiuiFreeFormManagerService = XposedHelpers.getObjectField(param.thisObject, "mMiuiFreeFormManagerService"); + Object miuiFreeFormActivityStack = XposedHelpers.callMethod(mMiuiFreeFormManagerService, "getMiuiFreeFormActivityStack", taskId); + String pkgName = (String) XposedHelpers.callMethod(miuiFreeFormActivityStack, "getStackPackageName"); + if (fwBlackList.contains(pkgName)) return; + if (!fwApps.containsKey(pkgName)) { + fwApps.put(pkgName, new Pair(0f, null)); + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + storeFwAppsInSetting(mContext); + } + } + }); - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - private boolean isHooked = false; + Helpers.findAndHookMethod("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "onSystemReady", new MethodHook() { @Override protected void after(MethodHookParam param) throws Throwable { - if (!isHooked) { - isHooked = true; - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - Resources modRes = Helpers.getModuleRes(mContext); - for (int slot = 1; slot <= 2; slot++) { - for (int lvl = 0; lvl <= 5; lvl++) { - for (String colorMode : colorModeList) { - if (!selectedIconStyle.equals("theme") || !colorMode.equals("tint") ) { - String dualIconResName = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!selectedIconStyle.equals("") ? ("_" + selectedIconStyle) : ""); - int iconResId = modRes.getIdentifier(dualIconResName, "drawable", Helpers.modulePkg); - dualSignalResMap.put(dualIconResName, MainModule.resHooks.addResource(dualIconResName, iconResId)); - } - } + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + restoreFwAppsInSetting(mContext); + Class MiuiMultiWindowAdapter = findClass("android.util.MiuiMultiWindowAdapter", lpparam.classLoader); + List blackList = (List) XposedHelpers.getStaticObjectField(MiuiMultiWindowAdapter, "FREEFORM_BLACK_LIST"); + blackList.clear(); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if ("miui.intent.action_launch_fullscreen_from_freeform".equals(action)) { + XposedHelpers.setAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear", true); } } - } + }, new IntentFilter("miui.intent.action_launch_fullscreen_from_freeform")); } }); - SparseIntArray signalResToLevelMap = new SparseIntArray(); - boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); - String ControllerImplName = moveSignalLeft ? "MiuiDripLeftStatusBarIconControllerImpl" : "StatusBarIconControllerImpl"; - Helpers.hookAllMethods("com.android.systemui.statusbar.phone." + ControllerImplName, lpparam.classLoader, "setMobileIcons", new MethodHook() { - private boolean isHooked = false; + Helpers.hookAllMethods("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "resizeTask", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - if (!isHooked) { - isHooked = true; - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - Resources res = mContext.getResources(); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_0", "drawable", lpparam.packageName), 0); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_1", "drawable", lpparam.packageName), 1); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_2", "drawable", lpparam.packageName), 2); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_3", "drawable", lpparam.packageName), 3); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_4", "drawable", lpparam.packageName), 4); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_5", "drawable", lpparam.packageName), 5); - signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_null", "drawable", lpparam.packageName), 6); - } - List iconStates = (List) param.args[1]; - if (iconStates.size() == 2) { - Object mainIconState = iconStates.get(0); - Object subIconState = iconStates.get(1); - boolean mainDataConnected = (boolean) XposedHelpers.getObjectField(mainIconState, "dataConnected"); - boolean subDataConnected = (boolean) XposedHelpers.getObjectField(subIconState, "dataConnected"); - XposedHelpers.setObjectField(mainIconState, "dataConnected", mainDataConnected || subDataConnected); - XposedHelpers.setObjectField(subIconState, "visible", false); - int mainSignalResId = (int) XposedHelpers.getObjectField(mainIconState, "strengthId"); - int subSignalResId = (int) XposedHelpers.getObjectField(subIconState, "strengthId"); - int mainLevel = signalResToLevelMap.get(mainSignalResId); - int subLevel = signalResToLevelMap.get(subSignalResId); - int level; - if (subDataConnected) { - level = subLevel * 10 + mainLevel; - String showName = (String) XposedHelpers.getObjectField(subIconState, "showName"); - XposedHelpers.setObjectField(mainIconState, "showName", showName); + String pkgName = getTaskPackageName(param.thisObject, (int)param.args[0]); + if (pkgName != null) { + Object skipClear = XposedHelpers.getAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear"); + boolean skipFreeFormStateClear = false; + if (skipClear != null) { + skipFreeFormStateClear = (boolean) skipClear; + } + if (skipFreeFormStateClear) { + XposedHelpers.setAdditionalInstanceField(param.thisObject, "skipFreeFormStateClear", false); } else { - level = mainLevel * 10 + subLevel; + if (fwBlackList.contains(pkgName)) return; + Object mMiuiFreeFormManagerService = XposedHelpers.getObjectField(param.thisObject, "mMiuiFreeFormManagerService"); + Object miuiFreeFormActivityStack = XposedHelpers.callMethod(mMiuiFreeFormManagerService, "getMiuiFreeFormActivityStack", param.args[0]); + if (fwApps.containsKey(pkgName)) { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + float sScale = (float) XposedHelpers.callMethod(miuiFreeFormActivityStack, "getFreeFormScale"); + fwApps.put(pkgName, new Pair(sScale, new Rect((Rect)param.args[1]))); + storeFwAppsInSetting(mContext); + } } - XposedHelpers.setObjectField(mainIconState, "strengthId", level); - param.args[1] = iconStates; } } }); + } - MethodHook beforeUpdate = new MethodHook() { - @Override - protected void before(final MethodHookParam param) throws Throwable { - Object mobileIconState = param.args[0]; - boolean visible = (boolean) XposedHelpers.getObjectField(mobileIconState, "visible"); - boolean airplane = (boolean) XposedHelpers.getObjectField(mobileIconState, "airplane"); - int level = (int) XposedHelpers.getObjectField(mobileIconState, "strengthId"); - if (!visible || airplane || level == 0 || level > 100) { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "subStrengthId", -1); - } - else { - XposedHelpers.setAdditionalInstanceField(param.thisObject, "subStrengthId", level % 10); - XposedHelpers.setObjectField(mobileIconState, "fiveGDrawableId", 0); - } - } - }; - MethodHook afterUpdate = new MethodHook() { + public static void MessagingStyleLinesSysHook() { + Helpers.findAndHookMethod("android.app.Notification.MessagingStyle", null, "makeMessagingView", boolean.class, boolean.class, new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - int subStrengthId = (int) XposedHelpers.getAdditionalInstanceField(param.thisObject, "subStrengthId"); - if (subStrengthId < 0) return; - Object mSmallHd = XposedHelpers.getObjectField(param.thisObject, "mSmallHd"); - XposedHelpers.callMethod(mSmallHd, "setVisibility", 8); - Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); - XposedHelpers.callMethod(mSmallRoaming, "setVisibility", 0); + protected void after(MethodHookParam param) throws Throwable { + if ((boolean)param.args[0] && (boolean)param.args[1]) return; + RemoteViews remote = (RemoteViews)param.getResult(); + Context mContext = (Context)XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mBuilder"), "mContext"); + remote.setInt(mContext.getResources().getIdentifier("notification_messaging", "id", "android"), "setMaxDisplayedLines", MainModule.mPrefs.getInt("system_messagingstylelines", Integer.MAX_VALUE)); } - }; - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", beforeUpdate); - Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", afterUpdate); + }); + } - MethodHook resetImageDrawable = new MethodHook() { + public static void MessagingStyleLinesHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.systemui.statusbar.notification.NotificationMessagingTemplateViewWrapper", lpparam.classLoader, new MethodHook() { @Override - protected void before(final MethodHookParam param) throws Throwable { - int subStrengthId = (int) XposedHelpers.getAdditionalInstanceField(param.thisObject, "subStrengthId"); - if (subStrengthId < 0) return; - if (subStrengthId == 6) subStrengthId = 0; - Object mobileIconState = XposedHelpers.getObjectField(param.thisObject, "mState"); - int level1 = (int) XposedHelpers.getObjectField(mobileIconState, "strengthId"); - level1 = level1 / 10; - if (level1 == 6) level1 = 0; - boolean mLight = (boolean) XposedHelpers.getObjectField(param.thisObject, "mLight"); - boolean mUseTint = (boolean) XposedHelpers.getObjectField(param.thisObject, "mUseTint"); - Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); - Object mMobile = XposedHelpers.getObjectField(param.thisObject, "mMobile"); - String colorMode = ""; - if (mUseTint && !selectedIconStyle.equals("theme")) { - colorMode = "_tint"; - } - else if (!mLight) { - colorMode = "_dark"; - } - String iconStyle = ""; - if (!selectedIconStyle.equals("")) { - iconStyle = "_" + selectedIconStyle; - } - String sim1IconId = "statusbar_signal_1_" + level1 + colorMode + iconStyle; - String sim2IconId = "statusbar_signal_2_" + subStrengthId + colorMode + iconStyle; - int sim1ResId = dualSignalResMap.get(sim1IconId); - int sim2ResId = dualSignalResMap.get(sim2IconId); - XposedHelpers.callMethod(mMobile, "setImageResource", sim1ResId); - XposedHelpers.callMethod(mSmallRoaming, "setImageResource", sim2ResId); + protected void after(MethodHookParam param) throws Throwable { + Object mMessagingLinearLayout = XposedHelpers.getObjectField(param.thisObject, "mMessagingLinearLayout"); + int mMaxDisplayedLines = XposedHelpers.getIntField(mMessagingLinearLayout, "mMaxDisplayedLines"); + if (mMaxDisplayedLines == Integer.MAX_VALUE) XposedHelpers.callMethod(mMessagingLinearLayout, "setMaxDisplayedLines", MainModule.mPrefs.getInt("system_messagingstylelines", Integer.MAX_VALUE)); } - }; - Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyDarknessInternal", resetImageDrawable); - int rightMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_rightmargin", 0); - int leftMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_leftmargin", 0); - int iconScale = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_scale", 10); - if (rightMargin > 0 || leftMargin > 0 || iconScale != 10) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "init", new MethodHook() { + }); + } + + public static void MultiWindowPlusHook(LoadPackageParam lpparam) { + if (lpparam.packageName.equals("com.miui.home")) { + Helpers.findAndHookMethodSilently("com.android.systemui.shared.recents.model.Task", lpparam.classLoader, "isSupportSplit", XC_MethodReplacement.returnConstant(true)); + Helpers.hookAllMethods("com.miui.home.recents.views.RecentMenuView", lpparam.classLoader, "onMessageEvent", new MethodHook() { @Override - protected void after(final MethodHookParam param) throws Throwable { - LinearLayout mobileView = (LinearLayout) param.thisObject; - Context mContext = mobileView.getContext(); - Resources res = mContext.getResources(); - int rightSpacing = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - rightMargin * 0.5f, - res.getDisplayMetrics() - ); - int leftSpacing = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - leftMargin * 0.5f, - res.getDisplayMetrics() - ); - mobileView.setPadding(leftSpacing, 0, rightSpacing, 0); - - if (iconScale != 10) { - View mMobile = (View) XposedHelpers.getObjectField(param.thisObject, "mMobile"); - View mSmallRoaming = (View) XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mMobile.getLayoutParams(); - int mIconHeight = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 20 * iconScale / 10f, - res.getDisplayMetrics() - ); - Helpers.log("fad " + (layoutParams != null)); - if (layoutParams == null) { - layoutParams = new FrameLayout.LayoutParams(-2, mIconHeight); - } else { - layoutParams.height = mIconHeight; + protected void after(MethodHookParam param) throws Throwable { + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler"); + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + ImageView mMenuItemMultiWindow = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mMenuItemMultiWindow"); + ImageView mMenuItemSmallWindow = (ImageView)XposedHelpers.getObjectField(param.thisObject, "mMenuItemSmallWindow"); + mMenuItemMultiWindow.setEnabled(true); + mMenuItemMultiWindow.setImageAlpha(255); + mMenuItemSmallWindow.setEnabled(true); + mMenuItemSmallWindow.setImageAlpha(255); } - layoutParams.gravity = Gravity.CENTER; - mMobile.setLayoutParams(layoutParams); - mSmallRoaming.setLayoutParams(layoutParams); - } + }, 200); } }); } + else if (lpparam.packageName.equals("android")) { + MainModule.resHooks.setResReplacement("android", "array", "miui_resize_black_list", R.array.miui_resize_black_list); + MainModule.resHooks.setResReplacement("com.miui.rom", "array", "miui_resize_black_list", R.array.miui_resize_black_list); + Class AtmClass = XposedHelpers.findClassIfExists("com.android.server.wm.ActivityTaskManagerServiceImpl", lpparam.classLoader); + if (AtmClass != null) { + Helpers.findAndHookMethod(AtmClass, "updateResizeBlackList", Context.class, XC_MethodReplacement.DO_NOTHING); + Helpers.findAndHookMethod(AtmClass, "getSplitScreenBlackListFromXml", XC_MethodReplacement.DO_NOTHING); + Helpers.hookAllMethods(AtmClass, "inResizeBlackList", XC_MethodReplacement.returnConstant(false)); + } + } +// else { +// Class AtmClass = XposedHelpers.findClassIfExists("android.app.ActivityTaskManager", lpparam.classLoader); +// if (AtmClass != null) { +// Helpers.hookAllMethods(AtmClass, "supportsSplitScreen", XC_MethodReplacement.returnConstant(true)); +// } +// } } - public static void AddFiveGTileHook(LoadPackageParam lpparam) { - final boolean[] isListened = {false}; - - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - if (!isListened[0]) { - isListened[0] = true; - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - int stockTilesResId = mContext.getResources().getIdentifier("miui_quick_settings_tiles_stock", "string", lpparam.packageName); - String stockTiles = mContext.getString(stockTilesResId) + ",custom_5G"; - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "string", "miui_quick_settings_tiles_stock", stockTiles); - MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "string", "miui_quick_settings_tiles_stock", stockTiles); - MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "string", "quick_settings_tiles_stock", stockTiles); - } - } - }); - String QSFactoryCls = Helpers.isTPlus() ? "com.android.systemui.qs.tileimpl.MiuiQSFactory" : "com.android.systemui.qs.tileimpl.QSFactoryImpl"; - Class ResourceIconClass = findClass("com.android.systemui.qs.tileimpl.QSTileImpl$ResourceIcon", lpparam.classLoader); - Helpers.findAndHookMethod(QSFactoryCls, lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { + public static void SecureControlCenterHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethodSilently("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader, "supportExpandableStatusbarUnderKeyguard", XC_MethodReplacement.returnConstant(false)); + Helpers.hookAllMethods("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader, "onContentChanged", new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - String tileName = (String) param.args[0]; - if (tileName.startsWith("custom_")) { - String nfcField = Helpers.isTPlus() ? "nfcTileProvider" : "mNfcTileProvider"; - Object provider = XposedHelpers.getObjectField(param.thisObject, nfcField); - Object tile = XposedHelpers.callMethod(provider, "get"); - XposedHelpers.setAdditionalInstanceField(tile, "customName", tileName); - param.setResult(tile); + String key = (String) param.args[0]; + if ("expandable_under_lock_screen".equals(key)) { + param.args[1] = "0"; } } }); - String NfcTileCls = Helpers.isTPlus() ? "com.android.systemui.qs.tiles.MiuiNfcTile" : "com.android.systemui.qs.tiles.NfcTile"; - Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "isAvailable", new MethodHook() { + } + + public static void MinimalNotificationViewHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateNotification", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); - if (customName != null) { - String tileName = (String) customName; - if ("custom_5G".equals(tileName)) { - param.setResult(TelephonyManager.getDefault().isFiveGCapable()); - } - else { - param.setResult(false); - } - } + protected void after(final MethodHookParam param) throws Throwable { + if (param.args.length != 3) return; + Object expandableRow = XposedHelpers.getObjectField(param.args[0], "row"); + Object mNotificationData = XposedHelpers.getObjectField(param.thisObject, "mNotificationData"); + boolean newLowPriority = (boolean)XposedHelpers.callMethod(mNotificationData, "isAmbient", XposedHelpers.callMethod(param.args[1], "getKey")) && !(boolean)XposedHelpers.callMethod(XposedHelpers.callMethod(param.args[1], "getNotification"), "isGroupSummary"); + boolean hasEntry = XposedHelpers.callMethod(mNotificationData, "get", XposedHelpers.getObjectField(param.args[0], "key")) != null; + boolean isLowPriority = (boolean)XposedHelpers.callMethod(expandableRow, "isLowPriority"); + XposedHelpers.callMethod(expandableRow, "setIsLowPriority", newLowPriority); + boolean hasLowPriorityChanged = hasEntry && isLowPriority != newLowPriority; + XposedHelpers.callMethod(expandableRow, "setLowPriorityStateUpdated", hasLowPriorityChanged); + XposedHelpers.callMethod(expandableRow, "updateNotification", param.args[0]); } }); - Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "getTileLabel", new MethodHook() { + } + + public static void NotificationChannelSettingsHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.systemui.statusbar.notification.row.MiuiNotificationMenuRow", lpparam.classLoader, "onClickInfoItem", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); - if (customName != null) { - String tileName = (String) customName; - if ("custom_5G".equals(tileName)) { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - Resources modRes = Helpers.getModuleRes(mContext); - param.setResult(modRes.getString(R.string.qs_toggle_5g)); - } + protected void before(final MethodHookParam param) throws Throwable { + Context mContext = (Context)param.args[0]; + Object entry = XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mParent"), "getEntry"); + String id = (String)XposedHelpers.callMethod(XposedHelpers.callMethod(entry, "getChannel"), "getId"); + if ("miscellaneous".equals(id)) return; + Object notification = XposedHelpers.callMethod(entry, "getSbn"); + Class nuCls = findClassIfExists("com.android.systemui.miui.statusbar.notification.NotificationUtil", lpparam.classLoader); + if (nuCls != null) { + boolean isHybrid = (boolean)XposedHelpers.callStaticMethod(nuCls, "isHybrid", notification); + if (isHybrid) return; } - } - }); - Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "handleSetListening", boolean.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); - if (customName != null) { - String tileName = (String) customName; - if ("custom_5G".equals(tileName)) { - Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); - boolean mListening = (boolean) param.args[0]; - if (mListening) { - ContentObserver contentObserver = new ContentObserver(new Handler(mContext.getMainLooper())) { - @Override - public void onChange(boolean z) { - XposedHelpers.callMethod(param.thisObject, "refreshState"); - } - }; - mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor("fiveg_user_enable"), false, contentObserver); - mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor("dual_nr_enabled"), false, contentObserver); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "tileListener", contentObserver); - } - else { - ContentObserver contentObserver = (ContentObserver) XposedHelpers.getAdditionalInstanceField(param.thisObject, "tileListener"); - mContext.getContentResolver().unregisterContentObserver(contentObserver); - } - } + String pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName"); + int user = (int)XposedHelpers.callMethod(notification, "getAppUid"); + + Bundle bundle = new Bundle(); + bundle.putString("android.provider.extra.CHANNEL_ID", id); + bundle.putString("package", pkgName); + bundle.putInt("uid", user); + bundle.putString("miui.targetPkg", pkgName); + Intent intent = new Intent("android.intent.action.MAIN"); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(":android:show_fragment", "com.android.settings.notification.ChannelNotificationSettings"); + intent.putExtra(":android:show_fragment_args", bundle); + intent.setClassName("com.android.settings", "com.android.settings.SubSettings"); + try { + XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, android.os.Process.myUserHandle()); param.setResult(null); + Object ModalController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", mContext.getClassLoader()), "get", findClass("com.android.systemui.statusbar.notification.modal.ModalController", mContext.getClassLoader())); + XposedHelpers.callMethod(ModalController, "animExitModelCollapsePanels"); + } catch (Throwable ignore) { + Helpers.log(ignore); } } }); - Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "getLongClickIntent", new MethodHook() { + } + + public static void SkipAppLockHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.miui.server.AccessController", lpparam.classLoader, new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); - if (customName != null) { - String tileName = (String) customName; - if ("custom_5G".equals(tileName)) { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - intent.setComponent(new ComponentName("com.android.phone", "com.android.phone.settings.PreferredNetworkTypeListPreference")); - param.setResult(intent); - } - else { - param.setResult(null); + protected void after(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mWorkHandler"); + + new Helpers.SharedPrefObserver(mContext, mHandler) { + @Override + public void onChange(Uri uri) { + try { + String type = uri.getPathSegments().get(1); + String key = uri.getPathSegments().get(2); + if (key.contains("pref_key_system_applock_skip_activities") && "string".equals(type)) + MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "")); + } catch (Throwable t) { + XposedBridge.log(t); + } } - } + }; } }); - Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "handleClick", View.class, new MethodHook() { + + Helpers.hookAllMethods("com.miui.server.AccessController", lpparam.classLoader, "skipActivity", new MethodHook() { @Override - protected void before(MethodHookParam param) throws Throwable { - Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); - if (customName != null) { - String tileName = (String) customName; - if ("custom_5G".equals(tileName)) { - TelephonyManager manager = TelephonyManager.getDefault(); - manager.setUserFiveGEnabled(!manager.isUserFiveGEnabled()); - } - param.setResult(null); + protected void after(MethodHookParam param) throws Throwable { + Intent intent = (Intent)param.args[0]; + if (intent == null || intent.getComponent() == null) return; + String pkgName = intent.getComponent().getPackageName(); + String actName = intent.getComponent().getClassName(); + String key = "system_applock_skip_activities"; + String itemStr = MainModule.mPrefs.getString(key, ""); + if (itemStr == null || itemStr.isEmpty()) return; + String[] itemArr = itemStr.trim().split("\\|"); + for (String uuid: itemArr) { + String pkgAct = MainModule.mPrefs.getString(key + "_" + uuid + "_activity", ""); + if (pkgAct.equals(pkgName + "|" + actName)) param.setResult(true); } } }); + } - int fiveGIconResId = MainModule.resHooks.addResource("ic_qs_5g_on", R.drawable.ic_qs_5g_on); - int fiveGIconOffResId = MainModule.resHooks.addResource("ic_qs_5g_off", R.drawable.ic_qs_5g_off); - Helpers.hookAllMethods(NfcTileCls, lpparam.classLoader, "handleUpdateState", new MethodHook() { + public static void HideLockScreenHintHook(LoadPackageParam lpparam) { + MethodHook hook = new MethodHook() { @Override protected void before(MethodHookParam param) throws Throwable { - Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); - if (customName != null) { - String tileName = (String) customName; - if ("custom_5G".equals(tileName)) { - Object booleanState = param.args[0]; - TelephonyManager manager = TelephonyManager.getDefault(); - boolean isEnable = manager.isUserFiveGEnabled(); - XposedHelpers.setObjectField(booleanState, "value", isEnable); - XposedHelpers.setObjectField(booleanState, "state", isEnable ? 2 : 1); - String tileLabel = (String) XposedHelpers.callMethod(param.thisObject, "getTileLabel"); - XposedHelpers.setObjectField(booleanState, "label", tileLabel); - XposedHelpers.setObjectField(booleanState, "contentDescription", tileLabel); - XposedHelpers.setObjectField(booleanState, "expandedAccessibilityClassName", Switch.class.getName()); - Object mIcon = XposedHelpers.callStaticMethod(ResourceIconClass, "get", isEnable ? fiveGIconResId : fiveGIconOffResId); - XposedHelpers.setObjectField(booleanState, "icon", mIcon); - } - param.setResult(null); - } + XposedHelpers.setObjectField(param.thisObject, "mUpArrowIndication", null); } - }); - } - - private static float scaledTileWidthDim = -1f; - public static void SystemCCGridHook(LoadPackageParam lpparam) { - int cols = MainModule.mPrefs.getInt("system_ccgridcolumns", 4); - int rows = MainModule.mPrefs.getInt("system_ccgridrows", 4); - if (cols > 4) { - MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_columns", cols); + }; + if (Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController", lpparam.classLoader, "hasIndicationsExceptResting", XC_MethodReplacement.returnConstant(true)); + } + else { + Helpers.findAndHookMethod("com.android.systemui.statusbar.KeyguardIndicationController", lpparam.classLoader, "updateIndication", boolean.class, boolean.class, hook); } + } - Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { - private boolean isHooked = false; + public static void HideLockScreenStatusBarHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - if (!isHooked) { - isHooked = true; - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); - Resources res = mContext.getResources(); - float density = res.getDisplayMetrics().density; - int tileWidthResId = res.getIdentifier("qs_control_center_tile_width", "dimen", "com.android.systemui"); - float tileWidthDim = res.getDimension(tileWidthResId); - if (cols > 4) { - tileWidthDim = tileWidthDim / density; - scaledTileWidthDim = tileWidthDim * 4 / cols; - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "qs_control_center_tile_width", scaledTileWidthDim); - MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_control_center_tile_width", scaledTileWidthDim); - MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "qs_control_tile_icon_bg_size", scaledTileWidthDim); - MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_control_tile_icon_bg_size", scaledTileWidthDim); - MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85f); - } - } + protected void after(final MethodHookParam param) throws Throwable { + View mKeyguardStatusBar = (View) XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mNotificationPanelViewController"), "mKeyguardStatusBar"); + mKeyguardStatusBar.setTranslationY(-999f); } }); + } - String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; - Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { - private boolean isHooked = false; - @Override - protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { - isHooked = true; - if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); - } - if (cols > 4) { - Helpers.findAndHookConstructor("miui.systemui.controlcenter.qs.QSPager", pluginLoader, Context.class, AttributeSet.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - XposedHelpers.setObjectField(param.thisObject, "columns", cols); - } - }); - if (!MainModule.mPrefs.getBoolean("system_qsnolabels")) { - Helpers.hookAllMethods("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader, "handleStateChanged", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object label = XposedHelpers.getObjectField(param.thisObject, "label"); - if (label != null) { - TextView lb = (TextView) label; - lb.setMaxLines(1); - lb.setSingleLine(true); - lb.setEllipsize(TextUtils.TruncateAt.MARQUEE); - lb.setMarqueeRepeatLimit(0); - } - } - }); + public static void MuteVisibleNotificationsHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.media.NotificationPlayer$CreationAndCompletionThread", lpparam.classLoader, "run", new MethodHook() { + @Override + @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") + protected void before(final MethodHookParam param) throws Throwable { + Object mCmd = XposedHelpers.getObjectField(param.thisObject, "mCmd"); + if (mCmd == null) return; + int code = XposedHelpers.getIntField(mCmd, "code"); + if (code != 1) return; + AudioAttributes attributes = (AudioAttributes)XposedHelpers.getObjectField(mCmd, "attributes"); + if (attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION || attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE || attributes.getUsage() == AudioAttributes.USAGE_UNKNOWN) + if (attributes.getContentType() == AudioAttributes.CONTENT_TYPE_SONIFICATION || attributes.getContentType() == AudioAttributes.CONTENT_TYPE_UNKNOWN) { + Context context = (Context)XposedHelpers.getObjectField(mCmd, "context"); + PowerManager powerMgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + if (powerMgr.isInteractive()) { + Thread thread = (Thread)param.thisObject; + synchronized (thread) { thread.notify(); } + param.setResult(null); } } - if (rows != 4) { - Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.QSPager", pluginLoader, "distributeTiles", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - boolean collapse = (boolean) XposedHelpers.getObjectField(param.thisObject, "collapse"); - if (collapse) { - ArrayList pages = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "pages"); - for (Object tileLayoutImpl : pages) { - XposedHelpers.callMethod(tileLayoutImpl, "removeTiles"); - } - ArrayList pageTiles = new ArrayList(); - int currentRow = 2; - ArrayList records = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "records"); - Iterator it2 = records.iterator(); - int i3 = 0; - int pageNow = 0; - Object bigHeader = XposedHelpers.getObjectField(param.thisObject, "header"); - while (it2.hasNext()) { - Object tileRecord = it2.next(); - pageTiles.add(tileRecord); - i3++; - if (i3 >= cols) { - currentRow++; - i3 = 0; - } - if (currentRow >= rows || !it2.hasNext()) { - XposedHelpers.callMethod(pages.get(pageNow), "setTiles", pageTiles, pageNow == 0 ? bigHeader : null); - pageTiles.clear(); - int totalRows = (int) XposedHelpers.getObjectField(param.thisObject, "rows"); - if (currentRow > totalRows) { - XposedHelpers.setObjectField(param.thisObject, "rows", currentRow); - } - if (it2.hasNext()) { - pageNow++; - currentRow = 0; - } - } - } - Iterator it3 = pages.iterator(); - while (it3.hasNext()) { - Object next2 = it3.next(); - boolean isEmpty = (boolean) XposedHelpers.callMethod(next2, "isEmpty"); - if (isEmpty) { - it3.remove(); - } - } - Object pageIndicator = XposedHelpers.getObjectField(param.thisObject, "pageIndicator"); - if (pageIndicator != null) { - XposedHelpers.callMethod(pageIndicator, "setNumPages", pages.size()); - } - Object adapter = XposedHelpers.getObjectField(param.thisObject, "adapter"); - XposedHelpers.callMethod(param.thisObject, "setAdapter", adapter); -// XposedHelpers.callMethod(param.thisObject, "notifyDataSetChanged"); - } - } - }); - } - } } }); } - public static void CCTileCornerHook(LoadPackageParam lpparam) { - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_unavailable", R.drawable.ic_qs_tile_bg_disabled); - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_disabled", R.drawable.ic_qs_tile_bg_disabled); - MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_warning", R.drawable.ic_qs_tile_bg_warning); - - String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; - Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { - private boolean isHooked = false; + public static void NetworkIndicatorWifi(LoadPackageParam lpparam) { + MethodHook hideWifiActivity = new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; - if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { - isHooked = true; - if (pluginLoader == null) { - pluginLoader = (ClassLoader) param.getResult(); - } - Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.tileview.ExpandableIconView", pluginLoader, "setCornerRadius", float.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getPluginContext"); - float radius = 18; - if (scaledTileWidthDim > 0) { - radius *= scaledTileWidthDim / 65; - } - param.args[0] = mContext.getResources().getDisplayMetrics().density * radius; - } - }); - - Helpers.findAndHookMethod("miui.systemui.dagger.PluginComponentFactory", pluginLoader, "create", Context.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - Context mContext = (Context) param.args[0]; - int enabledTileBackgroundResId = mContext.getResources().getIdentifier("qs_background_enabled", "drawable", "miui.systemui.plugin"); - int enabledTileColorResId = mContext.getResources().getIdentifier("qs_enabled_color", "color", "miui.systemui.plugin"); - Helpers.findAndHookMethod("android.content.res.Resources", pluginLoader, "getDrawable", int.class, new MethodHook() { - @Override - protected void before(MethodHookParam param) throws Throwable { - int resId = (int) param.args[0]; - if (resId == enabledTileBackgroundResId && resId != 0) { - Resources modRes = Helpers.getModuleRes(mContext); - Drawable enableTile = modRes.getDrawable(R.drawable.ic_qs_tile_bg_enabled, null); - enableTile.setTint(mContext.getResources().getColor(enabledTileColorResId, null)); - param.setResult(enableTile); - } - } - }); - } - }); - } + protected void after(final MethodHookParam param) throws Throwable { + Object mWifiActivityView = XposedHelpers.getObjectField(param.thisObject, "mWifiActivityView"); + XposedHelpers.callMethod(mWifiActivityView, "setVisibility", 4); } - }); + }; + Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarWifiView", lpparam.classLoader, "applyWifiState", hideWifiActivity); } - public static void DualRowStatusbarHook(LoadPackageParam lpparam) { - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + public static void SetLockscreenWallpaperHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.server.wallpaper.WallpaperManagerService", lpparam.classLoader, "setWallpaper", new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - FrameLayout sbView = (FrameLayout) param.thisObject; - Context mContext = sbView.getContext(); - LinearLayout leftLayout = new LinearLayout(mContext); - LinearLayout rightLayout = new LinearLayout(mContext); - LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); - ViewGroup rightContainer = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mSystemIconArea"); - View switchUserView = null; - if (Helpers.isTPlus()) { - int userViewId = sbView.getResources().getIdentifier("user_switcher_container", "id", lpparam.packageName); - switchUserView = sbView.findViewById(userViewId); - ((ViewGroup) switchUserView.getParent()).removeView(switchUserView); - } - int firstRowLeftPadding = 0; - int firstRowRightPadding = 0; - if (MainModule.mPrefs.getBoolean("system_statusbar_dualrows_firstrow_horizmargin")) { - firstRowLeftPadding = MainModule.mPrefs.getInt("system_statusbar_dualrows_firstrow_horizmargin_left", 0); - firstRowRightPadding = MainModule.mPrefs.getInt("system_statusbar_dualrows_firstrow_horizmargin_right", 0); - } - LinearLayout statusBarcontents = (LinearLayout) rightContainer.getParent(); - statusBarcontents.removeView(leftContainer); - statusBarcontents.removeView(rightContainer); - statusBarcontents.addView(leftLayout, 0); - statusBarcontents.addView(rightLayout); - XposedHelpers.setObjectField(param.thisObject, "mSystemIconArea", rightLayout); - leftLayout.addView(leftContainer); - if (firstRowLeftPadding > 0) { - leftContainer.setPaddingRelative(firstRowLeftPadding, 0, 0, 0); - } - LinearLayout secondLeft = new LinearLayout(mContext); - leftLayout.addView(secondLeft); - LinearLayout firstRight = new LinearLayout(mContext); - rightLayout.addView(firstRight); - firstRight.setGravity(Gravity.END); - if (firstRowRightPadding > 0) { - firstRight.setPaddingRelative(0, 0, firstRowRightPadding, 0); - } - LinearLayout secondRight = new LinearLayout(mContext); - rightLayout.addView(secondRight); - secondRight.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); - View mBattery = (View) XposedHelpers.getObjectField(param.thisObject, "mBattery"); - ((ViewGroup) mBattery.getParent()).removeView(mBattery); - if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright") && MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) { - TextView batteryView = createBatteryDetailView(mContext, new LinearLayout.LayoutParams(-2, -2)); - secondRight.addView(batteryView); - mBatteryDetailViews.add(batteryView); - Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); - Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); - Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); - Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); - XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); - updateTempAndCurrent(ChargeUtilsClass); - } - secondRight.addView(mBattery); + protected void after(final MethodHookParam param) throws Throwable { + if (param.getThrowable() != null || param.getResult() == null || (int)param.args[5] == 1 || "com.android.thememanager".equals(param.args[1])) return; - if (Helpers.isTPlus()) { - if (switchUserView != null) { - secondRight.addView(switchUserView); - } - } + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + if (mContext == null) return; - XposedHelpers.setAdditionalInstanceField(param.thisObject, "leftLayout", leftLayout); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "rightLayout", rightLayout); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "firstRight", firstRight); - XposedHelpers.setAdditionalInstanceField(param.thisObject, "secondLeft", secondLeft); + int handleIncomingUser = 0; + try { + handleIncomingUser = (int)XposedHelpers.callStaticMethod(ActivityManager.class, "handleIncomingUser", Binder.getCallingPid(), Binder.getCallingUid(), param.args[7], false, true, "changing wallpaper", null); + } catch (Throwable ignore) {} + Object wallpaperData = XposedHelpers.callMethod(param.thisObject, "getWallpaperSafeLocked", handleIncomingUser, param.args[5]); + File wallpaper = (File)XposedHelpers.getObjectField(wallpaperData, "wallpaperFile"); - View mFullscreenStatusBarNotificationIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mFullscreenStatusBarNotificationIconArea"); - ((ViewGroup) mFullscreenStatusBarNotificationIconArea.getParent()).removeView(mFullscreenStatusBarNotificationIconArea); - secondLeft.addView(mFullscreenStatusBarNotificationIconArea); - View mDripStatusBarNotificationIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarNotificationIconArea"); - ((ViewGroup) mDripStatusBarNotificationIconArea.getParent()).removeView(mDripStatusBarNotificationIconArea); - secondLeft.addView(mDripStatusBarNotificationIconArea); - View mStatusBarStatusIcons = (View) XposedHelpers.getObjectField(param.thisObject, "mStatusBarStatusIcons"); - ((ViewGroup) mStatusBarStatusIcons.getParent()).removeView(mStatusBarStatusIcons); - firstRight.addView(mStatusBarStatusIcons); - int resSystemIconsId = sbView.getResources().getIdentifier("system_icons", "id", lpparam.packageName); - firstRight.setId(resSystemIconsId); - } - }); + new Handler(mContext.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + if (!wallpaper.exists()) return; - Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); - LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); - LinearLayout leftLayout = (LinearLayout) leftContainer.getParent(); - LinearLayout rightLayout = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "rightLayout"); - LinearLayout rightContainer = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "firstRight"); - LinearLayout secondLeft = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "secondLeft"); - LinearLayout secondRight = (LinearLayout) rightLayout.getChildAt(1); - LinearLayout statusBarcontents = (LinearLayout) leftLayout.getParent(); - boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); - - statusBarcontents.setOrientation(mCurrentStatusBarType == 0 ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); - if (mCurrentStatusBarType == 0) { - if (leftLayout.getChildAt(1) != rightContainer) { - leftLayout.removeViewAt(1); - rightLayout.removeViewAt(0); - leftLayout.addView(rightContainer); - rightLayout.addView(secondLeft, 0); - } - leftLayout.setOrientation(LinearLayout.HORIZONTAL); - rightLayout.setOrientation(LinearLayout.HORIZONTAL); - LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(-1, 0, 1); - leftLayout.setLayoutParams(leftLayoutLp); - LinearLayout.LayoutParams rightLayoutLp = new LinearLayout.LayoutParams(-1, 0, 1); - rightLayout.setLayoutParams(rightLayoutLp); - - LinearLayout.LayoutParams firstRowlp = new LinearLayout.LayoutParams(-2, -1, 0); - leftContainer.setLayoutParams(firstRowlp); - firstRowlp = new LinearLayout.LayoutParams(0, -1, 1); - rightContainer.setLayoutParams(firstRowlp); - - LinearLayout.LayoutParams secondRowLp = new LinearLayout.LayoutParams(0, -1, 1); - secondLeft.setLayoutParams(secondRowLp); - secondRight.setLayoutParams(secondRowLp); - } - else { - if (leftLayout.getChildAt(1) != secondLeft) { - leftLayout.removeViewAt(1); - rightLayout.removeViewAt(0); - leftLayout.addView(secondLeft); - rightLayout.addView(rightContainer, 0); + String lockWallpaperPath = "/data/system/theme/thirdparty_lock_wallpaper"; + Helpers.copyFile(wallpaper.getAbsolutePath(), lockWallpaperPath); + Class ThemeUtils = XposedHelpers.findClass("miui.content.res.ThemeNativeUtils", lpparam.classLoader); + XposedHelpers.callStaticMethod(ThemeUtils, "updateFilePermissionWithThemeContext", lockWallpaperPath); + JSONObject data = new JSONObject(); + JSONObject ex = new JSONObject(); + try { + File lockWallpaper = new File(lockWallpaperPath); + ex + .put("link_type", "0") + .put("title_size", "26") + .put("item_id", "wallpaper1") + .put("title_color", "#ffffffff") + .put("index_in_album", "1") + .put("tag_list", "CustoMIUIzer,mod") + .put("content_color", "#ffffffff") + .put("total_of_album", "1") + .put("img_level", "0") + .put("album_id", "1") + .put("title_customized", "0") + .put("lks_entry_text", "Some wallpaper"); + + data + .put("authority", "name.mikanoshi.customiuizer.mods.set_lockscreen_wallpaper") + .put("content", "Wallpaper set by some app") + .put("contentColorValue", 0) + .put("cp", "CustoMIUIzer") + .put("cpColorValue", 0) + .put("definition", -1) + .put("ex", ex.toString()) + .put("fromColorValue", 0) + .put("hasAcc", false) + .put("indexInAlbum", -1) + .put("isAd", false) + .put("isCustom", false) + .put("isFd", false) + .put("isFrontCover", false) + .put("key", "wallpaper1") + .put("like", false) + .put("linkType", 0) + .put("noApply", false) + .put("noDislike", false) + .put("noSave", false) + .put("noShare", false) + .put("pos", 0) + .put("supportLike", true) + .put("title", "Some wallpaper") + .put("titleColorValue", 0) + .put("titleTextSize", -1) + .put("totalOfAlbum", -1) + .put("wallpaperUri", lockWallpaper.toURI()); + } catch (Throwable t) { + XposedBridge.log(t); + } + + Intent setIntent = new Intent("com.miui.miwallpaper.UPDATE_LOCKSCREEN_WALLPAPER"); + setIntent.putExtra("wallpaperInfo", data.toString()); + setIntent.putExtra("apply", true); + mContext.sendBroadcast(setIntent); } - Object mMiuiEndIconManager = XposedHelpers.getObjectField(param.thisObject, "mMiuiEndIconManager"); - XposedHelpers.callMethod(mMiuiEndIconManager, "setDripEnd", false); - Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); - XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); - View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); - mDripStatusBarLeftStatusIconArea.setVisibility(moveSignalLeft ? View.VISIBLE : View.GONE); - leftLayout.setOrientation(LinearLayout.VERTICAL); - rightLayout.setOrientation(LinearLayout.VERTICAL); - LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); - leftLayout.setLayoutParams(leftLayoutLp); - LinearLayout.LayoutParams rightLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); - rightLayout.setLayoutParams(rightLayoutLp); - - LinearLayout.LayoutParams leftLp = new LinearLayout.LayoutParams(-1, 0, 1); - leftContainer.setLayoutParams(leftLp); - secondLeft.setLayoutParams(leftLp); - - LinearLayout.LayoutParams rightLp = new LinearLayout.LayoutParams(-1, 0, 1); - rightContainer.setLayoutParams(rightLp); - secondRight.setLayoutParams(rightLp); - } - secondLeft.setGravity(Gravity.CENTER_VERTICAL | Gravity.START); + }, 1800); } }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showSystemIconArea", boolean.class, new MethodHook() { - @Override - protected void after(MethodHookParam param) throws Throwable { - Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); - View rightLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "rightLayout"); - View leftLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "leftLayout"); - leftLayout.setVisibility(LinearLayout.VISIBLE); - rightLayout.setVisibility(LinearLayout.VISIBLE); - } - }); - Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "hideSystemIconArea", boolean.class, new MethodHook() { + } + + public static void BetterPopupsCenteredHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.HeadsUpManager", lpparam.classLoader, "getHeadsUpTopMargin", Context.class, new MethodHook() { @Override - protected void after(MethodHookParam param) throws Throwable { - Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); - View rightLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "rightLayout"); - View leftLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "leftLayout"); - leftLayout.setVisibility(LinearLayout.GONE); - rightLayout.setVisibility(LinearLayout.GONE); + protected void after(final MethodHookParam param) throws Throwable { + Context context = (Context)param.args[0]; + Resources res = context.getResources(); + int maxPopupHeight = res.getDimensionPixelSize(res.getIdentifier("notification_max_heads_up_height", "dimen", "com.android.systemui")); + if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) maxPopupHeight /= 3; + param.setResult(Math.round(context.getResources().getDisplayMetrics().heightPixels / 2.0f - maxPopupHeight / 2.0f)); } }); } + public static void WallpaperScaleLevelHook(LoadPackageParam lpparam) { Helpers.hookAllConstructors("com.android.server.wm.WallpaperController", lpparam.classLoader, new MethodHook() { @Override diff --git a/app/src/main/java/name/mikanoshi/customiuizer/mods/SystemUI.java b/app/src/main/java/name/mikanoshi/customiuizer/mods/SystemUI.java new file mode 100644 index 00000000..8a7424a3 --- /dev/null +++ b/app/src/main/java/name/mikanoshi/customiuizer/mods/SystemUI.java @@ -0,0 +1,3209 @@ +package name.mikanoshi.customiuizer.mods; + +import static java.lang.System.currentTimeMillis; +import static java.lang.System.nanoTime; +import static de.robv.android.xposed.XposedHelpers.findClass; +import static de.robv.android.xposed.XposedHelpers.findClassIfExists; +import static de.robv.android.xposed.XposedHelpers.findMethodExactIfExists; +import static name.mikanoshi.customiuizer.mods.GlobalActions.ACTION_PREFIX; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.ActivityManager; +import android.app.ActivityOptions; +import android.app.AndroidAppHelper; +import android.app.KeyguardManager; +import android.app.MiuiNotification; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.PendingIntent; +import android.app.TaskStackBuilder; +import android.app.WallpaperColors; +import android.app.WallpaperManager; +import android.appwidget.AppWidgetProviderInfo; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.database.ContentObserver; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.PointF; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.hardware.usb.UsbManager; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.MediaMetadata; +import android.media.MediaPlayer; +import android.media.SoundPool; +import android.media.session.MediaController; +import android.media.session.PlaybackState; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.net.TrafficStats; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.os.BadParcelableException; +import android.os.BatteryManager; +import android.os.Binder; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.Parcelable; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.MediaStore; +import android.provider.Settings; +import android.telephony.PhoneStateListener; +import android.text.Layout; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.text.format.DateUtils; +import android.text.style.AbsoluteSizeSpan; +import android.text.style.TypefaceSpan; +import android.util.ArrayMap; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Pair; +import android.util.SparseArray; +import android.util.SparseIntArray; +import android.util.TypedValue; +import android.view.Display; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.SurfaceControl; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.view.Window; +import android.view.WindowManager; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.Interpolator; +import android.widget.AbsListView; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.HorizontalScrollView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Magnifier; +import android.widget.RelativeLayout; +import android.widget.RemoteViews; +import android.widget.ScrollView; +import android.widget.SeekBar; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import org.json.JSONObject; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; +import java.net.NetworkInterface; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import de.robv.android.xposed.XC_MethodHook.MethodHookParam; +import de.robv.android.xposed.XC_MethodReplacement; +import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.XposedHelpers; +import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; +import de.robv.android.xposed.callbacks.XCallback; +import miui.telephony.TelephonyManager; +import name.mikanoshi.customiuizer.MainModule; +import name.mikanoshi.customiuizer.R; +import name.mikanoshi.customiuizer.utils.AudioVisualizer; +import name.mikanoshi.customiuizer.utils.BatteryIndicator; +import name.mikanoshi.customiuizer.utils.Helpers; +import name.mikanoshi.customiuizer.utils.Helpers.MethodHook; +import name.mikanoshi.customiuizer.utils.Helpers.MimeType; +import name.mikanoshi.customiuizer.utils.ResourceHooks; +import name.mikanoshi.customiuizer.utils.SoundData; + +public class SystemUI { + private final static String StatusBarCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfacesImpl" : "com.android.systemui.statusbar.phone.StatusBar"; + + private static int statusbarTextIconLayoutResId = 0; + private static int notifVolumeOnResId; + private static int notifVolumeOffResId; + public static void setupStatusBar(LoadPackageParam lpparam) { + statusbarTextIconLayoutResId = MainModule.resHooks.addResource("statusbar_text_icon", R.layout.statusbar_text_icon); + if (MainModule.mPrefs.getBoolean("system_statusbar_topmargin")) { + int topMargin = MainModule.mPrefs.getInt("system_statusbar_topmargin_val", 1); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_top", topMargin); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_horizmargin")) { + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_start", 0); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "status_bar_padding_end", 0); + } + if (MainModule.mPrefs.getBoolean("system_cc_enable_style_switch")) { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "integer", "force_use_control_panel", 0); + } + if (MainModule.mPrefs.getBoolean("system_qs_force_systemfonts")) { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "bool", "header_big_time_use_system_font", true); + } + if (MainModule.mPrefs.getBoolean("system_separatevolume") && MainModule.mPrefs.getBoolean("system_separatevolume_slider")) { + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_content_width_expanded", R.dimen.miui_volume_content_width_expanded); + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_ringer_layout_width_expanded", R.dimen.miui_volume_ringer_layout_width_expanded); + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_column_width_expanded", R.dimen.miui_volume_column_width_expanded); + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "dimen", "miui_volume_column_margin_horizontal_expanded", R.dimen.miui_volume_column_margin_horizontal_expanded); + notifVolumeOnResId = MainModule.resHooks.addResource("ic_miui_volume_notification", R.drawable.ic_miui_volume_notification); + notifVolumeOffResId = MainModule.resHooks.addResource("ic_miui_volume_notification_mute", R.drawable.ic_miui_volume_notification_mute); + } + } + public static void DisplayBatteryDetailHook(LoadPackageParam lpparam) { + Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); + Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); + Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); + Class StatusBarIconHolder = XposedHelpers.findClass("com.android.systemui.statusbar.phone.StatusBarIconHolder", lpparam.classLoader); + boolean atRight = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright"); + if (atRight && !MainModule.mPrefs.getBoolean("system_statusbar_dualrows")) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + Object iconController = XposedHelpers.getObjectField(param.thisObject, "mStatusBarIconController"); + int slotIndex = (int) XposedHelpers.callMethod(iconController, "getSlotIndex", "battery_detail"); + Object iconHolder = XposedHelpers.callMethod(iconController, "getIcon", slotIndex, 0); + if (iconHolder == null) { + iconHolder = XposedHelpers.newInstance(StatusBarIconHolder); + XposedHelpers.setObjectField(iconHolder, "mType", 91); + XposedHelpers.callMethod(iconController, "setIcon", slotIndex, iconHolder); + } + if (!isHooked) { + isHooked = true; + updateTempAndCurrent(ChargeUtilsClass); + } + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBarIconController$IconManager", lpparam.classLoader, "addHolder", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (param.args.length != 4) return; + Object iconHolder = param.args[3]; + int type = (int) XposedHelpers.callMethod(iconHolder, "getType"); + if (type == 91) { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) XposedHelpers.callMethod(param.thisObject, "onCreateLayoutParams"); + TextView batteryView = createBatteryDetailView(mContext, lp); + int i = (int) param.args[0]; + ViewGroup mGroup = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mGroup"); + mGroup.addView(batteryView, i); + mBatteryDetailViews.add(batteryView); + param.setResult(batteryView); + } + } + }); + Class NetworkSpeedViewClass = XposedHelpers.findClass("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader); + Helpers.findAndHookMethod(NetworkSpeedViewClass, "getSlot", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customSlot = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCustomSlot"); + if (customSlot != null) { + param.setResult(customSlot); + } + } + }); + } + else if (!atRight) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getContext"); + TextView mSplitter = (TextView) XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedSplitter"); + ViewGroup batteryViewContainer = (ViewGroup) mSplitter.getParent(); + int bvIndex = batteryViewContainer.indexOfChild(mSplitter); + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSplitter.getLayoutParams(); + TextView batteryView = createBatteryDetailView(mContext, lp); + batteryViewContainer.addView(batteryView, bvIndex + 1); + mBatteryDetailViews.add(batteryView); + Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); + XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mBatteryView", batteryView); + if (!isHooked) { + isHooked = true; + updateTempAndCurrent(ChargeUtilsClass); + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showClock", boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); + if (bv != null) { + XposedHelpers.callMethod(bv, "setVisibilityByController", true); + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "hideClockInternal", int.class, boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object bv = XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryView"); + if (bv != null) { + XposedHelpers.callMethod(bv, "setVisibilityByController", false); + } + } + }); + } + } + + private static TextView createBatteryDetailView(Context mContext, LinearLayout.LayoutParams lp) { + TextView batteryView = (TextView) LayoutInflater.from(mContext).inflate(statusbarTextIconLayoutResId, null); + XposedHelpers.setObjectField(batteryView, "mVisibilityByDisableInfo", 0); + XposedHelpers.setObjectField(batteryView, "mVisibleByController", true); + XposedHelpers.setObjectField(batteryView, "mShown", true); + XposedHelpers.setAdditionalInstanceField(batteryView, "mCustomSlot", "battery_detail"); + Resources res = mContext.getResources(); + int styleId = res.getIdentifier("TextAppearance.StatusBar.Clock", "style", "com.android.systemui"); + batteryView.setTextAppearance(styleId); + float fontSize = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_fontsize", 16) * 0.5f; + int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); + if (opt == 1 && MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_singlerow")) { + batteryView.setLineSpacing(0, fontSize > 8.5f ? 0.85f : 0.9f); + batteryView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + } + batteryView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize); + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_bold")) { + batteryView.setTypeface(Typeface.DEFAULT_BOLD); + } + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_leftmargin", 8); + leftMargin = (int)TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin * 0.5f, + res.getDisplayMetrics() + ); + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_rightmargin", 8); + rightMargin = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin * 0.5f, + res.getDisplayMetrics() + ); + batteryView.setPaddingRelative(leftMargin, 0, rightMargin, 0); + + int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_batterytempandcurrent_verticaloffset", 8); + if (verticalOffset != 8) { + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + res.getDisplayMetrics() + ); + lp.topMargin = (int) (marginTop); + } + batteryView.setLayoutParams(lp); + return batteryView; + } + static final ArrayList mBatteryDetailViews = new ArrayList(); + + private static void updateTempAndCurrent(Class ChargeUtilsClass) { + Handler handler = new Handler(Looper.getMainLooper()); + Runnable refreshRunner = new Runnable() { + @Override + public void run() { + String batteryInfo = ""; + FileInputStream fis = null; + Properties props = null; + boolean showInfo = true; + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_incharge") && ChargeUtilsClass != null) { + Object batteryStatus = Helpers.getStaticObjectFieldSilently(ChargeUtilsClass, "sBatteryStatus"); + if (batteryStatus == null) { + showInfo = false; + } + else { + showInfo = (boolean) XposedHelpers.callMethod(batteryStatus, "isCharging"); + } + } + if (showInfo) { + try { + fis = new FileInputStream("/sys/class/power_supply/battery/uevent"); + props = new Properties(); + props.load(fis); + } + catch (Throwable ign) {} + finally { + try { + fis.close(); + } + catch (Throwable ign) {} + } + if (props != null) { + int tempVal = Integer.parseInt(props.getProperty("POWER_SUPPLY_TEMP")); + int currVal = -1 * Math.round(Integer.parseInt(props.getProperty("POWER_SUPPLY_CURRENT_NOW")) / 1000); + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_positive")) { + currVal = Math.abs(currVal); + } + int opt = MainModule.mPrefs.getStringAsInt("system_statusbar_batterytempandcurrent_content", 1); + String simpleTempVal = tempVal % 10 == 0 ? (tempVal / 10 + "") : (tempVal / 10f + ""); + if (opt == 1) { + String splitChar = MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_singlerow") + ? " " : "\n"; + batteryInfo = simpleTempVal + "℃" + splitChar + currVal + "mA"; + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_reverseorder")) { + batteryInfo = currVal + "mA" + splitChar + simpleTempVal + "℃"; + } + } + else if (opt == 2) { + batteryInfo = simpleTempVal + "℃"; + } + else { + batteryInfo = currVal + "mA"; + } + } + } + for (TextView tv:mBatteryDetailViews) { + XposedHelpers.callMethod(tv, "setBlocked", !showInfo); + XposedHelpers.callMethod(tv, "setNetworkSpeed", batteryInfo); + } + handler.postDelayed(this, 1500); + } + }; + handler.post(refreshRunner); + } + + public static void AddFiveGTileHook(LoadPackageParam lpparam) { + + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isListened = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isListened) { + isListened = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + int stockTilesResId = mContext.getResources().getIdentifier("miui_quick_settings_tiles_stock", "string", lpparam.packageName); + String stockTiles = mContext.getString(stockTilesResId) + ",custom_5G"; + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "string", "miui_quick_settings_tiles_stock", stockTiles); + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "string", "miui_quick_settings_tiles_stock", stockTiles); + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "string", "quick_settings_tiles_stock", stockTiles); + } + } + }); + String QSFactoryCls = Helpers.isTPlus() ? "com.android.systemui.qs.tileimpl.MiuiQSFactory" : "com.android.systemui.qs.tileimpl.QSFactoryImpl"; + Class ResourceIconClass = findClass("com.android.systemui.qs.tileimpl.QSTileImpl$ResourceIcon", lpparam.classLoader); + Helpers.findAndHookMethod(QSFactoryCls, lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String tileName = (String) param.args[0]; + if (tileName.startsWith("custom_")) { + String nfcField = Helpers.isTPlus() ? "nfcTileProvider" : "mNfcTileProvider"; + Object provider = XposedHelpers.getObjectField(param.thisObject, nfcField); + Object tile = XposedHelpers.callMethod(provider, "get"); + XposedHelpers.setAdditionalInstanceField(tile, "customName", tileName); + param.setResult(tile); + } + } + }); + String NfcTileCls = Helpers.isTPlus() ? "com.android.systemui.qs.tiles.MiuiNfcTile" : "com.android.systemui.qs.tiles.NfcTile"; + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "isAvailable", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); + if (customName != null) { + String tileName = (String) customName; + if ("custom_5G".equals(tileName)) { + param.setResult(TelephonyManager.getDefault().isFiveGCapable()); + } + else { + param.setResult(false); + } + } + } + }); + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "getTileLabel", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); + if (customName != null) { + String tileName = (String) customName; + if ("custom_5G".equals(tileName)) { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + Resources modRes = Helpers.getModuleRes(mContext); + param.setResult(modRes.getString(R.string.qs_toggle_5g)); + } + } + } + }); + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "handleSetListening", boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); + if (customName != null) { + String tileName = (String) customName; + if ("custom_5G".equals(tileName)) { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + boolean mListening = (boolean) param.args[0]; + if (mListening) { + ContentObserver contentObserver = new ContentObserver(new Handler(mContext.getMainLooper())) { + @Override + public void onChange(boolean z) { + XposedHelpers.callMethod(param.thisObject, "refreshState"); + } + }; + mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor("fiveg_user_enable"), false, contentObserver); + mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor("dual_nr_enabled"), false, contentObserver); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "tileListener", contentObserver); + } + else { + ContentObserver contentObserver = (ContentObserver) XposedHelpers.getAdditionalInstanceField(param.thisObject, "tileListener"); + mContext.getContentResolver().unregisterContentObserver(contentObserver); + } + } + param.setResult(null); + } + } + }); + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "getLongClickIntent", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); + if (customName != null) { + String tileName = (String) customName; + if ("custom_5G".equals(tileName)) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + intent.setComponent(new ComponentName("com.android.phone", "com.android.phone.settings.PreferredNetworkTypeListPreference")); + param.setResult(intent); + } + else { + param.setResult(null); + } + } + } + }); + Helpers.findAndHookMethod(NfcTileCls, lpparam.classLoader, "handleClick", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); + if (customName != null) { + String tileName = (String) customName; + if ("custom_5G".equals(tileName)) { + TelephonyManager manager = TelephonyManager.getDefault(); + manager.setUserFiveGEnabled(!manager.isUserFiveGEnabled()); + } + param.setResult(null); + } + } + }); + + int fiveGIconResId = MainModule.resHooks.addResource("ic_qs_5g_on", R.drawable.ic_qs_5g_on); + int fiveGIconOffResId = MainModule.resHooks.addResource("ic_qs_5g_off", R.drawable.ic_qs_5g_off); + Helpers.hookAllMethods(NfcTileCls, lpparam.classLoader, "handleUpdateState", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object customName = XposedHelpers.getAdditionalInstanceField(param.thisObject, "customName"); + if (customName != null) { + String tileName = (String) customName; + if ("custom_5G".equals(tileName)) { + Object booleanState = param.args[0]; + TelephonyManager manager = TelephonyManager.getDefault(); + boolean isEnable = manager.isUserFiveGEnabled(); + XposedHelpers.setObjectField(booleanState, "value", isEnable); + XposedHelpers.setObjectField(booleanState, "state", isEnable ? 2 : 1); + String tileLabel = (String) XposedHelpers.callMethod(param.thisObject, "getTileLabel"); + XposedHelpers.setObjectField(booleanState, "label", tileLabel); + XposedHelpers.setObjectField(booleanState, "contentDescription", tileLabel); + XposedHelpers.setObjectField(booleanState, "expandedAccessibilityClassName", Switch.class.getName()); + Object mIcon = XposedHelpers.callStaticMethod(ResourceIconClass, "get", isEnable ? fiveGIconResId : fiveGIconOffResId); + XposedHelpers.setObjectField(booleanState, "icon", mIcon); + } + param.setResult(null); + } + } + }); + } + + public static void DualRowStatusbarHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + FrameLayout sbView = (FrameLayout) param.thisObject; + Context mContext = sbView.getContext(); + LinearLayout leftLayout = new LinearLayout(mContext); + LinearLayout rightLayout = new LinearLayout(mContext); + LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); + ViewGroup rightContainer = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mSystemIconArea"); + View switchUserView = null; + if (Helpers.isTPlus()) { + int userViewId = sbView.getResources().getIdentifier("user_switcher_container", "id", lpparam.packageName); + switchUserView = sbView.findViewById(userViewId); + ((ViewGroup) switchUserView.getParent()).removeView(switchUserView); + } + int firstRowLeftPadding = 0; + int firstRowRightPadding = 0; + if (MainModule.mPrefs.getBoolean("system_statusbar_dualrows_firstrow_horizmargin")) { + firstRowLeftPadding = MainModule.mPrefs.getInt("system_statusbar_dualrows_firstrow_horizmargin_left", 0); + firstRowRightPadding = MainModule.mPrefs.getInt("system_statusbar_dualrows_firstrow_horizmargin_right", 0); + } + LinearLayout statusBarcontents = (LinearLayout) rightContainer.getParent(); + statusBarcontents.removeView(leftContainer); + statusBarcontents.removeView(rightContainer); + statusBarcontents.addView(leftLayout, 0); + statusBarcontents.addView(rightLayout); + XposedHelpers.setObjectField(param.thisObject, "mSystemIconArea", rightLayout); + leftLayout.addView(leftContainer); + if (firstRowLeftPadding > 0) { + leftContainer.setPaddingRelative(firstRowLeftPadding, 0, 0, 0); + } + LinearLayout secondLeft = new LinearLayout(mContext); + leftLayout.addView(secondLeft); + LinearLayout firstRight = new LinearLayout(mContext); + rightLayout.addView(firstRight); + firstRight.setGravity(Gravity.END); + if (firstRowRightPadding > 0) { + firstRight.setPaddingRelative(0, 0, firstRowRightPadding, 0); + } + LinearLayout secondRight = new LinearLayout(mContext); + rightLayout.addView(secondRight); + secondRight.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); + View mBattery = (View) XposedHelpers.getObjectField(param.thisObject, "mBattery"); + ((ViewGroup) mBattery.getParent()).removeView(mBattery); + if (MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent_atright") && MainModule.mPrefs.getBoolean("system_statusbar_batterytempandcurrent")) { + TextView batteryView = createBatteryDetailView(mContext, new LinearLayout.LayoutParams(-2, -2)); + secondRight.addView(batteryView); + mBatteryDetailViews.add(batteryView); + Class ChargeUtilsClass = findClass("com.android.keyguard.charge.ChargeUtils", lpparam.classLoader); + Class DarkIconDispatcherClass = XposedHelpers.findClass("com.android.systemui.plugins.DarkIconDispatcher", lpparam.classLoader); + Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); + Object DarkIconDispatcher = XposedHelpers.callStaticMethod(Dependency, "get", DarkIconDispatcherClass); + XposedHelpers.callMethod(DarkIconDispatcher, "addDarkReceiver", batteryView); + updateTempAndCurrent(ChargeUtilsClass); + } + secondRight.addView(mBattery); + + if (Helpers.isTPlus()) { + if (switchUserView != null) { + secondRight.addView(switchUserView); + } + } + + XposedHelpers.setAdditionalInstanceField(param.thisObject, "leftLayout", leftLayout); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "rightLayout", rightLayout); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "firstRight", firstRight); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "secondLeft", secondLeft); + + View mFullscreenStatusBarNotificationIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mFullscreenStatusBarNotificationIconArea"); + ((ViewGroup) mFullscreenStatusBarNotificationIconArea.getParent()).removeView(mFullscreenStatusBarNotificationIconArea); + secondLeft.addView(mFullscreenStatusBarNotificationIconArea); + View mDripStatusBarNotificationIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarNotificationIconArea"); + ((ViewGroup) mDripStatusBarNotificationIconArea.getParent()).removeView(mDripStatusBarNotificationIconArea); + secondLeft.addView(mDripStatusBarNotificationIconArea); + View mStatusBarStatusIcons = (View) XposedHelpers.getObjectField(param.thisObject, "mStatusBarStatusIcons"); + ((ViewGroup) mStatusBarStatusIcons.getParent()).removeView(mStatusBarStatusIcons); + firstRight.addView(mStatusBarStatusIcons); + int resSystemIconsId = sbView.getResources().getIdentifier("system_icons", "id", lpparam.packageName); + firstRight.setId(resSystemIconsId); + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); + LinearLayout leftContainer = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mStatusBarLeftContainer"); + LinearLayout leftLayout = (LinearLayout) leftContainer.getParent(); + LinearLayout rightLayout = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "rightLayout"); + LinearLayout rightContainer = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "firstRight"); + LinearLayout secondLeft = (LinearLayout) XposedHelpers.getAdditionalInstanceField(param.thisObject, "secondLeft"); + LinearLayout secondRight = (LinearLayout) rightLayout.getChildAt(1); + LinearLayout statusBarcontents = (LinearLayout) leftLayout.getParent(); + boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); + + statusBarcontents.setOrientation(mCurrentStatusBarType == 0 ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); + if (mCurrentStatusBarType == 0) { + if (leftLayout.getChildAt(1) != rightContainer) { + leftLayout.removeViewAt(1); + rightLayout.removeViewAt(0); + leftLayout.addView(rightContainer); + rightLayout.addView(secondLeft, 0); + } + leftLayout.setOrientation(LinearLayout.HORIZONTAL); + rightLayout.setOrientation(LinearLayout.HORIZONTAL); + LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(-1, 0, 1); + leftLayout.setLayoutParams(leftLayoutLp); + LinearLayout.LayoutParams rightLayoutLp = new LinearLayout.LayoutParams(-1, 0, 1); + rightLayout.setLayoutParams(rightLayoutLp); + + LinearLayout.LayoutParams firstRowlp = new LinearLayout.LayoutParams(-2, -1, 0); + leftContainer.setLayoutParams(firstRowlp); + firstRowlp = new LinearLayout.LayoutParams(0, -1, 1); + rightContainer.setLayoutParams(firstRowlp); + + LinearLayout.LayoutParams secondRowLp = new LinearLayout.LayoutParams(0, -1, 1); + secondLeft.setLayoutParams(secondRowLp); + secondRight.setLayoutParams(secondRowLp); + } + else { + if (leftLayout.getChildAt(1) != secondLeft) { + leftLayout.removeViewAt(1); + rightLayout.removeViewAt(0); + leftLayout.addView(secondLeft); + rightLayout.addView(rightContainer, 0); + } + Object mMiuiEndIconManager = XposedHelpers.getObjectField(param.thisObject, "mMiuiEndIconManager"); + XposedHelpers.callMethod(mMiuiEndIconManager, "setDripEnd", false); + Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); + XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); + View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); + mDripStatusBarLeftStatusIconArea.setVisibility(moveSignalLeft ? View.VISIBLE : View.GONE); + leftLayout.setOrientation(LinearLayout.VERTICAL); + rightLayout.setOrientation(LinearLayout.VERTICAL); + LinearLayout.LayoutParams leftLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); + leftLayout.setLayoutParams(leftLayoutLp); + LinearLayout.LayoutParams rightLayoutLp = new LinearLayout.LayoutParams(0, -1, 1); + rightLayout.setLayoutParams(rightLayoutLp); + + LinearLayout.LayoutParams leftLp = new LinearLayout.LayoutParams(-1, 0, 1); + leftContainer.setLayoutParams(leftLp); + secondLeft.setLayoutParams(leftLp); + + LinearLayout.LayoutParams rightLp = new LinearLayout.LayoutParams(-1, 0, 1); + rightContainer.setLayoutParams(rightLp); + secondRight.setLayoutParams(rightLp); + } + secondLeft.setGravity(Gravity.CENTER_VERTICAL | Gravity.START); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showSystemIconArea", boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); + View rightLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "rightLayout"); + View leftLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "leftLayout"); + leftLayout.setVisibility(LinearLayout.VISIBLE); + rightLayout.setVisibility(LinearLayout.VISIBLE); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "hideSystemIconArea", boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar"); + View rightLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "rightLayout"); + View leftLayout = (View) XposedHelpers.getAdditionalInstanceField(mStatusBar, "leftLayout"); + leftLayout.setVisibility(LinearLayout.GONE); + rightLayout.setVisibility(LinearLayout.GONE); + } + }); + } + + public static void DualRowSignalHook(LoadPackageParam lpparam) { + boolean mobileTypeSingle = MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single"); + if (!mobileTypeSingle) { + MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_type_half_to_top_distance", 3); + MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_left_inout_over_strength", 0); + MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "status_bar_mobile_type_middle_to_strength_start", -0.4f); + } + + HashMap dualSignalResMap = new HashMap(); + String[] colorModeList = {"", "dark", "tint"}; +// String[] iconStyles = {"", "thick", "theme"}; + String selectedIconStyle = MainModule.mPrefs.getString("system_statusbar_dualsimin2rows_style", ""); + + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isHooked) { + isHooked = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + Resources modRes = Helpers.getModuleRes(mContext); + for (int slot = 1; slot <= 2; slot++) { + for (int lvl = 0; lvl <= 5; lvl++) { + for (String colorMode : colorModeList) { + if (!selectedIconStyle.equals("theme") || !colorMode.equals("tint") ) { + String dualIconResName = "statusbar_signal_" + slot + "_" + lvl + (!colorMode.equals("") ? ("_" + colorMode) : "") + (!selectedIconStyle.equals("") ? ("_" + selectedIconStyle) : ""); + int iconResId = modRes.getIdentifier(dualIconResName, "drawable", Helpers.modulePkg); + dualSignalResMap.put(dualIconResName, MainModule.resHooks.addResource(dualIconResName, iconResId)); + } + } + } + } + } + } + }); + + SparseIntArray signalResToLevelMap = new SparseIntArray(); + boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); + String ControllerImplName = moveSignalLeft ? "MiuiDripLeftStatusBarIconControllerImpl" : "StatusBarIconControllerImpl"; + Helpers.hookAllMethods("com.android.systemui.statusbar.phone." + ControllerImplName, lpparam.classLoader, "setMobileIcons", new MethodHook() { + private boolean isHooked = false; + @Override + protected void before(MethodHookParam param) throws Throwable { + if (!isHooked) { + isHooked = true; + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + Resources res = mContext.getResources(); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_0", "drawable", lpparam.packageName), 0); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_1", "drawable", lpparam.packageName), 1); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_2", "drawable", lpparam.packageName), 2); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_3", "drawable", lpparam.packageName), 3); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_4", "drawable", lpparam.packageName), 4); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_5", "drawable", lpparam.packageName), 5); + signalResToLevelMap.put(res.getIdentifier("stat_sys_signal_null", "drawable", lpparam.packageName), 6); + } + List iconStates = (List) param.args[1]; + if (iconStates.size() == 2) { + Object mainIconState = iconStates.get(0); + Object subIconState = iconStates.get(1); + boolean mainDataConnected = (boolean) XposedHelpers.getObjectField(mainIconState, "dataConnected"); + boolean subDataConnected = (boolean) XposedHelpers.getObjectField(subIconState, "dataConnected"); + XposedHelpers.setObjectField(mainIconState, "dataConnected", mainDataConnected || subDataConnected); + XposedHelpers.setObjectField(subIconState, "visible", false); + int mainSignalResId = (int) XposedHelpers.getObjectField(mainIconState, "strengthId"); + int subSignalResId = (int) XposedHelpers.getObjectField(subIconState, "strengthId"); + int mainLevel = signalResToLevelMap.get(mainSignalResId); + int subLevel = signalResToLevelMap.get(subSignalResId); + int level; + if (subDataConnected) { + level = subLevel * 10 + mainLevel; + String showName = (String) XposedHelpers.getObjectField(subIconState, "showName"); + XposedHelpers.setObjectField(mainIconState, "showName", showName); + } + else { + level = mainLevel * 10 + subLevel; + } + XposedHelpers.setObjectField(mainIconState, "strengthId", level); + param.args[1] = iconStates; + } + } + }); + + MethodHook beforeUpdate = new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Object mobileIconState = param.args[0]; + boolean visible = (boolean) XposedHelpers.getObjectField(mobileIconState, "visible"); + boolean airplane = (boolean) XposedHelpers.getObjectField(mobileIconState, "airplane"); + int level = (int) XposedHelpers.getObjectField(mobileIconState, "strengthId"); + if (!visible || airplane || level == 0 || level > 100) { + XposedHelpers.setAdditionalInstanceField(param.thisObject, "subStrengthId", -1); + } + else { + XposedHelpers.setAdditionalInstanceField(param.thisObject, "subStrengthId", level % 10); + XposedHelpers.setObjectField(mobileIconState, "fiveGDrawableId", 0); + } + } + }; + MethodHook afterUpdate = new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + int subStrengthId = (int) XposedHelpers.getAdditionalInstanceField(param.thisObject, "subStrengthId"); + if (subStrengthId < 0) return; + Object mSmallHd = XposedHelpers.getObjectField(param.thisObject, "mSmallHd"); + XposedHelpers.callMethod(mSmallHd, "setVisibility", 8); + Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); + XposedHelpers.callMethod(mSmallRoaming, "setVisibility", 0); + } + }; + Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", beforeUpdate); + Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", afterUpdate); + + MethodHook resetImageDrawable = new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + int subStrengthId = (int) XposedHelpers.getAdditionalInstanceField(param.thisObject, "subStrengthId"); + if (subStrengthId < 0) return; + if (subStrengthId == 6) subStrengthId = 0; + Object mobileIconState = XposedHelpers.getObjectField(param.thisObject, "mState"); + int level1 = (int) XposedHelpers.getObjectField(mobileIconState, "strengthId"); + level1 = level1 / 10; + if (level1 == 6) level1 = 0; + boolean mLight = (boolean) XposedHelpers.getObjectField(param.thisObject, "mLight"); + boolean mUseTint = (boolean) XposedHelpers.getObjectField(param.thisObject, "mUseTint"); + Object mSmallRoaming = XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); + Object mMobile = XposedHelpers.getObjectField(param.thisObject, "mMobile"); + String colorMode = ""; + if (mUseTint && !selectedIconStyle.equals("theme")) { + colorMode = "_tint"; + } + else if (!mLight) { + colorMode = "_dark"; + } + String iconStyle = ""; + if (!selectedIconStyle.equals("")) { + iconStyle = "_" + selectedIconStyle; + } + String sim1IconId = "statusbar_signal_1_" + level1 + colorMode + iconStyle; + String sim2IconId = "statusbar_signal_2_" + subStrengthId + colorMode + iconStyle; + int sim1ResId = dualSignalResMap.get(sim1IconId); + int sim2ResId = dualSignalResMap.get(sim2IconId); + XposedHelpers.callMethod(mMobile, "setImageResource", sim1ResId); + XposedHelpers.callMethod(mSmallRoaming, "setImageResource", sim2ResId); + } + }; + Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyDarknessInternal", resetImageDrawable); + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_rightmargin", 0); + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_leftmargin", 0); + int iconScale = MainModule.mPrefs.getInt("system_statusbar_dualsimin2rows_scale", 10); + if (rightMargin > 0 || leftMargin > 0 || iconScale != 10) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "init", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + LinearLayout mobileView = (LinearLayout) param.thisObject; + Context mContext = mobileView.getContext(); + Resources res = mContext.getResources(); + int rightSpacing = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin * 0.5f, + res.getDisplayMetrics() + ); + int leftSpacing = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin * 0.5f, + res.getDisplayMetrics() + ); + mobileView.setPadding(leftSpacing, 0, rightSpacing, 0); + + if (iconScale != 10) { + View mMobile = (View) XposedHelpers.getObjectField(param.thisObject, "mMobile"); + View mSmallRoaming = (View) XposedHelpers.getObjectField(param.thisObject, "mSmallRoaming"); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mMobile.getLayoutParams(); + int mIconHeight = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 20 * iconScale / 10f, + res.getDisplayMetrics() + ); + Helpers.log("fad " + (layoutParams != null)); + if (layoutParams == null) { + layoutParams = new FrameLayout.LayoutParams(-2, mIconHeight); + } else { + layoutParams.height = mIconHeight; + } + layoutParams.gravity = Gravity.CENTER; + mMobile.setLayoutParams(layoutParams); + mSmallRoaming.setLayoutParams(layoutParams); + } + } + }); + } + } + + public static void StatusBarIconsPositionAdjustHook(LoadPackageParam lpparam, boolean moveRight) { + boolean swapWifiSignal = MainModule.mPrefs.getBoolean("system_statusbaricons_swap_wifi_mobile"); + boolean moveSignalLeft = MainModule.mPrefs.getBoolean("system_statusbaricons_wifi_mobile_atleft"); + String[] signalIcons; + if (!swapWifiSignal) { + signalIcons = new String[]{"no_sim", "mobile", "demo_mobile", "airplane", "hotspot", "slave_wifi", "wifi", "demo_wifi"}; + } + else { + signalIcons = new String[]{"hotspot", "slave_wifi", "wifi", "demo_wifi", "no_sim", "mobile", "demo_mobile", "airplane"}; + } + ArrayList signalRelatedIcons = new ArrayList(Arrays.asList(signalIcons)); + if (moveRight) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String slot = (String) param.args[0]; + if (("alarm_clock".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) + || ("volume".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) + || ("zen".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) + || ("nfc".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) + || ("headset".equals(slot) && MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) + ) { + param.args[1] = false; + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isHooked = false; + + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isHooked) { + isHooked = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + Class MiuiEndIconManager = findClass("com.android.systemui.statusbar.phone.MiuiEndIconManager", lpparam.classLoader); + Object blockList = Helpers.getStaticObjectFieldSilently(MiuiEndIconManager, "RIGHT_BLOCK_LIST"); + ArrayList rightBlockList; + Resources res = mContext.getResources(); + if (blockList != null) { + rightBlockList = (ArrayList) blockList; + } + else { + int blockResId = res.getIdentifier("config_drip_right_block_statusBarIcons", "array", lpparam.packageName); + rightBlockList = new ArrayList(Arrays.asList(res.getStringArray(blockResId))); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright")) { + rightBlockList.remove("network_speed"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_alarm_atright")) { + rightBlockList.remove("alarm_clock"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_sound_atright")) { + rightBlockList.remove("volume"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_dnd_atright")) { + rightBlockList.remove("zen"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_btbattery_atright")) { + rightBlockList.remove("bluetooth_handsfree_battery"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_nfc_atright")) { + rightBlockList.remove("nfc"); + } + if (MainModule.mPrefs.getBoolean("system_statusbar_headset_atright")) { + rightBlockList.remove("headset"); + } + if (blockList != null) { + XposedHelpers.setStaticObjectField(MiuiEndIconManager, "RIGHT_BLOCK_LIST", rightBlockList); + } + else { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "array", "config_drip_right_block_statusBarIcons", rightBlockList.toArray(new String[0])); + } + } + } + }); + } + ArrayList dripLeftIcons = new ArrayList(); + if (swapWifiSignal || moveSignalLeft) { + Helpers.findAndHookConstructor("com.android.systemui.statusbar.phone.StatusBarIconList", lpparam.classLoader, String[].class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean isRightController = "StatusBarIconControllerImpl".equals(param.thisObject.getClass().getSimpleName()); + ArrayList allStatusIcons = new ArrayList(Arrays.asList((String[]) param.args[0])); + if (isRightController) { + int startIndex = allStatusIcons.indexOf("no_sim"); + int endIndex = allStatusIcons.indexOf("demo_wifi") + 1; + List removedIcons = allStatusIcons.subList(startIndex, endIndex); + removedIcons.clear(); + if (!moveSignalLeft) { + startIndex = allStatusIcons.indexOf("ethernet"); + allStatusIcons.addAll(startIndex + 1, signalRelatedIcons); + } + param.args[0] = allStatusIcons.toArray(new String[0]); + } + else if (moveSignalLeft) { + dripLeftIcons.addAll(allStatusIcons); + allStatusIcons.addAll(0, signalRelatedIcons); + param.args[0] = allStatusIcons.toArray(new String[0]); + } + } + }); + } + + if (moveSignalLeft) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiStatusBarSignalPolicy", lpparam.classLoader, "initMiuiSlot", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); + XposedHelpers.setObjectField(param.thisObject, "mIconController", dripLeftController); + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "initMiuiViewsOnViewCreated", View.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); + Object mDripIconManager = XposedHelpers.getObjectField(param.thisObject, "mDripLeftDarkIconManager"); + ArrayList blockList = new ArrayList(); + int mCurrentStatusBarType = (int) XposedHelpers.getAdditionalInstanceField(dripLeftController, "mCurrentStatusBarType"); + if (mCurrentStatusBarType != 1) { + blockList.addAll(dripLeftIcons); + } + XposedHelpers.callMethod(mDripIconManager, "setBlockList", blockList); + XposedHelpers.callMethod(dripLeftController, "refreshIconGroup", mDripIconManager); + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "setStatusBarType", int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int mCurrentStatusBarType = XposedHelpers.getIntField(param.thisObject, "mCurrentStatusBarType"); + Object dripLeftController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader)); + XposedHelpers.setAdditionalInstanceField(dripLeftController, "mCurrentStatusBarType", mCurrentStatusBarType); + } + }); + } + + boolean netspeedRight = MainModule.mPrefs.getBoolean("system_statusbar_netspeed_atright"); + if (moveSignalLeft || netspeedRight) { + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); + if (mCurrentStatusBarType == 1) { + if (netspeedRight) { + Object mDripNetworkSpeedView = XposedHelpers.getObjectField(param.thisObject, "mDripNetworkSpeedView"); + XposedHelpers.callMethod(mDripNetworkSpeedView, "setBlocked", true); + } + } + else { + boolean dualRows = MainModule.mPrefs.getBoolean("system_statusbar_dualrows"); + if (moveSignalLeft && !dualRows) { + View mDripStatusBarLeftStatusIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mDripStatusBarLeftStatusIconArea"); + mDripStatusBarLeftStatusIconArea.setVisibility(View.VISIBLE); + } + } + } + }); + } + + if (netspeedRight) { + Helpers.hookAllMethods("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "setDripNetworkSpeedView", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + param.args[0] = null; + } + }); + } + } + + public static void StatusBarClockAtRightHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + FrameLayout sbView = (FrameLayout) param.thisObject; + Context mContext = sbView.getContext(); + Resources res = mContext.getResources(); + TextView mClockView = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMiuiClock"); + ((ViewGroup)mClockView.getParent()).removeView(mClockView); + int contentId = res.getIdentifier("status_bar_contents", "id", lpparam.packageName); + LinearLayout mContentsContainer = sbView.findViewById(contentId); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT); + mContentsContainer.addView(mClockView, lp); + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiPhoneStatusBarView", lpparam.classLoader, "updateCutoutLocation", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + int mCurrentStatusBarType = (int) XposedHelpers.getObjectField(param.thisObject, "mCurrentStatusBarType"); + if (mCurrentStatusBarType == 0) { + View mSystemIconArea = (View) XposedHelpers.getObjectField(param.thisObject, "mSystemIconArea"); + LinearLayout.LayoutParams mSystemIconAreaLp = (LinearLayout.LayoutParams) mSystemIconArea.getLayoutParams(); + mSystemIconAreaLp.width = 0; + mSystemIconAreaLp.weight = 1.0f; + } + } + }); + } + + public static void NoNetworkSpeedSeparatorHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.views.NetworkSpeedSplitter", lpparam.classLoader, "updateVisibility", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "mNetworkSpeedVisibility", View.GONE); + } + }); + } + + public static void HideNetworkSpeedUnitHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "formatSpeed", Context.class, long.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + String speedText = (String) param.getResult(); + param.setResult(speedText.replaceFirst("B?[/']s", "")); + } + }); + } + + public static void HideLowNetworkSpeedHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "formatSpeed", Context.class, long.class, new MethodHook(100) { + @Override + protected void before(MethodHookParam param) throws Throwable { + int lowLevel = MainModule.mPrefs.getInt("system_detailednetspeed_lowlevel", 1) * 1024; + long speedVal = (long) param.args[1]; + if (speedVal < lowLevel) { + param.setResult(""); + } + } + }); + } + + public static void NetSpeedStyleHook(LoadPackageParam lpparam) { + Helpers.hookAllConstructors("com.android.systemui.statusbar.views.NetworkSpeedView", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + TextView meter = (TextView)param.thisObject; + if (meter == null) return; + if (meter.getTag() == null || !"slot_text_icon".equals(meter.getTag())) { + int fontSize = MainModule.mPrefs.getInt("system_netspeed_fontsize", 13); + if (MainModule.mPrefs.getBoolean("system_detailednetspeed")) { + if (fontSize > 20) fontSize = 16; + } + else { + if (fontSize < 20) fontSize = 27; + } + if (fontSize != 13) { + meter.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); + } + if (MainModule.mPrefs.getBoolean("system_netspeed_bold")) { + meter.setTypeface(Typeface.DEFAULT_BOLD); + } + + int horizMargin = 0; + if (MainModule.mPrefs.getBoolean("system_fixmeter")) { + horizMargin = Math.round(meter.getResources().getDisplayMetrics().density * 4); + } + int topMargin = 0; + int verticalOffset = MainModule.mPrefs.getInt("system_netspeed_verticaloffset", 8); + if (verticalOffset != 8) { + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + meter.getResources().getDisplayMetrics() + ); + topMargin = (int) (marginTop); + } + meter.setPaddingRelative(horizMargin, topMargin, horizMargin, 0); + + if (MainModule.mPrefs.getBoolean("system_detailednetspeed")) { + float spacing = 0.9f; + meter.setSingleLine(false); + meter.setLines(2); + meter.setMaxLines(2); + if (fontSize > 8.5f) { + spacing = 0.85f; + } + meter.setLineSpacing(0, spacing); + } + } + } + }); + } + public static void MobileTypeSingleHook(LoadPackageParam lpparam) { + MethodHook showSingleMobileType = new MethodHook(MethodHook.PRIORITY_HIGHEST) { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Object mobileIconState = param.args[0]; + XposedHelpers.setObjectField(mobileIconState, "showMobileDataTypeSingle", true); + XposedHelpers.setObjectField(mobileIconState, "fiveGDrawableId", 0); + } + }; + Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", showSingleMobileType); + + MethodHook afterUpdate = new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Object mMobileLeftContainer = XposedHelpers.getObjectField(param.thisObject, "mMobileLeftContainer"); + XposedHelpers.callMethod(mMobileLeftContainer, "setVisibility", 8); + } + }; + Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", afterUpdate); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "init", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + Resources res = mContext.getResources(); + LinearLayout mMobileGroup = (LinearLayout) XposedHelpers.getObjectField(param.thisObject, "mMobileGroup"); + TextView mMobileTypeSingle = (TextView) XposedHelpers.getObjectField(param.thisObject, "mMobileTypeSingle"); + if (!MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single_atleft")) { + mMobileGroup.removeView(mMobileTypeSingle); + mMobileGroup.addView(mMobileTypeSingle); + } + ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) mMobileTypeSingle.getLayoutParams(); + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_leftmargin", 4); + float marginLeft = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin * 0.5f, + res.getDisplayMetrics() + ); + mlp.leftMargin = (int) marginLeft; + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_rightmargin", 0); + if (rightMargin > 0) { + float marginRight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin * 0.5f, + res.getDisplayMetrics() + ); + mlp.rightMargin = (int) marginRight; + } + int verticalOffset = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_verticaloffset", 8); + if (verticalOffset != 8) { + float marginTop = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + (verticalOffset - 8) * 0.5f, + res.getDisplayMetrics() + ); + mlp.topMargin = (int) marginTop; + } + mMobileTypeSingle.setLayoutParams(mlp); + int fontSize = MainModule.mPrefs.getInt("system_statusbar_mobiletype_single_fontsize", 27); + mMobileTypeSingle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize * 0.5f); + if (MainModule.mPrefs.getBoolean("system_statusbar_mobiletype_single_bold")) { + mMobileTypeSingle.setTypeface(Typeface.DEFAULT_BOLD); + } + } + }); + } + + private static ClassLoader pluginLoader = null; + + public static void VolumeDialogAutohideDelayHook(ClassLoader classLoader) { + Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "computeTimeoutH", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean mHovering = XposedHelpers.getBooleanField(param.thisObject, "mHovering"); + if (mHovering) { + param.setResult(16000); + return; + } + boolean mSafetyWarning; + try { + mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mIsSafetyShowing"); + } + catch (Throwable e) { + mSafetyWarning = (boolean) XposedHelpers.getObjectField(param.thisObject, "mSafetyWarning"); + } + if (mSafetyWarning) { + int opt = MainModule.mPrefs.getInt("system_volumedialogdelay_expanded", 0); + param.setResult(opt > 0 ? opt : 5000); + return; + } + boolean mExpanded = XposedHelpers.getBooleanField(param.thisObject, "mExpanded"); + int opt = MainModule.mPrefs.getInt(mExpanded ? "system_volumedialogdelay_expanded" : "system_volumedialogdelay_collapsed", 0); + if (opt > 0) param.setResult(opt); + } + }); + } + + private static float blurCollapsed = 0.0f; + private static float blurExpanded = 0.0f; + + public static void BlurVolumeDialogBackgroundHook(ClassLoader classLoader) { + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_collapsed", 0f); + MainModule.resHooks.setObjectReplacement("miui.systemui.plugin", "fraction", "miui_volume_dim_behind_expanded", 0f); + + Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "updateDialogWindowH", boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + boolean mExpanded = XposedHelpers.getBooleanField(param.thisObject, "mExpanded"); + float blurRatio = blurCollapsed; + boolean isVisible = (boolean) param.args[0]; + if (mExpanded && !isVisible) { + blurRatio = blurExpanded; + } + if (!mExpanded && blurCollapsed > 0.001f) { + Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); + mWindow.clearFlags(8); + } + if (mExpanded) { + XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurRatio, 0); + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "showH", int.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + if (blurCollapsed > 0.001f) { + Window mWindow = (Window) XposedHelpers.getObjectField(param.thisObject, "mWindow"); + mWindow.clearFlags(8); + XposedHelpers.callMethod(param.thisObject, "startBlurAnim", 0f, blurCollapsed, 0); + } + } + }); + Helpers.hookAllMethods("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", classLoader, "initDialog", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Handler mHandler = new Handler(mContext.getMainLooper()); + + blurCollapsed = MainModule.mPrefs.getInt("system_volumeblur_collapsed", 0) / 100f; + blurExpanded = MainModule.mPrefs.getInt("system_volumeblur_expanded", 0) / 100f; + new Helpers.SharedPrefObserver(mContext, mHandler) { + @Override + public void onChange(Uri uri) { + try { + String key = uri.getPathSegments().get(2); + if (key.equals("pref_key_system_volumeblur_collapsed")) blurCollapsed = Helpers.getSharedIntPref(mContext, key, 0) / 100f; + if (key.equals("pref_key_system_volumeblur_expanded")) blurExpanded = Helpers.getSharedIntPref(mContext, key, 0) / 100f; + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }; + } + }); + } + + public static void BlurMTKVolumeBarHook(ClassLoader classLoader) { + Helpers.findAndHookMethod("com.android.systemui.miui.volume.Util", classLoader, "isSupportBlurS", XC_MethodReplacement.returnConstant(true)); + } + + public static void MIUIVolumeDialogHook(LoadPackageParam lpparam) { + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { + isHooked = true; + if (pluginLoader == null) { + pluginLoader = (ClassLoader) param.getResult(); + } + Class MiuiVolumeDialogImpl = XposedHelpers.findClassIfExists("com.android.systemui.miui.volume.MiuiVolumeDialogImpl", pluginLoader); + if (MainModule.mPrefs.getBoolean("system_separatevolume") && MainModule.mPrefs.getBoolean("system_separatevolume_slider")) { + Helpers.hookAllMethods(MiuiVolumeDialogImpl, "addColumn", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (param.args.length != 4) return; + int streamType = (int) param.args[0]; + if (streamType == 4) { + XposedHelpers.callMethod(param.thisObject, "addColumn", 5, notifVolumeOnResId, notifVolumeOffResId, true, false); + } + } + }); + } + if (MainModule.mPrefs.getBoolean("system_nosilentvibrate")) { + Helpers.hookAllMethods(MiuiVolumeDialogImpl, "vibrateH", XC_MethodReplacement.DO_NOTHING); + } + if (MainModule.mPrefs.getInt("system_volumedialogdelay_collapsed", 0) > 0 || MainModule.mPrefs.getInt("system_volumedialogdelay_expanded", 0) > 0) { + VolumeDialogAutohideDelayHook(pluginLoader); + } + if (MainModule.mPrefs.getInt("system_volumeblur_collapsed", 0) > 0 || MainModule.mPrefs.getInt("system_volumeblur_expanded", 0) > 0) { + BlurVolumeDialogBackgroundHook(pluginLoader); + } + if (MainModule.mPrefs.getBoolean("system_volumebar_blur_mtk")) { + BlurMTKVolumeBarHook(pluginLoader); + } + if (MainModule.mPrefs.getBoolean("system_qs_force_systemfonts")) { + Helpers.findAndHookMethod("miui.systemui.util.SystemUIResourcesHelperImpl", pluginLoader, "getBoolean", String.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String key = (String) param.args[0]; + if (key.equals("header_big_time_use_system_font")) { + param.setResult(Boolean.TRUE); + } + } + }); + } + if (MainModule.mPrefs.getBoolean("system_qsnolabels")) { + HideCCLabelsHook(pluginLoader); + } + } + } + }); + } + + private static float scaledTileWidthDim = -1f; + public static void SystemCCGridHook(LoadPackageParam lpparam) { + int cols = MainModule.mPrefs.getInt("system_ccgridcolumns", 4); + int rows = MainModule.mPrefs.getInt("system_ccgridrows", 4); + if (cols > 4) { + MainModule.resHooks.setObjectReplacement(lpparam.packageName, "dimen", "qs_control_tiles_columns", cols); + } + + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isHooked) { + isHooked = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + Resources res = mContext.getResources(); + float density = res.getDisplayMetrics().density; + int tileWidthResId = res.getIdentifier("qs_control_center_tile_width", "dimen", "com.android.systemui"); + float tileWidthDim = res.getDimension(tileWidthResId); + if (cols > 4) { + tileWidthDim = tileWidthDim / density; + scaledTileWidthDim = tileWidthDim * 4 / cols; + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "qs_control_center_tile_width", scaledTileWidthDim); + MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_control_center_tile_width", scaledTileWidthDim); + MainModule.resHooks.setDensityReplacement(lpparam.packageName, "dimen", "qs_control_tile_icon_bg_size", scaledTileWidthDim); + MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_control_tile_icon_bg_size", scaledTileWidthDim); + MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85f); + } + } + } + }); + + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { + isHooked = true; + if (pluginLoader == null) { + pluginLoader = (ClassLoader) param.getResult(); + } + if (cols > 4) { + Helpers.findAndHookConstructor("miui.systemui.controlcenter.qs.QSPager", pluginLoader, Context.class, AttributeSet.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.setObjectField(param.thisObject, "columns", cols); + } + }); + if (!MainModule.mPrefs.getBoolean("system_qsnolabels")) { + Helpers.hookAllMethods("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader, "handleStateChanged", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object label = XposedHelpers.getObjectField(param.thisObject, "label"); + if (label != null) { + TextView lb = (TextView) label; + lb.setMaxLines(1); + lb.setSingleLine(true); + lb.setEllipsize(TextUtils.TruncateAt.MARQUEE); + lb.setMarqueeRepeatLimit(0); + } + } + }); + } + } + if (rows != 4) { + Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.QSPager", pluginLoader, "distributeTiles", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + boolean collapse = (boolean) XposedHelpers.getObjectField(param.thisObject, "collapse"); + if (collapse) { + ArrayList pages = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "pages"); + for (Object tileLayoutImpl : pages) { + XposedHelpers.callMethod(tileLayoutImpl, "removeTiles"); + } + ArrayList pageTiles = new ArrayList(); + int currentRow = 2; + ArrayList records = (ArrayList) XposedHelpers.getObjectField(param.thisObject, "records"); + Iterator it2 = records.iterator(); + int i3 = 0; + int pageNow = 0; + Object bigHeader = XposedHelpers.getObjectField(param.thisObject, "header"); + while (it2.hasNext()) { + Object tileRecord = it2.next(); + pageTiles.add(tileRecord); + i3++; + if (i3 >= cols) { + currentRow++; + i3 = 0; + } + if (currentRow >= rows || !it2.hasNext()) { + XposedHelpers.callMethod(pages.get(pageNow), "setTiles", pageTiles, pageNow == 0 ? bigHeader : null); + pageTiles.clear(); + int totalRows = (int) XposedHelpers.getObjectField(param.thisObject, "rows"); + if (currentRow > totalRows) { + XposedHelpers.setObjectField(param.thisObject, "rows", currentRow); + } + if (it2.hasNext()) { + pageNow++; + currentRow = 0; + } + } + } + Iterator it3 = pages.iterator(); + while (it3.hasNext()) { + Object next2 = it3.next(); + boolean isEmpty = (boolean) XposedHelpers.callMethod(next2, "isEmpty"); + if (isEmpty) { + it3.remove(); + } + } + Object pageIndicator = XposedHelpers.getObjectField(param.thisObject, "pageIndicator"); + if (pageIndicator != null) { + XposedHelpers.callMethod(pageIndicator, "setNumPages", pages.size()); + } + Object adapter = XposedHelpers.getObjectField(param.thisObject, "adapter"); + XposedHelpers.callMethod(param.thisObject, "setAdapter", adapter); +// XposedHelpers.callMethod(param.thisObject, "notifyDataSetChanged"); + } + } + }); + } + } + } + }); + } + + public static void QQSGridRes() { + int cols = MainModule.mPrefs.getInt("system_qqsgridcolumns", 2); + int colsResId = R.integer.quick_quick_settings_num_rows_5; + switch (cols) { + case 3: colsResId = R.integer.quick_quick_settings_num_rows_3; break; + case 4: colsResId = R.integer.quick_quick_settings_num_rows_4; break; + case 5: colsResId = R.integer.quick_quick_settings_num_rows_5; break; + case 6: colsResId = R.integer.quick_quick_settings_num_rows_6; break; + case 7: colsResId = R.integer.quick_quick_settings_num_rows_7; break; + } + MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_qqs_count", colsResId); + } + + public static void QSGridRes() { + int cols = MainModule.mPrefs.getInt("system_qsgridcolumns", 2); + int rows = MainModule.mPrefs.getInt("system_qsgridrows", 1); + int colsRes = R.integer.quick_settings_num_columns_3; + int rowsRes = R.integer.quick_settings_num_rows_4; + + switch (cols) { + case 3: colsRes = R.integer.quick_settings_num_columns_3; break; + case 4: colsRes = R.integer.quick_settings_num_columns_4; break; + case 5: colsRes = R.integer.quick_settings_num_columns_5; break; + case 6: colsRes = R.integer.quick_settings_num_columns_6; break; + case 7: colsRes = R.integer.quick_settings_num_columns_7; break; + } + + switch (rows) { + case 2: rowsRes = R.integer.quick_settings_num_rows_2; break; + case 3: rowsRes = R.integer.quick_settings_num_rows_3; break; + case 4: rowsRes = R.integer.quick_settings_num_rows_4; break; + case 5: rowsRes = R.integer.quick_settings_num_rows_5; break; + } + + if (cols > 2) MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_num_columns", colsRes); + if (rows > 1) MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_num_rows", rowsRes); + } + + private static void updateLabelsVisibility(Object mRecord, int mRows, int orientation) { + if (mRecord == null) return; + Object tileView = XposedHelpers.getObjectField(mRecord, "tileView"); + if (tileView != null) { + ViewGroup mLabelContainer = null; + try { + mLabelContainer = (ViewGroup)XposedHelpers.getObjectField(tileView, "mLabelContainer"); + } + catch (Throwable ignore) {} + + if (mLabelContainer != null) { + mLabelContainer.setVisibility( + MainModule.mPrefs.getBoolean("system_qsnolabels") || + orientation == Configuration.ORIENTATION_PORTRAIT && mRows >= 5 || + orientation == Configuration.ORIENTATION_LANDSCAPE && mRows >= 3 ? View.GONE : View.VISIBLE + ); + } + } + } + + private static void HideCCLabelsHook(ClassLoader pluginLoader) { + MainModule.resHooks.setDensityReplacement("miui.systemui.plugin", "dimen", "qs_cell_height", 85f); + Class QSController = XposedHelpers.findClassIfExists("miui.systemui.controlcenter.qs.tileview.StandardTileView", pluginLoader); + Helpers.hookAllMethods(QSController, "init", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + if (param.args.length != 1) return; + View mLabelContainer = (View)XposedHelpers.getObjectField(param.thisObject, "labelContainer"); + if (mLabelContainer != null) { + mLabelContainer.setVisibility(View.GONE); + } + } + }); + } + + public static void QSGridLabelsHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods("com.android.systemui.qs.MiuiTileLayout", lpparam.classLoader, "addTile", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + updateLabelsVisibility(param.args[0], XposedHelpers.getIntField(param.thisObject, "mRows"), ((ViewGroup)param.thisObject).getResources().getConfiguration().orientation); + } + }); + + Helpers.hookAllMethods("com.android.systemui.qs.MiuiPagedTileLayout", lpparam.classLoader, "addTile", new MethodHook() { + @Override + @SuppressWarnings("unchecked") + protected void before(MethodHookParam param) throws Throwable { + ArrayList mPages = (ArrayList)XposedHelpers.getObjectField(param.thisObject, "mPages"); + if (mPages == null) return; + int mRows = 0; + if (mPages.size() > 0) mRows = XposedHelpers.getIntField(mPages.get(0), "mRows"); + updateLabelsVisibility(param.args[0], mRows, ((ViewGroup)param.thisObject).getResources().getConfiguration().orientation); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.qs.MiuiTileLayout", lpparam.classLoader, "updateResources", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + if (MainModule.mPrefs.getInt("system_qsgridrows", 1) != 2) return; + if (!(boolean)param.getResult()) return; + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) return; + XposedHelpers.setIntField(param.thisObject, "mCellHeight", Math.round(XposedHelpers.getIntField(param.thisObject, "mCellHeight") / 1.5f)); + ((ViewGroup)param.thisObject).requestLayout(); + } + }); + + if (MainModule.mPrefs.getInt("system_qsgridrows", 1) == 4) + Helpers.findAndHookMethod("com.android.systemui.qs.tileimpl.MiuiQSTileView", lpparam.classLoader, "createLabel", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + ViewGroup mLabelContainer = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mLabelContainer"); + if (mLabelContainer != null) mLabelContainer.setPadding( + mLabelContainer.getPaddingLeft(), + Math.round(mLabelContainer.getResources().getDisplayMetrics().density * 2), + mLabelContainer.getPaddingRight(), + mLabelContainer.getPaddingBottom() + ); + } + }); + } + + public static void VolumeTimerValuesRes(LoadPackageParam lpparam) { + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "array", "miui_volume_timer_segments", R.array.miui_volume_timer_segments); + + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { + isHooked = true; + if (pluginLoader == null) { + pluginLoader = (ClassLoader) param.getResult(); + } + Helpers.findAndHookMethod("com.android.systemui.miui.volume.MiuiVolumeTimerDrawableHelper", pluginLoader, "initTimerString", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + String[] mTimeSegmentTitle = new String[11]; + int timerOffId = mContext.getResources().getIdentifier("timer_off", "string", "miui.systemui.plugin"); + int minuteId = mContext.getResources().getIdentifier("timer_30_minutes", "string", "miui.systemui.plugin"); + int hourId = mContext.getResources().getIdentifier("timer_1_hour", "string", "miui.systemui.plugin"); + mTimeSegmentTitle[0] = mContext.getResources().getString(timerOffId); + mTimeSegmentTitle[1] = mContext.getResources().getString(minuteId, 30); + mTimeSegmentTitle[2] = mContext.getResources().getString(hourId, 1); + mTimeSegmentTitle[3] = mContext.getResources().getString(hourId, 2); + mTimeSegmentTitle[4] = mContext.getResources().getString(hourId, 3); + mTimeSegmentTitle[5] = mContext.getResources().getString(hourId, 4); + mTimeSegmentTitle[6] = mContext.getResources().getString(hourId, 5); + mTimeSegmentTitle[7] = mContext.getResources().getString(hourId, 6); + mTimeSegmentTitle[8] = mContext.getResources().getString(hourId, 8); + mTimeSegmentTitle[9] = mContext.getResources().getString(hourId, 10); + mTimeSegmentTitle[10] = mContext.getResources().getString(hourId, 12); + XposedHelpers.setObjectField(param.thisObject, "mTimeSegmentTitle", mTimeSegmentTitle); + } + }); + Helpers.findAndHookMethod("com.android.systemui.miui.volume.TimerItem", pluginLoader, "getTimePos", int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Object timer = XposedHelpers.getObjectField(param.thisObject, "mTimerTime"); + float halfTimerWidth = ((int) XposedHelpers.callMethod(timer, "getWidth")) / 2.0f; + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + float seekWidth = mContext.getResources().getDimension(mContext.getResources().getIdentifier("miui_volume_timer_seelbar_width", "dimen", "miui.systemui.plugin")); + int marginLeft = mContext.getResources().getDimensionPixelSize(mContext.getResources().getIdentifier("miui_volume_timer_seekbar_margin_left", "dimen", "miui.systemui.plugin")); + int seg = (int) XposedHelpers.getObjectField(param.thisObject, "mDeterminedSegment"); + param.setResult(seekWidth / 10 * seg + marginLeft - halfTimerWidth); + } + }); + } + } + }); + } + + public static void CCTileCornerHook(LoadPackageParam lpparam) { + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_unavailable", R.drawable.ic_qs_tile_bg_disabled); + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_disabled", R.drawable.ic_qs_tile_bg_disabled); + MainModule.resHooks.setResReplacement("miui.systemui.plugin", "drawable", "qs_background_warning", R.drawable.ic_qs_tile_bg_warning); + + String pluginLoaderClass = Helpers.isTPlus() ? "com.android.systemui.shared.plugins.PluginInstance$Factory" : "com.android.systemui.shared.plugins.PluginManagerImpl"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { + isHooked = true; + if (pluginLoader == null) { + pluginLoader = (ClassLoader) param.getResult(); + } + Helpers.findAndHookMethod("miui.systemui.controlcenter.qs.tileview.ExpandableIconView", pluginLoader, "setCornerRadius", float.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getPluginContext"); + float radius = 18; + if (scaledTileWidthDim > 0) { + radius *= scaledTileWidthDim / 65; + } + param.args[0] = mContext.getResources().getDisplayMetrics().density * radius; + } + }); + + Helpers.findAndHookMethod("miui.systemui.dagger.PluginComponentFactory", pluginLoader, "create", Context.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Context mContext = (Context) param.args[0]; + int enabledTileBackgroundResId = mContext.getResources().getIdentifier("qs_background_enabled", "drawable", "miui.systemui.plugin"); + int enabledTileColorResId = mContext.getResources().getIdentifier("qs_enabled_color", "color", "miui.systemui.plugin"); + Helpers.findAndHookMethod("android.content.res.Resources", pluginLoader, "getDrawable", int.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int resId = (int) param.args[0]; + if (resId == enabledTileBackgroundResId && resId != 0) { + Resources modRes = Helpers.getModuleRes(mContext); + Drawable enableTile = modRes.getDrawable(R.drawable.ic_qs_tile_bg_enabled, null); + enableTile.setTint(mContext.getResources().getColor(enabledTileColorResId, null)); + param.setResult(enableTile); + } + } + }); + } + }); + } + } + }); + } + + private static boolean isSlidingStart = false; + private static boolean isSliding = false; + private static float tapStartX = 0; + private static float tapStartY = 0; + private static float tapStartPointers = 0; + private static float tapStartBrightness = 0; + private static float tapCurrentBrightness = 0; + private static float topMinimumBacklight = 0.0f; + private static float topMaximumBacklight = 1.0f; + private static float currentTouchX = 0; + private static long currentTouchTime = 0; + + public static void StatusBarGesturesHook(LoadPackageParam lpparam) { + + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "makeStatusBarView", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { + @Override + public void onChange(Uri uri) { + try { + String key = uri.getPathSegments().get(2); + if ("pref_key_system_statusbarcontrols_single".equals(key) || "pref_key_system_statusbarcontrols_dual".equals(key)) + MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "1")); + else if ("pref_key_system_statusbarcontrols_sens_bright".equals(key) || "pref_key_system_statusbarcontrols_sens_vol".equals(key)) + MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "2")); + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }; + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "setExpandedHeightInternal", new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + float mExpandedFraction = (float) XposedHelpers.callMethod(param.thisObject, "getExpandedFraction"); + if (mExpandedFraction > 0.33f) { + currentTouchTime = 0; + currentTouchX = 0; + } + } + }); + + MethodHook hook = new MethodHook() { + Object mBrightnessController = null; + private int sbHeight = 0; + @Override + @SuppressLint("SetTextI18n") + protected void before(final MethodHookParam param) throws Throwable { + String clsName = param.thisObject.getClass().getSimpleName(); + boolean isInControlCenter = "ControlPanelWindowView".equals(clsName) || "ControlCenterWindowViewImpl".equals(clsName); + if (Helpers.isTPlus() && isInControlCenter) { + if (param.args.length == 2 && (boolean) param.args[1]) { + return ; + } + Object statusBarStateController = XposedHelpers.getObjectField(param.thisObject, "statusBarStateController"); + int state = (int) XposedHelpers.callMethod(statusBarStateController, "getState"); + if (state == 1 || state == 2) { + return; + } + } + Context mContext = isInControlCenter ? ((View)param.thisObject).getContext() : (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + Resources res = mContext.getResources(); + if (sbHeight == 0) { + sbHeight = res.getDimensionPixelSize(res.getIdentifier("status_bar_height", "dimen", "android")); + } + MotionEvent event = (MotionEvent)param.args[0]; + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + tapStartX = event.getX(); + tapStartY = event.getY(); + isSlidingStart = isInControlCenter ? tapStartY <= sbHeight : !XposedHelpers.getBooleanField(param.thisObject, "mPanelExpanded"); + tapStartPointers = 1; + if (mBrightnessController == null) { + Object mControlCenterController; + if (Helpers.isTPlus() && isInControlCenter) { + mControlCenterController = XposedHelpers.getObjectField(param.thisObject, "controlCenterController"); + } + else { + mControlCenterController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); + } + mBrightnessController = XposedHelpers.callMethod(XposedHelpers.getObjectField(mControlCenterController, "brightnessController"), "get"); + } + Object mDisplayManager = XposedHelpers.getObjectField(mBrightnessController, "mDisplayManager"); + int mDisplayId = mContext.getDisplay().getDisplayId(); + topMinimumBacklight = (float) XposedHelpers.getObjectField(mBrightnessController, "mMinimumBacklight"); + topMaximumBacklight = (float) XposedHelpers.getObjectField(mBrightnessController, "mMaximumBacklight"); + tapStartBrightness = (float) XposedHelpers.callMethod(mDisplayManager, "getBrightness", mDisplayId); + break; + case MotionEvent.ACTION_POINTER_DOWN: + tapStartPointers = event.getPointerCount(); + break; + case MotionEvent.ACTION_UP: + long lastTouchTime = currentTouchTime; + float lastTouchX = currentTouchX; + currentTouchTime = currentTimeMillis(); + currentTouchX = event.getX(); + if (currentTouchTime - lastTouchTime < 250L && Math.abs(currentTouchX - lastTouchX) < 100F) { + currentTouchTime = 0L; + currentTouchX = 0F; + GlobalActions.handleAction(mContext, "pref_key_system_statusbarcontrols_dt"); + } + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_CANCEL: + isSlidingStart = false; + isSliding = false; + break; + case MotionEvent.ACTION_MOVE: + if (!isSlidingStart) return; + DisplayMetrics metrics = res.getDisplayMetrics(); + if (event.getY() - tapStartY > sbHeight) return; + float delta = event.getX() - tapStartX; + if (delta == 0) return; + if (!isSliding && Math.abs(delta) > metrics.widthPixels / 10f) isSliding = true; + if (!isSliding) return; + int opt = MainModule.mPrefs.getStringAsInt(tapStartPointers == 2 ? "system_statusbarcontrols_dual" : "system_statusbarcontrols_single", 1); + if (opt == 2) { + int sens = MainModule.mPrefs.getStringAsInt("system_statusbarcontrols_sens_bright", 2); + float ratio = delta / metrics.widthPixels; + ratio = (sens == 1 ? 0.66f : (sens == 3 ? 1.66f : 1.0f)) * ratio * 0.618f; + float nextLevel = Math.min(topMaximumBacklight, Math.max(topMinimumBacklight, tapStartBrightness + (topMaximumBacklight - topMinimumBacklight) * ratio)); + XposedHelpers.callMethod(mBrightnessController, "setBrightness", nextLevel); + tapCurrentBrightness = nextLevel; + } else if (opt == 3) { + tapCurrentBrightness = -1.0f; + int sens = MainModule.mPrefs.getStringAsInt("system_statusbarcontrols_sens_vol", 2); + if (Math.abs(delta) < metrics.widthPixels / ((sens == 1 ? 0.66f : (sens == 3 ? 1.66f : 1.0f)) * 20 * metrics.density)) return; + tapStartX = event.getX(); + AudioManager audioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); + audioManager.adjustVolume(delta > 0 ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, 1 << 12 /* FLAG_FROM_KEY */ | AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_ALLOW_RINGER_MODES | AudioManager.FLAG_VIBRATE); + } + break; + } + } + }; + String eventMethod = Helpers.isTPlus() ? "onTouchEvent" : "interceptTouchEvent"; + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, eventMethod, MotionEvent.class, hook); + if (Helpers.isTPlus()) { + String pluginLoaderClass = "com.android.systemui.shared.plugins.PluginInstance$Factory"; + Helpers.hookAllMethods(pluginLoaderClass, lpparam.classLoader, "getClassLoader", new MethodHook() { + private boolean isHooked = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + ApplicationInfo appInfo = (ApplicationInfo) param.args[0]; + if ("miui.systemui.plugin".equals(appInfo.packageName) && !isHooked) { + isHooked = true; + if (pluginLoader == null) { + pluginLoader = (ClassLoader) param.getResult(); + } + Helpers.findAndHookMethod("miui.systemui.controlcenter.windowview.ControlCenterWindowViewImpl", pluginLoader, "handleMotionEvent", MotionEvent.class, boolean.class, hook); + } + } + }); + } + else { + Helpers.findAndHookMethod("com.android.systemui.controlcenter.phone.ControlPanelWindowView", lpparam.classLoader, "onTouchEvent", MotionEvent.class, hook); + } + } + + public static void HorizMarginHook(LoadPackageParam lpparam) { + MethodHook horizHook = new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Context context; + if (param.method.getName().equals("paddingNeededForCutoutAndRoundedCorner")) { + context = Helpers.findContext(); + } + else { + context = (Context) XposedHelpers.getObjectField(param.thisObject, "context"); + } + int leftMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_left", 16); + float marginLeft = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + leftMargin, + context.getResources().getDisplayMetrics() + ); + leftMargin = (int) marginLeft; + int rightMargin = MainModule.mPrefs.getInt("system_statusbar_horizmargin_right", 16); + float marginRight = TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + rightMargin, + context.getResources().getDisplayMetrics() + ); + rightMargin = (int) marginRight; + param.setResult(new Pair(Integer.valueOf(leftMargin), Integer.valueOf(rightMargin))); + } + }; + String StatusBarWindowViewCls = Helpers.isTPlus() ? "com.android.systemui.statusbar.window.StatusBarWindowView" : "com.android.systemui.statusbar.phone.StatusBarWindowView"; + Helpers.hookAllMethods(StatusBarWindowViewCls, lpparam.classLoader, "paddingNeededForCutoutAndRoundedCorner", horizHook); + if (Helpers.isTPlus()) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider", lpparam.classLoader, "getStatusBarContentInsetsForCurrentRotation", horizHook); + } + } + + public static void LockScreenTopMarginHook(LoadPackageParam lpparam) { + final int[] statusBarPaddingTop = new int[1]; + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + int dimenResId = mContext.getResources().getIdentifier("status_bar_padding_top", "dimen", lpparam.packageName); + statusBarPaddingTop[0] = mContext.getResources().getDimensionPixelSize(dimenResId); + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "updateViewStatusBarPaddingTop", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View view = (View) param.args[0]; + if (view != null) { + view.setPadding(view.getPaddingLeft(), statusBarPaddingTop[0], view.getPaddingRight(), view.getPaddingBottom()); + param.setResult(null); + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiKeyguardStatusBarView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "onDensityOrFontScaleChanged"); + } + }); + } + + public static void HideIconsClockHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiCollapsedStatusBarFragment", lpparam.classLoader, "showClock", boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + XposedHelpers.callMethod(param.thisObject, "hideClockInternal", 8, false); + XposedHelpers.callMethod(param.thisObject, "hideNetworkSpeedSplitter", 8, false); + param.setResult(null); + } + }); + } + + public static void HideIconsVoWiFiHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethodSilently("com.android.systemui.MiuiOperatorCustomizedPolicy$MiuiOperatorConfig", lpparam.classLoader, "getHideVowifi", XC_MethodReplacement.returnConstant(true)); + } + + public static void HideIconsSignalHook(LoadPackageParam lpparam) { + MethodHook beforeUpdate = new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Object mobileIconState = param.args[0]; + if (MainModule.mPrefs.getBoolean("system_statusbaricons_signal")) { + XposedHelpers.setObjectField(mobileIconState, "visible", false); + return; + } + int subId = (int) XposedHelpers.getObjectField(mobileIconState, "subId"); + if ((MainModule.mPrefs.getBoolean("system_statusbaricons_sim1") && subId == 1) + || (MainModule.mPrefs.getBoolean("system_statusbaricons_sim2") && subId == 2) + ) { + XposedHelpers.setObjectField(mobileIconState, "visible", false); + return; + } + if (MainModule.mPrefs.getBoolean("system_statusbaricons_roaming")) { + XposedHelpers.setObjectField(mobileIconState, "roaming", false); + } + if (MainModule.mPrefs.getBoolean("system_statusbaricons_volte")) { + XposedHelpers.setObjectField(mobileIconState, "volte", false); + XposedHelpers.setObjectField(mobileIconState, "speechHd", false); + } + } + }; + Helpers.hookAllMethods("com.android.systemui.statusbar.StatusBarMobileView", lpparam.classLoader, "applyMobileState", beforeUpdate); + } + + private static boolean checkSlot(String slotName) { + try { + return "headset".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_headset") || + "volume".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_sound") || + "zen".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_dnd") || + "volume".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_mute") || + "speakerphone".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_speaker") || + "call_record".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_record") || + "alarm_clock".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_alarm") || + "managed_profile".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_profile") || + "vpn".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_vpn") || + "nfc".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nfc") || + "location".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_gps") || + "wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_wifi") || + "slave_wifi".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_dualwifi") || + "hotspot".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_hotspot") || + "no_sim".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_nosims") || + "bluetooth_handsfree_battery".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_btbattery") || + "hd".equals(slotName) && MainModule.mPrefs.getBoolean("system_statusbaricons_volte"); + } catch (Throwable t) { + XposedBridge.log(t); + return false; + } + } + + public static void HideIconsHook(LoadPackageParam lpparam) { + MethodHook iconHook = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String iconType = (String)param.args[0]; + if (checkSlot(iconType)) { + param.args[1] = false; + } + } + }; + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, iconHook); + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiDripLeftStatusBarIconControllerImpl", lpparam.classLoader, "setIconVisibility", String.class, boolean.class, iconHook); + } + + public static void BatteryIndicatorHook(LoadPackageParam lpparam) { + Helpers.hookAllMethods(StatusBarCls, lpparam.classLoader, "createAndAddWindows", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + ViewGroup mStatusBarWindow; + if (Helpers.isTPlus()) { + Object sbWindowController = XposedHelpers.getObjectField(param.thisObject, "mStatusBarWindowController"); + mStatusBarWindow = (ViewGroup) XposedHelpers.getObjectField(sbWindowController, "mStatusBarWindowView"); + } + else { + mStatusBarWindow = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mPhoneStatusBarWindow"); + } + + BatteryIndicator indicator = new BatteryIndicator(mContext); + View panel = mStatusBarWindow.findViewById(mContext.getResources().getIdentifier("notification_panel", "id", lpparam.packageName)); + mStatusBarWindow.addView(indicator, panel != null ? mStatusBarWindow.indexOfChild(panel) + 1 : Math.max(mStatusBarWindow.getChildCount() - 1, 2)); + indicator.setAdjustViewBounds(false); + indicator.init(param.thisObject); + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mBatteryIndicator", indicator); + Object mNotificationIconAreaController = XposedHelpers.getObjectField(param.thisObject, "mNotificationIconAreaController"); + XposedHelpers.setAdditionalInstanceField(mNotificationIconAreaController, "mBatteryIndicator", indicator); + Object mBatteryController = XposedHelpers.getObjectField(param.thisObject, "mBatteryController"); + XposedHelpers.setAdditionalInstanceField(mBatteryController, "mBatteryIndicator", indicator); + XposedHelpers.callMethod(mBatteryController, "fireBatteryLevelChanged"); + XposedHelpers.callMethod(mBatteryController, "firePowerSaveChanged"); + } + }); + + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "setPanelExpanded", boolean.class, new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); + BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); + if (indicator != null) indicator.onExpandingChanged(!isKeyguardShowing && (boolean)param.args[0]); + } + }); + + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "setQsExpanded", boolean.class, new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); + if (!isKeyguardShowing) return; + BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); + if (indicator != null) indicator.onExpandingChanged((boolean)param.args[0]); + } + }); + + Helpers.findAndHookMethod(StatusBarCls, lpparam.classLoader, "updateIsKeyguard", boolean.class, new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + boolean isKeyguardShowing = (boolean)XposedHelpers.callMethod(param.thisObject, "isKeyguardShowing"); + BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); + if (indicator != null) indicator.onKeyguardStateChanged(isKeyguardShowing); + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.NotificationIconAreaController", lpparam.classLoader, "onDarkChanged", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); + if (indicator != null) indicator.onDarkModeChanged((float)param.args[1], (int)param.args[2]); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.MiuiBatteryControllerImpl", lpparam.classLoader, "fireBatteryLevelChanged", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); + int mLevel = XposedHelpers.getIntField(param.thisObject, "mLevel"); + boolean mCharging = XposedHelpers.getBooleanField(param.thisObject, "mCharging"); + boolean mCharged = XposedHelpers.getBooleanField(param.thisObject, "mCharged"); + if (indicator != null) indicator.onBatteryLevelChanged(mLevel, mCharging, mCharged); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.BatteryControllerImpl", lpparam.classLoader, "firePowerSaveChanged", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + BatteryIndicator indicator = (BatteryIndicator)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mBatteryIndicator"); + if (indicator != null) indicator.onPowerSaveChanged(XposedHelpers.getBooleanField(param.thisObject, "mPowerSave")); + } + }); + } + public static void TempHideOverlaySystemUIHook(LoadPackageParam lpparam) { + + Helpers.hookAllMethods("com.android.wm.shell.pip.PipTaskOrganizer", lpparam.classLoader, "onTaskAppeared", new MethodHook() { + private boolean isActListened = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + if (!isActListened) { + isActListened = true; + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction("miui.intent.TAKE_SCREENSHOT"); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) return; + if (action.equals("miui.intent.TAKE_SCREENSHOT")) { + boolean state = intent.getBooleanExtra("IsFinished", true); + Object mState; + if (Helpers.isTPlus()) { + mState = XposedHelpers.getObjectField(param.thisObject, "mPipTransitionState"); + } + else { + mState = XposedHelpers.getObjectField(param.thisObject, "mState"); + } + boolean isPip = (boolean) XposedHelpers.callMethod(mState, "isInPip"); + if (isPip) { + Object mSurfaceControlTransactionFactory = XposedHelpers.getObjectField(param.thisObject, "mSurfaceControlTransactionFactory"); + SurfaceControl.Transaction transaction = (SurfaceControl.Transaction) XposedHelpers.callMethod(mSurfaceControlTransactionFactory, "getTransaction"); + SurfaceControl mLeash = (SurfaceControl) XposedHelpers.getObjectField(param.thisObject, "mLeash"); + transaction.setVisibility(mLeash, state); + transaction.apply(); + } + } + } + }, intentFilter); + } + } + }); + } + + private static long measureTime = 0; + private static long txBytesTotal = 0; + private static long rxBytesTotal = 0; + private static long txSpeed = 0; + private static long rxSpeed = 0; + + private static Pair getTrafficBytes(Object thisObject) { + long tx = -1L; + long rx = -1L; + + try { + for (Enumeration list = NetworkInterface.getNetworkInterfaces(); list.hasMoreElements();) { + NetworkInterface iface = list.nextElement(); + if (iface.isUp() && !iface.isVirtual() && !iface.isLoopback() && !iface.isPointToPoint() && !"".equals(iface.getName())) { + tx += (long)XposedHelpers.callStaticMethod(TrafficStats.class, "getTxBytes", iface.getName()); + rx += (long)XposedHelpers.callStaticMethod(TrafficStats.class, "getRxBytes", iface.getName()); + } + } + } catch (Throwable t) { + XposedBridge.log(t); + tx = TrafficStats.getTotalTxBytes(); + rx = TrafficStats.getTotalRxBytes(); + } + + return new Pair(tx, rx); + } + + @SuppressLint("DefaultLocale") + private static String humanReadableByteCount(Context ctx, long bytes) { + try { + Resources modRes = Helpers.getModuleRes(ctx); + boolean hideSecUnit = MainModule.mPrefs.getBoolean("system_detailednetspeed_secunit"); + String unitSuffix = modRes.getString(R.string.Bs); + if (hideSecUnit) { + unitSuffix = ""; + } + if (bytes < 1024) return bytes + " " + (hideSecUnit ? "B" : unitSuffix); + int exp = (int) (Math.log(bytes) / Math.log(1024)); + char pre = modRes.getString(R.string.speedunits).charAt(exp-1); + DecimalFormat df = new DecimalFormat("0.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); + df.setMinimumFractionDigits(0); + df.setMaximumFractionDigits(1); + return df.format(bytes / Math.pow(1024, exp)) + " " + String.format("%s" + unitSuffix, pre); + } catch (Throwable t) { + XposedBridge.log(t); + return ""; + } + } + + public static void NetSpeedIntervalHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader, "postUpdateNetworkSpeedDelay", long.class, new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + long originInterval = (long) param.args[0]; + if (originInterval == 4000L) { + long newInterval = MainModule.mPrefs.getInt("system_netspeedinterval", 4) * 1000L; + param.args[0] = newInterval; + } + } + }); + } + + public static void DetailedNetSpeedHook(LoadPackageParam lpparam) { + Class nscCls = XposedHelpers.findClassIfExists("com.android.systemui.statusbar.policy.NetworkSpeedController", lpparam.classLoader); + if (nscCls == null) { + Helpers.log("DetailedNetSpeedHook", "No NetworkSpeed view or controller"); + return; + } + + Helpers.findAndHookMethod(nscCls, "getTotalByte", new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Pair bytes = getTrafficBytes(param.thisObject); + txBytesTotal = bytes.first; + rxBytesTotal = bytes.second; + measureTime = nanoTime(); + } + }); + + Helpers.findAndHookMethod(nscCls, "updateNetworkSpeed", new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + boolean isConnected = false; + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + ConnectivityManager mConnectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + Network nw = mConnectivityManager.getActiveNetwork(); + if (nw != null) { + NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(nw); + if (capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))) { + isConnected = true; + } + } + if (isConnected) { + long nanoTime = nanoTime(); + long newTime = nanoTime - measureTime; + measureTime = nanoTime; + if (newTime == 0) newTime = Math.round(4 * Math.pow(10, 9)); + Pair bytes = getTrafficBytes(param.thisObject); + long newTxBytes = bytes.first; + long newRxBytes = bytes.second; + long newTxBytesFixed = newTxBytes - txBytesTotal; + long newRxBytesFixed = newRxBytes - rxBytesTotal; + if (newTxBytesFixed < 0 || txBytesTotal == 0) newTxBytesFixed = 0; + if (newRxBytesFixed < 0 || rxBytesTotal == 0) newRxBytesFixed = 0; + txSpeed = Math.round(newTxBytesFixed / (newTime / Math.pow(10, 9))); + rxSpeed = Math.round(newRxBytesFixed / (newTime / Math.pow(10, 9))); + txBytesTotal = newTxBytes; + rxBytesTotal = newRxBytes; + } else { + txSpeed = 0; + rxSpeed = 0; + } + } + }); + + Helpers.findAndHookMethod(nscCls, "updateText", String.class, new MethodHook() { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + boolean hideLow = MainModule.mPrefs.getBoolean("system_detailednetspeed_low"); + int lowLevel = MainModule.mPrefs.getInt("system_detailednetspeed_lowlevel", 1) * 1024; + int icons = Integer.parseInt(MainModule.mPrefs.getString("system_detailednetspeed_icon", "2")); + + String txarrow = ""; + String rxarrow = ""; + if (icons == 2) { + txarrow = txSpeed < lowLevel ? "△" : "▲"; + rxarrow = rxSpeed < lowLevel ? "▽" : "▼"; + } else if (icons == 3) { + txarrow = txSpeed < lowLevel ? " ☖" : " ☗"; + rxarrow = rxSpeed < lowLevel ? " ⛉" : " ⛊"; + } + + String tx = hideLow && txSpeed < lowLevel ? "" : humanReadableByteCount(mContext, txSpeed) + txarrow; + String rx = hideLow && rxSpeed < lowLevel ? "" : humanReadableByteCount(mContext, rxSpeed) + rxarrow; + param.args[0] = tx + "\n" + rx; + } + }); + } + + private static Bitmap processAlbumArt(Context context, Bitmap bitmap) { + if (context == null || bitmap == null) return bitmap; + int rescale = Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_albumartonlock_scale", "1")); + boolean grayscale = Helpers.getSharedBoolPref(context, "pref_key_system_albumartonlock_gray", false); + if (rescale == 1 && !grayscale) return bitmap; + + Paint paint = new Paint(); + Matrix transformation = new Matrix(); + int width = 0; + int height = 0; + + if (grayscale) { + width = bitmap.getWidth(); + height = bitmap.getHeight(); + + ColorMatrix matrix = new ColorMatrix(); + matrix.setSaturation(0); + paint.setColorFilter(new ColorMatrixColorFilter(matrix)); + } + + if (rescale != 1) { + Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + Point point = new Point(); + display.getRealSize(point); + width = point.x; + height = point.y; + + float originalWidth = bitmap.getWidth(); + float originalHeight = bitmap.getHeight(); + float scale = rescale == 2 ? Math.min(width / originalWidth, height / originalHeight) : Math.max(width / originalWidth, height / originalHeight); + float xTranslation = (width - originalWidth * scale) / 2.0f; + float yTranslation = (height - originalHeight * scale) / 2.0f; + + transformation.postTranslate(xTranslation, yTranslation); + transformation.preScale(scale, scale); + + paint.setFilterBitmap(true); + } + + Bitmap processed = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(processed); + canvas.drawBitmap(bitmap, transformation, paint); + return processed; + } + + public static void LockScreenAlbumArtHook(LoadPackageParam lpparam) { + Class MiuiThemeUtilsClass = XposedHelpers.findClassIfExists("com.android.keyguard.utils.MiuiKeyguardUtils", lpparam.classLoader); + + Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + if (isDefaultLockScreenTheme) { + Object mBlurRatioChangedListener = XposedHelpers.getObjectField(param.thisObject, "mBlurRatioChangedListener"); + Object notificationShadeDepthController = XposedHelpers.getObjectField(param.thisObject, "notificationShadeDepthController"); + XposedHelpers.callMethod(notificationShadeDepthController, "removeListener", mBlurRatioChangedListener); + View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); + view.setAlpha(1.0f); + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); + view.getContext().registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) return; + if (action.equals(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART")) { + try { + XposedHelpers.callMethod(param.thisObject, "updateThemeBackground"); + } + catch (Throwable e) { + XposedHelpers.callMethod(param.thisObject, "updateThemeBackgroundVisibility"); + } + } + } + }, intentFilter); + } + } + }); + MethodHook updateLockscreenHook = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + if (!isDefaultLockScreenTheme) { + return ; + } + View view = (View) XposedHelpers.getObjectField(param.thisObject, "mThemeBackgroundView"); + boolean isOnShade = (boolean) XposedHelpers.callMethod(param.thisObject, "isOnShade"); + if (isOnShade) { + view.setVisibility(View.GONE); + } + else { + Object mAlbumArt = XposedHelpers.getAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt"); + if (mAlbumArt != null) { + view.setBackground(new BitmapDrawable(view.getContext().getResources(), (Bitmap) mAlbumArt)); + } + view.setVisibility(mAlbumArt != null ? View.VISIBLE : View.GONE); + } + param.setResult(null); + } + }; + Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackground", updateLockscreenHook); + + if (Helpers.isTPlus()) { + Helpers.findAndHookMethodSilently("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateThemeBackgroundVisibility", updateLockscreenHook); + } + Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMediaManager", lpparam.classLoader, "updateMediaMetaData", boolean.class, boolean.class, new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + if (!isDefaultLockScreenTheme) { + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); + return; + } + MediaMetadata mMediaMetadata = (MediaMetadata)XposedHelpers.getObjectField(param.thisObject, "mMediaMetadata"); + Bitmap art = null; + if (mMediaMetadata != null) { + art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART); + if (art == null) art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); + if (art == null) art = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON); + } + Bitmap mAlbumArt = (Bitmap)XposedHelpers.getAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource"); + try { + if (art == null && mAlbumArt == null) return; + if (art != null && art.sameAs(mAlbumArt)) return; + } catch (Throwable ignore) {} + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", art); + + int blur = Helpers.getSharedIntPref(mContext, "pref_key_system_albumartonlock_blur", 0); + Bitmap blurArt = processAlbumArt(mContext, art != null && blur > 0 ? Helpers.fastBlur(art, blur + 1) : art); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", blurArt); + + Intent updateAlbumWallpaper = new Intent(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); + updateAlbumWallpaper.setPackage("com.android.systemui"); + mContext.sendBroadcast(updateAlbumWallpaper); + + if (blurArt != null) { + Intent updateFakeWallpaper = new Intent("miui.intent.action.LOCK_WALLPAPER_CHANGED"); + updateFakeWallpaper.setPackage("com.android.systemui"); + WallpaperColors fromBitmap = WallpaperColors.fromBitmap(blurArt); + boolean isWallpaperColorLight = (fromBitmap.getColorHints() & 1) == 1; + updateFakeWallpaper.putExtra("is_wallpaper_color_light", isWallpaperColorLight); + mContext.sendBroadcast(updateFakeWallpaper); + } + } + }); + Helpers.findAndHookMethod("com.android.systemui.statusbar.NotificationMediaManager", lpparam.classLoader, "clearCurrentMediaNotification", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + boolean isDefaultLockScreenTheme = (boolean) XposedHelpers.callStaticMethod(MiuiThemeUtilsClass, "isDefaultLockScreenTheme"); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArtSource", null); + XposedHelpers.setAdditionalStaticField(MiuiThemeUtilsClass, "mAlbumArt", null); + if (isDefaultLockScreenTheme) { + Intent updateAlbumWallpaper = new Intent(GlobalActions.EVENT_PREFIX + "UPDATE_LS_ALBUM_ART"); + updateAlbumWallpaper.setPackage("com.android.systemui"); + mContext.sendBroadcast(updateAlbumWallpaper); + } + } + }); + } + + private static boolean modifyCameraImage(Context mContext, View mKeyguardRightView, boolean mDarkMode) { + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { + restoreCameraImage(mKeyguardRightView); + return false; + } + + final String key = "pref_key_system_lockscreenshortcuts_right"; + + int action = Helpers.getSharedIntPref(mContext, key + "_action", 1); + if (action <= 1) { + restoreCameraImage(mKeyguardRightView); + return false; + } + + String str = Helpers.getActionName(mContext, key); + if (str == null) { + restoreCameraImage(mKeyguardRightView); + return false; + } + + Drawable icon = Helpers.getActionImage(mContext, key); + mKeyguardRightView.setBackgroundColor(Color.TRANSPARENT); + mKeyguardRightView.setForeground(icon); + mKeyguardRightView.setForegroundGravity(Gravity.CENTER); + + float density = mContext.getResources().getDisplayMetrics().density; + int size = Math.round(mContext.getResources().getConfiguration().smallestScreenWidthDp * density); + + Bitmap bmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bmp); + Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setShadowLayer(2 * density, 0, 0, mDarkMode ? Color.argb(90, 255, 255, 255) : Color.argb(90, 0, 0, 0)); + paint.setTextSize(20 * density); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(density); + paint.setColor(mDarkMode ? Color.WHITE : Color.BLACK); + paint.setAlpha(90); + + Rect bounds = new Rect(); + paint.getTextBounds(str, 0, str.length(), bounds); + float x = size / 2f - bounds.width() / 2f; + float y = size / 2f + bounds.height() / 2f + (icon == null ? 0 : icon.getIntrinsicHeight() / 2f + 30 * density); + canvas.drawText(str, x, y, paint); + paint.setStyle(Paint.Style.FILL); +// paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); + paint.clearShadowLayer(); + paint.setColor(mDarkMode ? Color.BLACK : Color.WHITE); + paint.setAlpha(mDarkMode ? 160 : 230); + canvas.drawText(str, x, y, paint); + + BitmapDrawable bmpDrawable = new BitmapDrawable(mContext.getResources(), bmp); + if (mKeyguardRightView instanceof ImageView) { + ((ImageView)mKeyguardRightView).setScaleType(ImageView.ScaleType.CENTER); + ((ImageView)mKeyguardRightView).setImageDrawable(bmpDrawable); + } else { + bmpDrawable.setGravity(Gravity.CENTER); + mKeyguardRightView.setBackground(bmpDrawable); + } + + return true; + } + + private static void restoreCameraImage(View mKeyguardRightView) { + mKeyguardRightView.setBackgroundColor(Color.BLACK); + mKeyguardRightView.setForeground(null); + if (mKeyguardRightView instanceof ImageView) + ((ImageView)mKeyguardRightView).setScaleType(ImageView.ScaleType.FIT_END); + } + + private static Object notificationPanelView = null; + public static void LockScreenShortcutHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView$MiuiDefaultLeftButton", lpparam.classLoader, "getIcon", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object img = param.getResult(); + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { + Object thisObject = XposedHelpers.getSurroundingThis(param.thisObject); + Context mContext = (Context) XposedHelpers.getObjectField(thisObject, "mContext"); + boolean mDarkMode = XposedHelpers.getBooleanField(thisObject, "mDarkStyle"); + Drawable flashlightDrawable = Helpers.getModuleRes(mContext).getDrawable( + mDarkMode ? R.drawable.keyguard_bottom_flashlight_img_dark : R.drawable.keyguard_bottom_flashlight_img_light, + mContext.getTheme() + ); + XposedHelpers.setObjectField(img, "drawable", flashlightDrawable); + } else if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) + XposedHelpers.setObjectField(img, "isVisible", false); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView$MiuiDefaultRightButton", lpparam.classLoader, "getIcon", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object img = param.getResult(); + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { + XposedHelpers.setObjectField(img, "isVisible", false); + return; + } + + boolean opt = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image"); + if (!opt) return; + Object thisObject = XposedHelpers.getSurroundingThis(param.thisObject); + Context mContext = (Context) XposedHelpers.getObjectField(thisObject, "mContext"); + boolean mDarkMode = XposedHelpers.getBooleanField(thisObject, "mDarkStyle"); + XposedHelpers.setObjectField(img, "drawable", Helpers.getModuleRes(mContext).getDrawable( + mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, + mContext.getTheme() + )); + } + }); + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "initTipsView", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + boolean opt = MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image"); + if (!opt) return; + boolean isLeft = (boolean) param.args[0]; + if (!isLeft) { + TextView mRightAffordanceViewTips = (TextView) XposedHelpers.getObjectField(param.thisObject, "mRightAffordanceViewTips"); + if (mRightAffordanceViewTips != null) + mRightAffordanceViewTips.setText(Helpers.getModuleRes(mRightAffordanceViewTips.getContext()).getString(R.string.system_lockscreenshortcuts_right_image_hint)); + } + } + }); + + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_tapaction")) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onFinishInflate", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); + mLeftAffordanceView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); + boolean z = !(boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); + XposedHelpers.callMethod(flashlightController, "setFlashlight", z); + XposedHelpers.callMethod(param.thisObject, "updateLeftAffordanceIcon"); + return true; + } + }); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "updateLeftAffordanceIcon", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + Object mLeftAffordanceView = XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); + Object flashlightController = XposedHelpers.getObjectField(param.thisObject, "mFlashlightController"); + boolean isOn = (boolean) XposedHelpers.callMethod(flashlightController, "isEnabled"); + XposedHelpers.callMethod(mLeftAffordanceView, "setCircleRadiusWithoutAnimation", isOn ? 66f : 0f); + } + }); + + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "onClick", View.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View view = (View) param.args[0]; + View mLeftAffordanceView = (View) XposedHelpers.getObjectField(param.thisObject, "mLeftAffordanceView"); + if (view == mLeftAffordanceView) { + param.setResult(null); + } + } + }); + } + + Helpers.hookAllMethods("com.android.systemui.statusbar.phone.KeyguardBottomAreaView", lpparam.classLoader, "launchCamera", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + if (GlobalActions.handleAction(mContext, "pref_key_system_lockscreenshortcuts_right", true)) { + param.setResult(null); + Object PanelInjector = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClass("com.android.keyguard.injector.KeyguardPanelViewInjector", lpparam.classLoader)); + Object panelController = XposedHelpers.getObjectField(PanelInjector, "mPanelViewController"); + final View mNotificationPanelView = (View) XposedHelpers.getObjectField(PanelInjector, "mPanelView"); + mNotificationPanelView.postDelayed(new Runnable() { + @Override + public void run() { + XposedHelpers.callMethod(panelController, "resetViews", false); + } + }, 500); + } + } + }); + + Helpers.hookAllMethods("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "setDarkStyle", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image")) { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + boolean mDarkMode = XposedHelpers.getBooleanField(param.thisObject, "mDarkStyle"); + XposedHelpers.callMethod(param.thisObject, "setPreviewImageDrawable", Helpers.getModuleRes(mContext).getDrawable(mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, mContext.getTheme())); + } + } + }); + + Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "updatePreView", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View mPreViewContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); + if ("active".equals(mPreViewContainer.getTag())) { + XposedHelpers.setFloatField(param.thisObject, "mIconCircleAlpha", 0.0f); + ((View) param.thisObject).invalidate(); + } + } + }); + + Helpers.hookAllMethods("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "setPreviewImageDrawable", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + + boolean mDarkMode = XposedHelpers.getBooleanField(param.thisObject, "mDarkStyle"); + ImageView mIconView = (ImageView) XposedHelpers.getObjectField(param.thisObject, "mIconView"); + if (mIconView != null) + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_image")) + mIconView.setImageDrawable(Helpers.getModuleRes(mContext).getDrawable(mDarkMode ? R.drawable.keyguard_bottom_miuizer_img_dark : R.drawable.keyguard_bottom_miuizer_img_light, mContext.getTheme())); + else + mIconView.setImageDrawable(mContext.getDrawable(mDarkMode ? mContext.getResources().getIdentifier("keyguard_bottom_camera_img_dark", "drawable", lpparam.packageName) : mContext.getResources().getIdentifier("keyguard_bottom_camera_img", "drawable", lpparam.packageName))); + + View mPreView = (View) XposedHelpers.getObjectField(param.thisObject, "mPreView"); + View mPreViewContainer = (View) XposedHelpers.getObjectField(param.thisObject, "mPreViewContainer"); + View mBackgroundView = (View) XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); + Paint mIconCircleStrokePaint = (Paint) XposedHelpers.getObjectField(param.thisObject, "mIconCircleStrokePaint"); + ViewOutlineProvider mPreViewOutlineProvider = (ViewOutlineProvider) XposedHelpers.getObjectField(param.thisObject, "mPreViewOutlineProvider"); + boolean result = modifyCameraImage(mContext, mPreView, mDarkMode); + if (result) param.setResult(null); + if (mPreViewContainer != null) { + mPreViewContainer.setBackgroundColor(result ? Color.TRANSPARENT : Color.BLACK); + mPreViewContainer.setOutlineProvider(result ? null : mPreViewOutlineProvider); + mPreViewContainer.setTag(result ? "active" : "inactive"); + } + if (mBackgroundView != null) + mBackgroundView.setBackgroundColor(result ? Color.TRANSPARENT : Color.BLACK); + if (mIconCircleStrokePaint != null) + mIconCircleStrokePaint.setColor(result ? Color.TRANSPARENT : Color.WHITE); + } + }); + + Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "handleMoveDistanceChanged", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View mIconView = (View) XposedHelpers.getObjectField(param.thisObject, "mIconView"); + if (MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) { + if (mIconView != null) mIconView.setVisibility(View.GONE); + param.setResult(null); + } else if (mIconView != null) mIconView.setVisibility(View.VISIBLE); + } + }); + + Helpers.findAndHookMethod("com.android.keyguard.MiuiKeyguardCameraView", lpparam.classLoader, "startFullScreenAnim", new MethodHook() { + @Override + protected void after(MethodHookParam param) throws Throwable { + int action = MainModule.mPrefs.getInt("system_lockscreenshortcuts_right_action", 1); + if (action <= 1) return; + AnimatorSet mAnimatorSet = (AnimatorSet) XposedHelpers.getObjectField(param.thisObject, "mAnimatorSet"); + if (mAnimatorSet == null) return; + param.setResult(null); + mAnimatorSet.pause(); + mAnimatorSet.removeAllListeners(); + mAnimatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + GlobalActions.handleAction(mContext, "pref_key_system_lockscreenshortcuts_right", true); + Object mCallBack = XposedHelpers.getObjectField(param.thisObject, "mCallBack"); + if (mCallBack != null) + XposedHelpers.callMethod(mCallBack, "onCompletedAnimationEnd"); + XposedHelpers.setBooleanField(param.thisObject, "mIsPendingStartCamera", false); + XposedHelpers.callMethod(param.thisObject, "dismiss"); + View mBackgroundView = (View) XposedHelpers.getObjectField(param.thisObject, "mBackgroundView"); + if (mBackgroundView != null) mBackgroundView.setAlpha(1.0f); + } + }); + mAnimatorSet.resume(); + } + }); + + Helpers.hookAllConstructors("com.android.systemui.statusbar.phone.NotificationPanelView", lpparam.classLoader, new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + notificationPanelView = param.thisObject; + Context mContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); + new Helpers.SharedPrefObserver(mContext, new Handler(mContext.getMainLooper())) { + @Override + public void onChange(Uri uri) { + try { + String type = uri.getPathSegments().get(1); + String key = uri.getPathSegments().get(2); + if (!key.contains("pref_key_system_lockscreenshortcuts")) return; + + switch (type) { + case "string": + MainModule.mPrefs.put(key, Helpers.getSharedStringPref(mContext, key, "")); + break; + case "integer": + MainModule.mPrefs.put(key, Helpers.getSharedIntPref(mContext, key, 1)); + break; + case "boolean": + MainModule.mPrefs.put(key, Helpers.getSharedBoolPref(mContext, key, false)); + break; + } + + if (key.contains("pref_key_system_lockscreenshortcuts_right")) + try { + XposedHelpers.callMethod(notificationPanelView, "setCameraImage", false); + } catch (Throwable t1) { + try { + XposedHelpers.callMethod(notificationPanelView, "setCameraImage"); + } catch (Throwable t2) { + } + } + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }; + } + }); + + Helpers.findAndHookMethod("com.android.keyguard.KeyguardMoveHelper", lpparam.classLoader, "setTranslation", float.class, boolean.class, boolean.class, boolean.class, boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int mCurrentScreen = XposedHelpers.getIntField(param.thisObject, "mCurrentScreen"); + if (mCurrentScreen != 1) return; + if ((float) param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) + param.args[0] = 0.0f; + else if ((float) param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) + param.args[0] = 0.0f; + } + }); + + Helpers.findAndHookMethod("com.android.keyguard.KeyguardMoveHelper", lpparam.classLoader, "fling", float.class, boolean.class, boolean.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + int mCurrentScreen = XposedHelpers.getIntField(param.thisObject, "mCurrentScreen"); + if (mCurrentScreen != 1) return; + if ((float) param.args[0] < 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_right_off")) + param.setResult(null); + else if ((float) param.args[0] > 0 && MainModule.mPrefs.getBoolean("system_lockscreenshortcuts_left_off")) + param.setResult(null); + } + }); + } + + public static void LockScreenSecureLaunchHook() { + Helpers.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new MethodHook() { + @SuppressWarnings("ConstantConditions") + protected void after(MethodHookParam param) throws Throwable { + Activity act = (Activity)param.thisObject; + if (act == null) return; + Intent intent = act.getIntent(); + if (intent == null) return; + boolean mFromSecureKeyguard = intent.getBooleanExtra("StartActivityWhenLocked", false); + boolean mStartedFromLockScreen = false; + try { + mStartedFromLockScreen = (boolean)XposedHelpers.getAdditionalInstanceField(act.getApplication(), "wasStartedFromLockScreen"); + } catch (Throwable ignore) {} + if (mFromSecureKeyguard || mStartedFromLockScreen) { + XposedHelpers.setAdditionalInstanceField(act.getApplication(), "wasStartedFromLockScreen", true); + act.setShowWhenLocked(true); + act.setInheritShowWhenLocked(true); + } + } + }); + } + + private static final List securedTiles = new ArrayList(); + + public static void SecureQSTilesHook(LoadPackageParam lpparam) { + Class tileHostCls = XposedHelpers.findClassIfExists("com.android.systemui.qs.QSTileHost", lpparam.classLoader); + + MethodHook hook = new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + BroadcastReceiver mAfterUnlockReceiver = new BroadcastReceiver() { + @Override + @SuppressWarnings("unchecked") + public void onReceive(Context context, Intent intent) { + try { + String tileName = intent.getStringExtra("tileName"); + boolean expandAfter = intent.getBooleanExtra("expandAfter", false); + boolean usingCenter = intent.getBooleanExtra("usingCenter", false); + if ("edit".equals(tileName) || expandAfter) { + Intent expandIntent = new Intent(ACTION_PREFIX + "ExpandSettings"); + expandIntent.putExtra("forceExpand", true); + context.sendBroadcast(expandIntent); + } + LinkedHashMap mTiles = (LinkedHashMap)XposedHelpers.getObjectField(param.thisObject, "mTiles"); + Object tile = mTiles.get(tileName); + if (tile == null) { + if (usingCenter) { + Object mController = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", lpparam.classLoader), "get", findClassIfExists("com.android.systemui.miui.statusbar.policy.ControlPanelController", lpparam.classLoader)); + Object mControlCenter = XposedHelpers.getObjectField(mController, "mControlCenter"); + Object mControlPanelContentView = XposedHelpers.getObjectField(mControlCenter, "mControlPanelContentView"); + Object mControlCenterPanel = XposedHelpers.callMethod(mControlPanelContentView, "getControlCenterPanel"); + Object mBigTile = null; + if ("bt".equals(tileName)) mBigTile = XposedHelpers.getObjectField(mControlCenterPanel, "mBigTile1"); + else if ("cell".equals(tileName)) mBigTile = XposedHelpers.getObjectField(mControlCenterPanel, "mBigTile2"); + else if ("wifi".equals(tileName)) mBigTile = XposedHelpers.getObjectField(mControlCenterPanel, "mBigTile3"); + if (mBigTile != null) tile = XposedHelpers.getObjectField(mBigTile, "mQSTile"); + if (tile == null) return; + } + return; + } + XposedHelpers.setAdditionalInstanceField(tile, "mCalledAfterUnlock", true); + Method clickHandler = XposedHelpers.findMethodExact(tile.getClass(), "handleClick", View.class); + clickHandler.invoke(tile, new Object[]{ null }); + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }; + mContext.registerReceiver(mAfterUnlockReceiver, new IntentFilter(ACTION_PREFIX + "HandleQSTileClick")); + } + }; + + Helpers.hookAllConstructors(tileHostCls, hook); + + String FactoryImpl = Helpers.isTPlus() ? "com.android.systemui.qs.tileimpl.MiuiQSFactory" : "com.android.systemui.qs.tileimpl.QSFactoryImpl"; + Helpers.findAndHookMethod(FactoryImpl, lpparam.classLoader, "createTileInternal", String.class, new MethodHook() { + @Override + protected void after(final MethodHookParam param) throws Throwable { + Object tile = param.getResult(); + if (tile == null) return; + String tileClass = tile.getClass().getCanonicalName(); + final String tileName = (String)param.args[0]; + String name = tileName; + if (name.startsWith("intent(")) name = "intent"; + else if (name.startsWith("custom(")) name = "custom"; + final HashSet secureTitles = new HashSet(); + if (MainModule.mPrefs.getBoolean("system_secureqs_wifi")) secureTitles.add("wifi"); + if (MainModule.mPrefs.getBoolean("system_secureqs_bt")) secureTitles.add("bt"); + if (MainModule.mPrefs.getBoolean("system_secureqs_mobiledata")) secureTitles.add("cell"); + if (MainModule.mPrefs.getBoolean("system_secureqs_airplane")) secureTitles.add("airplane"); + if (MainModule.mPrefs.getBoolean("system_secureqs_location")) secureTitles.add("gps"); + if (MainModule.mPrefs.getBoolean("system_secureqs_hotspot")) secureTitles.add("hotspot"); + if (MainModule.mPrefs.getBoolean("system_secureqs_nfc")) secureTitles.add("nfc"); + if (MainModule.mPrefs.getBoolean("system_secureqs_sync")) secureTitles.add("sync"); + if (MainModule.mPrefs.getBoolean("system_secureqs_edit")) secureTitles.add("edit"); + if (MainModule.mPrefs.getBoolean("system_secureqs_custom")) { + secureTitles.add("intent"); + secureTitles.add("custom"); + } + if (secureTitles.contains(name) && !securedTiles.contains(tileClass)) { + MethodHook hook = new MethodHook(10) { + @Override + protected void before(final MethodHookParam param) throws Throwable { + Boolean mCalledAfterUnlock = (Boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mCalledAfterUnlock"); + if (mCalledAfterUnlock != null && mCalledAfterUnlock) { + XposedHelpers.setAdditionalInstanceField(param.thisObject, "mCalledAfterUnlock", false); + return; + } + Boolean isScreenLockDisabled = (Boolean)XposedHelpers.getAdditionalStaticField(findClass("com.android.systemui.keyguard.KeyguardViewMediator", lpparam.classLoader), "isScreenLockDisabled"); + isScreenLockDisabled = isScreenLockDisabled != null && isScreenLockDisabled; + if (isScreenLockDisabled) return; + Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext"); + KeyguardManager kgMgr = (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE); + if (!kgMgr.isKeyguardLocked() || !kgMgr.isKeyguardSecure()) return; + Handler mHandler = new Handler(mContext.getMainLooper()); + mHandler.post(new Runnable() { + @Override + public void run() { + try { + Class DependencyClass = findClass("com.android.systemui.Dependency", lpparam.classLoader); + String StatusbarClsForDep = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfaces" : "com.android.systemui.statusbar.phone.StatusBar"; + Object mStatusBar = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists(StatusbarClsForDep, lpparam.classLoader)); + boolean usingControlCenter; + Object mController = XposedHelpers.callStaticMethod(DependencyClass, "get", findClassIfExists("com.android.systemui.controlcenter.policy.ControlCenterControllerImpl", lpparam.classLoader)); + usingControlCenter = (boolean)XposedHelpers.callMethod(mController, "isUseControlCenter"); + if (usingControlCenter) XposedHelpers.callMethod(mController, "collapseControlCenter", true); + boolean keepOpened = MainModule.mPrefs.getBoolean("system_secureqs_keepopened"); + final boolean usingCenter = usingControlCenter; + final boolean expandAfter = usingControlCenter && keepOpened; +// if (!usingControlCenter && keepOpened) +// XposedHelpers.callMethod(XposedHelpers.getObjectField(mStatusBar, "mStatusBarStateController"), "setLeaveOpenOnKeyguardHide", true); + XposedHelpers.callMethod(mStatusBar, "postQSRunnableDismissingKeyguard", !keepOpened, new Runnable() { + public void run() { + Intent intent = new Intent(ACTION_PREFIX + "HandleQSTileClick"); + intent.putExtra("tileName", tileName); + intent.putExtra("expandAfter", expandAfter); + intent.putExtra("usingCenter", usingCenter); + mContext.sendBroadcast(intent); + } + }); + } catch (Throwable t) { + XposedBridge.log(t); + } + } + }); + param.setResult(null); + } + }; + Helpers.findAndHookMethod(tileClass, lpparam.classLoader, "handleClick", View.class, hook); + Helpers.hookAllMethodsSilently(tileClass, lpparam.classLoader, "handleSecondaryClick", hook); + securedTiles.add(tileClass); + } + } + }); + } + + public static void ExtendedPowerMenuHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.SystemUIApplication", lpparam.classLoader, "onCreate", new MethodHook() { + private boolean isListened = false; + @Override + protected void after(MethodHookParam param) throws Throwable { + if (!isListened) { + isListened = true; + Context mContext = (Context) XposedHelpers.callMethod(param.thisObject, "getApplicationContext"); + File powermenu = new File(mContext.getCacheDir(), "extended_power_menu"); + if (powermenu == null) { + Helpers.log("ExtendedPowerMenuHook", "No writable path found!"); + return; + } + if (powermenu.exists()) powermenu.delete(); + + InputStream inputStream; + FileOutputStream outputStream; + byte[] fileBytes; + Resources resources = Helpers.getModuleRes(mContext); + inputStream = resources.openRawResource(resources.getIdentifier("extended_power_menu", "raw", Helpers.modulePkg)); + fileBytes = new byte[inputStream.available()]; + inputStream.read(fileBytes); + outputStream = new FileOutputStream(powermenu); + outputStream.write(fileBytes); + outputStream.close(); + inputStream.close(); + + if (!powermenu.exists()) { + Helpers.log("ExtendedPowerMenuHook", "MAML file not found in cache"); + } + else { + Helpers.findAndHookConstructor("com.miui.maml.util.ZipResourceLoader", lpparam.classLoader, String.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + String res = (String) param.args[0]; + if ("/system/media/theme/default/powermenu".equals(res)) { + param.args[0] = powermenu.getPath(); + } + } + }); + } + } + } + }); + Helpers.findAndHookMethod("com.miui.maml.ScreenElementRoot", lpparam.classLoader, "issueExternCommand", String.class, Double.class, String.class, new MethodHook() { + @Override + @SuppressLint("MissingPermission") + protected void before(MethodHookParam param) throws Throwable { + String cmd = (String)param.args[0]; + Object scrContext = XposedHelpers.getObjectField(param.thisObject, "mContext"); + Context mContext = (Context)XposedHelpers.getObjectField(scrContext, "mContext"); + PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); + Object mService = XposedHelpers.getObjectField(pm, "mService"); + Object mSystemExternCommandListener = XposedHelpers.getObjectField(param.thisObject, "mSystemExternCommandListener"); + + boolean custom = false; + if ("recovery".equals(cmd)) { + XposedHelpers.callMethod(mService, "reboot", false, "recovery", false); + custom = true; + } else if ("bootloader".equals(cmd)) { + XposedHelpers.callMethod(mService, "reboot", false, "bootloader", false); + custom = true; + } else if ("softreboot".equals(cmd)) { + mContext.sendBroadcast(new Intent(ACTION_PREFIX + "FastReboot")); + custom = true; + } else if ("killsysui".equals(cmd)) { + mContext.sendBroadcast(new Intent(ACTION_PREFIX + "RestartSystemUI")); + custom = true; + } else if ("killlauncher".equals(cmd)) { + ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + ResolveInfo launcherInfo = mContext.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); + if (launcherInfo != null) { + String pkgName = launcherInfo.activityInfo.packageName; + if (pkgName != null) XposedHelpers.callMethod(am, "forceStopPackage", pkgName); + } + custom = true; + } + + if (custom) { + if (mSystemExternCommandListener != null) XposedHelpers.callMethod(mSystemExternCommandListener, "onCommand", param.args[0], param.args[1], param.args[2]); + param.setResult(null); + } + } + }); + + Helpers.findAndHookMethod("com.android.systemui.plugins.PluginEnablerImpl", lpparam.classLoader, "isEnabled", ComponentName.class, new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + ComponentName componentName = (ComponentName) param.args[0]; + if (componentName.getClassName().contains("GlobalActions")) { + param.setResult(false); + } + } + }); + } + + public static void HideDismissViewHook(LoadPackageParam lpparam) { + Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.MiuiNotificationPanelViewController", lpparam.classLoader, "updateDismissView", new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + View mDismissView = (View)XposedHelpers.getObjectField(param.thisObject, "mDismissView"); + if (mDismissView != null) { + mDismissView.setVisibility(View.GONE); + param.setResult(null); + } + } + }); + } + + public static void ReplaceShortcutAppHook(LoadPackageParam lpparam) { + MethodHook openAppHook = new MethodHook() { + @Override + protected void before(MethodHookParam param) throws Throwable { + Context mContext = AndroidAppHelper.currentApplication(); + int user = 0; + String pkgAppName = ""; + if (param.method.getName().equals("startCalendarApp")) { + user = Helpers.getSharedIntPref(mContext, "pref_key_system_calendar_app_user", 0); + pkgAppName = Helpers.getSharedStringPref(mContext, "pref_key_system_calendar_app", ""); + } + else if (param.method.getName().equals("startClockApp")) { + user = Helpers.getSharedIntPref(mContext, "pref_key_system_clock_app_user", 0); + pkgAppName = Helpers.getSharedStringPref(mContext, "pref_key_system_clock_app", ""); + } + else if (param.method.getName().equals("startSettingsApp")) { + user = Helpers.getSharedIntPref(mContext, "pref_key_system_shortcut_app_user", 0); + pkgAppName = Helpers.getSharedStringPref(mContext, "pref_key_system_shortcut_app", ""); + } + if (pkgAppName != null && !pkgAppName.equals("")) { + String[] pkgAppArray = pkgAppName.split("\\|"); + if (pkgAppArray.length < 2) return; + + ComponentName name = new ComponentName(pkgAppArray[0], pkgAppArray[1]); + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + intent.setComponent(name); + if (user != 0) { + try { + Class Dependency = findClass("com.android.systemui.Dependency", lpparam.classLoader); + String StatusbarClsForDep = Helpers.isTPlus() ? "com.android.systemui.statusbar.phone.CentralSurfaces" : "com.android.systemui.statusbar.phone.StatusBar"; + Object mStatusBar = XposedHelpers.callStaticMethod(Dependency, "get", findClass(StatusbarClsForDep, lpparam.classLoader)); + XposedHelpers.callMethod(mStatusBar, "collapsePanels"); + XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user)); + } catch (Throwable t) { + XposedBridge.log(t); + } + } else { + Object activiyStarter = XposedHelpers.callStaticMethod(findClass("com.android.systemui.Dependency", mContext.getClassLoader()), "get", findClass("com.android.systemui.plugins.ActivityStarter", mContext.getClassLoader())); + XposedHelpers.callMethod(activiyStarter, "startActivity", intent, true); + } + param.setResult(null); + } + } + }; + if (!MainModule.mPrefs.getString("system_shortcut_app", "").equals("")) { + Helpers.findAndHookMethod("com.miui.systemui.util.CommonUtil", lpparam.classLoader, "startSettingsApp", openAppHook); + } + if (!MainModule.mPrefs.getString("system_calendar_app", "").equals("")) { + Helpers.findAndHookMethod("com.miui.systemui.util.CommonUtil", lpparam.classLoader, "startCalendarApp", Context.class, openAppHook); + } + if (!MainModule.mPrefs.getString("system_clock_app", "").equals("")) { + Helpers.findAndHookMethod("com.miui.systemui.util.CommonUtil", lpparam.classLoader, "startClockApp", openAppHook); + } + } +} \ No newline at end of file From 38a59c21562aabc2e93fb61b6902603d8c59adbe Mon Sep 17 00:00:00 2001 From: MonwF Date: Wed, 1 Feb 2023 18:16:51 +0800 Subject: [PATCH 326/627] feat: folder blur --- .idea/gradle.xml | 1 - .../mikanoshi/customiuizer/MainModule.java | 2 +- .../mikanoshi/customiuizer/mods/Launcher.java | 77 +++++++------------ .../mikanoshi/customiuizer/subs/Launcher.java | 8 -- .../subs/Launcher_FolderBlur.java | 19 ----- app/src/main/res/values-pl-rPL/strings.xml | 6 -- app/src/main/res/values-ru-rRU/strings.xml | 6 -- app/src/main/res/values-zh-rCN/strings.xml | 8 +- app/src/main/res/values-zh-rTW/strings.xml | 6 -- app/src/main/res/values/strings.xml | 6 -- app/src/main/res/xml/prefs_launcher.xml | 14 +++- .../res/xml/prefs_launcher_folderblur.xml | 74 ------------------ gradle.properties | 1 + 13 files changed, 42 insertions(+), 186 deletions(-) delete mode 100644 app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher_FolderBlur.java delete mode 100644 app/src/main/res/xml/prefs_launcher_folderblur.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml index da919dcd..00d25f9e 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -7,7 +7,6 @@