Compare commits

..

1 Commits

Author SHA1 Message Date
wenyifan
f6f2504158 config 2022-11-26 23:56:28 +08:00
13 changed files with 223 additions and 40 deletions

View File

@ -7,7 +7,6 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Android Studio default JDK" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="temurin-11" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -28,6 +28,5 @@ android {
}
dependencies {
compileOnly files('libs/XposedBridgeAPI-89.jar')
}

View File

@ -1,11 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="run.evan.hotspotip">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
android:supportsRtl="true"
tools:ignore="MissingApplicationIcon"
android:theme="@style/AppTheme">
<activity
android:name="run.evan.hotspotip.SettingsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
</intent-filter>
</activity>
<meta-data
android:name="xposedmodule"
android:value="true" />
@ -15,7 +28,6 @@
<meta-data
android:name="xposedminversion"
android:value="53" />
<meta-data
android:name="xposedscope"
android:resource="@array/scope" />

View File

@ -1,55 +1,83 @@
package run.evan.hotspotip;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class MainHook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.android.networkstack.tethering.inprocess")) {
XposedBridge.log("Hotspot IP init process="+loadPackageParam.packageName);
XposedHelpers.findAndHookMethod("com.android.networkstack.tethering.PrivateAddressCoordinator", loadPackageParam.classLoader, "requestDownstreamAddress", "android.net.ip.IpServer", boolean.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return buildPrivateAddressResponse(methodHookParam, loadPackageParam);
}
});
}
XSharedPreferences prefs = new XSharedPreferences("run.evan.hotspotip", "conf");
XposedBridge.log("Hotspot Ip init");
XposedHelpers.findAndHookMethod("com.android.networkstack.tethering.PrivateAddressCoordinator", loadPackageParam.classLoader, "requestDownstreamAddress", "android.net.ip.IpServer", boolean.class, new XC_MethodHook() {
if (loadPackageParam.packageName.equals("com.android.networkstack.tethering")) {
XposedBridge.log("Hotspot IP init process="+loadPackageParam.packageName);
XposedHelpers.findAndHookMethod("com.android.networkstack.tethering.PrivateAddressCoordinator", loadPackageParam.classLoader, "requestDownstreamAddress", "android.net.ip.IpServer",int.class, boolean.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return buildPrivateAddressResponse(methodHookParam, loadPackageParam);
}
});
}
}
private static Object buildPrivateAddressResponse(XC_MethodHook.MethodHookParam methodHookParam, XC_LoadPackage.LoadPackageParam loadPackageParam) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
prefs.reload();
Class linkAddressClass = XposedHelpers.findClass("android.net.LinkAddress", loadPackageParam.classLoader);
Constructor linkAddressConstructor = linkAddressClass.getConstructor(String.class);
Class ipServerClass = XposedHelpers.findClass("android.net.ip.IpServer", loadPackageParam.classLoader);
Method interfaceTypeMethod = ipServerClass.getDeclaredMethod("interfaceType");
int iFaceType = (int) interfaceTypeMethod.invoke(methodHookParam.args[0]);
switch (iFaceType) {
case 3:
return linkAddressConstructor.newInstance("192.168.49.1/24");
case 0:
return linkAddressConstructor.newInstance("192.168.6.1/24");
case 1:
return linkAddressConstructor.newInstance("192.168.7.1/24");
default:
return linkAddressConstructor.newInstance("192.168.8.1/24");
int iFaceType = (int) interfaceTypeMethod.invoke(param.args[0]);
XposedBridge.log("Hotspot Ip process ifaceType=" + iFaceType);
XposedBridge.log(prefs.getString("usb_ip", "192.168.7.2/24"));
if (prefs.getBoolean("wlan_persistent_enable", true)) {
XposedBridge.log("Hotspot Ip fixed wlanA");
param.setResult(linkAddressConstructor.newInstance("192.168.6.1/24"));
}else {
XposedBridge.log("Hotspot Ip fixed wlan not enable");
}
// switch (iFaceType) {
// case 0:
// if (prefs.getBoolean("wlan_persistent_enable", true)) {
// XposedBridge.log("Hotspot Ip fixed wlan");
// param.setResult(linkAddressConstructor.newInstance("192.168.6.1/24"));
// }else {
// XposedBridge.log("Hotspot Ip fixed wlan not enable");
// }
// case 1:
// if (prefs.getBoolean("usb_persistent_enable", true)) {
// param.setResult(linkAddressConstructor.newInstance(prefs.getString("usb_ip", "192.168.7.1/24")));
// }
// case 2:
// if (prefs.getBoolean("bluetooth_persistent_enable", true)) {
// param.setResult(linkAddressConstructor.newInstance(prefs.getString("usb_ip", "192.168.8.1/24")));
// }
// default:
// //super.afterHookedMethod(param);
//
// }
}
//
// @Override
// protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
// Class linkAddressClass = XposedHelpers.findClass("android.net.LinkAddress", loadPackageParam.classLoader);
// Constructor linkAddressConstructor = linkAddressClass.getConstructor(String.class);
// Class ipServerClass = XposedHelpers.findClass("android.net.ip.IpServer", loadPackageParam.classLoader);
// Method interfaceTypeMethod = ipServerClass.getDeclaredMethod("interfaceType");
// int iFaceType = (int) interfaceTypeMethod.invoke(methodHookParam.args[0]);
// switch (iFaceType) {
// case 3:
// return linkAddressConstructor.newInstance("192.168.49.1/24");
// case 0:
// return linkAddressConstructor.newInstance("192.168.6.1/24");
// case 1:
// return linkAddressConstructor.newInstance("192.168.7.1/24");
// default:
// return linkAddressConstructor.newInstance("192.168.8.1/24");
// }
// }
});
}
}
}

View File

@ -0,0 +1,73 @@
package run.evan.hotspotip;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.view.View;
public class SettingsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
checkEdXposed();
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, new SettingsFragment()).commit();
}
}
@SuppressLint("WorldReadableFiles")
private void checkEdXposed() {
try {
// getSharedPreferences will hooked by LSPosed and change xml file path to /data/misc/edxp**
// will not throw SecurityException
//noinspection deprecation
getSharedPreferences("conf", Context.MODE_WORLD_READABLE);
} catch (SecurityException exception) {
new AlertDialog.Builder(this)
.setMessage("AA")
.setPositiveButton(android.R.string.ok, (dialog12, which) -> finish())
.setNegativeButton("BB", null)
.show();
}
}
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName("conf");
addPreferencesFromResource(R.xml.root_preferences);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
View list = view.findViewById(android.R.id.list);
list.setOnApplyWindowInsetsListener((v, insets) -> {
list.setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getStableInsetBottom());
return insets.consumeSystemWindowInsets();
});
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
@Override
public void onDestroy() {
super.onDestroy();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@ -1,4 +1,8 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material">
<item name="android:colorAccent">#3F51B5</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>

View File

@ -2,4 +2,12 @@
<resources>
<string name="app_name">固定热点IP</string>
<string name="module_desc">使热点的IP固定不变</string>
<string name="wlan_hotspot">无线热点</string>
<string name="usb_hotspot">USB网络共享</string>
<string name="bluetooth_hotspot">蓝牙网络共享</string>
<string name="fixed_ip">固定IP开关</string>
<string name="custom_ip">自定义IP</string>
<string name="wlan_title">Custom IP</string>
</resources>

View File

@ -2,6 +2,5 @@
<resources>
<string-array name="scope">
<item>android</item>
<item>com.android.networkstack</item>
</string-array>
</resources>

View File

@ -1,4 +1,12 @@
<resources>
<string name="app_name">Fixed Hotspot IP</string>
<string name="module_desc">Make hotspot IP fixed</string>
<string name="wlan_hotspot">WLAN Hotspot</string>
<string name="usb_hotspot">USB Hotspot</string>
<string name="bluetooth_hotspot">Bluetooth Hotspot</string>
<string name="fixed_ip">Fixed IP</string>
<string name="custom_ip">Custom IP</string>
<string name="wlan_title">Custom IP</string>
</resources>

View File

@ -1,4 +1,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.LightStatusBar">
<item name="android:colorAccent">#3F51B5</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>

View File

@ -0,0 +1,44 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/wlan_hotspot">
<SwitchPreference
android:defaultValue="true"
android:key="wlan_persistent_enable"
android:title="@string/fixed_ip" />
<EditTextPreference
android:defaultValue="192.168.6.1/24"
android:key="wlan_ip"
android:singleLine="true"
android:title="@string/custom_ip" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/usb_hotspot">
<SwitchPreference
android:defaultValue="true"
android:key="usb_persistent_enable"
android:title="@string/fixed_ip" />
<EditTextPreference
android:defaultValue="192.168.7.1/24"
android:key="usb_ip"
android:singleLine="true"
android:title="@string/custom_ip" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/bluetooth_hotspot">
<SwitchPreference
android:defaultValue="true"
android:key="bluetooth_persistent_enable"
android:title="@string/fixed_ip" />
<EditTextPreference
android:defaultValue="192.168.8.1/24"
android:key="bluetooth_ip"
android:singleLine="true"
android:title="@string/custom_ip" />
</PreferenceCategory>
</PreferenceScreen>