PermissionControllerService killed
一、PermissionControllerService 在开机的时候被lmkd kill 导致开机卡在开机界面
log如下:
I am_proc_start: [0,xxx,10253,com.google.android.permissioncontroller,service,{com.google.android.permissioncontroller/com.android.permissioncontroller.permission.service.PermissionControllerServiceImpl}]
killinfo: [xxx,10253,......
- 看到xxx进程也就是com.google.android.permissioncontroller 刚刚被调起就被kill,这个killinfo是lmkd打印的。
- 查看 SystemServerTiming StartPermissionPolicyService 被卡住在Permission_callback_waiting
SystemServerTiming: StartPermissionPolicyService
SystemServiceManager: Starting com.android.server.policy.PermissionPolicyService
SystemServerTiming: OnBootPhase_550_com.android.server.tracing.TracingServiceProxy
SystemServerTiming: OnBootPhase_550_com.android.server.policy.PermissionPolicyService
SystemServerTiming: Permission_grant_default_permissions-0
SystemServerTiming: Permission_callback_waiting-0
- 这个waiting导致了ANR
held mutexes=
at jdk.internal.misc.Unsafe.park(Native method)
- waiting on an unknown object
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
at java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1772)
at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3129)
at java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1799)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1974)
at com.android.server.policy.PermissionPolicyService.grantOrUpgradeDefaultRuntimePermissionsIfNeeded(PermissionPolicyService.java:603)
at com.android.server.policy.PermissionPolicyService.onStartUser(PermissionPolicyService.java:535)
at com.android.server.policy.PermissionPolicyService.onBootPhase(PermissionPolicyService.java:405)
at com.android.server.SystemServiceManager.startBootPhase(SystemServiceManager.java:294)
at com.android.server.SystemServer.lambda$startOtherServices$5$com-android-server-SystemServer(SystemServer.java:2899)
at com.android.server.SystemServer$$ExternalSyntheticLambda7.run(unavailable:30)
at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:8236)
at com.android.server.SystemServer.startOtherServices(SystemServer.java:2896)
at com.android.server.SystemServer.run(SystemServer.java:946)
at com.android.server.SystemServer.main(SystemServer.java:656)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:920)
二、查看对应的代码
PermissionPolicyService.java :
1 这里的future.complete不执行下面的future.get会一直阻塞,导致ANR
// We need to create a local manager that does not schedule work on the main
// there as we are on the main thread and want to block until the work is
// completed or we time out.
final PermissionControllerManager permissionControllerManager =
new PermissionControllerManager(
getUserContext(getContext(), UserHandle.of(userId)),
FgThread.getHandler());
permissionControllerManager.grantOrUpgradeDefaultRuntimePermissions(
FgThread.getExecutor(), successful -> {
if (successful) {
future.complete(null);
} else {
// We are in an undefined state now, let us crash and have
// rescue party suggest a wipe to recover to a good one.
final String message = "Error granting/upgrading runtime permissions"
+ " for user " + userId;
Slog.wtf(LOG_TAG, message);
future.completeExceptionally(new IllegalStateException(message));
}
});
try {
t.traceBegin("Permission_callback_waiting-" + userId);
future.get();
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException(e);
} finally {
t.traceEnd();
}
2 只有这里的postAsync 返回后让下面的,callback.accept 执行才会回调回去
/**
* Grant or upgrade runtime permissions. The upgrade could be performed
* based on whether the device upgraded, whether the permission database
* version is old, or because the permission policy changed.
*
* @param executor Executor on which to invoke the callback
* @param callback Callback to receive the result
*
* @hide
*/
@RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
public void grantOrUpgradeDefaultRuntimePermissions(
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
mRemoteService.postAsync(service -> {
AndroidFuture<Boolean> grantOrUpgradeDefaultRuntimePermissionsResult =
new AndroidFuture<>();
service.grantOrUpgradeDefaultRuntimePermissions(
grantOrUpgradeDefaultRuntimePermissionsResult);
return grantOrUpgradeDefaultRuntimePermissionsResult;
}).whenCompleteAsync((grantOrUpgradeDefaultRuntimePermissionsResult, err) -> {
if (err != null) {
Log.e(TAG, "Error granting or upgrading runtime permissions", err);
callback.accept(false);
} else {
callback.accept(Boolean.TRUE.equals(grantOrUpgradeDefaultRuntimePermissionsResult));
}
}, executor);
}
ServiceConnector.java:
3 这里的task.mDelegate 现在就是job了只有它,看它在哪里执行的,enqueue(task)
@Override
public <R> AndroidFuture<R> postAsync(@NonNull Job<I, CompletableFuture<R>> job) {
CompletionAwareJob<I, R> task = new CompletionAwareJob<>();
task.mDelegate = Objects.requireNonNull((Job) job);
task.mAsync = true;
enqueue(task);
return task;
}
4 这里的强转了一下
private void enqueue(@NonNull CompletionAwareJob<I, ?> task) {
if (!enqueue((Job<I, ?>) task)) {
task.completeExceptionally(new IllegalStateException(
"Failed to post a job to handler. Likely "
+ mHandler.getLooper() + " is exiting"));
}
}
5 将job加入 mQueue队列中
8 在这里绑定的服务
void enqueueJobThread(@NonNull Job<I, ?> job) {
if (DEBUG) {
Log.i(LOG_TAG, "post(" + job + ", this = " + this + ")");
}
cancelTimeout();
if (mUnbinding) {
completeExceptionally(job,
new IllegalStateException("Service is unbinding. Ignoring " + job));
} else if (!mQueue.offer(job)) {//zsg 5
completeExceptionally(job,
new IllegalStateException("Failed to add to queue: " + job));
} else if (isBound()) {
processQueue();
} else if (!mBinding) {
if (bindService(mServiceConnection)) { //zsg 8 在这里绑定的服务
mBinding = true;
} else {
completeExceptionally(job,
new IllegalStateException("Failed to bind to service " + mIntent));
}
}
}
6 取出job,然后job.run(service) ,那么这个service是谁呢?
private void processQueue() {
if (DEBUG) {
logTrace();
}
Job<I, ?> job;
while ((job = mQueue.poll()) != null) {//zsg mQueue.poll() 取出
CompletionAwareJob task = castOrNull(job, CompletionAwareJob.class);
try {
I service = mService;
if (service == null) {
return;
}
Object result = job.run(service);// zsg 回调回去
if (DEBUG) {
Log.i(LOG_TAG, "complete(" + job + ", result = " + result + ")");
}
if (task != null) {
if (task.mAsync) {
mUnfinishedJobs.add(task);
((CompletionStage) result).whenComplete(task);
} else {
task.complete(result);
}
}
} catch (Throwable e) {
completeExceptionally(job, e);
}
}
maybeScheduleUnbindTimeout();
}
7 mService 在这里赋值的,看看这个onServiceConnected是谁
@Override
public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder binder) {
if (mUnbinding) {
Log.i(LOG_TAG, "Ignoring onServiceConnected due to ongoing unbinding: " + this);
return;
}
if (DEBUG) {
logTrace();
}
I service = binderAsInterface(binder);
mService = service; //zsg 这里就是上面和第5点在一起的那个第8点bind的
mBinding = false;
try {
binder.linkToDeath(ServiceConnector.Impl.this, 0);
} catch (RemoteException e) {
Log.e(LOG_TAG, "onServiceConnected " + name + ": ", e);
}
dispatchOnServiceConnectionStatusChanged(service, true);
processQueue();
}
9 哪么这个mIntent是要去哪里呢?
/**
* {@link Context#bindServiceAsUser Binds} to the service.
*
* <p>
* If overridden, implementation must use at least the provided {@link ServiceConnection}
*/
protected boolean bindService(@NonNull ServiceConnection serviceConnection) {
if (DEBUG) {
logTrace();
}
return mContext.bindService(mIntent, Context.BIND_AUTO_CREATE | mBindingFlags,
mExecutor, serviceConnection);
}
10 intent 在这里传入 的
/**
* Creates an instance of {@link ServiceConnector}
*
* See {@code protected} methods for optional parameters you can override.
*
* @param context to be used for {@link Context#bindServiceAsUser binding} and
* {@link Context#unbindService unbinding}
* @param intent to be used for {@link Context#bindServiceAsUser binding}
* @param bindingFlags to be used for {@link Context#bindServiceAsUser binding}
* @param userId to be used for {@link Context#bindServiceAsUser binding}
* @param binderAsInterface to be used for converting an {@link IBinder} provided in
* {@link ServiceConnection#onServiceConnected} into a specific
* {@link IInterface}.
* Typically this is {@code IMyInterface.Stub::asInterface}
*/
public Impl(@NonNull Context context, @NonNull Intent intent, int bindingFlags,
@UserIdInt int userId, @Nullable Function<IBinder, I> binderAsInterface) {
mContext = context.createContextAsUser(UserHandle.of(userId), 0);
mIntent = intent;
mBindingFlags = bindingFlags;
mBinderAsInterface = binderAsInterface;
mHandler = getJobHandler();
mExecutor = new HandlerExecutor(mHandler);
}
11 permissionControllerManager intent就是这里传入的了,这个SERVICE_INTERFACE = "android.permission.PermissionControllerService"就是调用远程的服务
/**
* Create a new {@link PermissionControllerManager}.
*
* @param context to create the manager for
* @param handler handler to schedule work
*
* @hide
*/
public PermissionControllerManager(@NonNull Context context, @NonNull Handler handler) {
synchronized (sLock) {
Pair<Integer, Thread> key = new Pair<>(context.getUserId(),
handler.getLooper().getThread());
ServiceConnector<IPermissionController> remoteService = sRemoteServices.get(key);
if (remoteService == null) {
Intent intent = new Intent(SERVICE_INTERFACE);//zsg 这里
String pkgName = context.getPackageManager().getPermissionControllerPackageName();
intent.setPackage(pkgName);
ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0);
if (serviceInfo == null) {
String errorMsg = "No PermissionController package (" + pkgName + ") for user "
+ context.getUserId();
Log.wtf(TAG, errorMsg);
throw new IllegalStateException(errorMsg);
}
remoteService = new ServiceConnector.Impl<IPermissionController>(
ActivityThread.currentApplication() /* context */,
new Intent(SERVICE_INTERFACE)
.setComponent(serviceInfo.getComponentInfo().getComponentName()),
0 /* bindingFlags */, context.getUserId(),
IPermissionController.Stub::asInterface) {
@Override
protected Handler getJobHandler() {
return handler;
}
@Override
protected long getRequestTimeoutMs() {
return REQUEST_TIMEOUT_MILLIS;
}
@Override
protected long getAutoDisconnectTimeoutMs() {
return UNBIND_TIMEOUT_MILLIS;
}
};
sRemoteServices.put(key, remoteService);
}
mRemoteService = remoteService;
}
mContext = context;
mHandler = handler;
}
- 虽然这是由于低内存引起的问题,但有的机器内存确实小,那怎么解决呢?
- 解决办法:设置个定时器Timer 只要future.get()还一直在阻塞状态那就过一段时间去执行一下permissionControllerManager.grantOrUpgradeDefaultRuntimePermissions
- 直到future.complete 被执行后释放future.get(),然后在future.get()的finally方法里取消定时器
三、CompletableFuture 学习 AndroidFuture extends CompletableFuture
https://developer.android.google.cn/reference/kotlin/java/util/concurrent/CompletableFuture
https://blog.youkuaiyun.com/qq_34250794/article/details/136393249
四、Collection 学习 Queue extends Collection (todo)