/* * Copyright (C) 2013 75py * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.nagopy.android.xposed.utilities; import android.app.KeyguardManager; import android.content.Context; import android.content.res.XResources; import android.os.Build; import android.util.TypedValue; import android.view.KeyEvent; import android.widget.Button; import com.nagopy.android.xposed.util.XConst; import com.nagopy.android.xposed.util.XUtil; import com.nagopy.android.xposed.utilities.XposedModules.HandleLoadPackage; import com.nagopy.android.xposed.utilities.XposedModules.InitZygote; import com.nagopy.android.xposed.utilities.XposedModules.XMinSdkVersion; import com.nagopy.android.xposed.utilities.XposedModules.XposedModule; import com.nagopy.android.xposed.utilities.setting.ModOtherUtilitiesSettingsGen; import de.robv.android.xposed.IXposedHookZygoteInit.StartupParam; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; @XposedModule(setting = ModOtherUtilitiesSettingsGen.class) public class ModOtherUtilities { @InitZygote(summary = "IME通知表示有無") public static void setShowOngoingImeSwitcher(StartupParam startupParam, ModOtherUtilitiesSettingsGen mOtherUtilitiesSettings) throws Throwable { XResources.setSystemWideReplacement("android", "bool", "show_ongoing_ime_switcher", mOtherUtilitiesSettings.showOngoingImeSwitcher); } @InitZygote(summary = "ActionMenuのテキスト表示") public static void setConfigAllowActionMenuItemTextWithIcon(StartupParam startupParam, ModOtherUtilitiesSettingsGen mOtherUtilitiesSettings) throws Throwable { XResources.setSystemWideReplacement("android", "bool", "config_allowActionMenuItemTextWithIcon", mOtherUtilitiesSettings.configAllowActionMenuItemTextWithIcon); } @InitZygote(summary = "カメラ シャッター音") @XMinSdkVersion(Build.VERSION_CODES.JELLY_BEAN_MR1) public static void setConfigCameraSoundForced(StartupParam startupParam, ModOtherUtilitiesSettingsGen mOtherUtilitiesSettings) throws Throwable { XResources.setSystemWideReplacement("android", "bool", "config_camera_sound_forced", mOtherUtilitiesSettings.configCameraSoundForced); } @InitZygote(summary = "音量ボタンでスリープ復帰") @XMinSdkVersion(Build.VERSION_CODES.JELLY_BEAN_MR1) public static void volumeRockerWake(StartupParam startupParam, ModOtherUtilitiesSettingsGen mOtherUtilitiesSettings) throws Throwable { if (!mOtherUtilitiesSettings.volumeRockerWake) { return; } // PhoneWindowManagerのクラスを取得 Class<?> phoneWindowManager = XposedHelpers.findClass( "com.android.internal.policy.impl.PhoneWindowManager", null); // isWakeKeyWhenScreenOffを書き換え XposedHelpers.findAndHookMethod(phoneWindowManager, "isWakeKeyWhenScreenOff", int.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { int keyCode = (Integer) param.args[0]; switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: // 音量アップ・ダウンボタンの場合はtrueを返す return true; default: // それ以外のボタンの場合は、オリジナルのメソッドを実行 return XUtil.invokeOriginalMethod(param); } } }); } @HandleLoadPackage(summary = "メニューキー表示", targetPackage = XConst.PKG_SYSTEM_UI) public static void setMenuVisibility(String modulePath, LoadPackageParam lpparam, ModOtherUtilitiesSettingsGen mOtherUtilitiesSettings) throws Throwable { if (!mOtherUtilitiesSettings.showMenuKey) { return; } Class<?> navigationBarViewClass = XposedHelpers.findClass( "com.android.systemui.statusbar.phone.NavigationBarView", lpparam.classLoader); XposedHelpers.findAndHookMethod(navigationBarViewClass, "setMenuVisibility", boolean.class, boolean.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { Context mContext = (Context) XposedHelpers.getObjectField( param.thisObject, "mContext"); KeyguardManager keyguardManager = (KeyguardManager) mContext .getSystemService(Context.KEYGUARD_SERVICE); if (keyguardManager.inKeyguardRestrictedInputMode()) { return XUtil.invokeOriginalMethod(param); } // キーガード表示中以外ではtrue(表示)にして実行する Object[] args = { true, true }; return XposedBridge.invokeOriginalMethod(param.method, param.thisObject, args); } }); XposedBridge.hookAllConstructors(navigationBarViewClass, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { XposedHelpers.setBooleanField(param.thisObject, "mShowMenu", true); } }); } @HandleLoadPackage(targetPackage = XConst.PKG_KEYGUARD, summary = "緊急通報ボタン") @XMinSdkVersion(Build.VERSION_CODES.KITKAT) public static void preventEmergencyButtonMissTap( final String modulePath, final LoadPackageParam lpparam, final ModOtherUtilitiesSettingsGen settings) throws Throwable { if (!settings.preventEmergencyButtonMissTap) { return; } Class<?> clsEmergencyButton = XposedHelpers.findClass( "com.android.keyguard.EmergencyButton", lpparam.classLoader); XposedHelpers.findAndHookMethod(clsEmergencyButton, "onFinishInflate", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { Button button = (Button) param.thisObject; XposedHelpers.setAdditionalInstanceField(button, "size", button.getTextSize()); } }); XposedHelpers.findAndHookMethod(clsEmergencyButton, "takeEmergencyCallAction", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { Button button = (Button) param.thisObject; Object flag = XposedHelpers.getAdditionalInstanceField(button, "flag"); if (flag == null) { XposedHelpers.setAdditionalInstanceField(button, "flag", true); button.setTextSize(TypedValue.COMPLEX_UNIT_PX, button.getTextSize() * 1.25f); param.setResult(null); } else { XposedHelpers.removeAdditionalInstanceField(button, "flag"); button.setTextSize(TypedValue.COMPLEX_UNIT_PX, (Float) XposedHelpers .getAdditionalInstanceField(button, "size")); } } }); XposedHelpers.findAndHookMethod(clsEmergencyButton, "onAttachedToWindow", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { XposedHelpers.removeAdditionalInstanceField(param.thisObject, "flag"); Button button = (Button) param.thisObject; button.setTextSize(TypedValue.COMPLEX_UNIT_PX, (Float) XposedHelpers .getAdditionalInstanceField(button, "size")); } }); } }