package kz.virtex.htc.tweaker.mods;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import kz.virtex.htc.tweaker.Const;
import kz.virtex.htc.tweaker.Misc;
import kz.virtex.htc.tweaker.R;
import kz.virtex.htc.tweaker.XMain;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.XModuleResources;
import android.content.res.XResources;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
import android.telephony.TelephonyManager;
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.XC_MethodHook.MethodHookParam;
import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
public class Phone
{
private static Object DualCallSettingsPreference;
private static Object CallFeaturesSetting;
public static void hookServiceState()
{
final Class<?> IccRecords = XposedHelpers.findClass("android.telephony.ServiceState", null);
XposedHelpers.findAndHookConstructor(IccRecords, "android.os.Parcel", new XC_MethodHook()
{
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
//XposedBridge.log("--------------");
//XposedBridge.log("mOperatorAlphaLong: " + XposedHelpers.getObjectField(param.thisObject, "mOperatorAlphaLong"));
//XposedBridge.log("mOperatorAlphaShort: " + XposedHelpers.getObjectField(param.thisObject, "mOperatorAlphaShort"));
//XposedBridge.log("mOperatorNumeric: " + XposedHelpers.getObjectField(param.thisObject, "mOperatorNumeric"));
//XposedBridge.log("mPhoneType: " + XposedHelpers.getObjectField(param.thisObject, "mPhoneType"));
//XposedHelpers.setObjectField(param.thisObject, "mOperatorAlphaLong", "Long " + XposedHelpers.getObjectField(param.thisObject, "mPhoneType"));
//XposedHelpers.setObjectField(param.thisObject, "mOperatorAlphaShort", "Short " + XposedHelpers.getObjectField(param.thisObject, "mPhoneType"));
//XposedHelpers.setObjectField(param.thisObject, "mOperatorNumeric", "Number " + XposedHelpers.getObjectField(param.thisObject, "mPhoneType"));
}
});
}
/*
public static void hookServiceState2()
{
final Class<?> IccRecords = XposedHelpers.findClass("com.android.internal.telephony.cdma.HtcCdmaOperatorName", null);
XposedHelpers.findAndHookMethod(IccRecords, "getOperatorInfo", new XC_MethodHook()
{
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
Object OperatorInfo = param.getResult();
XposedHelpers.setObjectField(OperatorInfo, "showSpn", true);
XposedHelpers.setObjectField(OperatorInfo, "showPlmn", false);
XposedHelpers.setObjectField(OperatorInfo, "spn", XMain.pref.getString("spn_1_user_text", (String) XposedHelpers.getObjectField(OperatorInfo, "spn")));
}
});
}
*/
public static void hookServiceProviderName()
{
final Class<?> IccRecords = XposedHelpers.findClass("com.android.internal.telephony.uicc.IccRecords", null);
findAndHookMethod(IccRecords, "getServiceProviderName", new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
int getIccPhoneSlot = (Integer) XposedHelpers.callMethod(param.thisObject, "getIccPhoneSlot");
// int getIccPhoneType = (Integer)
// XposedHelpers.callMethod(param.thisObject,
// "getIccPhoneType");
if (TelephonyManager.PHONE_SLOT1 == getIccPhoneSlot)
return XMain.pref.getString("spn_1_user_text", (String) XposedHelpers.getObjectField(param.thisObject, "mSpn"));
if (TelephonyManager.PHONE_SLOT2 == getIccPhoneSlot)
return XMain.pref.getString("spn_2_user_text", (String) XposedHelpers.getObjectField(param.thisObject, "mSpn"));
// XposedBridge.log("PhoneSlot: " + getIccPhoneSlot);
// XposedBridge.log("PhoneType: " + getIccPhoneType);
return "Unknown";
}
});
}
/*
public static void hookOperatorName()
{
final Class<?> TelephonyManagerClass = XposedHelpers.findClass("android.telephony.TelephonyManager", null);
findAndHookMethod(TelephonyManagerClass, "getNetworkOperatorNameExt", int.class, new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
int PhoneType = (Integer) param.args[0];
// XposedBridge.log("PhoneType = " + PhoneType);
if (TelephonyManager.getMainPhoneType() == PhoneType)
return "Sloooooooooot 1";
else if (TelephonyManager.getSubPhoneType() == PhoneType)
return "Sloooooooooot 2";
else
return "Wazzzzzzzzzzzup!";
}
});
}
*/
/*
public static void hookOperatorName(final LoadPackageParam paramLoadPackageParam)
{
findAndHookMethod("com.android.phone.InCallScreen", paramLoadPackageParam.classLoader, "getOperatorName", int.class, new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
int PhoneType = (Integer) param.args[0];
Class<?> PhoneUtils = XposedHelpers.findClass("com.android.phone.PhoneUtils", paramLoadPackageParam.classLoader);
if (PhoneType == 0)
PhoneType = (Integer) XposedHelpers.callStaticMethod(PhoneUtils, "getCurrPhoneType");
int slot = (Integer) XposedHelpers.callStaticMethod(PhoneUtils, "getSimSlotTypeByPhoneType", PhoneType);
ContentResolver cr = (ContentResolver) XposedHelpers.callMethod(param.thisObject, "getContentResolver");
String operator;
if (slot == 1)
operator = Settings.System.getString(cr, "spn_1_user_text");
else
operator = Settings.System.getString(cr, "spn_2_user_text");
return operator;
}
});
}
*/
public static void hookCopyDialExtra(final LoadPackageParam paramLoadPackageParam)
{
findAndHookMethod("com.android.phone.PhoneUtils", paramLoadPackageParam.classLoader, "copyDialExtra", Intent.class, Intent.class, new XC_MethodHook()
{
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
Intent paramIntent2 = (Intent) param.args[1];
Class<?> PhoneGlobals = XposedHelpers.findClass("com.android.phone.PhoneGlobals", paramLoadPackageParam.classLoader);
Object getInstance = XposedHelpers.callStaticMethod(PhoneGlobals, "getInstance");
Context mContext = (Context) XposedHelpers.callMethod(getInstance, "getApplicationContext");
int force = Misc.getSystemSettingsInt(mContext, Const.TWEAK_FORCE_DIAL, 0);
Misc.x("Force dialing");
if (force != 0) {
Class<?> PhoneUtils = XposedHelpers.findClass("com.android.phone.PhoneUtils", paramLoadPackageParam.classLoader);
int action = Misc.getSystemSettingsInt(mContext, Const.TWEAK_FORCE_DIAL_ACTION, 0);
int phoneType;
if (force == 1)
phoneType = (Integer) XposedHelpers.callStaticMethod(PhoneUtils, "getSlot1PhoneType");
else
phoneType = (Integer) XposedHelpers.callStaticMethod(PhoneUtils, "getSlot2PhoneType");
// dial through available
if (action == 0) {
Misc.x("Dialing through available slot is requested");
// check if slot is available
if ((Boolean) XposedHelpers.callStaticMethod(PhoneUtils, "isSimReady", phoneType)) {
Misc.x("Desired slot is available");
Misc.x(" - dialing will be through slot " + phoneType);
// dial through desired slot
paramIntent2.putExtra("phone_type", phoneType);
} else {
Misc.x("Desired slot NOT available");
// slot not available, so lets get state of another
// slot
int anotherSlot;
if (force == 1)
anotherSlot = (Integer) XposedHelpers.callStaticMethod(PhoneUtils, "getSlot2PhoneType");
else
anotherSlot = (Integer) XposedHelpers.callStaticMethod(PhoneUtils, "getSlot1PhoneType");
// If another slot is ready
if ((Boolean) XposedHelpers.callStaticMethod(PhoneUtils, "isSimReady", anotherSlot)) {
Misc.x("Another slot is available");
Misc.x(" - dialing will be through slot " + anotherSlot);
// then dial through another
paramIntent2.putExtra("phone_type", anotherSlot);
} else {
Misc.x("Dialing through another slot is NOT available");
Misc.x(" - fail massage should appear on screen");
// otherwise get failed on desired slot
paramIntent2.putExtra("phone_type", phoneType);
}
}
} else {
Misc.x("Messaging through selected slot only: " + phoneType);
Misc.x(" - we do not care what next will happen");
// Dial and we do not care
paramIntent2.putExtra("phone_type", phoneType);
}
}
}
});
}
public static void handleSlotIndicator1(InitPackageResourcesParam resparam, String path, final int value)
{
final XModuleResources modRes = XModuleResources.createInstance(path, resparam.res);
if (resparam.packageName.equals("com.htc.sense.mms")) {
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "l_icon_indicator_slot1_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot1_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "l_icon_indicator_slot1", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot1), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot1", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot1), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
// XposedBridge.log(t);
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot1_dark_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot1_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot1_light_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot1_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot1_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot1_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
}
public static void handleSlotIndicator2(InitPackageResourcesParam resparam, String path, final int value)
{
final XModuleResources modRes = XModuleResources.createInstance(path, resparam.res);
if (resparam.packageName.equals("com.htc.sense.mms")) {
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "l_icon_indicator_slot2_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot2_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "l_icon_indicator_slot2", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot2), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot2", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot2), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
// XposedBridge.log(t);
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot2_dark_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot2_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot2_light_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot2_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
try {
resparam.res.setReplacement(resparam.packageName, "drawable", "icon_indicator_slot2_s", new XResources.DrawableLoader()
{
public Drawable newDrawable(XResources paramAnonymousXResources, int paramAnonymousInt) throws Throwable
{
return Misc.adjustHue(modRes.getDrawable(R.drawable.icon_indicator_slot2_s), Misc.getHueValue(value));
}
});
} catch (Throwable t) {
}
}
public static void hookShowDataDisconnectedRoaming(LoadPackageParam paramLoadPackageParam)
{
findAndHookMethod("com.android.phone.NotificationMgr", paramLoadPackageParam.classLoader, "showDataDisconnectedRoaming", new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
return null;
}
});
}
public static void disableNoiseSuppression(final LoadPackageParam paramLoadPackageParam)
{
findAndHookMethod("com.android.phone.PhoneUtils", paramLoadPackageParam.classLoader, "turnOnNoiseSuppression", Context.class, boolean.class, boolean.class, new XC_MethodHook()
{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable
{
param.args[1] = Boolean.valueOf(false);
param.args[2] = Boolean.valueOf(true);
}
});
findAndHookMethod("com.android.phone.PhoneUtils", paramLoadPackageParam.classLoader, "isNoiseSuppressionOn", Context.class, new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
return Boolean.valueOf(false);
}
});
}
public static void hookSIP(final LoadPackageParam paramLoadPackageParam)
{
findAndHookMethod("com.android.phone.PhoneUtils", paramLoadPackageParam.classLoader, "isVoipSupported", new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
return Boolean.valueOf(true);
}
});
Class<?> Features = XposedHelpers.findClass("com.android.phone.HtcFeatureList", paramLoadPackageParam.classLoader);
XposedHelpers.setStaticBooleanField(Features, "FEATURE_SUPPORT_SIP_CALL_SETTINGS", true);
findAndHookMethod("com.android.phone.CallFeaturesSetting", paramLoadPackageParam.classLoader, "onCreate", "android.os.Bundle", new XC_MethodHook()
{
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
CallFeaturesSetting = param.thisObject;
// XposedHelpers.callMethod(param.thisObject,
// "createSipCallSettings");
}
});
findAndHookMethod("com.android.phone.dualsim.DualCallSettingsPreference", paramLoadPackageParam.classLoader, "onCreate", "android.os.Bundle", new XC_MethodHook()
{
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
DualCallSettingsPreference = param.thisObject;
XposedHelpers.callMethod(CallFeaturesSetting, "createSipCallSettings");
}
});
findAndHookMethod("com.android.phone.CallFeaturesSetting", paramLoadPackageParam.classLoader, "createSipCallSettings", new XC_MethodHook()
{
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable
{
/*
*
* this.mSipManager = SipManager.newInstance(this);
* this.mSipSharedPreferences = new SipSharedPreferences(this);
* addPreferencesFromResource(2131034157);
* this.mButtonSipCallOptions = getSipCallOptionPreference();
* this.mButtonSipCallOptions
* .setOnPreferenceChangeListener(this);
* this.mButtonSipCallOptions
* .setValueIndex(this.mButtonSipCallOptions .findIndexOfValue
* (this.mSipSharedPreferences.getSipCallOption()));
* this.mButtonSipCallOptions.setSummary(this.
* mButtonSipCallOptions.getEntry());
*/
final Class<?> SipManager = XposedHelpers.findClass("android.net.sip.SipManager", paramLoadPackageParam.classLoader);
Object mSipManager = XposedHelpers.callStaticMethod(SipManager, "newInstance", param.thisObject);
XposedHelpers.setObjectField(param.thisObject, "mSipManager", mSipManager);
final Class<?> SipSharedPreferences = XposedHelpers.findClass("com.android.phone.sip.SipSharedPreferences", paramLoadPackageParam.classLoader);
Object mSipSharedPreferences = XposedHelpers.newInstance(SipSharedPreferences, param.thisObject);
XposedHelpers.setObjectField(param.thisObject, "mSipSharedPreferences", mSipSharedPreferences);
String package_path = (String) XposedHelpers.callMethod(param.thisObject, "getPackageResourcePath");
XModuleResources phoneRes = XModuleResources.createInstance(package_path, null);
int res_id = phoneRes.getIdentifier("sip_settings_category", "xml", "com.android.phone");
XposedHelpers.callMethod(DualCallSettingsPreference, "addPreferencesFromResource", res_id);
Object mButtonSipCallOptions;
Object localHtcListPreference1 = XposedHelpers.callMethod(DualCallSettingsPreference, "findPreference", "sip_call_options_key");
Object localHtcListPreference2 = XposedHelpers.callMethod(DualCallSettingsPreference, "findPreference", "sip_call_options_wifi_only_key");
Object localHtcPreferenceGroup = XposedHelpers.callMethod(DualCallSettingsPreference, "findPreference", "sip_settings_category_key");
Boolean isSipWifiOnly = (Boolean) XposedHelpers.callStaticMethod(SipManager, "isSipWifiOnly", param.thisObject);
if (isSipWifiOnly) {
XposedHelpers.callMethod(localHtcPreferenceGroup, "removePreference", localHtcListPreference1);
mButtonSipCallOptions = localHtcListPreference2;
XposedHelpers.setObjectField(param.thisObject, "mButtonSipCallOptions", localHtcListPreference2);
} else {
XposedHelpers.callMethod(localHtcPreferenceGroup, "removePreference", localHtcListPreference2);
mButtonSipCallOptions = localHtcListPreference1;
XposedHelpers.setObjectField(param.thisObject, "mButtonSipCallOptions", localHtcListPreference1);
}
/*
* private HtcListPreference getSipCallOptionPreference() {
* HtcListPreference localHtcListPreference1 =
* (HtcListPreference)findPreference ("sip_call_options_key");
* HtcListPreference localHtcListPreference2 =
* (HtcListPreference)findPreference
* ("sip_call_options_wifi_only_key"); HtcPreferenceGroup
* localHtcPreferenceGroup = (HtcPreferenceGroup
* )findPreference("sip_settings_category_key"); if
* (SipManager.isSipWifiOnly(this)) { localHtcPreferenceGroup
* .removePreference(localHtcListPreference1); return
* localHtcListPreference2; }
* localHtcPreferenceGroup.removePreference
* (localHtcListPreference2); return localHtcListPreference1; }
*/
XposedHelpers.callMethod(mButtonSipCallOptions, "setOnPreferenceChangeListener", param.thisObject);
Object getSipCallOption = XposedHelpers.callMethod(mSipSharedPreferences, "getSipCallOption");
Object findIndexOfValue = XposedHelpers.callMethod(mButtonSipCallOptions, "findIndexOfValue", getSipCallOption);
XposedHelpers.callMethod(mButtonSipCallOptions, "setValueIndex", findIndexOfValue);
Object getEntry = XposedHelpers.callMethod(mButtonSipCallOptions, "getEntry");
XposedHelpers.callMethod(mButtonSipCallOptions, "setSummary", getEntry);
}
});
}
public static void hookSIP2(LoadPackageParam paramLoadPackageParam)
{
findAndHookMethod("android.net.sip.SipManager", paramLoadPackageParam.classLoader, "isVoipSupported", "android.content.Context", new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
Boolean ret = true;
return ret;
}
});
findAndHookMethod("android.net.sip.SipManager", paramLoadPackageParam.classLoader, "isApiSupported", "android.content.Context", new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
Boolean ret = true;
return ret;
}
});
}
}