自从Android U版本开始,新项目上WiFi模块强制Google mainline。
这样就会导致基于源码无法实现一些WiFi or AP上的一些功能.
这篇文章会告诉你如何在WiFi模块强制Google mainline的同时来实现一些功能,
第一步需要添加服务。
添加服务的时候我们紧跟源码框架。
我们在下面路径下创建一个mywifi目录并创建两个文件MyWifiService.java和MyWifiServiceImpl.java
/frameworks/base/services/core/java/com/android/server/mywifi
//MyWifiService.java
//MyWifiService继承SystemService,为什么要继承这个,懂的都懂。肯定是咱这个服务在SystemService里面启动。
package com.android.server.wifi;
import android.content.Context;
import android.net.wifi.WifiContext;
import android.util.Log;
import com.android.server.SystemService;
import android.annotation.NonNull;
/**
* Service implementing Wi-Fi functionality. Delegates actual interface
* implementation to MyWifiServiceImpl.
*/
public final class MyWifiService extends SystemService {
private static final String TAG = "MyWifiService";
private final MyWifiServiceImpl mImpl;
private final Context mContext;
public MyWifiService (@NonNull Context contextBase) {
super(contextBase);
mContext= contextBase;
mImpl = new MyWifiServiceImpl(mContext); //这里是服务的具体实现
}
@Override
public void onStart() {
Log.i(TAG, "Registering mywifiservice");
publishBinderService(“mywifiservice”, mImpl);
}
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mImpl.checkAndStartWifi();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mImpl.handleBootCompleted();
}
}
@Override
public void onUserSwitching(TargetUser from, TargetUser to) {
//mImpl.handleUserSwitch(to.getUserHandle().getIdentifier());
}
@Override
public void onUserUnlocking(TargetUser user) {
//mImpl.handleUserUnlock(user.getUserHandle().getIdentifier());
}
@Override
public void onUserStopping(TargetUser user) {
//mImpl.handleUserStop(user.getUserHandle().getIdentifier());
}
}
下面我们开始实现MyWifiServiceImpl.java文件里面的内容
///frameworks/base/services/core/java/com/android/server/mywifi/MyWifiServiceImpl.java
//MyWifiServiceImpl.java
package com.android.server.wifi;
import android.util.Log;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerExecutor;
import android app.mywifi.IMyWifiService;
import android.net.wifi.WifiManager.SoftApCallback;
public class MyWifiServiceImpl extends IMyWifiService.Stub {
private static final String TAG = “MyWifiServiceImpl ”;
private final Context mContext;
private WifiManager mWifiManager;
private Handler mHandler;
public MyWifiServiceImpl (Context context) {
mContext = context;
mHandler = new Handler();
}
public void checkAndStartWifi(){}
public void handleBootCompleted() {
//MyWifiService启动后会第一时间执行这里,所以有相关的默认配置参数可以在这里实现
mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), new SoftApCallock() {
@Override
public void onStateChanged(int state, int failureReason) {
//这里是热点发生变化的时候进行处理的事情
}
});
}
@Override
public void test() {
Log.d(TAG, “test”);
}
}
//在SystemService 中添加服务启动
///frameworks/base/services/java/com/android/server/SystemService.java
import com.android.service.mywifi.MyWifiService;
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
/***略***/
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
t.traceBegin("StartWifiP2P");
mSystemServiceManager.startServiceFromJar(
WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
//写在这下面
t.traceBegin(“StartMyWifiService”);
Try {
Slog.i(TAG, “MyWifiService Service”);
mSystemServiceManager.startService(MyWifiService.class);
}catch (Throwable e) {
reportWtf(“staring MyWifiService”, e);
}
t.traceEnd();
/***略***/
}
到这里服务实现已经加上了
下面开始添加相关接口以及注册服务进行通信。
我们需要在下面路径再次创建目录mywifi,创建两个文件MyWifiManager.java 和 IMyWifiService.aidl
Frameworks/base/core/java/android/app/mywifi/
//MyWifiManager.java具体实现
package android.app.wifi;
import android.content.Context;
import android.annotation.SystemService;
import android.util.Log;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
import android.annotation.SuppressLint;
@SystemService("mywifiservice");
public class MyWifiManager{
private static final String TAG = “MyWifiManager”;
private IMyWifiService myService;
private Context mContext;
/**@hide*/
public MyWifiManager(@Nullable IMyWifiService iMyWifiService) {
myService = iMyWifiService;
}
//test
public void testFun() {
Try{
myService.test();
}catch() {
E.rethrowFromSystemServer();
}
}
}
//IMyWifiService.aidl具体实现
//frameworks/base/core/java/android/app/mywifi/IMyWifiService.aid
package android.app.mywifi;
interface IMyWifiService {
void testFun();
}
下来开始注册服务
//rameworks/base/core/java/android/app/SystemServiceRegistry.java
import android.app.mywifi.IMyWifiService;
import android.app.mywifi.MyWifiManager;
//加在WIFI_NL80211_SERVICE 后面
registerService(“mywifiservice”, MyWifiManager.class, new CachedServiceFetcher<MyWifiManager>) {
@Override
public MyWifiManager createService(ContextImpl ctx) throws ServiceNoundException {
IBinder b = ServiceManager.getServiceOrThrow(“mywifiservice”);
if (b == null) {
return null;
}
IMyWifiService service = IMyWifiService.stub.asInterface(b);
return new MyWifiManager(service);
}});
到这里我们就成功一半了,因为后面还有相关SELinux权限的添加。
//到这里我们就成功一半了,因为后面还有相关SELinux权限的添加。
//参考原生模板
///system/sepolicy/build/soong/service_fuzzer_bindings.go
“mywifiservice”: EXCEPTION_NO_FUZZER;
///system/sepolicy/private/service_contexts
Mywifiservice u:object_r:mywifiservice_service:s0
///system/sepolicy/public/service.te
Type mywifiservice_service, system_api_service, system_service_service, service_manager_type;
//system/sepolicy/prebuilt/api/底下也有、29、30、31、32、33、34里面的private/public对应的文件也要同样添加以下代码
Mywifiservice u:object_r:mywifiservice_service:s0
Type mywifiservice_service, system_api_service, system_service_service, service_manager_type;
**//不要想着偷懒,我试过,少写一个都不行。**
至此 更新接口
Make update-api
然后全编
刷机后查看服务是否启动
Adb shell service list | grep mywifiservice