1.Android\packages\modules\Permission\PermissionController中的DefaultAppActivity中接收,根据packagename进行追踪路径如下:
DefaultAppActivity.java
--->HandheldDefaultAppFragment.java
--->DefaultAppChildFragment.java:setDefaultApp()
--->ManageRoleHolderStateLiveData.java
--->RoleService.java addRoleHolderAsUser()
--->RoleControllerServiceImpl.java:onAddRoleHolder()
--->RoleManager.java:addRoleHolderFromController()
--->RoleService.java:addRoleHolderFromController()
--->RoleUserState.java:addRoleHolder():readFile()
--->RolesPersistenceImpl.java:ROLES_FILE_NAME = "roles.xml"
位于Android\packages\modules\Permission\PermissionController\res\xml\roles.xml
可以通过修改roles.xml,来修改默认应用,但是我需要的是动态的修改:
2.vendor/mediatek/proprietary/packages/apps/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java
通过setRoleHolderAsUser函数实现,传入roleName和packageName,最终调用
android.app.role.RoleManager->addRoleHolderAsUser(...);
public void setRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
boolean add, int flags, @NonNull UserHandle user, @NonNull Context context) {
if (getValue() != STATE_IDLE) {
Log.e(LOG_TAG, "Already (tried) managing role holders, requested role: " + roleName
+ ", requested package: " + packageName);
return;
}
if (DEBUG) {
Log.i(LOG_TAG, (add ? "Adding" : "Removing") + " package as role holder, role: "
+ roleName + ", package: " + packageName);
}
mLastPackageName = packageName;
mLastAdd = add;
mLastFlags = flags;
mLastUser = user;
setValue(STATE_WORKING);
RoleManager roleManager = context.getSystemService(RoleManager.class);
Executor executor = context.getMainExecutor();
Consumer<Boolean> callback = successful -> {
if (successful) {
if (DEBUG) {
Log.i(LOG_TAG, "Package " + (add ? "added" : "removed")
+ " as role holder, role: " + roleName + ", package: " + packageName);
}
setValue(STATE_SUCCESS);
} else {
if (DEBUG) {
Log.i(LOG_TAG, "Failed to " + (add ? "add" : "remove")
+ " package as role holder, role: " + roleName + ", package: "
+ packageName);
}
setValue(STATE_FAILURE);
}
};
if (add) {
roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
} else {
roleManager.removeRoleHolderAsUser(roleName, packageName, flags, user, executor,
callback);
}
}
各默认应用对应的 roleName 如下:
电话
role: android.app.role.DIALER, package: com.android.dialer
短信
role: android.app.role.SMS, package: com.android.mms
主屏幕
role: android.app.role.HOME, package: com.android.launcher3
浏览器
role: android.app.role.BROWSER, package: com.android.browser
可以通过RoleManager->addRoleHolderAsUser(...),在某个服务中重写默认的app包名!
// 默认浏览器
./frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
import android.app.role.RoleManager;
import android.os.UserHandle;
import android.os.Process;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
public void setDefaultBrowser(Context context, String packageName) {
String roleName = "android.app.role.BROWSER";
boolean add = true;
int flags = 0;
UserHandle user = Process.myUserHandle();
Log.d("TAG", "role: "+ roleName + ", package: " + packageName);
RoleManager roleManager = context.getSystemService(RoleManager.class);
Executor executor = context.getMainExecutor();
Consumer<Boolean> callback = successful -> {
if (successful) {
Log.d("TAG", "Success , role: " + roleName + ", package: " + packageName);
} else {
Log.d("TAG", "Failed , role: " + roleName + ", package: "+ packageName);
}
};
roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
}
@Override
public void systemReady() {
...
synchronized (mLock) {
mSystemReady = true;
mHandler.post(new Runnable() {
@Override
public void run() {
updateSettings();
}
});
// If this happens, for whatever reason, systemReady came later than systemBooted.
// And keyguard should be already bound from systemBooted
if (mSystemBooted) {
mKeyguardDelegate.onBootCompleted();
}
}
mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
setDefaultBrowser(mContext, "com.xx");//add
...
}
2.系统给与的pm命令,选中setHomeActivity
frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
PS C:\Users\Aaaa> adb shell -x
rk3566_r:/ $ pm set-home-activity com.xxx.mylauncher
Success
import android.app.role.IRoleManager;
import android.app.role.RoleManager;
import android.os.ServiceManager;
import java.util.concurrent.CompletableFuture;
import android.os.RemoteCallback;
import android.content.Context;
...
String default_home_package = SystemProperties.get("persist.sys.xxxxx", null);
final CompletableFuture<Boolean> future = new CompletableFuture<>();
final RemoteCallback callback = new RemoteCallback(res -> future.complete(res != null));
try {
IRoleManager roleManager = android.app.role.IRoleManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.ROLE_SERVICE));
roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, default_home_package,
0, 0, callback);
boolean success = future.get();
if (success) {
android.util.Log.v("tww", "DefaultActivity success");
} else {
android.util.Log.v("tww", "DefaultActivity Error: Failed to set default home.");
}
} catch (Exception e) {
e.printStackTrace();
}
...