Browse Source

[New] Compact notifications

[New] Enhanced Hidden apps
[New] Hide apps from recent tasks list
[New] Quick settings haptic feedback
[New] Toggle module's launcher icon
[Fixed] Fade screen rotation animation
[Fixed] Vibration in mods respects "Vibrate on tap" system setting
[Fixed] Module UI bugs
pull/109/head
Mikanoshi 2 years ago
parent
commit
0489c72013
37 changed files with 934 additions and 102 deletions
  1. +1
    -0
      .gitignore
  2. +10
    -0
      CHANGELOG
  3. +3
    -2
      app/build.gradle
  4. BIN
      app/lib/miuisystem.jar
  5. +20
    -4
      app/src/main/AndroidManifest.xml
  6. +5
    -0
      app/src/main/java/name/mikanoshi/customiuizer/ActivityEx.java
  7. +1
    -1
      app/src/main/java/name/mikanoshi/customiuizer/GateWayLauncher.java
  8. +5
    -0
      app/src/main/java/name/mikanoshi/customiuizer/GateWaySettings.java
  9. +9
    -4
      app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java
  10. +7
    -1
      app/src/main/java/name/mikanoshi/customiuizer/MainApplication.java
  11. +40
    -9
      app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java
  12. +4
    -0
      app/src/main/java/name/mikanoshi/customiuizer/MainModule.java
  13. +1
    -2
      app/src/main/java/name/mikanoshi/customiuizer/PreferenceFragmentBase.java
  14. +3
    -0
      app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java
  15. +1
    -5
      app/src/main/java/name/mikanoshi/customiuizer/mods/Controls.java
  16. +20
    -11
      app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java
  17. +92
    -5
      app/src/main/java/name/mikanoshi/customiuizer/mods/System.java
  18. +20
    -5
      app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java
  19. +14
    -3
      app/src/main/java/name/mikanoshi/customiuizer/prefs/ListPreferenceEx.java
  20. +16
    -4
      app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java
  21. +26
    -1
      app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java
  22. +68
    -16
      app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java
  23. +8
    -0
      app/src/main/java/name/mikanoshi/customiuizer/subs/System.java
  24. +50
    -11
      app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java
  25. +138
    -0
      app/src/main/java/name/mikanoshi/customiuizer/utils/PrivacyAppAdapter.java
  26. +1
    -1
      app/src/main/res/animator/fragment_close_enter.xml
  27. +1
    -1
      app/src/main/res/animator/fragment_close_exit.xml
  28. +1
    -1
      app/src/main/res/animator/fragment_open_enter.xml
  29. +1
    -1
      app/src/main/res/animator/fragment_open_exit.xml
  30. +18
    -2
      app/src/main/res/values-ru-rRU/strings.xml
  31. +269
    -0
      app/src/main/res/values-zh-rCN/strings.xml
  32. +2
    -0
      app/src/main/res/values/dimens.xml
  33. +19
    -3
      app/src/main/res/values/strings.xml
  34. +19
    -2
      app/src/main/res/xml/prefs_launcher.xml
  35. +13
    -3
      app/src/main/res/xml/prefs_main.xml
  36. +27
    -3
      app/src/main/res/xml/prefs_system.xml
  37. +1
    -1
      last_build

+ 1
- 0
.gitignore View File

@ -11,3 +11,4 @@
/build
/captures
.externalNativeBuild
/.idea/misc.xml

+ 10
- 0
CHANGELOG View File

@ -1,3 +1,13 @@
1.5.2
[New] Compact notifications
[New] Enhanced Hidden apps
[New] Hide apps from recent tasks list
[New] Quick settings haptic feedback
[New] Toggle module's launcher icon
[Fixed] Fade screen rotation animation
[Fixed] Vibration in mods respects "Vibrate on tap" system setting
[Fixed] Module UI bugs
1.5.1
[New][Expand notifications] Black & white list
[New][Control input cursor] Option to swap cursor moving directions


+ 3
- 2
app/build.gradle View File

@ -21,8 +21,8 @@ android {
applicationId "name.mikanoshi.customiuizer"
minSdkVersion 24
targetSdkVersion 28
versionCode 12
versionName "1.5.1"
versionCode 13
versionName "1.5.2"
signingConfig signingConfigs.dev
}
buildTypes {
@ -48,4 +48,5 @@ dependencies {
implementation "ch.acra:acra-core:$acraVersion"
compileOnly 'de.robv.android.xposed:api:82'
compileOnly files('lib/miui.jar')
compileOnly files('lib/miuisystem.jar')
}

BIN
app/lib/miuisystem.jar View File


+ 20
- 4
app/src/main/AndroidManifest.xml View File

@ -9,10 +9,14 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.DUMP" />
<uses-permission android:name="com.miui.securitycenter.permission.ACCESS_SECURITY_CENTER_PROVIDER" />
<application
android:allowBackup="false"
android:backupAgent="name.mikanoshi.customiuizer.utils.PrefBackupAgent"
@ -30,15 +34,27 @@
android:label="@string/title_activity_main"
android:theme="@style/AppTheme"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS"/>
</intent-filter>
</activity>
<activity-alias
android:label="@string/title_activity_main"
android:name=".GateWayLauncher"
android:targetActivity=".MainActivity"
android:enabled="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</intent-filter>
</activity-alias>
<activity-alias
android:label="@string/title_activity_main"
android:name=".GateWay"
android:name=".GateWaySettings"
android:targetActivity=".MainActivity"
android:enabled="true"
android:excludeFromRecents="true">


+ 5
- 0
app/src/main/java/name/mikanoshi/customiuizer/ActivityEx.java View File

@ -4,9 +4,14 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.backup.BackupManager;
import android.content.Context;
import android.os.Bundle;
import android.view.MenuItem;
import java.util.Locale;
import name.mikanoshi.customiuizer.utils.Helpers;
@SuppressLint("Registered")
public class ActivityEx extends Activity {
public boolean launch = true;


app/src/main/java/name/mikanoshi/customiuizer/GateWay.java → app/src/main/java/name/mikanoshi/customiuizer/GateWayLauncher.java View File

@ -2,4 +2,4 @@ package name.mikanoshi.customiuizer;
import android.app.Activity;
public class GateWay extends Activity {}
public class GateWayLauncher extends Activity {}

+ 5
- 0
app/src/main/java/name/mikanoshi/customiuizer/GateWaySettings.java View File

@ -0,0 +1,5 @@
package name.mikanoshi.customiuizer;
import android.app.Activity;
public class GateWaySettings extends Activity {}

+ 9
- 4
app/src/main/java/name/mikanoshi/customiuizer/MainActivity.java View File

@ -5,12 +5,15 @@ import android.app.Fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.FileObserver;
import android.util.Log;
import android.widget.Toast;
import java.util.Locale;
import name.mikanoshi.customiuizer.utils.Helpers;
public class MainActivity extends ActivityEx {
@ -20,14 +23,16 @@ public class MainActivity extends ActivityEx {
FileObserver mFileObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
protected void attachBaseContext(Context base) {
try {
Helpers.fixPermissionsAsync(this);
Helpers.prefs = Helpers.getProtectedContext(this).getSharedPreferences(Helpers.prefsName, Context.MODE_PRIVATE);
super.attachBaseContext(Helpers.getLocaleContext(base));
} catch (Throwable t) {
Log.e("prefs", "Failed to use protected storage!");
t.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefsChanged = new SharedPreferences.OnSharedPreferenceChangeListener() {


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

@ -24,6 +24,8 @@ import org.acra.config.CoreConfigurationBuilder;
import org.acra.data.StringFormat;
import org.acra.plugins.SimplePluginLoader;
import java.util.Locale;
import miui.core.SdkManager;
import name.mikanoshi.customiuizer.crashreport.DialogInteraction;
import name.mikanoshi.customiuizer.utils.Helpers;
@ -44,7 +46,11 @@ public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
try {
super.attachBaseContext(Helpers.getProtectedContext(base));
Context pContext = Helpers.getProtectedContext(base);
Helpers.fixPermissionsAsync(pContext);
Helpers.prefs = pContext.getSharedPreferences(Helpers.prefsName, Context.MODE_PRIVATE);
if (Helpers.prefs.getBoolean("pref_key_miuizer_forcelocale", false)) Locale.setDefault(Locale.ENGLISH);
super.attachBaseContext(pContext);
} catch (Throwable t) {
super.attachBaseContext(base);
Log.e("prefs", "Failed to use protected storage!");


+ 40
- 9
app/src/main/java/name/mikanoshi/customiuizer/MainFragment.java View File

@ -54,6 +54,10 @@ import name.mikanoshi.customiuizer.utils.Helpers;
public class MainFragment extends PreferenceFragmentBase {
public boolean miuizerModuleActive = false;
private System prefSystem = new System();
private Launcher prefLauncher = new Launcher();
private Controls prefControls = new Controls();
private Various prefVarious = new Various();
public MainFragment() {
super();
@ -206,14 +210,34 @@ public class MainFragment extends PreferenceFragmentBase {
showRestoreInfoDialog();
}
CheckBoxPreference.OnPreferenceChangeListener toggleIcon = new CheckBoxPreference.OnPreferenceChangeListener() {
CheckBoxPreference.OnPreferenceChangeListener toggleLauncherIcon = new CheckBoxPreference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
PackageManager pm = act.getPackageManager();
if ((Boolean)newValue)
pm.setComponentEnabledSetting(new ComponentName(act, GateWay.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(act, GateWayLauncher.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
else
pm.setComponentEnabledSetting(new ComponentName(act, GateWay.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(act, GateWayLauncher.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
return true;
}
};
CheckBoxPreference.OnPreferenceChangeListener toggleSettingsIcon = new CheckBoxPreference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
PackageManager pm = act.getPackageManager();
if ((Boolean)newValue)
pm.setComponentEnabledSetting(new ComponentName(act, GateWaySettings.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
else
pm.setComponentEnabledSetting(new ComponentName(act, GateWaySettings.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
return true;
}
};
CheckBoxPreference.OnPreferenceChangeListener toggleForceLocale = new CheckBoxPreference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
getActivity().recreate();
return true;
}
};
@ -234,9 +258,16 @@ public class MainFragment extends PreferenceFragmentBase {
}
};
CheckBoxPreference miuizerSettingsPreference = (CheckBoxPreference) findPreference("pref_key_miuizer_icon");
CheckBoxPreference launcherIconPreference = (CheckBoxPreference)findPreference("pref_key_miuizer_launchericon");
if (launcherIconPreference != null)
launcherIconPreference.setOnPreferenceChangeListener(toggleLauncherIcon);
CheckBoxPreference miuizerSettingsPreference = (CheckBoxPreference) findPreference("pref_key_miuizer_settingsicon");
if (miuizerSettingsPreference != null)
miuizerSettingsPreference.setOnPreferenceChangeListener(toggleIcon);
miuizerSettingsPreference.setOnPreferenceChangeListener(toggleSettingsIcon);
CheckBoxPreference forceLocalePreference = (CheckBoxPreference) findPreference("pref_key_miuizer_forcelocale");
if (forceLocalePreference != null)
forceLocalePreference.setOnPreferenceChangeListener(toggleForceLocale);
Preference miuizerCrashReportPreference = findPreference("pref_key_miuizer_sendreport");
if (miuizerCrashReportPreference != null)
miuizerCrashReportPreference.setOnPreferenceClickListener(sendCrashReport);
@ -483,16 +514,16 @@ public class MainFragment extends PreferenceFragmentBase {
switch (preference.getKey()) {
case "pref_key_system":
openSubFragment(new System(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system);
openSubFragment(prefSystem, null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.system_mods, R.xml.prefs_system);
break;
case "pref_key_launcher":
openSubFragment(new Launcher(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_mods, R.xml.prefs_launcher);
openSubFragment(prefLauncher, null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.launcher_mods, R.xml.prefs_launcher);
return true;
case "pref_key_controls":
openSubFragment(new Controls(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls);
openSubFragment(prefControls, null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.controls_mods, R.xml.prefs_controls);
break;
case "pref_key_various":
openSubFragment(new Various(), null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.various_mods, R.xml.prefs_various);
openSubFragment(prefVarious, null, Helpers.SettingsType.Preference, Helpers.ActionBarType.HomeUp, R.string.various_mods, R.xml.prefs_various);
break;
}
}


+ 4
- 0
app/src/main/java/name/mikanoshi/customiuizer/MainModule.java View File

@ -45,6 +45,7 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
if (mPrefs.getBoolean("system_popupnotif_fs")) System.PopupNotificationsFSHook();
if (Integer.parseInt(mPrefs.getString("system_rotateanim", "1")) > 1) System.RotationAnimationHook();
if (mPrefs.getBoolean("system_colorizenotiftitle")) System.ColorizedNotificationTitlesHook();
if (mPrefs.getBoolean("system_compactnotif")) System.CompactNotificationsRes();
Controls.VolumeMediaPlayerHook();
GlobalActions.setupUnhandledCatcher();
@ -93,6 +94,7 @@ public class MainModule implements IXposedHookZygoteInit, IXposedHookLoadPackage
mPrefs.getInt("controls_fingerprintlong_action", 1) > 1) Controls.FingerprintEventsHook(lpparam);
if (mPrefs.getInt("system_volumesteps", 10) > 10) System.VolumeStepsHook(lpparam);
if (mPrefs.getBoolean("system_downgrade")) System.NoVersionCheckHook(lpparam);
if (mPrefs.getBoolean("system_hidefromrecents")) System.HideFromRecentsHook(lpparam);
//System.AutoBrightnessHook(lpparam);
}
@ -124,6 +126,8 @@ 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_compactnotif")) System.CompactNotificationsHook(lpparam);
if (mPrefs.getBoolean("system_qshaptic")) System.QSHapticHook(lpparam);
}
// if (pkg.equals("com.android.incallui")) {


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

@ -12,7 +12,6 @@ import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import miui.preference.PreferenceFragment;
import name.mikanoshi.customiuizer.utils.Helpers;
@ -312,9 +311,9 @@ public class PreferenceFragmentBase extends PreferenceFragment {
if (top == null) return null;
final View content = top.findViewById(android.R.id.content);
//ValueAnimator.setFrameDelay(17);
ValueAnimator valAnimator = new ValueAnimator();
valAnimator.setDuration(animDur);
valAnimator.setInterpolator(new DecelerateInterpolator());
valAnimator.setFloatValues(0.0f, 1.0f);
if (nextAnim == R.animator.fragment_open_enter || nextAnim == R.animator.fragment_open_exit)


+ 3
- 0
app/src/main/java/name/mikanoshi/customiuizer/SubFragmentWithSearch.java View File

@ -18,6 +18,7 @@ import android.widget.TextView;
import miui.view.SearchActionMode;
import name.mikanoshi.customiuizer.utils.AppDataAdapter;
import name.mikanoshi.customiuizer.utils.PrivacyAppAdapter;
import name.mikanoshi.customiuizer.utils.ResolveInfoAdapter;
public class SubFragmentWithSearch extends SubFragment {
@ -125,6 +126,8 @@ public class SubFragmentWithSearch extends SubFragment {
if (adapter == null) return;
if (adapter instanceof AppDataAdapter)
((AppDataAdapter)listView.getAdapter()).getFilter().filter(filter);
else if (adapter instanceof PrivacyAppAdapter)
((PrivacyAppAdapter)listView.getAdapter()).getFilter().filter(filter);
else if (adapter instanceof ResolveInfoAdapter)
((ResolveInfoAdapter)listView.getAdapter()).getFilter().filter(filter);
}

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

@ -524,11 +524,7 @@ public class Controls {
public void run() {
if (isFingerprintPressed && miuiPWMContext != null) {
isFingerprintLongPressed = true;
Vibrator v = (Vibrator)miuiPWMContext.getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= 26)
v.vibrate(VibrationEffect.createOneShot(30, VibrationEffect.DEFAULT_AMPLITUDE));
else
v.vibrate(30);
Helpers.performVibration(miuiPWMContext, true);
}
}
};


+ 20
- 11
app/src/main/java/name/mikanoshi/customiuizer/mods/GlobalActions.java View File

@ -4,18 +4,18 @@ import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.RecentTaskInfo;
import android.app.Application;
import android.app.Notification;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
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.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.XModuleResources;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.wifi.WifiManager;
import android.nfc.NfcAdapter;
@ -28,7 +28,6 @@ import android.os.Vibrator;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.lang.reflect.Method;
@ -681,7 +680,11 @@ public class GlobalActions {
mGlobalContext.registerReceiver(mGlobalReceiver, intentfilter);
}
});
} catch (Throwable t) {
XposedBridge.log(t);
}
try {
XposedBridge.hookAllMethods(XposedHelpers.findClass("com.android.server.policy.PhoneWindowManager", lpparam.classLoader), "init", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
@ -713,6 +716,18 @@ public class GlobalActions {
} catch (Throwable t) {
XposedBridge.log(t);
}
// try {
// XposedBridge.hookAllMethods(XposedHelpers.findClass("com.android.server.am.ActivityStackSupervisor", lpparam.classLoader), "getComponentRestrictionForCallingPackage", new XC_MethodHook() {
// @Override
// protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// ActivityInfo ai = (ActivityInfo)param.args[0];
// if (ai != null && ai.name.equals("com.miui.privacyapps.ui.PrivacyAppsOperationTutorialActivity")) param.setResult(0);
// }
// });
// } catch (Throwable t) {
// XposedBridge.log(t);
// }
}
public static void setupStatusBar(LoadPackageParam lpparam) {
@ -1066,18 +1081,12 @@ public class GlobalActions {
return isAllowed;
}
@SuppressLint("MissingPermission")
public static void sendDownUpKeyEvent(Context mContext, int keyCode, boolean vibrate) {
AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
am.dispatchMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
am.dispatchMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
if (vibrate && Helpers.getSharedBoolPref(mContext, "pref_key_controls_volumemedia_vibrate", true)) {
Vibrator v = (Vibrator)mContext.getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= 26)
v.vibrate(VibrationEffect.createOneShot(30, VibrationEffect.DEFAULT_AMPLITUDE));
else
v.vibrate(30);
}
if (vibrate && Helpers.getSharedBoolPref(mContext, "pref_key_controls_volumemedia_vibrate", true))
Helpers.performVibration(mContext);
}
}

+ 92
- 5
app/src/main/java/name/mikanoshi/customiuizer/mods/System.java View File

@ -6,6 +6,7 @@ import android.app.Activity;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@ -31,12 +32,15 @@ import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.provider.Settings;
import android.util.Pair;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@ -55,6 +59,7 @@ import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
@ -310,6 +315,18 @@ public class System {
return Helpers.containsStringPair(trustedNetworks, wifiManager.getConnectionInfo().getBSSID());
}
// private static void setLockScreenDisabled(ClassLoader classLoader, Object thisObject, boolean state) {
// try {
// Class<?> kumCls = findClass("com.android.keyguard.KeyguardUpdateMonitor", classLoader);
// int user = (int)XposedHelpers.callStaticMethod(kumCls, "getCurrentUser");
// Object mLockPatternUtils = XposedHelpers.getObjectField(thisObject, "mLockPatternUtils");
// XposedHelpers.callMethod(mLockPatternUtils, "setLockScreenDisabled", state, user);
// XposedBridge.log("setLockScreenDisabled = " + state + ", " + user);
// } catch (Throwable t) {
// XposedBridge.log(t);
// }
// }
private static boolean isUnlockedOnce = false;
public static void NoScreenLockHook(LoadPackageParam lpparam) {
try {
@ -371,8 +388,7 @@ public class System {
if (Integer.parseInt(Helpers.getSharedStringPref(context, "pref_key_system_noscreenlock", "1")) == 4)
if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo netInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (netInfo.isConnected())
isTrusted = isTrustedWiFi(mContext);
if (netInfo.isConnected()) isTrusted = isTrustedWiFi(mContext);
}
if (isTrusted) {
@ -1309,11 +1325,11 @@ public class System {
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_0_enter", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_0_exit", modRes.fwd(exit));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_180_enter", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_180_exit", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_180_exit", modRes.fwd(exit));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_minus_90_enter", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_minus_90_exit", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_minus_90_exit", modRes.fwd(exit));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_plus_90_enter", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_plus_90_exit", modRes.fwd(enter));
XResources.setSystemWideReplacement("android", "anim", "screen_rotate_plus_90_exit", modRes.fwd(exit));
} catch (Throwable t) {
XposedBridge.log(t);
}
@ -1343,4 +1359,75 @@ public class System {
});
}
public static void CompactNotificationsHook(LoadPackageParam lpparam) {
try {
XposedBridge.hookAllMethods(findClass("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader), "needExtraTopPadding", XC_MethodReplacement.returnConstant(false));
XposedBridge.hookAllMethods(findClass("com.android.systemui.statusbar.phone.StatusBar", lpparam.classLoader), "needExtraBottomPadding", XC_MethodReplacement.returnConstant(false));
} catch (Throwable t) {
XposedBridge.log(t);
}
}
public static void CompactNotificationsRes() {
try {
XModuleResources modRes = XModuleResources.createInstance(MainModule.MODULE_PATH, null);
XResources.setSystemWideReplacement("android", "dimen", "notification_action_height", modRes.fwd(R.dimen.notification_action_height));
XResources.setSystemWideReplacement("android", "dimen", "notification_action_list_height", modRes.fwd(R.dimen.notification_action_height));
} catch (Throwable t) {
XposedBridge.log(t);
}
}
public static void HideFromRecentsHook(LoadPackageParam lpparam) {
XposedBridge.hookAllConstructors(findClass("com.android.server.am.TaskRecord", lpparam.classLoader), new XC_MethodHook() {
@Override
@SuppressLint("WrongConstant")
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
String pkgName = null;
ComponentName origActivity = (ComponentName)XposedHelpers.getObjectField(param.thisObject, "origActivity");
ComponentName realActivity = (ComponentName)XposedHelpers.getObjectField(param.thisObject, "realActivity");
String mCallingPackage = (String)XposedHelpers.getObjectField(param.thisObject, "mCallingPackage");
if (realActivity != null) pkgName = realActivity.getPackageName();
if (pkgName == null && origActivity != null) pkgName = origActivity.getPackageName();
if (pkgName == null) pkgName = mCallingPackage;
Context mContext = (Context)XposedHelpers.getObjectField(param.args[0], "mContext");
Set<String> selectedApps = Helpers.getSharedStringSetPref(mContext, "pref_key_system_hidefromrecents_apps");
if (selectedApps.contains(pkgName)) {
Intent intent = (Intent)XposedHelpers.getObjectField(param.thisObject, "intent");
Intent affinityIntent = (Intent)XposedHelpers.getObjectField(param.thisObject, "affinityIntent");
if (intent != null) intent.addFlags(8388608);
if (affinityIntent != null) affinityIntent.addFlags(8388608);
}
}
});
}
private static List<String> hookedTiles = new ArrayList<String>();
@SuppressLint("StaticFieldLeak") private static Context qsCtx = null;
@SuppressLint("MissingPermission")
public static void QSHapticHook(LoadPackageParam lpparam) {
XposedHelpers.findAndHookMethod("com.android.systemui.qs.tileimpl.QSFactoryImpl", lpparam.classLoader, "createTileInternal", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
Object mHost = XposedHelpers.getObjectField(param.thisObject, "mHost");
qsCtx = (Context)XposedHelpers.callMethod(mHost, "getContext");
Object res = param.getResult();
if (res != null && !hookedTiles.contains(res.getClass().getCanonicalName())) try {
XposedHelpers.findAndHookMethod(res.getClass().getCanonicalName(), lpparam.classLoader, "handleClick", new XC_MethodHook() {
@Override
protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
Helpers.performVibration(qsCtx);
}
});
hookedTiles.add(res.getClass().getCanonicalName());
} catch (Throwable t) {
XposedBridge.log(t);
}
}
});
}
}

+ 20
- 5
app/src/main/java/name/mikanoshi/customiuizer/prefs/CheckBoxPreferenceEx.java View File

@ -8,10 +8,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import name.mikanoshi.customiuizer.R;
public class CheckBoxPreferenceEx extends CheckBoxPreference {
private Resources res = getContext().getResources();
private int primary = res.getColor(res.getIdentifier("preference_primary_text_light", "color", "miui"), getContext().getTheme());
private int secondary = res.getColor(res.getIdentifier("preference_secondary_text_light", "color", "miui"), getContext().getTheme());
public CheckBoxPreferenceEx(Context context) {
super(context);
}
@ -24,12 +26,25 @@ public class CheckBoxPreferenceEx extends CheckBoxPreference {
super(context, attrs, defStyleAttr);
}
@Override
public View getView(View view, ViewGroup parent) {
View finalView = super.getView(view, parent);
TextView title = finalView.findViewById(android.R.id.title);
title.setTextColor(isEnabled() ? primary : secondary);
return finalView;
}
@Override
protected View onCreateView(ViewGroup parent) {
View view = super.onCreateView(parent);
Resources res = getContext().getResources();
((TextView)view.findViewById(android.R.id.title)).setMaxLines(3);
((TextView)view.findViewById(android.R.id.summary)).setTextColor(res.getColor(res.getIdentifier("preference_secondary_text_light", "color", "miui"), getContext().getTheme()));
TextView title = view.findViewById(android.R.id.title);
title.setMaxLines(3);
title.setTextColor(primary);
TextView summary = view.findViewById(android.R.id.summary);
summary.setTextColor(secondary);
return view;
}
}

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

@ -16,6 +16,9 @@ public class ListPreferenceEx extends ListPreference {
private boolean valueAsSummary;
private CharSequence sValue;
private Resources res = getContext().getResources();
private int primary = res.getColor(res.getIdentifier("preference_primary_text_light", "color", "miui"), getContext().getTheme());
private int secondary = res.getColor(res.getIdentifier("preference_secondary_text_light", "color", "miui"), getContext().getTheme());
public ListPreferenceEx(Context context, AttributeSet attrs) {
super(context, attrs);
@ -33,28 +36,36 @@ public class ListPreferenceEx extends ListPreference {
@Override
public View getView(View view, ViewGroup parent) {
View finalView = super.getView(view, parent);
TextView title = finalView.findViewById(android.R.id.title);
TextView summary = finalView.findViewById(android.R.id.summary);
TextView valSummary = finalView.findViewById(android.R.id.hint);
summary.setVisibility(valueAsSummary || summary.getText() == null || summary.getText().equals("") ? View.GONE : View.VISIBLE);
valSummary.setVisibility(valueAsSummary ? View.VISIBLE : View.GONE);
valSummary.setText(valueAsSummary ? sValue : "");
title.setTextColor(isEnabled() ? primary : secondary);
return finalView;
}
@Override
protected View onCreateView(ViewGroup parent) {
ViewGroup view = (ViewGroup)super.onCreateView(parent);
((TextView)view.findViewById(android.R.id.title)).setMaxLines(3);
TextView title = view.findViewById(android.R.id.title);
title.setMaxLines(3);
title.setTextColor(primary);
TextView summary = view.findViewById(android.R.id.summary);
summary.setTextColor(secondary);
Resources res = getContext().getResources();
summary.setTextColor(res.getColor(res.getIdentifier("preference_secondary_text_light", "color", "miui"), getContext().getTheme()));
TextView valSummary = new TextView(getContext());
valSummary.setTextSize(TypedValue.COMPLEX_UNIT_PX, summary.getTextSize());
valSummary.setTextColor(summary.getCurrentTextColor());
valSummary.setPadding(summary.getPaddingLeft(), summary.getPaddingTop(), res.getDimensionPixelSize(R.dimen.preference_summary_padding_right), summary.getPaddingBottom());
valSummary.setId(android.R.id.hint);
view.addView(valSummary, 2);
return view;
}
}

+ 16
- 4
app/src/main/java/name/mikanoshi/customiuizer/prefs/PreferenceEx.java View File

@ -17,6 +17,10 @@ import name.mikanoshi.customiuizer.utils.Helpers;
public class PreferenceEx extends Preference {
private Resources res = getContext().getResources();
private int primary = res.getColor(res.getIdentifier("preference_primary_text_light", "color", "miui"), getContext().getTheme());
private int secondary = res.getColor(res.getIdentifier("preference_secondary_text_light", "color", "miui"), getContext().getTheme());
private boolean countAsSummary;
public PreferenceEx(Context context, AttributeSet attrs) {
@ -27,31 +31,39 @@ public class PreferenceEx extends Preference {
}
@Override
@SuppressWarnings("ConstantConditions")
public View getView(View view, ViewGroup parent) {
View finalView = super.getView(view, parent);
TextView title = finalView.findViewById(android.R.id.title);
TextView summary = finalView.findViewById(android.R.id.summary);
TextView valSummary = finalView.findViewById(android.R.id.hint);
summary.setVisibility(countAsSummary || summary.getText() == null || summary.getText().equals("") ? View.GONE : View.VISIBLE);
valSummary.setVisibility(countAsSummary ? View.VISIBLE : View.GONE);
//noinspection ConstantConditions
valSummary.setText(countAsSummary ? String.valueOf(Helpers.prefs.getStringSet(getKey(), new LinkedHashSet<String>()).size()) : null);
title.setTextColor(isEnabled() ? primary : secondary);
return finalView;
}
@Override
protected View onCreateView(ViewGroup parent) {
ViewGroup view = (ViewGroup)super.onCreateView(parent);
((TextView)view.findViewById(android.R.id.title)).setMaxLines(3);
TextView title = view.findViewById(android.R.id.title);
title.setMaxLines(3);
title.setTextColor(primary);
TextView summary = view.findViewById(android.R.id.summary);
summary.setTextColor(secondary);
Resources res = getContext().getResources();
summary.setTextColor(res.getColor(res.getIdentifier("preference_secondary_text_light", "color", "miui"), getContext().getTheme()));
TextView valSummary = new TextView(getContext());
valSummary.setTextSize(TypedValue.COMPLEX_UNIT_PX, summary.getTextSize());
valSummary.setTextColor(summary.getCurrentTextColor());
valSummary.setPadding(summary.getPaddingLeft(), summary.getPaddingTop(), res.getDimensionPixelSize(R.dimen.preference_summary_padding_right), summary.getPaddingBottom());
valSummary.setId(android.R.id.hint);
view.addView(valSummary, 2);
return view;
}
}

+ 26
- 1
app/src/main/java/name/mikanoshi/customiuizer/subs/AppSelector.java View File

@ -1,11 +1,15 @@
package name.mikanoshi.customiuizer.subs;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Set;
@ -14,10 +18,12 @@ import name.mikanoshi.customiuizer.SubFragmentWithSearch;
import name.mikanoshi.customiuizer.utils.AppData;
import name.mikanoshi.customiuizer.utils.AppDataAdapter;
import name.mikanoshi.customiuizer.utils.Helpers;
import name.mikanoshi.customiuizer.utils.PrivacyAppAdapter;
public class AppSelector extends SubFragmentWithSearch {
boolean multi = false;
boolean privacy = false;
String key = null;
@Override
@ -31,6 +37,7 @@ public class AppSelector extends SubFragmentWithSearch {
super.onActivityCreated(savedInstanceState);
multi = getArguments().getBoolean("multi");
privacy = getArguments().getBoolean("privacy");
key = getArguments().getString("key");
final Runnable process = new Runnable() {
@ -39,6 +46,9 @@ public class AppSelector extends SubFragmentWithSearch {
if (multi && key != null) {
if (Helpers.installedAppsList == null) return;
listView.setAdapter(new AppDataAdapter(getContext(), Helpers.installedAppsList, key));
} else if (privacy) {
if (Helpers.installedAppsList == null) return;
listView.setAdapter(new PrivacyAppAdapter(getContext(), Helpers.installedAppsList));
} else {
if (Helpers.launchableAppsList == null) return;
listView.setAdapter(new AppDataAdapter(getContext(), Helpers.launchableAppsList));
@ -57,6 +67,21 @@ public class AppSelector extends SubFragmentWithSearch {
AppDataAdapter adapter = (AppDataAdapter)parent.getAdapter();
adapter.updateSelectedApps();
adapter.notifyDataSetChanged();
} else if (privacy) {
AppData app = (AppData)parent.getAdapter().getItem(position);
try {
@SuppressLint("WrongConstant") Object mSecurityManager = getActivity().getSystemService("security");
Method isPrivacyApp = mSecurityManager.getClass().getDeclaredMethod("isPrivacyApp", String.class, int.class);
isPrivacyApp.setAccessible(true);
Method setPrivacyApp = mSecurityManager.getClass().getDeclaredMethod("setPrivacyApp", String.class, int.class, boolean.class);
setPrivacyApp.setAccessible(true);
setPrivacyApp.invoke(mSecurityManager, app.pkgName, 0, !(boolean)isPrivacyApp.invoke(mSecurityManager, app.pkgName, 0));
PrivacyAppAdapter adapter = (PrivacyAppAdapter)parent.getAdapter();
adapter.notifyDataSetChanged();
getActivity().getContentResolver().notifyChange(Uri.parse("content://com.miui.securitycenter.provider/update_privacyapps_icon"), null);
} catch (Throwable t) {
t.printStackTrace();
}
} else {
Intent intent = new Intent(getContext(), this.getClass());
AppData app = (AppData)parent.getAdapter().getItem(position);
@ -75,7 +100,7 @@ public class AppSelector extends SubFragmentWithSearch {
public void run() {
try { sleep(animDur); } catch (Throwable e) {}
try {
if (multi && key != null) {
if (privacy || multi && key != null) {
if (Helpers.installedAppsList == null) Helpers.getInstalledApps(getActivity());
} else {
if (Helpers.launchableAppsList == null) Helpers.getLaunchableApps(getActivity());


+ 68
- 16
app/src/main/java/name/mikanoshi/customiuizer/subs/Launcher.java View File

@ -1,8 +1,11 @@
package name.mikanoshi.customiuizer.subs;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.provider.Settings;
import name.mikanoshi.customiuizer.R;
import name.mikanoshi.customiuizer.SubFragment;
@ -15,7 +18,7 @@ public class Launcher extends SubFragment {
super.onActivityCreated(savedInstanceState);
//setupImmersiveMenu();
CheckBoxPreference.OnPreferenceClickListener openSwipeEdit = new CheckBoxPreference.OnPreferenceClickListener() {
Preference.OnPreferenceClickListener openSwipeEdit = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Bundle args = new Bundle();
@ -25,21 +28,70 @@ public class Launcher extends SubFragment {
}
};
Preference swipePref;
swipePref = findPreference("pref_key_launcher_swipedown");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
swipePref = findPreference("pref_key_launcher_swipedown2");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
swipePref = findPreference("pref_key_launcher_swipeup");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
swipePref = findPreference("pref_key_launcher_swipeup2");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
swipePref = findPreference("pref_key_launcher_swiperight");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
swipePref = findPreference("pref_key_launcher_swipeleft");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
swipePref = findPreference("pref_key_launcher_shake");
swipePref.setOnPreferenceClickListener(openSwipeEdit);
CheckBoxPreference.OnPreferenceChangeListener switchPrivacyAppState = new CheckBoxPreference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Settings.Secure.putInt(getActivity().getContentResolver(), "is_privacy_apps_enable", (boolean)newValue ? 1 : 0);
return true;
}
};
Preference.OnPreferenceClickListener openPrivacyAppEdit = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Bundle args = new Bundle();
args.putBoolean("privacy", true);
AppSelector appSelector = new AppSelector();
appSelector.setTargetFragment(Launcher.this, 0);
openSubFragment(appSelector, args, Helpers.SettingsType.Edit, Helpers.ActionBarType.HomeUp, R.string.select_app, R.layout.prefs_app_selector);
return true;
}
};
Preference pref;
pref = findPreference("pref_key_launcher_swipedown");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_swipedown2");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_swipeup");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_swipeup2");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_swiperight");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_swipeleft");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_shake");
pref.setOnPreferenceClickListener(openSwipeEdit);
pref = findPreference("pref_key_launcher_privacyapps_list");
pref.setOnPreferenceClickListener(openPrivacyAppEdit);
pref = findPreference("pref_key_launcher_privacyapps_gest");
pref.setOnPreferenceChangeListener(switchPrivacyAppState);
PackageManager pm = getActivity().getPackageManager();
if (!checkPermissions()) {
pref = findPreference("pref_key_launcher_privacyapps");
pref.setEnabled(false);
pref.setTitle(R.string.launcher_privacyapps_fail);
}
}
@Override
public void onResume() {
super.onResume();
PackageManager pm = getActivity().getPackageManager();
if (checkPermissions()) {
Preference pref = findPreference("pref_key_launcher_privacyapps_gest");
((CheckBoxPreference)pref).setChecked(Settings.Secure.getInt(getActivity().getContentResolver(), "is_privacy_apps_enable", 0) == 1);
}
}
private boolean checkPermissions() {
PackageManager pm = getActivity().getPackageManager();
return pm.checkPermission(Manifest.permission.WRITE_SECURE_SETTINGS, Helpers.modulePkg) == PackageManager.PERMISSION_GRANTED &&
pm.checkPermission("com.miui.securitycenter.permission.ACCESS_SECURITY_CENTER_PROVIDER", Helpers.modulePkg) == PackageManager.PERMISSION_GRANTED;
}
// public boolean onCreateOptionsMenu(Menu menu) {


+ 8
- 0
app/src/main/java/name/mikanoshi/customiuizer/subs/System.java View File

@ -57,6 +57,14 @@ public class System extends SubFragment {
return true;
}
});
findPreference("pref_key_system_hidefromrecents_apps").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
openApps("pref_key_system_hidefromrecents_apps");
return true;
}
});
}
public void openWifiNetworks() {


+ 50
- 11
app/src/main/java/name/mikanoshi/customiuizer/utils/Helpers.java View File

@ -8,6 +8,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import android.Manifest;
@ -29,15 +30,21 @@ import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
import android.util.LruCache;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewGroup;
import de.robv.android.xposed.XposedBridge;
import miui.util.HapticFeedbackUtil;
import name.mikanoshi.customiuizer.GateWayLauncher;
import name.mikanoshi.customiuizer.MainModule;
import name.mikanoshi.customiuizer.R;
import name.mikanoshi.customiuizer.SharedPrefsProvider;
@ -74,6 +81,10 @@ public class Helpers {
HomeUp, Edit
}
public static boolean isLauncherIconVisible(Context context) {
return context.getPackageManager().getComponentEnabledSetting(new ComponentName(context, GateWayLauncher.class)) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
}
public static boolean isXposedInstallerInstalled(Context mContext) {
PackageManager pm = mContext.getPackageManager();
try {
@ -305,6 +316,32 @@ public class Helpers {
}
return null;
}
public static void performVibration(Context mContext) {
performVibration(mContext, false);
}
public static void performVibration(Context mContext, boolean ignoreOff) {
if (mContext == null) return;
HapticFeedbackUtil mHapticFeedbackUtil = new HapticFeedbackUtil(mContext, false);
mHapticFeedbackUtil.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, ignoreOff);
// int state = 1;
// int level = 1;
// try {
// state = Settings.System.getInt(mContext.getContentResolver(), "haptic_feedback_enabled");
// level = Settings.System.getInt(mContext.getContentResolver(), "haptic_feedback_level");
// } catch (Throwable t) {
// XposedBridge.log(t);
// }
// if (state == 0) return;
//
// Vibrator v = (Vibrator)mContext.getSystemService(Context.VIBRATOR_SERVICE);
// if (Build.VERSION.SDK_INT >= 26)
// v.vibrate(VibrationEffect.createOneShot(30, VibrationEffect.DEFAULT_AMPLITUDE));
// else
// v.vibrate(30);
}
// public static void removePref(PreferenceFragmentBase frag, String prefName, String catName) {
// if (frag.findPreference(prefName) != null) {
@ -324,15 +361,7 @@ public class Helpers {
@SuppressLint({"SetWorldReadable", "SetWorldWritable"})
public static void fixPermissionsAsync(Context context) {
AsyncTask.execute(() -> {
Context mContext;
try {
mContext = Helpers.getProtectedContext(context);
} catch (Throwable t) {
Log.e("prefs", "Failed to fix permissions on protected storage!");
mContext = context;
}
File pkgFolder = mContext.getDataDir();
File pkgFolder = context.getDataDir();
if (pkgFolder.exists()) {
pkgFolder.setExecutable(true, false);
pkgFolder.setReadable(true, false);
@ -379,13 +408,23 @@ public class Helpers {
}
}
public static synchronized Context getLocaleContext(Context context) throws Throwable {
if (prefs != null && prefs.getBoolean("pref_key_miuizer_forcelocale", false)) {
Configuration config = context.getResources().getConfiguration();
config.setLocale(Locale.ENGLISH);
return context.createConfigurationContext(config);
} else {
return context;
}
}
public static synchronized Context getModuleContext(Context context) throws Throwable {
return context.createPackageContext(modulePkg, Context.CONTEXT_IGNORE_SECURITY).createDeviceProtectedStorageContext();
}
public static synchronized Context getProtectedContext(Context context, Configuration config) throws Throwable {
Context mContext = context.isDeviceProtectedStorage() ? context : context.createDeviceProtectedStorageContext();
return (config == null ? mContext : mContext.createConfigurationContext(config));
return getLocaleContext(config == null ? mContext : mContext.createConfigurationContext(config));
}
public static synchronized Context getProtectedContext(Context context) throws Throwable {


+ 138
- 0
app/src/main/java/name/mikanoshi/customiuizer/utils/PrivacyAppAdapter.java View File

@ -0,0 +1,138 @@
package name.mikanoshi.customiuizer.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import name.mikanoshi.customiuizer.R;
public class PrivacyAppAdapter extends BaseAdapter implements Filterable {
private Context ctx;
private LayoutInflater mInflater;
private ThreadPoolExecutor pool;
private ItemFilter mFilter = new ItemFilter();
private ArrayList<AppData> originalAppList;
private ArrayList<AppData> filteredAppList;
private Object mSecurityManager;
private Method isPrivacyApp;
@SuppressLint("WrongConstant")
public PrivacyAppAdapter(Context context, ArrayList<AppData> arr) {
ctx = context;
mInflater = LayoutInflater.from(context);
originalAppList = arr;
filteredAppList = arr;
int cpuCount = Runtime.getRuntime().availableProcessors();
pool = new ThreadPoolExecutor(cpuCount + 1, cpuCount * 2 + 1, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
try {
mSecurityManager = context.getSystemService("security");
isPrivacyApp = mSecurityManager.getClass().getDeclaredMethod("isPrivacyApp", String.class, int.class);
isPrivacyApp.setAccessible(true);
} catch (Throwable t) {
t.printStackTrace();
}
}
public int getCount() {
return filteredAppList.size();
}
public AppData getItem(int position) {
return filteredAppList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View row;
if (convertView != null)
row = convertView;
else
row = mInflater.inflate(R.layout.applist_item, parent, false);
ImageView itemIsDis = row.findViewById(R.id.am_isDisable_icon);
CheckBox itemChecked = row.findViewById(R.id.am_checked_icon);
TextView itemTitle = row.findViewById(R.id.am_label);
ImageView itemIcon = row.findViewById(R.id.am_icon);
AppData ad = getItem(position);
itemIcon.setTag(position);
itemTitle.setText(ad.label);
itemIsDis.setVisibility(ad.enabled ? View.INVISIBLE : View.VISIBLE);
Bitmap icon = Helpers.memoryCache.get(ad.pkgName + "|" + ad.actName);
//int iconSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
if (icon == null) {
Drawable[] dualIcon = new Drawable[1];
dualIcon[0] = ctx.getResources().getDrawable(R.drawable.card_icon_default, ctx.getTheme());
TransitionDrawable crossfader = new TransitionDrawable(dualIcon);
crossfader.setCrossFadeEnabled(true);
itemIcon.setImageDrawable(crossfader);
(new BitmapCachedLoader(itemIcon, ad, ctx)).executeOnExecutor(pool);
} else {
itemIcon.setImageBitmap(icon);
}
try {
itemChecked.setVisibility(View.VISIBLE);
itemChecked.setChecked((boolean)isPrivacyApp.invoke(mSecurityManager, ad.pkgName, 0));
} catch (Throwable t) {
itemChecked.setVisibility(View.GONE);
}
return row;
}
private class ItemFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
int count = originalAppList.size();
final ArrayList<AppData> nlist = new ArrayList<AppData>();
AppData filterableData;
for (int i = 0; i < count; i++) {
filterableData = originalAppList.get(i);
if (filterableData.label.toLowerCase().contains(filterString)) nlist.add(filterableData);
}
results.values = nlist;
results.count = nlist.size();
return results;
}
@Override
@SuppressWarnings("unchecked")
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredAppList = (ArrayList<AppData>)results.values;
notifyDataSetChanged();
}
}
@Override
public Filter getFilter() {
return mFilter;
}
}

+ 1
- 1
app/src/main/res/animator/fragment_close_enter.xml View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<set></set>
<set />

+ 1
- 1
app/src/main/res/animator/fragment_close_exit.xml View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<set></set>
<set />

+ 1
- 1
app/src/main/res/animator/fragment_open_enter.xml View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<set></set>
<set />

+ 1
- 1
app/src/main/res/animator/fragment_open_exit.xml View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<set></set>
<set />

app/src/main/res/values-ru/strings.xml → app/src/main/res/values-ru-rRU/strings.xml View File

@ -216,8 +216,12 @@
<string name="miuizer_acrasend_summ">Собрать данные об устройтве и переменных окружения, logcat и Xposed лог, и отправить их разработчику.\nДля отправки требуется интернет</string>
<string name="miuizer_acrasend_title">Отправить подробный отчёт</string>
<string name="miuizer_theme_title">Тема</string>
<string name="miuizer_show_icon_summ">Показывать иконку в Настройках</string>
<string name="miuizer_show_icon_title">Иконка быстрого доступа</string>
<string name="miuizer_show_launchericon_title">Иконка в ланчере</string>
<string name="miuizer_show_launchericon_summ">Показывать иконку в ланчерах</string>
<string name="miuizer_show_settingsicon_title">Иконка быстрого доступа</string>
<string name="miuizer_show_settingsicon_summ">Показывать иконку в Настройках</string>
<string name="miuizer_forcelocale_title">Интерфейс на английском</string>
<string name="miuizer_forcelocale_summ">Всегда отображать интерфейс модуля на английском языке</string>
<string name="open_xposed">Открыть Xposed Installer</string>
<string name="search_input_description">Поиск</string>
<string name="wifi_networks">Wi-Fi сети</string>
@ -234,6 +238,12 @@
<string name="launcher_folder_cols_title">Число колонок в папках</string>
<string name="launcher_foldershade_title">Фон папок</string>
<string name="launcher_foldershade_summ">Затемнённый фон папок</string>
<string name="launcher_privacyapps">Скрытые приложения</string>
<string name="launcher_privacyapps_fail">Не получены необходимые разрешения</string>
<string name="launcher_privacyapps_gest_title">Скрытая папка</string>
<string name="launcher_privacyapps_gest_summ">Для открытия папки со скрытыми приложениями необходимо развести два пальца на рабочем столе MIUI. Перезагрузка не требуется.</string>
<string name="launcher_privacyapps_list_title">Список приложений для скрытия</string>
<string name="launcher_privacyapps_list_summ">Улучшенная версия функции Скрытые приложения, позволяющая скрыть любое установленное приложение. Перезагрузка не требуется.</string>
<string name="settings">Настройки</string>
<string name="support_repo_summ">Git репозиторий с исходниками и дистрибутивами модуля</string>
<string name="support_repo_title">Репозиторий CustoMIUIzer</string>
@ -245,6 +255,8 @@
<string name="system_iconlabletoasts_title">Расширенные уведомления *</string>
<string name="system_downgrade_title">Разрешить понижение версии</string>
<string name="system_downgrade_summ">Делает возможным установку старой версии приложения поверх новой</string>
<string name="system_hidefromrecents_title">Скрыть в недавних</string>
<string name="system_hidefromrecents_summ">Убирает выбранные приложения из списка недавно использованных</string>
<string name="system_mods">Система</string>
<string name="system_mods_screen">Экран</string>
<string name="system_mods_audio">Аудио</string>
@ -256,6 +268,8 @@
<string name="system_betterpopups_nohide_summ">Отключает автоматическое скрытие</string>
<string name="system_betterpopups_swipedown_title">Активировать свайп вниз</string>
<string name="system_betterpopups_swipedown_summ">Открывает панель уведомлений по свайпу вниз</string>
<string name="system_qshaptic_title">Виброотклик при переключении настроек</string>
<string name="system_qshaptic_summ">Включает вибрирование при нажатии на переключатели в Быстрых настройках</string>
<string name="system_clockseconds_title">Показывать секунды</string>
<string name="system_clockseconds_summ">Отображает секунды на часах в статусбаре</string>
<string name="system_mobiletypeicon_title">Скрывать тип мобильной сети</string>
@ -272,6 +286,8 @@
<string name="system_detailednetspeed_lowlevel_summ">Задаёт уровень, ниже которого скорость будет считаться низкой и будет иметь другую иконку</string>
<string name="system_fixmeter_title">Отступ скорости соединения</string>
<string name="system_fixmeter_summ">Увеличивает отступ справа для индикатора скорости соединения</string>
<string name="system_compactnotif_title">Компактные уведомления</string>
<string name="system_compactnotif_summ">Уменьшает вертикальные отступы в уведомлениях</string>
<string name="system_colorizenotiftitle_title">Раскрасить заголовок уведомления</string>
<string name="system_colorizenotiftitle_summ">Применяет цвет иконки к заголовку (только для стиля уведомлений Android)</string>
<string name="system_expandnotifs_title">Разворачивать уведомления</string>

+ 269
- 0
app/src/main/res/values-zh-rCN/strings.xml View File

@ -0,0 +1,269 @@
<?xml version="1.0"?>
<resources>
<string name="app_about">关于</string>
<string name="about_version">版本 %1$s</string>
<string name="about_dev">作者 Mikanoshi</string>
<string name="about_dynamic">通常,激活或者停用模块需要软重启,但那些标记*的模块在其值从默认值更改为自定义值后只需软重启一次,以后的更改将立即应用。</string>
<string name="mods">模块</string>
<string name="system_mods">系统</string>
<string name="system_mods_screen">屏幕</string>
<string name="system_mods_audio">音频</string>
<string name="system_mods_screenanim">屏幕动画*</string>
<string name="system_clockseconds_title">显示秒</string>
<string name="system_clockseconds_summ">在状态栏时钟显示秒</string>
<string name="system_netspeedinterval_title">网速更新间隔</string>
<string name="system_netspeedinterval_summ">需要修改系统设置权限</string>
<string name="system_detailednetspeed_title">详细的网速指示器</string>
<string name="system_detailednetspeed_summ">分别显示传入和传出的网络速度</string>
<string name="system_detailednetspeed_icon_title">指示器图标</string>
<string name="system_detailednetspeed_icon_summ">网速旁显示传入/传出流量图标 (并非所有的自定义字体都包含所有图标)</string>
<string name="system_detailednetspeed_low_title">隐藏低速</string>
<string name="system_detailednetspeed_low_summ">网速低时不再显示指示器</string>
<string name="system_detailednetspeed_lowlevel_title">低速水平</string>
<string name="system_detailednetspeed_lowlevel_summ">网速值低于此水平时将被视为低并将显示不同的指示器图标</string>
<string name="system_fixmeter_title">网速间距</string>
<string name="system_fixmeter_summ">增加网速指示器的右侧边距</string>
<string name="system_chargeanimtime_title">充电动画屏幕超时*</string>
<string name="system_chargeanimtime_summ">充电动画开始后保持亮屏的时间</string>
<string name="system_nolightuponcharges_title">充电时不亮起屏幕</string>
<string name="system_nolightuponcharges_summ">当您连接或者断开充电器时不打开屏幕</string>
<string name="system_nolightuponheadset_title">连接耳机时不亮起屏幕</string>
<string name="system_nolightuponheadset_summ">当您连接耳机时不打开屏幕</string>
<string name="system_separatevolume_title">独立音量控制</string>
<string name="system_separatevolume_summ">允许单独配置设置中的铃声/通知/系统声音的音量</string>
<string name="system_volumesteps_title">音量级数倍增器</string>
<string name="system_volumesteps_summ">增加每种流类型的音量级数</string>
<string name="notification_volume">通知音量</string>
<string name="system_volume">系统声音音量</string>
<string name="system_scramblepin_title">乱序PIN</string>
<string name="system_scramblepin_summ">随机更改PIN键盘顺序</string>
<string name="system_securelock_title">增强屏幕锁</string>
<string name="system_securelock_summ">屏幕锁激活时禁用电源菜单</string>
<string name="system_nopassword_title">开机免密</string>
<string name="system_nopassword_summ">开机后首次解锁不需要密码</string>
<string name="system_noscreenlock_act_title">屏幕锁覆盖</string>
<string name="system_noscreenlock_act_summ">激活动态屏幕锁控制</string>
<string name="system_noscreenlock_title">禁用屏幕锁*</string>
<string name="system_noscreenlock_summ">选择性禁用屏幕锁(不会更改任何应用的安全性,也不会移除指纹数据)</string>
<string name="system_noscreenlock_scr_title">跳过屏幕锁*</string>
<string name="system_noscreenlock_scr_summ">屏幕锁禁用时不再显示锁屏</string>
<string name="system_noscreenlock_wifi_title">受信任的Wi-Fi网络*</string>
<string name="system_noscreenlock_wifi_summ">连接到这些网络时暂时禁用屏幕锁</string>
<string name="system_screenanim_duration_title">关闭动画*</string>
<string name="system_screenanim_duration_summ">配置动画长度</string>
<string name="system_screenanim_desc">值太低会禁用动画</string>
<string name="system_mods_blur">模糊度*</string>
<string name="system_recents_blur_title">最近应用</string>
<string name="system_recents_blur_summ">最近应用的背景模糊度</string>
<string name="system_drawer_blur_title">通知抽屉</string>
<string name="system_drawer_blur_summ">通知抽屉的背景模糊度</string>
<string name="system_drawer_opacity_title">主题背景不透明度</string>
<string name="system_drawer_opacity_summ">主题通知抽屉背景的不透明度</string>
<string name="system_mods_lockscreen">锁屏</string>
<string name="system_iconlabletoasts_title">增强toast*</string>
<string name="system_iconlabletoasts_summ">将应用程序的图标和文字添加到其toast</string>
<string name="system_rotateanim_title">旋转动画</string>
<string name="system_dttosleep_title">双击熄屏</string>
<string name="system_dttosleep_summ">双击锁屏任意空白处关闭屏幕</string>
<string name="system_mods_statusbar">状态栏和通知抽屉</string>
<string name="launcher_mods">MIUI启动器</string>
<string name="launcher_gestures">