PermissionPolicyService

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.csdn.net/qq_34250794/article/details/136393249

四、Collection 学习 Queue extends Collection (todo)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值