需求
近期有一个网络白名单的需求,需要实现
- 用户通过输入IP/IP+端口,添加到白名单,添加后只允许白名单中的数据通行
- 重启后也生效
- 用户可进行删除,和清空
平台
基于展锐 T618
Android11
方案
在android
系统层通过调用iptables
命令来实现
iptables
是Linux
系统的IP
信息包过滤工具,实际就是一个Linux
命令,通过这个命令,可以对整个系统发出去的包,接收到的包,以及转发的包进行拦截、修改、拒绝等操作。刚好Android
也是基于Linux
内核的系统,也集成了iptables
,是否可以用它来限制上网行为呢?经过试验,发现是可行的。
- 优点:能从底层限制访问某些网站,而不必在浏览器层面阻止,不仅减少了定制或修改浏览器的成本,而且控制灵活,因为能够定制各种策略;
- 缺点:运行
iptables
需要root
权限。
并且可以通过iptables
命令查看当前的防火墙规则,具体可以百度了解一下命令
Netd
是Network Daemon
的缩写,Netd
是Android Linux Kernel
与Framework
之间通信的桥梁,表示Network
守护进程。Netd
负责跟一些涉及网络的配置,操作,管理,查询等相关的功能实现,比如,例如带宽控制(Bandwidth
),流量统计,带宽控制,网络地址转换(NAT
),个人局域网(pan
),PPP
链接,soft-ap
,共享上网(Tether
),配置路由表,interface
配置管理,等等。
Framework
部分通常会有一个对应的service
与本地进程(如Netd
)通信,并且提供API
供应用层调用,轻易地找到了NetworkManagementService
,在源码中位于/frameworks/base/services/java/com/android/server/NetworkManagementService.java
其中一个代码片段:
// frameworks/base/services/core/java/com/android/server/net/NetworkManagementService.java
@Override
public void setFirewallEnabled(boolean enabled) {
enforceSystemUid();
try {
mNetdService.firewallSetFirewallType(
enabled ? INetd.FIREWALL_ALLOWLIST : INetd.FIREWALL_DENYLIST);
mFirewallEnabled = enabled;
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
发现调用的是在INet
接口中,在跟一根找到它的实现
// /system/netd/server/NetdNativeService.cpp
binder::Status NetdNativeService::firewallSetFirewallType(int32_t firewallType) {
NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
auto type = static_cast<FirewallType>(firewallType);
int res = gCtls->firewallCtrl.setFirewallType(type);
return statusFromErrcode(res);
}
// /system/netd/server/FirewallController.cpp
int FirewallController::setFirewallType(FirewallType ftype) {
int res = 0;
if (mFirewallType != ftype) {
// flush any existing rules
resetFirewall();
if (ftype == WHITELIST) {
// create default rule to drop all traffic
std::string command =
"*filter\n"
"-A fw_INPUT -j DROP\n"
"-A fw_OUTPUT -j REJECT\n"
"-A fw_FORWARD -j REJECT\n"
"COMMIT\n";
res = execIptablesRestore(V4V6, command.c_str());
}
// Set this after calling disableFirewall(), since it defaults to WHITELIST there
mFirewallType = ftype;
}
return res ? -EREMOTEIO : 0;
}
最后发现具体的实现都是在FirewallController.cpp
中,因为我们可以加在这里,当然被调用的接口也要加上去
这里直接放个简单的流程图
相关类图:
修改流程
1.system/netd
涉及修改文件
system/netd/server/NetdNativeService.cpp
system/netd/server/NetdNativeService.h
system/netd/server/FirewallController.cpp
system/netd/server/FirewallController.h
system/netd/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
system/netd/server/binder/android/net/INetd.aidl
--------------------------------------------------
# 以下文件或目录是自动生成或更新
system/netd/server/Android.bp
system/netd/server/aidl_api/netd_aidl_interface/5/
修改详细内容:
diff --git a/server/Android.bp b/server/Android.bp
index 2f897e5..14d567c 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -33,6 +33,7 @@ aidl_interface {
"2",
"3",
"4",
+ "5",
],
}
diff --git a/server/FirewallController.cpp b/server/FirewallController.cpp
index 3c070ce..ea2be49 100644
--- a/server/FirewallController.cpp
+++ b/server/FirewallController.cpp
@@ -74,6 +74,7 @@ const char* FirewallController::LOCAL_DOZABLE = "fw_dozable";
const char* FirewallController::LOCAL_STANDBY = "fw_standby";
const char* FirewallController::LOCAL_POWERSAVE = "fw_powersave";
+int netDrop = 0;
// ICMPv6 types that are required for any form of IPv6 connectivity to work. Note that because the
// fw_dozable chain is called from both INPUT and OUTPUT, this includes both packets that we need
// to be able to send (e.g., RS, NS), and packets that we need to receive (e.g., RA, NA).
@@ -397,5 +398,133 @@ uid_t FirewallController::discoverMaximumValidUid(const std::string& fileName) {
return maxUid;
}
+int FirewallController::enableDNSPort(int protocol, int port) {
+ char protocolStr[16];
+ if(protocol == 0) {
+ sprintf(protocolStr, "udp");
+ } else {
+ sprintf(protocolStr, "tcp");
+ }
+
+ char portStr[16];
+
+ sprintf(portStr, "%d", port);
+
+ std::string command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-I fw_INPUT -p %s --sport %s -j ACCEPT\n", protocolStr, portStr),
+ StringPrintf("-I fw_OUTPUT -p %s --dport %s -j ACCEPT\n", protocolStr, portStr),
+ "COMMIT\n"
+ }, "\n");
+
+ return (execIptablesRestore(V4, command) == 0) ? 0 : -EREMOTEIO;
+}
+
+int FirewallController::enableUrl(const char * addr) {
+ std::string command;
+ if (netDrop == 0) {
+ command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-I fw_INPUT -s %s -j ACCEPT\n", addr),
+ StringPrintf("-I fw_OUTPUT -d %s -j ACCEPT\n", addr),
+ StringPrintf("-A fw_INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT\n"),
+ StringPrintf("-I fw_INPUT -i lo -j ACCEPT\n"),
+ StringPrintf("-I fw_INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n"),
+ StringPrintf("-A fw_OUTPUT -j DROP\n"),
+ "COMMIT\n"
+ }, "\n");
+ netDrop = 1;
+ } else {
+ command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-I fw_INPUT -s %s -j ACCEPT\n", addr),
+ StringPrintf("-I fw_OUTPUT -d %s -j ACCEPT\n", addr),
+ StringPrintf("-A fw_INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT\n"),
+ StringPrintf("-I fw_INPUT -i lo -j ACCEPT\n"),
+ StringPrintf("-I fw_INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n"),
+ "COMMIT\n"
+ }, "\n");
+ }
+ return (execIptablesRestore(V4, command) == 0) ? 0 : -EREMOTEIO;
+}
+
+int FirewallController::disableUrl(const char * addr) {
+ std::string command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-D fw_INPUT -s %s -j ACCEPT\n", addr),
+ StringPrintf("-D fw_OUTPUT -d %s -j ACCEPT\n", addr),
+ StringPrintf("-D fw_INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT\n"),
+ StringPrintf("-D fw_INPUT -i lo -j ACCEPT\n"),
+ StringPrintf("-D fw_INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n"),
+ "COMMIT\n"
+ }, "\n");
+ return (execIptablesRestore(V4, command) == 0) ? 0 : -EREMOTEIO;
+}
+
+int FirewallController::enableIpAndPort(int protocol, const char * addr, int port) {
+ char protocolStr[16];
+ if(protocol == 0) {
+ sprintf(protocolStr, "udp");
+ } else {
+ sprintf(protocolStr, "tcp");
+ }
+
+ char portStr[16];
+
+ sprintf(portStr, "%d", port);
+ std::string command;
+ if (netDrop == 0) {
+ command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-I fw_INPUT -s %s -p %s --sport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-I fw_OUTPUT -d %s -p %s --sport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-I fw_OUTPUT -d %s -p %s --dport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-A fw_OUTPUT -j DROP\n"),
+ "COMMIT\n"
+ }, "\n");
+ netDrop = 1;
+ } else {
+ command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-I fw_INPUT -s %s -p %s --sport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-I fw_OUTPUT -d %s -p %s --sport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-I fw_OUTPUT -d %s -p %s --dport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ "COMMIT\n"
+ }, "\n");
+ }
+
+ return (execIptablesRestore(V4, command) == 0) ? 0 : -EREMOTEIO;
+}
+
+int FirewallController::disableIpAndPort(int protocol, const char * addr, int port) {
+ char protocolStr[16];
+ if(protocol == 0) {
+ sprintf(protocolStr, "udp");
+ } else {
+ sprintf(protocolStr, "tcp");
+ }
+
+ char portStr[16];
+
+ sprintf(portStr, "%d", port);
+ std::string command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-D fw_INPUT -s %s -p %s --sport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-D fw_OUTPUT -d %s -p %s --dport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ StringPrintf("-D fw_OUTPUT -d %s -p %s --sport %s -j ACCEPT\n", addr, protocolStr, portStr),
+ "COMMIT\n"
+ }, "\n");
+ return (execIptablesRestore(V4, command) == 0) ? 0 : -EREMOTEIO;
+}
+
+int FirewallController::closeFirewall() {
+ std::string command = Join(std::vector<std::string> {
+ "*filter\n",
+ StringPrintf("-D fw_OUTPUT -j DROP\n"),
+ "COMMIT\n"
+ }, "\n");
+ netDrop = 0;
+ return (execIptablesRestore(V4, command) == 0) ? 0 : -EREMOTEIO;
+}
} // namespace net
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/server/FirewallController.h b/server/FirewallController.h
index 620f196..a41f52b 100644
--- a/server/FirewallController.h
+++ b/server/FirewallController.h
@@ -73,6 +73,12 @@ public:
int replaceUidChain(const std::string&, bool, const std::vector<int32_t>&);
+ int enableDNSPort(int protocol, int port);
+ int enableUrl(const char *addr);
+ int enableIpAndPort(int protocol, const char * addr, int port);
+ int disableUrl(const char *addr);
+ int disableIpAndPort(int protocol, const char * addr, int port);
+ int closeFirewall();
static std::string makeCriticalCommands(IptablesTarget target, const char* chainName);
static uid_t discoverMaximumValidUid(const std::string& fileName);
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 3bf879b..cc6894f 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -1182,6 +1182,45 @@ binder::Status NetdNativeService::firewallEnableChildChain(int32_t childChain, b
return statusFromErrcode(res);
}
+// Add for white list access internet begin
+binder::Status NetdNativeService::firewallEnableDNSPort(int32_t protocol, int32_t port) {
+ NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
+ int res = gCtls->firewallCtrl.enableDNSPort(protocol, port);
+ return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::firewallEnableUrl(const std::string& url) {
+ NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
+ int res = gCtls->firewallCtrl.enableUrl(url.c_str());
+ return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::firewallEnableIpAndPort(int32_t protocol, const std::string& url, int port) {
+ NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
+ int res = gCtls->firewallCtrl.enableIpAndPort(protocol, url.c_str(), port);
+ return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::firewallDisableUrl(const std::string& url) {
+ NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
+ int res = gCtls->firewallCtrl.disableUrl(url.c_str());
+ return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::firewallDisableIpAndPort(int32_t protocol, const std::string& url, int port) {
+ NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
+ int res = gCtls->firewallCtrl.disableIpAndPort(protocol, url.c_str(), port);
+ return statusFromErrcode(res);
+}
+
+binder::Status NetdNativeService::firewallCloseRules() {
+ NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
+ int res = gCtls->firewallCtrl.closeFirewall();
+ return statusFromErrcode(res);
+}
+
+//Add for white list access internet end 2023-05-17
+
binder::Status NetdNativeService::firewallAddUidInterfaceRules(const std::string& ifName,
const std::vector<int32_t>& uids) {
ENFORCE_NETWORK_STACK_PERMISSIONS();
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index 7b7f9b3..c37afa3 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -49,7 +49,12 @@ class NetdNativeService : public BinderService<NetdNativeService>, public BnNetd
binder::Status firewallAddUidInterfaceRules(const std::string& ifName,
const std::vector<int32_t>& uids) override;
binder::Status firewallRemoveUidInterfaceRules(const std::vector<int32_t>& uids) override;
-
+ binder::Status firewallEnableDNSPort(int32_t protocol, int32_t port) override;
+ binder::Status firewallEnableUrl(const std::string& url) override;
+ binder::Status firewallEnableIpAndPort(int32_t protocol, const std::string& ip, int32_t port) override;
+ binder::Status firewallDisableUrl(const std::string& url) override;
+ binder::Status firewallDisableIpAndPort(int32_t protocol, const std::string& ip, int32_t port) override;
+ binder::Status firewallCloseRules();
// Bandwidth control commands.
binder::Status bandwidthEnableDataSaver(bool enable, bool *ret) override;
binder::Status bandwidthSetInterfaceQuota(const std::string& ifName, int64_t bytes) override;
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
index 47e2931..6e26cf3 100644
--- a/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
+++ b/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
@@ -122,6 +122,12 @@ interface INetd {
android.net.TetherStatsParcel[] tetherOffloadGetStats();
void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
+ void firewallEnableDNSPort(int protocol, int port);
+ void firewallEnableUrl(in @utf8InCpp String url);
+ void firewallEnableIpAndPort(int protocol, in @utf8InCpp String url, int port);
+ void firewallDisableUrl(in @utf8InCpp String url);
+ void firewallDisableIpAndPort(int protocol, in @utf8InCpp String url, int port);
+ void firewallCloseRules();
const int IPV4 = 4;
const int IPV6 = 6;
const int CONF = 1;
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index 3b221cf..41159c1 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -1309,4 +1309,16 @@ interface INetd {
* cause of the failure.
*/
TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
+
+ void firewallEnableDNSPort(int protocol, int port);
+
+ void firewallEnableUrl(in @utf8InCpp String url);
+
+ void firewallEnableIpAndPort(int protocol, in @utf8InCpp String url, int port);
+
+ void firewallDisableUrl(in @utf8InCpp String url);
+
+ void firewallDisableIpAndPort(int protocol, in @utf8InCpp String url, int port);
+
+ void firewallCloseRules();
}
2. frameworks/base
涉及修改,供APP调用
frameworks/base/core/java/android/os/INetworkManagementService.aidl
frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
修改详细内容:
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 5c200bc..152b8fd 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -394,4 +394,16 @@ interface INetworkManagementService
* destory Sockets by Uid
*/
void destorySocketByUid(int uid);
+
+ void enableUrl(boolean isIp, String url);
+
+ void enablePort(int port);
+
+ void enableIpAndPort(String ip, int port);
+
+ void disableUrl(String url);
+
+ void disableIpAndPort(String ip, int port);
+
+ void closeFirewall();
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 0c9bc35..c63b1cc 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -112,6 +112,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.net.UnknownHostException;
/**
* @hide
@@ -1583,6 +1584,112 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
+ public void enableUrl(boolean isIp, String url) {
+ enforceSystemUid();
+ Log.d(TAG, "enable url is: " + url + ", isIp: " + isIp + ", mFirewallEnabled: " + mFirewallEnabled);
+ if (mFirewallEnabled) {
+ try {
+ Log.d(TAG, "Firewall is enabled, Open dns port is: 53");
+ mNetdService.firewallEnableDNSPort(0, 53);
+ mNetdService.firewallEnableDNSPort(1, 53);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ new Thread(() -> {
+ InetAddress[] ipArray;
+ try {
+ ipArray = InetAddress.getAllByName(url);
+ Log.d(TAG, "enableUrl url: " + url + " ipArray: " + Arrays.toString(ipArray));
+ if (ipArray != null) {
+ for(InetAddress address : ipArray) {
+ mNetdService.firewallEnableUrl(address.getHostAddress());
+ Log.d(TAG, "enableUrl url: " + address + " success");
+ }
+ }
+ } catch(UnknownHostException e) {
+ Log.e(TAG, "Gets all IP addresses associated with the given host "" + url +"" faild. Because the host name can not be resolved.");
+ e.printStackTrace();
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
+ }
+ }).start();
+ }
+
+ @Override
+ public void enablePort(int port) {
+ enforceSystemUid();
+ Log.d(TAG, "enablePort port: " + port);
+ try {
+ mNetdService.firewallEnableDNSPort(0, port);
+ mNetdService.firewallEnableDNSPort(1, port);
+ Log.d(TAG, "enablePort port: " + port + " success");
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void enableIpAndPort(String ip, int port) {
+ enforceSystemUid();
+ Log.d(TAG, "enableIpAndPort ip: " + ip + " port: " + port);
+ try {
+ mNetdService.firewallEnableIpAndPort(0, ip, port);
+ mNetdService.firewallEnableIpAndPort(1, ip, port);
+ Log.d(TAG, "enableIpAndPort ip: " + ip + " port: " + port + " success");
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void disableUrl(String url) {
+ enforceSystemUid();
+ Log.d(TAG, "disableUrl url is: " + url + ", mFirewallEnabled: " + mFirewallEnabled);
+ new Thread(() -> {
+ InetAddress[] ipArray;
+ try {
+ ipArray = InetAddress.getAllByName(url);
+ Log.d(TAG, "disableUrl url: " + url + " ipArray: " + Arrays.toString(ipArray));
+ if (ipArray != null) {
+ for(InetAddress address : ipArray) {
+ mNetdService.firewallDisableUrl(address.getHostAddress());
+ Log.d(TAG, "disableUrl url: " + address + " success");
+ }
+ }
+ } catch(UnknownHostException e) {
+ Log.e(TAG, "Gets all IP addresses associated with the given host "" + url +"" faild. Because the host name can not be resolved.");
+ e.printStackTrace();
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
+ }
+ }).start();
+ }
+
+ @Override
+ public void disableIpAndPort(String ip, int port) {
+ enforceSystemUid();
+ Log.d(TAG, "disableIpAndPort ip: " + ip + " port: " + port);
+ try {
+ mNetdService.firewallDisableIpAndPort(0, ip, port);
+ mNetdService.firewallDisableIpAndPort(1, ip, port);
+ Log.d(TAG, "disableIpAndPort ip: " + ip + " port: " + port + " success");
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void closeFirewall() {
+ try {
+ mNetdService.firewallCloseRules();
+ Log.d(TAG, "closeFirewall");
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
public boolean isFirewallEnabled() {
enforceSystemUid();
return mFirewallEnabled;
3.APP调用方式
private INetworkManagementService mService;
IBinder ibinder = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mService = INetworkManagementService.Stub.asInterface(ibinder);
try {
mService.enableIpAndPort(ipStr, port);
} catch (Exception e) {
e.printStackTrace();
}
编译时需要注意APP的mk文件添加上LOCAL_PRIVATE_PLATFORM_APIS := true
,否则获取不到隐藏服务INetworkManagementService
,贴上完整Android.mk
:
# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_SRC_FILES := $(call all-subdir-java-files) \
LOCAL_PACKAGE_NAME := NetWhiteList
LOCAL_CERTIFICATE := platform
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
4. 编译及注意事项
- 在原有的
aidl
中的最后添加新的api
(在最后加API
,不要加到中间,打乱原API
顺序) - 执行
make update-api
,更新到current
目录下的文件 - 执行
make <name>-freeze-api
固定版本,会自动更新到Andrioid.bp
中的versions_with_info
,以及生成新版本对应的aidl_api<name>\x
目录及内容,如本次更新是netd_aidl_interface
中的API
,则执行
make netd_aidl_interface-freeze-api
- 整编版本验证结果
问题
编译报错显示
##############################################################
ERROR: Modification detected of stable AIDL API file #
##############################################################
Above AIDL file(s) has changed, resulting in a different hash. Hash values may be checked at runtime to verify interface stability.
没有固定版本号,git检查下/system/netd/目录下有没有生成过新版本的API
目录,没有则按照编译及注意事项第三点执行