1、系统IP设置流程
系统IP设置流程在源码目录frameworks/opt/net/ethernet/java/com/android/server/ethernet/下:
EthernetConfigStore.java:读取、写入/misc/ethernet/ipconfig.txt配置文件;
EthernetServiceImpl.java:通过实现IEthernetManager.aidl接口来处理一些远程的以太网请求;
EthernetNetworkFactory.java:以太网网络链接的管理类;
2、Provision介绍
Provision的作用很简单,就是一个系统初始化引导程序,原生的Android里面Provision只做了一件事,就是写入一个DEVICE_PROVISIONED标记。不过这个标记作用很大,这个标记只会在系统全新升级(双清)的时候写入一次,代表了Android系统升级准备完成,可以正常工作。
? ? ? ? ? ? <intent-filter android:priority="1"> ? ? ? ? ? ? ? ? <action android:name="android.intent.action.MAIN" /> ? ? ? ? ? ? ? ? <category android:name="android.intent.category.HOME" /> ? ? ? ? ? ? ? ? <category android:name="android.intent.category.DEFAULT" />
属于launcher,优先级为1,会比一般launcher先启动起来。
3、增加相关权限
packages/apps/Provision/AndroidManifest.xml:
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
4、DefaultActivity.java设置默认静态IP
packages/apps/Provision/src/com/android/provision/DefaultActivity.java:
package com.android.provision;
import android.app.Activity;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.provider.Settings;
import android.content.Context;
import android.util.Log;
import android.net.EthernetManager;
import android.net.StaticIpConfiguration;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.NetworkUtils;
import android.net.LinkAddress;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.regex.Pattern;
import android.os.SystemProperties;
import java.lang.reflect.Method;
/**
* Application that sets the provisioned bit, like SetupWizard does.
*/
public class DefaultActivity extends Activity {
static final String TAG = "DefaultActivity";
EthernetManager mEthManager;
StaticIpConfiguration mStaticIpConfiguration;
IpConfiguration mIpConfiguration;
String ipAddr = "192.168.1.100";
String netMask = "255.255.255.0";
String gateway = "192.168.1.1";
String dns1 = "8.8.8.8";
String dns2 = "0.0.0.0";
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Add a persistent setting to allow other apps to know the device has been provisioned.
Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
/** TODO setting static IP start **/
// 获取系统属性的首次刷固件标识,没获取到值时默认为true
boolean firstBoot = SystemProperties.getBoolean("persist.sys.firstboot", true);
Log.i(TAG, "system is firstBoot:" + firstBoot);
if (firstBoot){
Log.i(TAG, "setting static IP start...");
mEthManager = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE);
mStaticIpConfiguration = new StaticIpConfiguration();
Settings.System.putString(getContentResolver(), "ethernet_static_ip", ipAddr);
Settings.System.putString(getContentResolver(), "ethernet_static_gateway", gateway);
Settings.System.putString(getContentResolver(), "ethernet_static_netmask", netMask);
Settings.System.putString(getContentResolver(), "ethernet_static_dns1", dns1);
Settings.System.putString(getContentResolver(), "ethernet_static_dns2", dns2);
/*
* get ip address, netmask,dns ,gw etc.
*/
Inet4Address inetAddr = getIPv4Address(ipAddr);
int prefixLength = maskStr2InetMask(netMask);
InetAddress gatewayAddr = getIPv4Address(gateway);
InetAddress dnsAddr = getIPv4Address(dns1);
String dnsStr2 = dns2;
mStaticIpConfiguration.ipAddress = new LinkAddress(inetAddr, prefixLength);
mStaticIpConfiguration.gateway = gatewayAddr;
mStaticIpConfiguration.dnsServers.add(dnsAddr);
mStaticIpConfiguration.dnsServers.add(getIPv4Address(dnsStr2));
mIpConfiguration = new IpConfiguration(IpAssignment.STATIC, ProxySettings.NONE, mStaticIpConfiguration, null);
mEthManager.setConfiguration(mIpConfiguration);
// 默认静态IP设置成功后,系统属性记录首次刷固件标识,避免后续OTA升级重复执行该代码
SystemProperties.set("persist.sys.firstboot", "false");
Log.i(TAG, "setting static IP end...");
}
/** TODO setting static IP end **/
// remove this activity from the package manager.
PackageManager pm = getPackageManager();
ComponentName name = new ComponentName(this, DefaultActivity.class);
pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
// terminate the activity.
finish();
}
private Inet4Address getIPv4Address(String text) {
try {
return (Inet4Address) NetworkUtils.numericToInetAddress(text);
} catch (IllegalArgumentException|ClassCastException e) {
return null;
}
}
private int maskStr2InetMask(String maskStr) {
StringBuffer sb;
String str;
int inetmask = 0;
int count = 0;
/*
* check the subMask format
*/
Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
if (pattern.matcher(maskStr).matches() == false) {
Log.e("Liheng, Setting static IP:", "subMask is error");
return 0;
}
String[] ipSegment = maskStr.split("\\.");
for (int n = 0; n < ipSegment.length; n++) {
sb = new StringBuffer(Integer.toBinaryString(Integer.parseInt(ipSegment[n])));
str = sb.reverse().toString();
count = 0;
for (int i = 0; i < str.length(); i++) {
i = str.indexOf("1", i);
if (i == -1)
break;
count++;
}
inetmask += count;
}
return inetmask;
}
}
1.Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);//代表申请完成,写文件位于/data/system/users/0/global.xml,也就是此apk只在清空数据格式化升级和强刷升级会执行
2.执行完后禁止Provision自己的Activity组件
void setComponentEnabledSetting (ComponentName componentName, int newState, int flags) componentName:组件名称? newState:组件新的状态,可以设置三个值,分别是如下:? COMPONENT_ENABLED_STATE_DISABLED:不可用状态 COMPONENT_ENABLED_STATE_ENABLED:可用状态 COMPONENT_ENABLED_STATE_DEFAULT:默认状态 flags:行为标签,值可以是DONT_KILL_APP或者0。 0说明杀死包含该组件的app
|