Browse Source

[New] Action: Toggle one-handed mode; resolves #35

[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; resolves #40
- 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
pull/109/head v1.8.0
Mikanoshi 2 years ago
parent
commit
cfb71dceaa
45 changed files with 1383 additions and 330 deletions
  1. +2
    -2
      BUGS_EN
  2. +2
    -2
      BUGS_RU
  3. +25
    -0
      CHANGELOG_EN
  4. +25
    -0
      CHANGELOG_RU
  5. +2
    -2
      app/build.gradle
  6. +3
    -0
      app/src/main/AndroidManifest.xml
  7. BIN
      app/src/main/ic_launcher-web.png
  8. +6
    -0
      app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java
  9. +5
    -1
      app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java
  10. +14
    -3
      app/src/main/java/name/mikanoshi/customiuizer/MainModule.java
  11. +0
    -1
      app/src/main/java/name/mikanoshi/customiuizer/SubFragment.java
  12. +204
    -125
      app/src/main/java/name/mikanoshi/customiuizer/crashreport/Dialog.java
  13. +83
    -8
      app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java
  14. +100
    -1
      app/src/main/java/name/mikanoshi/customiuizer/mods/Launcher.java
  15. +334
    -90
      app/src/main/java/name/mikanoshi/customiuizer/mods/System.java
  16. +191
    -1
      app/src/main/java/name/mikanoshi/customiuizer/mods/Various.java
  17. +9
    -1
      app/src/main/java/name/mikanoshi/customiuizer/subs/ActivitySelector.java
  18. +21
    -12
      app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java
  19. +0
    -22
      app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java
  20. +16
    -5
      app/src/main/java/name/mikanoshi/customiuizer/subs/MultiAction.java
  21. +1
    -1
      app/src/main/java/name/mikanoshi/customiuizer/subs/System.java
  22. +2
    -0
      app/src/main/java/name/mikanoshi/customiuizer/subs/System_Visualizer.java
  23. +1
    -0
      app/src/main/java/name/mikanoshi/customiuizer/utils/AppData.java
  24. +47
    -10
      app/src/main/java/name/mikanoshi/customiuizer/utils/AppDataAdapter.java
  25. +7
    -1
      app/src/main/java/name/mikanoshi/customiuizer/utils/AudioVisualizer.java
  26. +95
    -15
      app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java
  27. +9
    -7
      app/src/main/java/name/mikanoshi/customiuizer/utils/LockedAppAdapter.java
  28. +6
    -4
      app/src/main/java/name/mikanoshi/customiuizer/utils/PrivacyAppAdapter.java
  29. BIN
      app/src/main/res/drawable-xxhdpi-v4/am_card_item_disabled.png
  30. BIN
      app/src/main/res/drawable-xxhdpi-v4/ic_xspace.png
  31. BIN
      app/src/main/res/drawable-xxxhdpi-v4/am_card_item_disabled.png
  32. +12
    -0
      app/src/main/res/layout/applist_item.xml
  33. +5
    -0
      app/src/main/res/values-land/integers.xml
  34. +18
    -2
      app/src/main/res/values-ru-rRU/strings.xml
  35. +16
    -0
      app/src/main/res/values-tr/strings.xml
  36. +14
    -4
      app/src/main/res/values-uk-rUK/strings.xml
  37. +19
    -3
      app/src/main/res/values-zh-rCN/strings.xml
  38. +16
    -0
      app/src/main/res/values/arrays.xml
  39. +5
    -0
      app/src/main/res/values/integers.xml
  40. +18
    -2
      app/src/main/res/values/strings.xml
  41. +26
    -4
      app/src/main/res/xml/prefs_launcher.xml
  42. +6
    -0
      app/src/main/res/xml/prefs_system.xml
  43. +11
    -0
      app/src/main/res/xml/prefs_system_visualizer.xml
  44. +6
    -0
      app/src/main/res/xml/prefs_various.xml
  45. +1
    -1
      last_build

+ 2
- 2
BUGS_EN View File

@ -1,4 +1,4 @@
Known bugs:
- Latest versions of some Xiaomi apps 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, using stable ones is recommended
- 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

+ 2
- 2
BUGS_RU View File

@ -1,4 +1,4 @@
Известные баги:
- Код в последних версиях некоторых Xiaomi приложений обфусцирован, поэтому они не совместимы с модами в данном модуле (и никогда не будут)
- Не все моды совместимы с последними бета прошивками сразу после их выхода, рекомендуется использовать стабильные прошивки
- Код в последних версиях некоторых Xiaomi приложений (например POCO Launcher после версии 2.6.8) обфусцирован, поэтому они не совместимы с модами в данном модуле (и никогда не будут)
- Не все моды совместимы с последними бета прошивками сразу после их выхода

+ 25
- 0
CHANGELOG_EN View File

@ -1,3 +1,28 @@
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


+ 25
- 0
CHANGELOG_RU View File

@ -1,3 +1,28 @@
1.8.0
[Новое] Действие: Переключение режима управления одной рукой
[Новое] Отображение данных об устанавливаемом приложении в окне инсталлера
[Новое] Отключение избыточной прокрутки в списках
[Новое] Размер шрифта для названий в ланчере
[Новое] Отступ сверху для названий в ланчере
[Новое] Поддержка клонированных приложений в модах:
- Защита приложений
- Скрытые приложения
- Очистка меню "Поделиться"
- Очистка меню "Открыть с помощью"
- Доп. сведения о приложении
- Расширенное меню уведомления
- Приложение быстрого доступа/часов/календаря в панели уведомлений
- Действия Запустить приложение и Запустить компонент
[Улучшено][Число колонок в папках ланчера] Увеличенная ширина сетки в папках
[Улучшено][Конфигурация USB по умолчанию] Не показывать диалог при подключении автоматически на последних прошивках
[Улучшено][Визуализация музыки] Настраиваемый интервал смены динамического цвета
[Исправлено][Минимальная автояркость] Совместимость с некоторыми прошивками
[Исправлено][Скрывать тип мобильной сети] Совместимость с некоторыми прошивками
[Исправлено][Пользовательские действия на локскрине] Совместимость с последними прошивками
[Исправлено][Убрать скрытую папку] Совместимость с последними прошивками
[Исправлено][Число колонок в свёрнутой панели Быстрых Настроек] Совместимость с последними прошивками
Сжатие подробных отчётов для сохранения драгоценного траффика
1.7.5
[Новое] Отключение проверки подписи APK при обновлении приложений
[Новое] Продолжительность затемнения перед автоматическим выключением экрана


+ 2
- 2
app/build.gradle View File

@ -21,8 +21,8 @@ android {
applicationId "name.mikanoshi.customiuizer"
minSdkVersion 24
targetSdkVersion 28
versionCode 32
versionName "1.7.5"
versionCode 33
versionName "1.8.0"
signingConfig signingConfigs.dev
}
buildTypes {


+ 3
- 0
app/src/main/AndroidManifest.xml View File

@ -12,11 +12,14 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
<uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE" />
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.MANAGE_USB" />
<uses-permission android:name="android.permission.READ_LOGS" />


BIN
app/src/main/ic_launcher-web.png View File

Before After
Width: 512  |  Height: 512  |  Size: 103 KiB

+ 6
- 0
app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java View File

@ -161,6 +161,12 @@ public class MainActivity extends Activity {
else
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);
}


+ 5
- 1
app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java View File

@ -390,7 +390,7 @@ public class MainFragment extends PreferenceFragmentBase {
findPreference("pref_key_miuizer_sendreport").setOnPreferenceClickListener(new CheckBoxPreference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
ACRA.getErrorReporter().handleException(null);
if (Helpers.checkStoragePerm(act, Helpers.REQUEST_PERMISSIONS_REPORT)) createReport();
return true;
}
});
@ -733,6 +733,10 @@ public class MainFragment extends PreferenceFragmentBase {
}
}
public void createReport() {
ACRA.getErrorReporter().handleException(null);
}
public void showBackupRestoreDialog() {
final Activity act = getActivity();


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

@ -73,6 +73,9 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("system_notifmediaseekbar")) System.MediaNotificationSeekBarHook();
if (mPrefs.getBoolean("system_disableanynotif") && !Helpers.isNougat()) 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();
if (mPrefs.getBoolean("controls_volumecursor")) Controls.VolumeCursorHook();
if (mPrefs.getBoolean("controls_fsg_horiz")) Controls.FSGesturesHook();
if (mPrefs.getBoolean("various_alarmcompat")) Various.AlarmCompatHook();
@ -124,8 +127,8 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("system_orientationlock")) System.OrientationLockHook(lpparam);
if (mPrefs.getBoolean("system_noducking")) System.NoDuckingHook(lpparam);
if (mPrefs.getBoolean("system_epm")) System.ExtendedPowerMenuHook(lpparam);
if (mPrefs.getBoolean("system_cleanshare")) System.CleanShareMenuHook(lpparam);
if (mPrefs.getBoolean("system_cleanopenwith")) System.CleanOpenWithMenuHook(lpparam);
if (mPrefs.getBoolean("system_cleanshare")) System.CleanShareMenuServiceHook(lpparam);
if (mPrefs.getBoolean("system_cleanopenwith")) System.CleanOpenWithMenuServiceHook(lpparam);
if (mPrefs.getBoolean("system_limitminbrightness")) System.MinAutoBrightnessHook(lpparam);
if (mPrefs.getBoolean("system_applock")) System.AppLockHook(lpparam);
if (mPrefs.getBoolean("various_alarmcompat")) Various.AlarmCompatServiceHook(lpparam);
@ -238,6 +241,11 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
GlobalActions.miuizerSettingsInit(lpparam);
if (mPrefs.getBoolean("system_separatevolume")) System.NotificationVolumeSettingsHook(lpparam);
if (mPrefs.getBoolean("system_disableanynotif")) System.DisableAnyNotificationHook();
if (!mPrefs.getString("system_defaultusb", "none").equals("none")) System.USBConfigSettingsHook(lpparam);
}
if (pkg.equals("com.google.android.packageinstaller") || pkg.equals("com.android.packageinstaller")) {
if (mPrefs.getBoolean("various_installappinfo")) Various.AppInfoDuringInstallHook(lpparam);
}
if (pkg.equals("com.miui.home") || pkg.equals("com.mi.android.globallauncher"))
@ -252,8 +260,10 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
mPrefs.getInt("launcher_swiperight_action", 1) != 1) Launcher.HotSeatSwipesHook(lpparam);
if (mPrefs.getInt("launcher_shake_action", 1) != 1) Launcher.ShakeHook(lpparam);
if (mPrefs.getInt("launcher_doubletap_action", 1) != 1) Launcher.LauncherDoubleTapHook(lpparam);
if (mPrefs.getInt("launcher_folder_cols", 3) != 3) Launcher.FolderColumnsHook(lpparam);
if (mPrefs.getInt("launcher_folder_cols", 1) > 1) Launcher.FolderColumnsHook(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.getBoolean("launcher_noclockhide")) Launcher.NoClockHideHook(lpparam);
if (mPrefs.getBoolean("launcher_renameapps")) Launcher.RenameShortcutsHook(lpparam);
if (mPrefs.getBoolean("launcher_closefolder")) Launcher.CloseFolderOnLaunchHook(lpparam);
@ -265,6 +275,7 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("controls_fsg_horiz")) Launcher.FSGesturesHook(lpparam);
if (mPrefs.getBoolean("launcher_fixstatusbarmode")) Launcher.FixStatusBarModeHook(lpparam);
if (mPrefs.getBoolean("launcher_hideseekpoints")) Launcher.HideSeekPointsHook(lpparam);
if (mPrefs.getBoolean("launcher_privacyapps_gest")) Launcher.PrivacyFolderHook(lpparam);
}
//if (!mPrefs.getString("system_clock_app", "").equals("")) Launcher.ReplaceClockAppHook(lpparam);
//if (!mPrefs.getString("system_calendar_app", "").equals("")) Launcher.ReplaceCalendarAppHook(lpparam);


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

@ -354,7 +354,6 @@ public class SubFragment extends PreferenceFragmentBase {
}
}
public void finish() {
if (isAnimating) return;
if (getActivity() == null) return;


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

@ -1,12 +1,11 @@
package name.mikanoshi.customiuizer.crashreport;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
@ -15,6 +14,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.zip.GZIPOutputStream;
import org.acra.ACRA;
import org.acra.ReportField;
@ -39,6 +39,7 @@ 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;
@ -48,13 +49,17 @@ import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
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;
@ -62,29 +67,19 @@ 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 String xposedLog;
private StringBuilder debugLog = new StringBuilder();
private EditText desc;
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private String getXposedLog() {
String errorLogPath = Helpers.getXposedInstallerErrorLog(this);
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(errorLogPath))))) {
String line;
while ((line = reader.readLine()) != null) sb.append(line).append("\n");
return sb.toString();
} catch (Throwable e) {
return null;
}
}
void showFinishDialog(boolean isOk, String details) {
AlertDialog.Builder dlg = new AlertDialog.Builder(this);
dlg.setTitle(R.string.crash_result);
@ -117,7 +112,7 @@ public class Dialog extends Activity {
ifc = Runtime.getRuntime().exec("getprop " + prop);
BufferedReader bis = new BufferedReader(new InputStreamReader(ifc.getInputStream()), 2048);
res = bis.readLine();
} catch (Throwable e) {} finally {
} catch (Throwable t) {} finally {
if (ifc != null) ifc.destroy();
}
return res;
@ -154,96 +149,16 @@ public class Dialog extends Activity {
return version.equals("unknown") ? version + " (" + Helpers.xposedVersion + ")" : version;
}
private void sendCrash() {
crashData.put(USER_COMMENT, desc.getText().toString());
private void sendCrash(final String xposedLogStr) {
CrashReportPersister persister = new CrashReportPersister();
SharedPreferences prefs;
try {
prefs = Helpers.getProtectedContext(this).getSharedPreferences(Helpers.prefsName, Context.MODE_PRIVATE);
} catch (Throwable t) {
Log.e("prefs", "Failed to use protected storage!");
return;
}
final CrashReportData crashData;
try {
crashData = persister.load(reportFile);
crashData.put(USER_COMMENT, desc.getText().toString());
crashData.put(USER_EMAIL, prefs.getString("acra.user.email", ""));
} catch (Throwable t) {
t.printStackTrace();
cancelReports();
showFinishDialog(false, "cannot read report file");
return;
}
try {
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);
StringBuilder sb = new StringBuilder();
try (FileInputStream in = new FileInputStream(new File(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) {}
final String[] xposedPropFiles = new String[]{
"/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"
};
for (String prop: xposedPropFiles) {
File propFile = new File(prop);
if (propFile.exists()) {
if (!propFile.canRead()) break;
crashData.put("XPOSED_VERSION", getXposedPropVersion(propFile));
break;
}
}
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
PackageManager pkgMgr = getPackageManager();
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);
}
crashData.put("SHARED_PREFERENCES", new JSONObject(prefs.getAll()));
if (!sb.toString().isEmpty())
crashData.put("UNCAUGHT_EXCEPTIONS", sb.toString());
if (xposedLogStr == null || xposedLogStr.trim().equals(""))
crashData.put(ReportField.CUSTOM_DATA, "Xposed log is empty...");
else
crashData.put(ReportField.CUSTOM_DATA, xposedLogStr);
} catch (Throwable e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
crashData.put(ReportField.CUSTOM_DATA, "Retrieval failed. Stack trace:\n" + sw.toString());
}
loader.setMessage(getResources().getString(R.string.crash_sending_report));
loader.show();
new Thread(() -> {
boolean res;
try {
res = sendReport(crashData);
res = sendReport();
} catch (Throwable t) {
res = false;
}
@ -252,21 +167,23 @@ public class Dialog extends Activity {
runOnUiThread(new Runnable() {
@Override
public void run() {
loader.hide();
if (finalRes) {
Helpers.emptyFile(Helpers.getProtectedContext(Dialog.this).getFilesDir().getAbsolutePath() + "/uncaught_exceptions", true);
cancelReports();
showFinishDialog(true, null);
} else {
showFinishDialog(false, "request failed");
showFinishDialog(false, "REQUEST_ERROR");
}
}
});
}).start();
}
protected boolean sendReport(CrashReportData report) {
protected boolean sendReport() {
try {
String json = report.toJSON();
byte[] jsonData = crashData.toJSON().getBytes(StandardCharsets.UTF_8);
if (jsonData.length == 0) 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");
@ -276,24 +193,34 @@ public class Dialog extends Activity {
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 (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))) {
writer.write(json);
writer.flush();
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 e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
@ -312,7 +239,6 @@ public class Dialog extends Activity {
}
@Override
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
protected final void onCreate(Bundle savedInstanceState) {
overridePendingTransition(0, 0);
Helpers.setMiuiTheme(this, R.style.ApplyInvisible);
@ -333,28 +259,171 @@ public class Dialog extends Activity {
finish();
}
loader = new ProgressDialog(this);
loader.setMessage(getResources().getString(R.string.crash_collecting_report));
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();
}
debugLog.append("Asking System UI to collect Xposed log\n");
sendBroadcast(new Intent(GlobalActions.ACTION_PREFIX + "CollectLogs"));
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);
int tries = 3;
xposedLog = null;
while (xposedLog == null && tries > 0) try {
tries--;
xposedLog = getXposedLog();
if (xposedLog == null) Thread.sleep(500);
} catch (Throwable e) {}
String errorLog = Helpers.getXposedInstallerErrorLog(this);
debugLog.append("Installer log path: ").append(errorLog).append("\n");
String xposedLog = null;
try {
File sdcardLog = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + Helpers.externalFolder + Helpers.logFile);
File errorLogFile = null;
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);
debugLog.append("Log found: ").append(errorLog).append("\n");
} else debugLog.append("No Xposed log found!\n");
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) {
debugLog.append("Error reading log: ").append(t.getMessage()).append("\n");
}
if (sdcardLog.exists()) sdcardLog.delete();
} catch (Throwable t) {}
SharedPreferences prefs = getSharedPreferences(Helpers.prefsName, Context.MODE_PRIVATE);
try {
prefs = Helpers.getProtectedContext(this).getSharedPreferences(Helpers.prefsName, Context.MODE_PRIVATE);
} catch (Throwable t) {
Log.e("miuizer", "Failed to use protected storage!");
}
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 {
CrashReportPersister persister = new CrashReportPersister();
CrashReportData crashData = persister.load(reportFile);
String payload = crashData.toJSON();
int payloadSize = payload.getBytes(StandardCharsets.UTF_8).length;
boolean isManualReport = crashData.getString(ReportField.STACK_TRACE).contains("Report requested by developer");
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());
StringBuilder sb = new StringBuilder();
try (FileInputStream in = new FileInputStream(new File(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) {}
final String[] xposedPropFiles = new String[]{
"/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"
};
for (String prop: xposedPropFiles) {
File propFile = new File(prop);
if (propFile.exists()) {
if (!propFile.canRead()) break;
crashData.put("XPOSED_VERSION", getXposedPropVersion(propFile));
break;
}
}
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
PackageManager pkgMgr = getPackageManager();
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);
}
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.toString());
}
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);
@ -375,6 +444,7 @@ public class Dialog extends Activity {
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;
@ -421,7 +491,7 @@ public class Dialog extends Activity {
dialogView.addView(feedbackNote);
mainText.setText(mainText.getText() + "\n" + getResources().getString(R.string.crash_dialog_manual_size) + ": " + Math.round(payloadSize / 1024.0f) + " KB");
} catch (Throwable e) {}
} catch (Throwable t) {}
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(title);
@ -440,6 +510,7 @@ public class Dialog extends Activity {
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
@ -449,8 +520,16 @@ public class Dialog extends Activity {
} else if (!isNetworkAvailable()) {
Toast.makeText(Dialog.this, R.string.crash_needs_inet, Toast.LENGTH_LONG).show();
} else {
try {
InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
View currentFocusedView = getCurrentFocus();
if (currentFocusedView != null)
inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
} catch (Throwable t) {
Log.e("miuizer", t.getMessage());
}
alertDlg.dismiss();
sendCrash(xposedLog);
sendCrash();
}
}
});


+ 83
- 8
app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java View File

@ -20,6 +20,7 @@ import android.net.wifi.WifiManager;
import android.nfc.NfcAdapter;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.os.UserHandle;
@ -32,6 +33,11 @@ import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@ -89,6 +95,8 @@ public class GlobalActions {
case 18: return volumeUp(context);
case 19: return volumeDown(context);
case 21: return switchKeyboard(context);
case 22: return switchOneHandedLeft(context);
case 23: return switchOneHandedRight(context);
default: return false;
}
}
@ -108,6 +116,33 @@ public class GlobalActions {
// if (floatSel != null) floatSel.hide();
// }
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);
}
}
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);
}
if (mStatusBar != null) {
if (action.equals(ACTION_PREFIX + "ExpandNotifications")) try {
Object mNotificationPanel = XposedHelpers.getObjectField(mStatusBar, "mNotificationPanel");
@ -203,13 +238,6 @@ public class GlobalActions {
XposedBridge.log(t);
}
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);
}
Object mToggleManager = XposedHelpers.getObjectField(mStatusBar, "mToggleManager");
if (mToggleManager == null) return;
if (action.equals(ACTION_PREFIX + "ToggleGPS")) {
@ -340,7 +368,17 @@ public class GlobalActions {
if (action.equals(ACTION_PREFIX + "LaunchIntent")) {
Intent launchIntent = intent.getParcelableExtra("intent");
if (launchIntent != null) context.startActivity(launchIntent);
if (launchIntent != null) {
int user = 0;
if (launchIntent.hasExtra("user")) {
user = launchIntent.getIntExtra("user", 0);
launchIntent.removeExtra("user");
}
if (user != 0)
XposedHelpers.callMethod(context, "startActivityAsUser", launchIntent, XposedHelpers.newInstance(UserHandle.class, user));
else
context.startActivity(launchIntent);
}
}
if (action.equals(ACTION_PREFIX + "VolumeUp")) {
@ -367,6 +405,18 @@ public class GlobalActions {
);
}
if (action.equals(ACTION_PREFIX + "SwitchOneHandedLeft")) {
Intent handyIntent = new Intent("miui.action.handymode.changemode");
handyIntent.putExtra("mode", 1);
context.sendBroadcast(handyIntent);
}
if (action.equals(ACTION_PREFIX + "SwitchOneHandedRight")) {
Intent handyIntent = new Intent("miui.action.handymode.changemode");
handyIntent.putExtra("mode", 2);
context.sendBroadcast(handyIntent);
}
if (action.equals(ACTION_PREFIX + "ToggleColorInversion")) {
int opt = Settings.Secure.getInt(context.getContentResolver(), "accessibility_display_inversion_enabled");
Settings.Secure.putInt(context.getContentResolver(), "accessibility_display_inversion_enabled", opt == 0 ? 1 : 0);
@ -699,6 +749,8 @@ public class GlobalActions {
intentfilter.addAction(ACTION_PREFIX + "GoBack");
intentfilter.addAction(ACTION_PREFIX + "OpenPowerMenu");
intentfilter.addAction(ACTION_PREFIX + "SwitchKeyboard");
intentfilter.addAction(ACTION_PREFIX + "SwitchOneHandedLeft");
intentfilter.addAction(ACTION_PREFIX + "SwitchOneHandedRight");
intentfilter.addAction(ACTION_PREFIX + "ToggleColorInversion");
intentfilter.addAction(ACTION_PREFIX + "SimulateMenu");
intentfilter.addAction(ACTION_PREFIX + "VolumeUp");
@ -822,6 +874,7 @@ public class GlobalActions {
intentfilter.addAction(ACTION_PREFIX + "HideQuickRecents");
intentfilter.addAction(ACTION_PREFIX + "ClearMemory");
intentfilter.addAction(ACTION_PREFIX + "CollectLogs");
mStatusBarContext.registerReceiver(mSBReceiver, intentfilter);
}
@ -929,6 +982,8 @@ public class GlobalActions {
if (pkgAppArray.length < 2) return null;
ComponentName name = new ComponentName(pkgAppArray[0], pkgAppArray[1]);
intent.setComponent(name);
int user = Helpers.getSharedIntPref(context, pref + "_user", 0);
if (user != 0) intent.putExtra("user", user);
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
@ -1080,6 +1135,26 @@ public class GlobalActions {
}
}
public static boolean switchOneHandedLeft(Context context) {
try {
context.sendBroadcast(new Intent(ACTION_PREFIX + "SwitchOneHandedLeft"));
return true;
} catch (Throwable t) {
XposedBridge.log(t);
return false;
}
}
public static boolean switchOneHandedRight(Context context) {
try {
context.sendBroadcast(new Intent(ACTION_PREFIX + "SwitchOneHandedRight"));
return true;
} catch (Throwable t) {
XposedBridge.log(t);
return false;
}
}
public static boolean toggleColorInversion(Context context) {
try {
context.sendBroadcast(new Intent(ACTION_PREFIX + "ToggleColorInversion"));


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

@ -23,12 +23,14 @@ import android.provider.Settings;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.HashSet;
@ -630,8 +632,22 @@ public class Launcher {
Helpers.findAndHookMethod("com.miui.home.launcher.Folder", lpparam.classLoader, "onFinishInflate", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
int cols = MainModule.mPrefs.getInt("launcher_folder_cols", 1);
GridView mContent = (GridView)XposedHelpers.getObjectField(param.thisObject, "mContent");
mContent.setNumColumns(MainModule.mPrefs.getInt("launcher_folder_cols", 3));
mContent.setNumColumns(cols);
ViewGroup.LayoutParams lp = mContent.getLayoutParams();
lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
mContent.setLayoutParams(lp);
ViewGroup mBackgroundView = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mBackgroundView");
if (mBackgroundView != null)
mBackgroundView.setPadding(
mBackgroundView.getPaddingLeft() / (cols > 3 ? 3 : 1),
mBackgroundView.getPaddingTop(),
mBackgroundView.getPaddingRight() / (cols > 3 ? 3 : 1),
mBackgroundView.getPaddingBottom()
);
}
});
}
@ -757,6 +773,89 @@ public class Launcher {
// });
}
public static void TitleFontSizeHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.miui.home.launcher.ItemIcon", lpparam.classLoader, "onFinishInflate", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
TextView mTitle = (TextView)XposedHelpers.getObjectField(param.thisObject, "mTitle");
if (mTitle != null) mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, MainModule.mPrefs.getInt("launcher_titlefontsize", 5));
}
});
if (lpparam.packageName.equals("com.mi.android.globallauncher"))
Helpers.hookAllMethods("com.miui.home.launcher.ItemIcon", lpparam.classLoader, "setTitleColorMode", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
TextView mTitle = (TextView)XposedHelpers.getObjectField(param.thisObject, "mTitle");
if (mTitle != null) mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, MainModule.mPrefs.getInt("launcher_titlefontsize", 5));
}
});
Helpers.hookAllMethods("com.miui.home.launcher.ShortcutIcon", lpparam.classLoader, "fromXml", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
Object buddyIcon = XposedHelpers.callMethod(param.args[3], "getBuddyIconView", param.args[2]);
if (buddyIcon == null) return;
TextView mTitle = (TextView)XposedHelpers.getObjectField(buddyIcon, "mTitle");
if (mTitle != null) mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, MainModule.mPrefs.getInt("launcher_titlefontsize", 5));
}
});
if (lpparam.packageName.equals("com.miui.home")) {
Helpers.hookAllMethods("com.miui.home.launcher.ShortcutIcon", lpparam.classLoader, "createShortcutIcon", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
Object buddyIcon = param.getResult();
if (buddyIcon == null) return;
TextView mTitle = (TextView)XposedHelpers.getObjectField(buddyIcon, "mTitle");
if (mTitle != null)
mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, MainModule.mPrefs.getInt("launcher_titlefontsize", 5));
}
});
Helpers.hookAllMethods("com.miui.home.launcher.common.Utilities", lpparam.classLoader, "adaptTitleStyleToWallpaper", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
TextView mTitle = (TextView)param.args[1];
if (mTitle != null)
mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, MainModule.mPrefs.getInt("launcher_titlefontsize", 5));
}
});
}
}
public static void TitleTopMarginHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.miui.home.launcher.ItemIcon", lpparam.classLoader, "onFinishInflate", new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
ViewGroup mTitleContainer = (ViewGroup)XposedHelpers.getObjectField(param.thisObject, "mTitleContainer");
if (mTitleContainer == null) return;
ViewGroup.LayoutParams lp = mTitleContainer.getLayoutParams();
int opt = Math.round(MainModule.mPrefs.getInt("launcher_titletopmargin", 0) * mTitleContainer.getResources().getDisplayMetrics().density);
if (lp instanceof RelativeLayout.LayoutParams) {
((RelativeLayout.LayoutParams)lp).topMargin = opt;
mTitleContainer.setLayoutParams(lp);
} else {
mTitleContainer.setTranslationY(opt);
mTitleContainer.setClipChildren(false);
mTitleContainer.setClipToPadding(false);
((ViewGroup)mTitleContainer.getParent()).setClipChildren(false);
((ViewGroup)mTitleContainer.getParent()).setClipToPadding(false);
}
}
});
}
public static void PrivacyFolderHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.miui.home.launcher.Launcher", lpparam.classLoader, "startSecurityHide", new MethodHook() {
@Override
protected void before(final MethodHookParam param) throws Throwable {
boolean opt = Helpers.getSharedBoolPref((Activity)param.thisObject, "pref_key_launcher_privacyapps_gest", false);
if (opt) param.setResult(null);
}
});
}
// public static void ReplaceClockAppHook(LoadPackageParam lpparam) {
// Helpers.findAndHookMethod("com.miui.home.launcher.common.Utilities", lpparam.classLoader, "startActivity", Context.class, String.class, View.class, new MethodHook() {
// @Override


+ 334
- 90
app/src/main/java/name/mikanoshi/customiuizer/mods/System.java View File

@ -1,5 +1,8 @@
package name.mikanoshi.customiuizer.mods;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -62,6 +65,7 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.os.UserHandle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.provider.Settings;
@ -80,6 +84,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
@ -940,6 +945,7 @@ public class System {
});
}
private static boolean is4GPlus = false;
public static void HideNetworkTypeHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.android.systemui.statusbar.SignalClusterView$PhoneState", lpparam.classLoader, "updateMobileType", String.class, new MethodHook() {
@Override
@ -957,13 +963,30 @@ public class System {
isMobileConnected = netCaps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
}
}
// View parent = (View)((View)XposedHelpers.getSurroundingThis(param.thisObject)).getParent().getParent().getParent().getParent();
// parent != null && parent.getId() != parent.getResources().getIdentifier("header_content", "id", lpparam.packageName)
if (opt == 3 || (opt == 2 && !isMobileConnected)) {
mMobileType.setText("");
mSignalDualNotchMobileType.setText("");
}
//Helpers.log(String.valueOf(parent) + ", " + String.valueOf(parent.getId()) + " != " + String.valueOf(mMobileType.getResources().getIdentifier("header_content", "id", lpparam.packageName)));
// try {
// View parent = (View)((View)XposedHelpers.getSurroundingThis(param.thisObject)).getParent().getParent().getParent().getParent();
// parent != null && parent.getId() != parent.getResources().getIdentifier("header_content", "id", lpparam.packageName)
// Helpers.log(parent + ", " + parent.getId() + " != " + mMobileType.getResources().getIdentifier("header_content", "id", lpparam.packageName));
// } catch (Throwable t) {
// XposedBridge.log(t);
// }
}
});
Helpers.findAndHookMethod("com.android.systemui.statusbar.SignalClusterView$PhoneState", lpparam.classLoader, "updateMobileTypeForNormal", boolean.class, String.class, new MethodHook() {
@Override
protected void before(MethodHookParam param) throws Throwable {
is4GPlus = (boolean)param.args[0];
param.args[0] = true;
}
@Override
protected void after(MethodHookParam param) throws Throwable {
param.setResult(is4GPlus);
}
});
}
@ -1096,16 +1119,9 @@ public class System {
param.args[2] = values;
}
});
}
if (!Helpers.isNougat())
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(Math.max(val, MainModule.mPrefs.getInt("system_minbrightness", 44)));
}
});
} else {
if (Helpers.isNougat())
Helpers.findAndHookMethod("com.android.server.display.AutomaticBrightnessController", lpparam.classLoader, "updateAutoBrightness", boolean.class, new MethodHook() {
@Override
protected void after(final MethodHookParam param) throws Throwable {
@ -1120,7 +1136,14 @@ public class System {
}
}
});
}
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(Math.max(val, MainModule.mPrefs.getInt("system_minbrightness", 44)));
}
});
Helpers.hookAllConstructors("com.android.server.display.AutomaticBrightnessController", lpparam.classLoader, new MethodHook() {
@Override
@ -1732,6 +1755,13 @@ public class System {
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) {
@ -1739,12 +1769,18 @@ public class System {
Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.setData(Uri.parse("package:" + pkgName));
mContext.startActivity(intent);
if (user != 0)
XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user));
else
mContext.startActivity(intent);
mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
} else if (iconResId == forceCloseIconResId) {
param.setResult(null);
ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
XposedHelpers.callMethod(am, "forceStopPackage", pkgName);
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));
@ -1857,8 +1893,15 @@ public class System {
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;
}
MainModule.resHooks.setObjectReplacement("com.android.systemui", "integer", "quick_settings_qqs_count_portrait", cols);
MainModule.resHooks.setObjectReplacement("com.android.systemui", "integer", "quick_settings_qqs_count", cols + 1);
MainModule.resHooks.setResReplacement("com.android.systemui", "integer", "quick_settings_qqs_count", colsResId);
}
public static void QSGridRes() {
@ -2175,6 +2218,7 @@ public class System {
mShortcut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int user = Helpers.getSharedIntPref(v.getContext(), "pref_key_system_shortcut_app_user", 0);
String pkgAppName = Helpers.getSharedStringPref(v.getContext(), "pref_key_system_shortcut_app", "");
if (pkgAppName == null || pkgAppName.equals("")) {
View.OnClickListener mOnClickListener = (View.OnClickListener)XposedHelpers.getObjectField(param.thisObject, "mOnClickListener");
@ -2191,7 +2235,15 @@ public class System {
intent.setComponent(name);
Object mActStarter = XposedHelpers.getObjectField(param.thisObject, "mActStarter");
XposedHelpers.callMethod(mActStarter, "startActivity", intent, true);
if (user != 0) try {
XposedHelpers.callMethod(mActStarter, "collapsePanels");
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user));
} catch (Throwable t) {
XposedBridge.log(t);
} else {
XposedHelpers.callMethod(mActStarter, "startActivity", intent, true);
}
}
});
}
@ -2206,6 +2258,7 @@ public class System {
mClock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int user = Helpers.getSharedIntPref(v.getContext(), "pref_key_system_clock_app_user", 0);
String pkgAppName = Helpers.getSharedStringPref(v.getContext(), "pref_key_system_clock_app", "");
if (pkgAppName == null || pkgAppName.equals("")) {
View.OnClickListener mOnClickListener = (View.OnClickListener)XposedHelpers.getObjectField(param.thisObject, "mOnClickListener");
@ -2222,7 +2275,15 @@ public class System {
intent.setComponent(name);
Object mActStarter = XposedHelpers.getObjectField(param.thisObject, "mActStarter");
XposedHelpers.callMethod(mActStarter, "startActivity", intent, true);
if (user != 0) try {
XposedHelpers.callMethod(mActStarter, "collapsePanels");
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user));
} catch (Throwable t) {
XposedBridge.log(t);
} else {
XposedHelpers.callMethod(mActStarter, "startActivity", intent, true);
}
}
});
}
@ -2237,6 +2298,7 @@ public class System {
mDateView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int user = Helpers.getSharedIntPref(v.getContext(), "pref_key_system_calendar_app_user", 0);
String pkgAppName = Helpers.getSharedStringPref(v.getContext(), "pref_key_system_calendar_app", "");
if (pkgAppName == null || pkgAppName.equals("")) {
View.OnClickListener mOnClickListener = (View.OnClickListener)XposedHelpers.getObjectField(param.thisObject, "mOnClickListener");
@ -2253,7 +2315,15 @@ public class System {
intent.setComponent(name);
Object mActStarter = XposedHelpers.getObjectField(param.thisObject, "mActStarter");
XposedHelpers.callMethod(mActStarter, "startActivity", intent, true);
if (user != 0) try {
XposedHelpers.callMethod(mActStarter, "collapsePanels");
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
XposedHelpers.callMethod(mContext, "startActivityAsUser", intent, XposedHelpers.newInstance(UserHandle.class, user));
} catch (Throwable t) {
XposedBridge.log(t);
} else {
XposedHelpers.callMethod(mActStarter, "startActivity", intent, true);
}
}
});
}
@ -2557,7 +2627,35 @@ public class System {
});
}
public static void CleanShareMenuHook(LoadPackageParam lpparam) {
public static void CleanShareMenuHook() {
Helpers.hookAllMethods("miui.securityspace.XSpaceResolverActivityHelper.ResolverActivityRunner", null, "run", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
Intent mOriginalIntent = (Intent)XposedHelpers.getObjectField(param.thisObject, "mOriginalIntent");
if (mOriginalIntent == null) return;
String action = mOriginalIntent.getAction();
if (action == null) return;
if (!action.equals(Intent.ACTION_SEND) && !action.equals(Intent.ACTION_SENDTO) && !action.equals(Intent.ACTION_SEND_MULTIPLE)) return;
if (mOriginalIntent.getDataString() != null && mOriginalIntent.getDataString().contains(":")) return;
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
String mAimPackageName = (String)XposedHelpers.getObjectField(param.thisObject, "mAimPackageName");
if (mContext == null || mAimPackageName == null) return;
Set<String> selectedApps = Helpers.getSharedStringSetPref(mContext, "pref_key_system_cleanshare_apps");
View mRootView = (View)XposedHelpers.getObjectField(param.thisObject, "mRootView");
int appResId1 = mContext.getResources().getIdentifier("app1", "id", "android.miui");
int appResId2 = mContext.getResources().getIdentifier("app2", "id", "android.miui");
boolean removeOriginal = selectedApps.contains(mAimPackageName) || selectedApps.contains(mAimPackageName + "|0");
boolean removeDual = selectedApps.contains(mAimPackageName + "|999");
View originalApp = mRootView.findViewById(appResId1);
View dualApp = mRootView.findViewById(appResId2);
if (removeOriginal)dualApp.performClick();
else if (removeDual) originalApp.performClick();
}
});
}
public static void CleanShareMenuServiceHook(LoadPackageParam lpparam) {
Helpers.findAndHookMethod("com.android.server.pm.PackageManagerService", lpparam.classLoader, "systemReady", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
@ -2588,9 +2686,20 @@ public class System {
if (intent.hasExtra("CustoMIUIzer") && intent.getBooleanExtra("CustoMIUIzer", false)) return;
Set<String> selectedApps = MainModule.mPrefs.getStringSet("system_cleanshare_apps");
List<ResolveInfo> resolved = (List<ResolveInfo>)param.getResult();
ResolveInfo resolveInfo;
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
PackageManager pm = mContext.getPackageManager();
Iterator itr = resolved.iterator();
while (itr.hasNext())
if (selectedApps.contains(((ResolveInfo)itr.next()).activityInfo.packageName)) itr.remove();
while (itr.hasNext()) {
resolveInfo = ((ResolveInfo)itr.next());
boolean removeOriginal = selectedApps.contains(resolveInfo.activityInfo.packageName) || selectedApps.contains(resolveInfo.activityInfo.packageName + "|0");
boolean removeDual = selectedApps.contains(resolveInfo.activityInfo.packageName + "|999");
boolean hasDual = false;
try {
hasDual = XposedHelpers.callMethod(pm, "getPackageInfoAsUser", resolveInfo.activityInfo.packageName, 0, 999) != null;
} catch (Throwable t) {}
if ((removeOriginal && !hasDual) || removeOriginal && hasDual && removeDual) itr.remove();
}
param.setResult(resolved);
} catch (Throwable t) {
if (!(t instanceof BadParcelableException)) XposedBridge.log(t);
@ -2602,7 +2711,33 @@ public class System {
Helpers.findAndHookMethod("com.android.server.pm.PackageManagerService", lpparam.classLoader, "queryIntentActivitiesInternal", Intent.class, String.class, int.class, int.class, hook);
}
public static void CleanOpenWithMenuHook(LoadPackageParam lpparam) {
public static void CleanOpenWithMenuHook() {
Helpers.hookAllMethods("miui.securityspace.XSpaceResolverActivityHelper.ResolverActivityRunner", null, "run", new MethodHook() {
@Override
protected void after(MethodHookParam param) throws Throwable {
Intent mOriginalIntent = (Intent)XposedHelpers.getObjectField(param.thisObject, "mOriginalIntent");
if (mOriginalIntent == null) return;
String action = mOriginalIntent.getAction();
if (!Intent.ACTION_VIEW.equals(action) || mOriginalIntent.getType() == null) return;
Context mContext = (Context)XposedHelpers.getObjectField(param.thisObject, "mContext");
String mAimPackageName = (String)XposedHelpers.getObjectField(param.thisObject, "mAimPackageName");
if (mContext == null || mAimPackageName == null) return;
Set<String