Browse Source

[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; resolves #148
[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
master v3.0.6
Mikanoshi 10 months ago
parent
commit
9d32f06a5e
34 changed files with 779 additions and 214 deletions
  1. +5
    -0
      .idea/jarRepositories.xml
  2. +16
    -2
      CHANGELOG_EN
  3. +16
    -2
      CHANGELOG_RU
  4. +5
    -4
      app/build.gradle
  5. +19
    -3
      app/src/main/java/name/mikanoshi/customiuizer/MainModule.java
  6. +18
    -0
      app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java
  7. +1
    -1
      app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java
  8. +1
    -2
      app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java
  9. +51
    -18
      app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java
  10. +7
    -7
      app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java
  11. +330
    -74
      app/src/main/java/name/mikanoshi/customiuizer/mods/System.java
  12. +5
    -2
      app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java
  13. +7
    -1
      app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java
  14. +17
    -2
      app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java
  15. +6
    -1
      app/src/main/java/name/mikanoshi/customiuizer/subs/System.java
  16. +28
    -8
      app/src/main/java/name/mikanoshi/customiuizer/utils/AppDataAdapter.java
  17. +67
    -45
      app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java
  18. +24
    -40
      app/src/main/java/name/mikanoshi/customiuizer/utils/ResourceHooks.java
  19. BIN
      app/src/main/res/drawable-night-xxhdpi-v4/icon_action_default.png
  20. BIN
      app/src/main/res/drawable-xxhdpi-v4/icon_action_allow.png
  21. BIN
      app/src/main/res/drawable-xxhdpi-v4/icon_action_default.png
  22. BIN
      app/src/main/res/drawable-xxhdpi-v4/icon_action_disallow.png
  23. +6
    -0
      app/src/main/res/layout/applist_item11.xml
  24. +2
    -0
      app/src/main/res/values-440dpi/dimens.xml
  25. +24
    -0
      app/src/main/res/values-es/strings.xml
  26. +49
    -0
      app/src/main/res/values-it/strings.xml
  27. +10
    -0
      app/src/main/res/values-ru-rRU/strings.xml
  28. +2
    -0
      app/src/main/res/values-xxhdpi/dimens.xml
  29. +10
    -0
      app/src/main/res/values-zh-rCN/strings.xml
  30. +2
    -0
      app/src/main/res/values/dimens.xml
  31. +10
    -0
      app/src/main/res/values/strings.xml
  32. +39
    -1
      app/src/main/res/xml/prefs_system.xml
  33. +1
    -0
      build.gradle
  34. +1
    -1
      last_build

+ 5
- 0
.idea/jarRepositories.xml View File

@ -21,5 +21,10 @@
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
</component>
</project>

+ 16
- 2
CHANGELOG_EN View File

@ -1,10 +1,24 @@
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:
[MIUI 12] Control center compatibility:
Show illuminance level
Show brightness percentage
Deactivate brightness slider
@ -16,7 +30,7 @@ Revert changes introduced in 3.0.2 that break some system mods
[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][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


+ 16
- 2
CHANGELOG_RU View File

@ -1,5 +1,19 @@
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.2, которые делают некоторые системные моды нерабочими
3.0.4
[Исправлено][Подробный индикатор скорости соединения] Отображение корректных значений при активном VPN
@ -16,7 +30,7 @@
[Новое][MIUI 12] Перманентные плавающие окна: запоминание состояния, позиции и размеров
[Новое][MIUI 12] Разрешить открывать любое приложение в плавающем окне
[Улучшено][Размытие фона списка последних приложений] Совместимость со списком из Рабочего стола MIUI
[Исправлено][Действие открытия Быстрых Настроек][MIUI 12] Также открывать центр управления
[Исправлено][Действие открытия Быстрых Настроек][MIUI 12] Также открывать Центр управления
[Исправлено][Подробный индикатор скорости соединения] Совместимость с Android 7.1
[Исправлено][Пользовательские действия на локскрине] Совместимость с Android 7.1
[Исправлено][MIUI 12] Вылет настроек модуля на бета прошивках


+ 5
- 4
app/build.gradle View File

@ -22,8 +22,8 @@ android {
minSdkVersion 24
//noinspection ExpiredTargetSdkVersion
targetSdkVersion 27
versionCode 60
versionName "3.0.5"
versionCode 61
versionName "3.0.6"
signingConfig signingConfigs.dev
}
buildTypes {
@ -59,8 +59,9 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "ch.acra:acra-core:$acraVersion"
implementation 'com.android.billingclient:billing:3.0.1'
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.3.72'
implementation 'com.android.billingclient:billing:3.0.2'
//noinspection DifferentStdlibGradleVersion
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.21'
implementation 'com.github.jinatonic.confetti:confetti:1.1.2'
implementation files('libs/WeatherView-2.0.3.aar')
compileOnly 'de.robv.android.xposed:api:82'


+ 19
- 3
app/src/main/java/name/mikanoshi/customiuizer/MainModule.java View File

@ -76,6 +76,7 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
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("various_gboardpadding_port", 0) > 0 || mPrefs.getInt("various_gboardpadding_land", 0) > 0) Various.GboardPaddingHook();
if (mPrefs.getBoolean("system_colorizenotiftitle")) System.ColorizedNotificationTitlesHook();
if (mPrefs.getBoolean("system_nopassword")) System.NoPasswordHook();
@ -233,7 +234,6 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("system_popupnotif")) System.PopupNotificationsHook(lpparam);
if (mPrefs.getBoolean("system_betterpopups_nohide")) System.BetterPopupsNoHideHook(lpparam);
if (mPrefs.getBoolean("system_betterpopups_swipedown")) System.BetterPopupsSwipeDownHook(lpparam);
if (mPrefs.getBoolean("system_betterpopups_allowfloat") && Helpers.is12()) System.BetterPopupsAllowFloatHook(lpparam);
if (mPrefs.getBoolean("system_hidemoreicon")) System.NoMoreIconHook(lpparam);
if (mPrefs.getBoolean("system_notifafterunlock")) System.ShowNotificationsAfterUnlockHook(lpparam);
if (mPrefs.getBoolean("system_notifrowmenu")) System.NotificationRowMenuHook(lpparam);
@ -247,7 +247,6 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("system_batteryindicator")) System.BatteryIndicatorHook(lpparam);
if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationHook();
if (mPrefs.getBoolean("system_lockscreenshortcuts")) System.LockScreenShortcutHook(lpparam);
if (mPrefs.getBoolean("system_notifmediaseekbar") && !Helpers.is12()) System.MediaNotificationSeekBarSysUIHook(lpparam);
if (mPrefs.getBoolean("system_4gtolte")) System.Network4GtoLTEHook(lpparam);
if (mPrefs.getBoolean("system_showlux")) System.BrightnessLuxHook(lpparam);
if (mPrefs.getBoolean("system_showpct")) System.BrightnessPctHook(lpparam);
@ -269,6 +268,7 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
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_fw_splitscreen")) System.MultiWindowPlusNativeHook(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);
@ -290,8 +290,18 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getStringAsInt("system_inactivebrightness", 1) > 1) System.InactiveBrightnessSliderHook(lpparam);
if (mPrefs.getStringAsInt("system_mobiletypeicon", 1) > 1) System.HideNetworkTypeHook(lpparam);
if (mPrefs.getStringAsInt("system_statusbaricons_bluetooth", 1) > 1) System.HideIconsBluetoothHook(lpparam);
if (mPrefs.getStringAsInt("system_maxsbicons", 0) != 0 && Helpers.is12()) System.MaxNotificationIconsHook(lpparam);
if (hideIconsActive) System.HideIconsHook(lpparam);
if (Helpers.is12()) {
if (mPrefs.getInt("system_messagingstylelines", 0) > 0) System.MessagingStyleLinesHook(lpparam);
if (mPrefs.getBoolean("system_betterpopups_allowfloat")) System.BetterPopupsAllowFloatHook(lpparam);
if (mPrefs.getBoolean("system_securecontrolcenter")) System.SecureControlCenterHook(lpparam);
if (mPrefs.getBoolean("system_minimalnotifview")) System.MinimalNotificationViewHook(lpparam);
if (mPrefs.getBoolean("system_notifchannelsettings")) System.NotificationChannelSettingsHook(lpparam);
if (mPrefs.getStringAsInt("system_maxsbicons", 0) != 0) System.MaxNotificationIconsHook(lpparam);
} else {
if (mPrefs.getBoolean("system_notifmediaseekbar")) System.MediaNotificationSeekBarSysUIHook(lpparam);
}
}
if (pkg.equals("com.android.incallui")) {
@ -328,6 +338,10 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("various_installappinfo")) Various.AppInfoDuringMiuiInstallHook(lpparam);
}
if (pkg.equals("org.meowcat.edxposed.manager")) {
GlobalActions.miuizerEdXposedManagerInit(lpparam);
}
final boolean isLauncherPkg = pkg.equals("com.miui.home") || pkg.equals("com.mi.android.globallauncher");
final boolean isLauncherPerf = mPrefs.getBoolean("launcher_compat");
final boolean isStatusBarColor = mPrefs.getBoolean("system_statusbarcolor") && !mPrefs.getStringSet("system_statusbarcolor_apps").contains(pkg);
@ -383,6 +397,8 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
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_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);


+ 18
- 0
app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java View File

@ -225,6 +225,14 @@ public class SubFragment extends PreferenceFragmentBase {
}
};
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) {
@ -322,6 +330,16 @@ public class SubFragment extends PreferenceFragmentBase {
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);


+ 1
- 1
app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java View File

@ -314,7 +314,7 @@ public class Dialog extends Activity {
xposedLog = sb.toString();
} catch (Throwable t) {
debugLog.append("Error reading log: ").append(t.getMessage()).append("\n");
} else debugLog.append("No accessble Xposed log found!\n");
} else debugLog.append("No accessible Xposed log found!\n");
if (sdcardLog.exists()) sdcardLog.delete();
} catch (Throwable t) {}


+ 1
- 2
app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java View File

@ -2,7 +2,6 @@ package name.mikanoshi.customiuizer.mods;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@ -273,7 +272,7 @@ public class Controls {
Helpers.findAndHookMethod("android.media.MediaPlayer", null, "pause", new MethodHook() {
@Override
protected void before(final MethodHookParam param) throws Throwable {
Application mContext = (Application)XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", null), "currentApplication");
Context mContext = Helpers.findContext();
int mStreamType = (int)XposedHelpers.findMethodExact(XposedHelpers.findClass("android.media.MediaPlayer", null), "getAudioStreamType").invoke(param.thisObject);
if (mContext != null && (mStreamType == AudioManager.STREAM_MUSIC || mStreamType == 0x80000000)) {
Intent intent = new Intent(GlobalActions.ACTION_PREFIX + "SaveLastMusicPausedTime");


+ 51
- 18
app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java View File

@ -12,10 +12,12 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
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;
@ -33,6 +35,7 @@ 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;
@ -44,7 +47,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
@ -158,24 +160,22 @@ public class GlobalActions {
Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL);
}
if (action.equals(ACTION_PREFIX + "CollectLogs")) {
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);
}
if (action.equals(ACTION_PREFIX + "CollectLogs")) 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")) {
@ -662,6 +662,39 @@ public class GlobalActions {
Helpers.emptyFile(lpparam.appInfo.dataDir + "/files/uncaught_exceptions", false);
}
public static void miuizerEdXposedManagerInit(LoadPackageParam lpparam) {
Helpers.hookAllMethodsSilently("org.meowcat.edxposed.manager.ModulesFragment$ModuleAdapter", lpparam.classLoader, "getView", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
View view = (View)param.getResult();
if (view == null) return;
TextView pkgName = view.findViewById(view.getResources().getIdentifier("package_name", "id", "org.meowcat.edxposed.manager"));
TextView title = view.findViewById(view.getResources().getIdentifier("title", "id", "org.meowcat.edxposed.manager"));
if (title == null) return;
Boolean tag = (Boolean)title.getTag();
if (Helpers.modulePkg.contentEquals(pkgName.getText())) {
if (tag == null || !tag) {
title.setTag(true);
title.setTypeface(title.getTypeface(), Typeface.BOLD);
if (title.getLayout() == null)
title.measure(View.MeasureSpec.makeMeasureSpec(title.getResources().getDisplayMetrics().widthPixels, View.MeasureSpec.AT_MOST), 0);
int baseColor = (title.getCurrentTextColor() & 0x00FFFFFF) | 0xFF000000;
title.getPaint().setShader(new LinearGradient(
(int)title.getLayout().getPrimaryHorizontal(5), 0,
(int)title.getLayout().getPrimaryHorizontal(9), 0,
new int[]{ baseColor, 0xFFFE9D8C, 0xFFFD7ABD, 0xFFE178E0, 0xFFD375F6, 0xFF9190F5, 0xFF5FA2FD, baseColor },
new float[]{ 0.0f, 0.01f, 0.2f, 0.4f, 0.6f, 0.8f, 0.99f, 1.0f }, Shader.TileMode.CLAMP)
);
}
} else if (tag != null) {
title.setTag(null);
title.setTypeface(title.getTypeface(), Typeface.NORMAL);
title.getPaint().setShader(null);
}
}
});
}
private static int settingsIconResId;
public static void miuizerSettingsResInit() {
settingsIconResId = MainModule.resHooks.addResource("ic_miuizer_settings", Helpers.is11() ? R.drawable.ic_miuizer_settings11 : R.drawable.ic_miuizer_settings10);


+ 7
- 7
app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java View File

@ -1422,14 +1422,14 @@ public class Launcher {
}
});
Helpers.hookAllMethods("com.miui.home.launcher.common.Utilities", lpparam.classLoader, "startBlurAnim", new MethodHook() {
@Override
protected void before(MethodHookParam param) throws Throwable {
param.args[2] = (float)param.args[2] * MainModule.mPrefs.getInt("system_recents_blur", 100) / 100f;
}
});
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.findAndHookMethod("com.miui.home.launcher.common.Utilities", lpparam.classLoader, "fastBlur", float.class, Window.class, new MethodHook() {
Helpers.hookAllMethods(utilsClass, "fastBlur", 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;


+ 330
- 74
app/src/main/java/name/mikanoshi/customiuizer/mods/System.java View File

@ -8,7 +8,6 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.Application;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.app.MiuiNotification;
@ -399,6 +398,20 @@ public class System {
return false;
}
private static boolean isUnlocked(Context mContext, ClassLoader classLoader) {
Class<?> kmvClas = findClass("com.android.systemui.keyguard.KeyguardViewMediator", classLoader);
XposedHelpers.setAdditionalStaticField(kmvClas, "isScreenLockDisabled", false);
if (!isAuthOnce()) return false;
int opt = MainModule.mPrefs.getStringAsInt("system_noscreenlock", 1);
if (forcedOption == 1) opt = 2;
boolean isTrusted = false;
if (opt == 3) isTrusted = isTrusted(mContext, classLoader);
if (opt == 2 || opt == 3 && isTrusted) {
XposedHelpers.setAdditionalStaticField(kmvClas, "isScreenLockDisabled", true);
return true;
} else return false;
}
private static void checkBTConnections(Context mContext) {
if (mContext == null)
Helpers.log("checkBTConnections", "mContext is NULL!");
@ -464,25 +477,18 @@ public class System {
@Override
protected void before(MethodHookParam param) throws Throwable {
if (forcedOption == 0) return;
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
if (!isAuthOnce()) return;
int opt = MainModule.mPrefs.getStringAsInt("system_noscreenlock", 1);
if (forcedOption == 1) opt = 2;
boolean isTrusted = false;
if (opt == 3) isTrusted = isTrusted(mContext, lpparam.classLoader);
if (opt == 2 || opt == 3 && isTrusted) {
boolean skip = MainModule.mPrefs.getBoolean("system_noscreenlock_skip");
if (skip) {
param.setResult(null);
XposedHelpers.callMethod(param.thisObject, "keyguardDone");
}
isUnlockedInnerCall = true;
XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mUpdateMonitor"), "reportSuccessfulStrongAuthUnlockAttempt");
Intent unlockIntent = new Intent(ACTION_PREFIX + "UnlockStrongAuth");
mContext.sendBroadcast(unlockIntent);
if (!isUnlocked(mContext, lpparam.classLoader)) return;
boolean skip = MainModule.mPrefs.getBoolean("system_noscreenlock_skip");
if (skip) {
param.setResult(null);
XposedHelpers.callMethod(param.thisObject, "keyguardDone");
}
isUnlockedInnerCall = true;
XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mUpdateMonitor"), "reportSuccessfulStrongAuthUnlockAttempt");
Intent unlockIntent = new Intent(ACTION_PREFIX + "UnlockStrongAuth");
mContext.sendBroadcast(unlockIntent);
}
});
@ -510,6 +516,7 @@ public class System {
if (MainModule.mPrefs.getStringAsInt("system_noscreenlock", 1) == 3)
if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo netInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (netInfo.getState() != NetworkInfo.State.CONNECTED && netInfo.getState() != NetworkInfo.State.DISCONNECTED) return;
if (netInfo.isConnected()) isTrusted = isTrustedWiFi(mContext);
} else if (action.equals(ACTION_PREFIX + "UnlockBTConnection")) {
isTrusted = isTrustedBt(lpparam.classLoader);
@ -518,6 +525,7 @@ public class System {
if (forcedOption == 0) isTrusted = false;
else if (forcedOption == 1) isTrusted = true;
XposedHelpers.setAdditionalStaticField(param.thisObject, "isScreenLockDisabled", isTrusted);
if (isTrusted) {
boolean skip = MainModule.mPrefs.getBoolean("system_noscreenlock_skip");
if (skip)
@ -528,6 +536,16 @@ public class System {
XposedHelpers.callMethod(XposedHelpers.getObjectField(param.thisObject, "mUpdateMonitor"), "reportSuccessfulStrongAuthUnlockAttempt");
Intent unlockIntent = new Intent(ACTION_PREFIX + "UnlockStrongAuth");
mContext.sendBroadcast(unlockIntent);
} else try {
Object mStatusBar = XposedHelpers.getObjectField(param.thisObject, "mStatusBar");
if (mStatusBar == null) return;
XposedHelpers.callMethod(mStatusBar, "updatePublicMode");
boolean isAnyProfilePublicMode = (boolean)XposedHelpers.callMethod(mStatusBar, "isAnyProfilePublicMode");
Object mStackScroller = XposedHelpers.getObjectField(mStatusBar, "mStackScroller");
XposedHelpers.callMethod(mStackScroller, "setHideSensitive", isAnyProfilePublicMode, true);
XposedHelpers.callMethod(mStatusBar, "updateNotificationViewsOnly");
} catch (Throwable t) {
XposedBridge.log(t);
}
}
}, filter);
@ -566,17 +584,10 @@ public class System {
@Override
protected void after(MethodHookParam param) throws Throwable {
if (forcedOption == 0) return;
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
boolean skip = MainModule.mPrefs.getBoolean("system_noscreenlock_skip");
if (skip) return;
if (!isAuthOnce()) return;
int opt = MainModule.mPrefs.getStringAsInt("system_noscreenlock", 1);
if (forcedOption == 1) opt = 2;
boolean isTrusted = false;
if (opt == 3) isTrusted = isTrusted(mContext, lpparam.classLoader);
if (opt == 1 || opt == 3 && !isTrusted) return;
if (!isUnlocked(mContext, lpparam.classLoader)) return;
Class<?> securityModeEnum = XposedHelpers.findClass("com.android.keyguard.KeyguardSecurityModel$SecurityMode", lpparam.classLoader);
Object securityModeNone = XposedHelpers.getStaticObjectField(securityModeEnum, "None");
@ -592,6 +603,37 @@ public class System {
}
});
String startClassName = Helpers.is12() ? "com.android.keyguard.faceunlock.FaceUnlockManager" : "com.android.keyguard.KeyguardUpdateMonitor";
Class<?> startClass = findClassIfExists(startClassName, lpparam.classLoader);
if (startClass == null) Helpers.log("NoScreenLockHook", "Face unlock class not found");
if (startClass != null) {
Helpers.hookAllMethods(startClass, "startFaceUnlock", new MethodHook() {
@Override
protected void before(MethodHookParam param) throws Throwable {
if (Helpers.is12() && 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);
}
});
Method showMsgMethod = findMethodExactIfExists(startClass, "isShowMessageWhenFaceUnlockSuccess");
if (showMsgMethod == null) findMethodExactIfExists(startClass, "isFaceUnlockSuccessAndShowMessage");
if (showMsgMethod == null) {
Helpers.log("NoScreenLockHook", "Show notification message method not found");
} else {
Helpers.hookAllMethods(startClass, showMsgMethod.getName(), new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
if (!(boolean)param.getResult()) return;
boolean isScreenLockDisabled = (boolean)XposedHelpers.getAdditionalStaticField(findClass("com.android.systemui.keyguard.KeyguardViewMediator", lpparam.classLoader), "isScreenLockDisabled");
if (isScreenLockDisabled) param.setResult(false);
}
});
}
}
Helpers.hookAllConstructors("com.android.systemui.statusbar.policy.BluetoothControllerImpl", lpparam.classLoader, new MethodHook(10) {
@Override
protected void after(MethodHookParam param) {
@ -1995,11 +2037,12 @@ public class System {
// });
}
public static int abHeight = 39;
public static void CompactNotificationsRes() {
int height = 39;
MainModule.resHooks.setDensityReplacement("android", "dimen", "notification_action_height", height);
MainModule.resHooks.setDensityReplacement("android", "dimen", "android_notification_action_height", height);
MainModule.resHooks.setDensityReplacement("android", "dimen", "notification_action_list_height", height);
MainModule.resHooks.setDensityReplacement("android", "dimen", "notification_action_height", abHeight);
MainModule.resHooks.setDensityReplacement("android", "dimen", "android_notification_action_height", abHeight);
MainModule.resHooks.setDensityReplacement("android", "dimen", "notification_action_list_height", abHeight);
MainModule.resHooks.setDensityReplacement("com.android.systemui", "dimen", "notification_row_extra_padding", 0);
}
@ -2016,7 +2059,7 @@ public class System {
FrameLayout container = mView.findViewById(mView.getResources().getIdentifier("actions_container", "id", "android"));
if (container == null) return;
float density = mView.getResources().getDisplayMetrics().density;
int height = Math.round(density * 39);
int height = Math.round(density * abHeight);
ViewGroup actions = (ViewGroup)container.getChildAt(0);
FrameLayout.LayoutParams lp1 = (FrameLayout.LayoutParams)actions.getLayoutParams();
lp1.height = height;
@ -2032,18 +2075,29 @@ public class System {
}
});
if (Helpers.is12())
Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.NotificationTemplateViewWrapper$GoogleStyleProcessor", lpparam.classLoader, "setGoogleContentMargins", View.class, new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
View view = (View)param.args[0];
FrameLayout container = view.findViewById(view.getResources().getIdentifier("actions_container", "id", "android"));
if (container == null || container.getVisibility() != View.VISIBLE) return;
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
lp.bottomMargin = 0;
view.setLayoutParams(lp);
}
});
if (Helpers.is12()) {
MethodHook hook = new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
View view = (View)param.args[0];
FrameLayout container = view.findViewById(view.getResources().getIdentifier("actions_container", "id", "android"));
if (container == null || container.getVisibility() != View.VISIBLE) return;
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
if ("MiuiStyleProcessor".equals(param.thisObject.getClass().getSimpleName())) {
float density = container.getResources().getDisplayMetrics().density;
lp.bottomMargin = Math.round(lp.bottomMargin * 0.666f);
ViewGroup.LayoutParams lpc = container.getLayoutParams();
lpc.height = Math.round(density * abHeight);
container.setLayoutParams(lpc);
} else {
lp.bottomMargin = 0;
}
view.setLayoutParams(lp);
}
};
Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.NotificationTemplateViewWrapper$GoogleStyleProcessor", lpparam.classLoader, "setGoogleContentMargins", View.class, hook);
Helpers.findAndHookMethod("com.android.systemui.statusbar.notification.NotificationTemplateViewWrapper$MiuiStyleProcessor", lpparam.classLoader, "setMiuiContentMargins", View.class, hook);
}
}
public static void HideFromRecentsHook(LoadPackageParam lpparam) {
@ -3665,29 +3719,29 @@ public class System {
protected void after(MethodHookParam param) throws Throwable {
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
if (mContext != null)
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
boolean mConnected = intent.getBooleanExtra("connected", false);
if (mConnected && mConnected != mUSBConnected) try {
int mPlugType = XposedHelpers.getIntField(param.thisObject, "mPlugType");
if (mPlugType != BatteryManager.BATTERY_PLUGGED_USB) return;
String func = MainModule.mPrefs.getString("system_defaultusb", "none");
if ("none".equals(func) || "1".equals(func)) return;
UsbManager usbMgr = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
if ((boolean)XposedHelpers.callMethod(usbMgr, "isFunctionEnabled", func))
return;
XposedHelpers.callMethod(usbMgr, "setCurrentFunction", func, MainModule.mPrefs.getBoolean("system_defaultusb_unsecure"));
} catch (Throwable t) {
XposedBridge.log(t);
}
mUSBConnected = mConnected;
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
boolean mConnected = intent.getBooleanExtra("connected", false);
if (mConnected && mConnected != mUSBConnected) try {
int mPlugType = XposedHelpers.getIntField(param.thisObject, "mPlugType");
if (mPlugType != BatteryManager.BATTERY_PLUGGED_USB) return;
String func = MainModule.mPrefs.getString("system_defaultusb", "none");
if ("none".equals(func) || "1".equals(func)) return;
UsbManager usbMgr = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
if ((boolean)XposedHelpers.callMethod(usbMgr, "isFunctionEnabled", func))
return;
XposedHelpers.callMethod(usbMgr, "setCurrentFunction", func, MainModule.mPrefs.getBoolean("system_defaultusb_unsecure"));
} catch (Throwable t) {
XposedBridge.log(t);
}
mUSBConnected = mConnected;
} catch (Throwable t) {
XposedBridge.log(t);
}
}, new IntentFilter("android.hardware.usb.action.USB_STATE"));
}
}, new IntentFilter("android.hardware.usb.action.USB_STATE"));
}
});
@ -4566,7 +4620,10 @@ public class System {
try {
int align = MainModule.mPrefs.getStringAsInt("system_lockscreenshortcuts_left_align", 2);
int margin = Math.round(mContext.getResources().getDisplayMetrics().density * 40);
lp.topMargin = lp.bottomMargin;
if (lp.topMargin < margin) lp.topMargin = margin;
if (lp.bottomMargin < margin) lp.bottomMargin = margin;
lp.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
if (align == 1)
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
@ -6664,12 +6721,16 @@ public class System {
// }
// });
// Helpers.findAndHookMethod(Math.class, "min", int.class, int.class, new MethodHook() {
// for (Member method: Math.class.getMethods())
// if (method.getName().equals("min")) XposedBridge.log("min method found! " + method);
// Set<XC_MethodHook.Unhook> unhooks = XposedBridge.hookAllMethods(Math.class, "min", new MethodHook() {
// @Override
// protected void before(MethodHookParam param) throws Throwable {
// XposedBridge.log("Math.min: " + param.args[0] + ", " + param.args[1]);
// XposedBridge.log("Math.min: " + param.args[1].getClass().getSimpleName() + ", " + param.args[1]);
// }
// });
// XposedBridge.log("unhooks: " + unhooks.size());
}
public static void MoreNotificationsHook(LoadPackageParam lpparam) {
@ -6799,7 +6860,7 @@ public class System {
@Override
protected void after(MethodHookParam param) throws Throwable {
SparseArray<SoundData> mSourceSoundData = (SparseArray<SoundData>)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData");
Application callerContext = (Application)XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", null), "currentApplication");
Context callerContext = Helpers.findContext();
if (callerContext == null) return;
String caller = callerContext.getPackageName();
if (param.args[0] instanceof Context) {
@ -6816,7 +6877,7 @@ public class System {
protected void before(MethodHookParam param) throws Throwable {
SparseArray<SoundData> mSourceSoundData = (SparseArray<SoundData>)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData");
if (mSourceSoundData != null) {
Application mContext = (Application)XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", null), "currentApplication");
Context mContext = Helpers.findContext();
if (mContext == null) return;
SoundData data = mSourceSoundData.get((Integer)param.args[0]);
SavePlayedSound(mContext, data);
@ -6830,7 +6891,7 @@ public class System {
@Override
protected void before(MethodHookParam param) throws Throwable {
if (Modifier.isPrivate(param.method.getModifiers())) return;
Application callerContext = (Application)XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", null), "currentApplication");
Context callerContext = Helpers.findContext();
if (callerContext == null) return;
String caller = callerContext.getPackageName();
SoundData soundData = null;
@ -6848,7 +6909,7 @@ public class System {
protected void before(MethodHookParam param) throws Throwable {
SoundData mSourceSoundData = (SoundData)XposedHelpers.getAdditionalInstanceField(param.thisObject, "mSourceSoundData");
if (mSourceSoundData != null) {
Application mContext = (Application)XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", null), "currentApplication");
Context mContext = Helpers.findContext();
if (mContext == null) return;
SavePlayedSound(mContext, mSourceSoundData);
Set<String> silencedSounds = Helpers.getSharedStringSetPref(mContext, "pref_key_system_audiosilencer_sounds");
@ -6865,10 +6926,16 @@ public class System {
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
Handler mHandler = (Handler)XposedHelpers.getObjectField(param.thisObject, "mHandler");
new Helpers.SharedPrefObserver(mContext, mHandler, "pref_key_system_betterpopups_allowfloat_apps") {
new Helpers.SharedPrefObserver(mContext, mHandler) {
@Override
public void onChange(String name) {
MainModule.mPrefs.put(name, Helpers.getSharedStringSetPref(mContext, name));
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);
}
}
};
}
@ -6880,9 +6947,10 @@ public class System {
Object notification = XposedHelpers.callMethod(param.args[1], "getNotification");
PendingIntent intent = (PendingIntent)XposedHelpers.callMethod(param.thisObject, "getIntent", notification);
if (intent == null) return;
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
Set<String> selectedApps = Helpers.getSharedStringSetPref(mContext, "pref_key_system_betterpopups_allowfloat_apps");
Set<String> selectedApps = MainModule.mPrefs.getStringSet("system_betterpopups_allowfloat_apps");
Set<String> selectedAppsBlack = MainModule.mPrefs.getStringSet("system_betterpopups_allowfloat_apps_black");
if (selectedApps.contains(intent.getCreatorPackage())) param.setResult(true);
else if (selectedAppsBlack.contains(intent.getCreatorPackage())) param.setResult(false);
}
});
}
@ -7036,7 +7104,22 @@ public class System {
Helpers.findAndHookMethod("com.android.server.wm.ActivityTaskManagerService", lpparam.classLoader, "onSystemReady", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
restoreFwAppsInSetting((Context)XposedHelpers.getObjectField(param.thisObject, "mContext"));
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
String pkgName = intent.getStringExtra("package");
if (pkgName != null) {
fwApps.put(pkgName, new Pair<Float, Rect>(0f, null));
storeFwAppsInSetting(mContext);
}
} catch (Throwable t) {
XposedBridge.log(t);
}
}
}, new IntentFilter(ACTION_PREFIX + "RememberFloatingWindow"));
restoreFwAppsInSetting(mContext);
}
});
@ -7053,6 +7136,179 @@ public class System {
});
}
public static void StickyFloatingWindowsLauncherHook(LoadPackageParam lpparam) {
Helpers.hookAllMethods("com.miui.home.smallwindow.BaseDelegateAdapter", lpparam.classLoader, "startFreeformActivity",new MethodHook() {
@Override
protected void before(MethodHookParam param) throws Throwable {
String pkgName = (String)param.args[1];
if (pkgName == null) return;
Intent intent = new Intent(ACTION_PREFIX + "RememberFloatingWindow");
intent.putExtra("package", pkgName);
((Context)param.args[0]).sendBroadcast(intent);
}
});
}
public static void MessagingStyleLinesSysHook() {
Helpers.findAndHookMethod("android.app.Notification.MessagingStyle", null, "makeMessagingView", boolean.class, boolean.class, 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));
}
});
}
public static void MessagingStyleLinesHook(LoadPackageParam lpparam) {
Helpers.hookAllConstructors("com.android.systemui.statusbar.notification.NotificationMessagingTemplateViewWrapper", lpparam.classLoader, 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));
}
});
}
public static void MultiWindowPlusNativeHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.android.systemui.recents.views.RecentMenuView", lpparam.classLoader, "onBusEvent", "com.android.systemui.recents.events.activity.ShowTaskMenuEvent", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
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);
}
});
// Helpers.findAndHookMethod("com.android.systemui.recents.RecentsActivity", lpparam.classLoader, "updateDockBtnVisible", new MethodHook() {
// @Override
// protected void after(MethodHookParam param) throws Throwable {
// View mDockBtn = (View)XposedHelpers.getObjectField(param.thisObject, "mDockBtn");
// mDockBtn.setVisibility(View.VISIBLE);
// }
// });
}
public static void MultiWindowPlusHook(LoadPackageParam lpparam) {
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);
}
});
}
public static void SecureControlCenterHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateKeyguardState", boolean.class, boolean.class, new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
Object mStatusBarWindow = XposedHelpers.callMethod(param.thisObject, "getStatusBarWindow");
if (mStatusBarWindow == null) return;
Object mControllerPanel = XposedHelpers.getObjectField(mStatusBarWindow, "mControllerPanel");
if (mControllerPanel == null) return;
Object mControlCenter = XposedHelpers.getObjectField(mControllerPanel, "mControlCenter");
if (mControlCenter == null) return;
KeyguardManager kgMgr = (KeyguardManager)XposedHelpers.getObjectField(param.thisObject, "mKeyguardManager");
XposedHelpers.setAdditionalInstanceField(mControlCenter, "isOnSecureKeyguard", kgMgr.isKeyguardLocked() && kgMgr.isKeyguardSecure());
}
});
Helpers.hookAllMethods("com.android.systemui.miui.statusbar.ControlCenter", lpparam.classLoader, "panelEnabled", new MethodHook() {
@Override
@SuppressWarnings("ConstantConditions")
protected void before(MethodHookParam param) throws Throwable {
boolean isOnSecureKeyguard = false;
try { isOnSecureKeyguard = (boolean)XposedHelpers.getAdditionalInstanceField(param.thisObject, "isOnSecureKeyguard"); } catch (Throwable ignore) {}
if (isOnSecureKeyguard) param.setResult(false);
}
});
}
public static void MinimalNotificationViewHook(LoadPackageParam lpparam) {
Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "updateNotification", 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]);
}
});
}
public static void NotificationChannelSettingsHook(LoadPackageParam lpparam) {
Helpers.hookAllMethods("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader, "onClickMenuSettings", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
if ((boolean)param.args[2]) return;
Object entry = XposedHelpers.callMethod(param.args[0], "getEntry");
String id = (String)XposedHelpers.callMethod(XposedHelpers.getObjectField(entry, "channel"), "getId");
if ("miscellaneous".equals(id)) return;
Object notification = XposedHelpers.getObjectField(entry, "notification");
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;
int user;
if ((boolean)XposedHelpers.callMethod(notification, "isSubstituteNotification")) {
pkgName = (String)XposedHelpers.callMethod(notification, "getBasePkg");
user = -1;
} else {
pkgName = (String)XposedHelpers.callMethod(notification, "getPackageName");
user = (int)XposedHelpers.callMethod(notification, "getAppUid");
}
Intent intent = new Intent("android.intent.action.MAIN");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName("com.android.settings", "com.android.settings.Settings$ChannelNotificationSettingsActivity");
intent.putExtra("package", pkgName);
intent.putExtra("android.provider.extra.CHANNEL_ID", id);
intent.putExtra("uid", user);
try {
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, android.os.Process.myUserHandle());
} catch (Throwable ignore) {}
}
});
}
public static void SkipAppLockHook(LoadPackageParam lpparam) {
Helpers.hookAllMethods("com.miui.server.AccessController", lpparam.classLoader, "skipActivity", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
XposedBridge.log("skipActivity: " + param.args[0]);
// Intent intent = (Intent)param.args[0];
// if (intent != null) {
// param.setResult(true);
// }
}
});
}
// @SuppressWarnings("unchecked")
// public static void MultiWindowHook() {
// HashMap<String, Integer> sAppList = (HashMap<String, Integer>)XposedHelpers.getStaticObjectField(findClass("android.util.MiuiMultiWindowUtils", null), "sAppList");


+ 5
- 2
app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java View File

@ -53,8 +53,11 @@ public class PreferenceEx extends Preference implements PreferenceState {
valSummary.setVisibility(customSummary != null || countAsSummary ? View.VISIBLE : View.GONE);
if (customSummary != null)
valSummary.setText(customSummary);
else
valSummary.setText(countAsSummary ? String.valueOf(Helpers.prefs.getStringSet(getKey(), new LinkedHashSet<String>()).size()) : null);
else if (countAsSummary) {
int count = Helpers.prefs.getStringSet(getKey(), new LinkedHashSet<String>()).size() + Helpers.prefs.getStringSet(getKey() + "_black", new LinkedHashSet<String>()).size();
valSummary.setText(String.valueOf(count));
} else
valSummary.setText(null);
if (warning)
title.setTextColor(Helpers.markColor);
else


+ 7
- 1
app/src/main/java/name/mikanoshi/customiuizer/prefs/SeekBarPreference.java View File

@ -20,6 +20,7 @@ public class SeekBarPreference extends Preference implements PreferenceState {
private boolean dynamic;
private boolean newmod = false;
private boolean unsupported = false;
private int mDefaultValue;
private int mMinValue;
@ -102,7 +103,7 @@ public class SeekBarPreference extends Preference implements PreferenceState {
public View getView(View view, ViewGroup parent) {
View finalView = super.getView(view, parent);
TextView mTitle = finalView.findViewById(android.R.id.title);
mTitle.setText(getTitle() + (dynamic ? " ⟲" : ""));
mTitle.setText(getTitle() + (unsupported ? " ⨯" : (dynamic ? " ⟲" : "")));
if (Helpers.is12()) mSeekBar.setAlpha(isEnabled() ? 1.0f : 0.75f);
if (newmod) Helpers.applyNewMod(mTitle);
return finalView;
@ -276,6 +277,11 @@ public class SeekBarPreference extends Preference implements PreferenceState {
Helpers.prefs.edit().putInt(getKey(), getValue()).apply();
}
public void setUnsupported(boolean value) {
unsupported = value;
setEnabled(!value);
}
@Override
public void markAsNew() {
newmod = true;


+ 17
- 2
app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java View File

@ -31,6 +31,7 @@ public class AppSelector extends SubFragmentWithSearch {
boolean initialized = false;
boolean standalone = false;
boolean multi = false;
boolean bwlist = false;
boolean privacy = false;
boolean applock = false;
boolean customTitles = false;
@ -47,6 +48,7 @@ public class AppSelector extends SubFragmentWithSearch {
standalone = getArguments().getBoolean("standalone");
multi = getArguments().getBoolean("multi");
bwlist = getArguments().getBoolean("bw");
privacy = getArguments().getBoolean("privacy");
applock = getArguments().getBoolean("applock");
customTitles = getArguments().getBoolean("custom_titles");
@ -69,7 +71,7 @@ public class AppSelector extends SubFragmentWithSearch {
listView.setAdapter(new AppDataAdapter(context, Helpers.shareAppsList, Helpers.AppAdapterType.Mutli, key));
} else {
if (Helpers.installedAppsList == null) return;
listView.setAdapter(new AppDataAdapter(context, Helpers.installedAppsList, Helpers.AppAdapterType.Mutli, key));
listView.setAdapter(new AppDataAdapter(context, Helpers.installedAppsList, Helpers.AppAdapterType.Mutli, key, bwlist));
}
} else if (privacy) {
if (Helpers.installedAppsList == null) return;
@ -96,7 +98,20 @@ public class AppSelector extends SubFragmentWithSearch {
if (multi && key != null) {
AppData app = (AppData)parent.getAdapter().getItem(position);
Set<String> selectedApps = new LinkedHashSet<String>(Helpers.prefs.getStringSet(key, new LinkedHashSet<String>()));
if (selectedApps.contains(share || openwith ? app.pkgName + "|" + app.user : app.pkgName)) {
if (bwlist) {
Set<String> selectedAppsBlack = new LinkedHashSet<String>(Helpers.prefs.getStringSet(key + "_black", new LinkedHashSet<String>()));
if (selectedApps.contains(app.pkgName)) {
selectedApps.remove(app.pkgName);
selectedAppsBlack.add(app.pkgName);
} else if (selectedAppsBlack.contains(app.pkgName)) {
selectedApps.remove(app.pkgName);
selectedAppsBlack.remove(app.pkgName);
} else {
selectedApps.add(app.pkgName);
selectedAppsBlack.remove(app.pkgName);
}
Helpers.prefs.edit().putStringSet(key + "_black", selectedAppsBlack).apply();
} else if (selectedApps.contains(share || openwith ? app.pkgName + "|" + app.user : app.pkgName)) {
selectedApps.remove(share || openwith ? app.pkgName + "|" + app.user : app.pkgName);
} else {
selectedApps.add(share || openwith ? app.pkgName + "|" + app.user : app.pkgName);


+ 6
- 1
app/src/main/java/name/mikanoshi/customiuizer/subs/System.java View File

@ -216,6 +216,10 @@ public class System extends SubFragment {
((CheckBoxPreferenceEx)findPreference("pref_key_system_notifmediaseekbar")).setChecked(false);
((CheckBoxPreferenceEx)findPreference("pref_key_system_notifmediaseekbar")).setUnsupported(true);
((CheckBoxPreferenceEx)findPreference("pref_key_system_notifmediaseekbar_full")).setUnsupported(true);
} else {
((SeekBarPreference)findPreference("pref_key_system_messagingstylelines")).setUnsupported(true);
((CheckBoxPreferenceEx)findPreference("pref_key_system_minimalnotifview")).setUnsupported(true);
((CheckBoxPreferenceEx)findPreference("pref_key_system_notifchannelsettings")).setUnsupported(true);
}
break;
@ -266,7 +270,7 @@ public class System extends SubFragment {
findPreference("pref_key_system_recommended_fourth").setOnPreferenceClickListener(openRecentsActions);
break;
case "pref_key_system_cat_betterpopups":
findPreference("pref_key_system_betterpopups_allowfloat_apps").setOnPreferenceClickListener(openAppsEdit);
findPreference("pref_key_system_betterpopups_allowfloat_apps").setOnPreferenceClickListener(openAppsBWEdit);
if (!Helpers.is12())
((CheckBoxPreferenceEx)findPreference("pref_key_system_betterpopups_allowfloat")).setUnsupported(true);
@ -334,6 +338,7 @@ public class System extends SubFragment {
});
((CheckBoxPreferenceEx)findPreference("pref_key_system_credentials")).setChecked(getActivity().getPackageManager().getComponentEnabledSetting(new ComponentName(getActivity(), CredentialsLauncher.class)) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
if (!Helpers.is12()) ((CheckBoxPreferenceEx)findPreference("pref_key_system_securecontrolcenter")).setUnsupported(true);
break;
case "pref_key_system_cat_other":


+ 28
- 8
app/src/main/java/name/mikanoshi/customiuizer/utils/AppDataAdapter.java View File

@ -39,8 +39,10 @@ public class AppDataAdapter extends BaseAdapter implements Filterable {
private final CopyOnWriteArrayList<AppData> filteredAppList = new CopyOnWriteArrayList<AppData>();
private String key = null;
private String selectedApp;
private boolean bwlist = false;
private int selectedUser = 0;
private Set<String> selectedApps = new LinkedHashSet<String>();
private Set<String> selectedAppsBlack = new LinkedHashSet<String>();
private Helpers.AppAdapterType aType = Helpers.AppAdapterType.Default;
private boolean multiUserSupport = false;
@ -54,11 +56,17 @@ public class AppDataAdapter extends BaseAdapter implements Filterable {
}
public AppDataAdapter(Context context, ArrayList<AppData> arr, Helpers.AppAdapterType adapterType, String prefKey) {
this(context, arr, adapterType, prefKey, false);
}
public AppDataAdapter(Context context, ArrayList<AppData> arr, Helpers.AppAdapterType adapterType, String prefKey, boolean isBW) {
this(context, arr);
key = prefKey;
aType = adapterType;
bwlist = isBW;
if (aType == Helpers.AppAdapterType.Mutli) {
selectedApps = Helpers.prefs.getStringSet(key, new LinkedHashSet<String>());
if (bwlist) selectedAppsBlack = Helpers.prefs.getStringSet(key + "_black", new LinkedHashSet<String>());
ArrayList<String> multiUserMods = new ArrayList<String>();
multiUserMods.add("pref_key_system_cleanshare_apps");
multiUserMods.add("pref_key_system_cleanopenwith_apps");
@ -94,9 +102,10 @@ public class AppDataAdapter extends BaseAdapter implements Filterable {
}
public void updateSelectedApps() {
if (aType == Helpers.AppAdapterType.Mutli)
if (aType == Helpers.AppAdapterType.Mutli) {
selectedApps = Helpers.prefs.getStringSet(key, new LinkedHashSet<String>());
else if (aType == Helpers.AppAdapterType.Standalone) {
if (bwlist) selectedAppsBlack = Helpers.prefs.getStringSet(key + "_black", new LinkedHashSet<String>());
} else if (aType == Helpers.AppAdapterType.Standalone) {
selectedApp = Helpers.prefs.getString(key, "");
selectedUser = Helpers.prefs.getInt(key + "_user", 0);
}
@ -107,12 +116,17 @@ public class AppDataAdapter extends BaseAdapter implements Filterable {
return (!multiUserSupport && (selectedApps.contains(pkgName) || selectedApps.contains(pkgName + "|0"))) || (multiUserSupport && selectedApps.contains(pkgName + "|" + user));
}
private boolean shouldSelectBW(String pkgName) {
return selectedApps.contains(pkgName) || selectedAppsBlack.contains(pkgName);
}
private void sortList() {
filteredAppList.sort(new Comparator<AppData>() {
public int compare(AppData app1, AppData app2) {
if (aType == Helpers.AppAdapterType.Mutli && selectedApps.size() > 0) {
boolean app1checked = shouldSelect(app1.pkgName, app1.user);
boolean app2checked = shouldSelect(app2.pkgName, app2.user);
if (aType == Helpers.AppAdapterType.Mutli) {
if (selectedApps.size() == 0 && selectedAppsBlack.size() == 0) return 0;
boolean app1checked = bwlist ? shouldSelectBW(app1.pkgName) : shouldSelect(app1.pkgName, app1.user);
boolean app2checked = bwlist ? shouldSelectBW(app2.pkgName) : shouldSelect(app2.pkgName, app2.user);
if (app1checked && app2checked)
return 0;
else if (app1checked)
@ -161,10 +175,11 @@ public class AppDataAdapter extends BaseAdapter implements Filterable {
ImageView itemIsDis = row.findViewById(R.id.icon_disable);
ImageView itemIsDual = row.findViewById(R.id.icon_dual);
CheckBox itemChecked = row.findViewById(android.R.id.checkbox);
if (itemChecked.getTag() == null || !(boolean)itemChecked.getTag()) {
if (!bwlist && (itemChecked.getTag() == null || !(boolean)itemChecked.getTag())) {
itemChecked.setTag(true);
Helpers.setMiuiCheckbox(itemChecked);
}
ImageView itemStateIcon = row.findViewById(android.R.id.selectedIcon);
TextView itemTitle = row.findViewById(android.R.id.title);
TextView itemSummary = row.findViewById(android.R.id.summary);
ImageView itemIcon = row.findViewById(android.R.id.icon);
@ -197,8 +212,13 @@ public class AppDataAdapter extends BaseAdapter implements Filterable {
if (aType == Helpers.AppAdapterType.Mutli) {
itemSummary.setVisibility(View.GONE);
itemChecked.setVisibility(View.VISIBLE);
itemChecked.setChecked(selectedApps.size() > 0 && shouldSelect(ad.pkgName, ad.user));
if (bwlist) {
itemStateIcon.setVisibility(View.VISIBLE);
itemStateIcon.setImageResource(selectedApps.contains(ad.pkgName) ? R.drawable.icon_action_allow : selectedAppsBlack.contains(ad.pkgName) ? R.drawable.icon_action_disallow : R.drawable.icon_action_default);
} else {
itemChecked.setVisibility(View.VISIBLE);
itemChecked.setChecked(shouldSelect(ad.pkgName, ad.user));
}
itemIsDual.setVisibility(ad.user != 0 ? View.VISIBLE : View.GONE);
} else if (aType == Helpers.AppAdapterType.CustomTitles) {
itemSummary.setText(Helpers.prefs.getString(key + ":" + ad.pkgName + "|" + ad.actName + "|" + ad.user, ""));


+ 67
- 45
app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java View File

<
@ -24,6 +24,7 @@ import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
@ -139,23 +140,25 @@ public class Helpers {
public static boolean showNewMods = true;
public static boolean miuizerModuleActive = false;
public static final HashSet<String> newMods = new HashSet<String>(Arrays.asList(
"pref_key_system_audiosilencer",
"pref_key_system_fw_noblacklist",
"pref_key_system_fw_sticky"
"pref_key_system_fw_splitscreen",
"pref_key_system_securecontrolcenter",
"pref_key_system_messagingstylelines",
"pref_key_system_minimalnotifview",
"pref_key_system_notifchannelsettings"
));
public static final HashMap<String, String> l10nProgress = new HashMap<String, String>() {{
put("ru-RU", "100.0%");
put("zh-CN", "100.0%");
put("id", "13.0%");
put("tr", "96.0%");
put("it", "96.0%");
put("pt-BR", "94.7%");
put("fr", "25.3%");
put("uk-UK", "97.0%");
put("es", "98.5%");
put("id", "12.8%");
put("tr", "95.0%");
put("it", "100.0%");
put("pt-BR", "93.7%");
put("fr", "25.5%");
put("uk-UK", "96.0%");
put("es", "100.0%");
put("sk", "3.1%");
put("cs", "0.0%");
put("de", "96.0%");
put("de", "95.0%");
}};
public static final ArrayList<String> shortcutIcons = new ArrayList<String>();
@ -204,7 +207,7 @@ public class Helpers {
public static void setMiuiTheme(Activity act, int overrideTheme, boolean noBackground) {
int themeResId = 0;
try { themeResId = act.getResources().getIdentifier("Theme.DayNight", "style", "miui"); } catch (Throwable t) {}
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 (!Helpers.is11()) act.getTheme().applyStyle(R.style.ActivityAnimation10, true);