|
启动指纹监听: 用户打开指纹识别开关时,开机初始化,唤醒,睡眠,都回调到 updateFingerprintListeningState更新是否打开指纹监听。 private void updateFingerprintListeningState() { boolean shouldListenForFingerprint = shouldListenForFingerprint(); if (mFingerprintDetectionRunning && !shouldListenForFingerprint){ stopListeningForFingerprint(); } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint){ startListeningForFingerprint(); } } startListeningForFingerprint 中调用mFpm.authenticate(null,mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);实现指纹监听扫描。 FingerprintManager 通过跨进程调用实现:它实际就调到了FingerprintService内部类 FingerprintServiceWrapper中的方法。如下:(关于mService为什么是FingerprintService后面有说明) mService.authenticate(mToken, sessionId, userId, mServiceReceiver,flags, mContext.getOpPackageName()); FingerprintService.java 内部类FingerprintServiceWrapper的方法: @Override // Binder call public void authenticate(final IBinder token, final long opId, final intgroupId, finalIFingerprintServiceReceiver receiver, final int flags, final String opPackageName) { if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) { Slog.w(TAG, "Can'tauthenticate non-current user"); return; } if (!canUseFingerprint(opPackageName)) { Slog.w(TAG, "Calling notgranted permission to use fingerprint"); return; } // Group ID is arbitrarily set to parent profile user ID. It justrepresents // the default fingerprints for the user. final int effectiveGroupId = getEffectiveUserId(groupId); final boolean restricted = isRestricted(); mHandler.post(new Runnable() { @Override public void run() { startAuthentication(token, opId,effectiveGroupId, receiver, flags, restricted); } }); } 关于mService为什么是FingerprintService后面有说明如下: FingerprintService.java在其中注册了FINGERPRINT_SERVICE服务,方便系统直接通过 SystemServer中调用FingerprintService的start方法最后调到publishBinderService来绑定服务 mSystemServiceManager.startService(FingerprintService.class);---》publishBinderService ServiceManager.getService进行获取: publishBinderService(Context.FINGERPRINT_SERVICE, newFingerprintServiceWrapper()); (publishBinderService 的实际实现systemService.java的ServiceManager.addService(name, service, allowIsolated);) 注册初始化:FingerprintManager,这样fingerprintManager就可以以代理的方式调用FingprintService SystemServiceRegistry.java中: registerService(Context.FINGERPRINT_SERVICE, FingerprintManager.class, newCachedServiceFetcher<FingerprintManager>() { @Override public FingerprintManager createService(ContextImpl ctx) { IBinder binder =ServiceManager.getService(Context.FINGERPRINT_SERVICE); IFingerprintService service =IFingerprintService.Stub.asInterface(binder); return newFingerprintManager(ctx.getOuterContext(), service); }}); mService.authenticate最后调到了: final int result = daemon.authenticate(opId,groupId); 这个也同样是跨进程调用,被调用的进程是fingerd (C++书写的守护进程)。 fingerd进程分析: 入口为fingerprintd.cpp文件中的main函数: android::sp<android::FingerprintDaemonProxy>proxy = android::FingerprintDaemonProxy::getInstance(); android::status_t ret = serviceManager->addService( android::FingerprintDaemonProxy::descriptor, proxy); 添加服务到serviceManager中这样framework代码就可以跨进程拿到这个服务也是aidl原理。不过这个是实现了c++层aidl. 那我们就开始看它核心(FingerprintDaemonProxy)proxy 到底做了些什么? 其中包括: FingerprintDaemonProxy::authenticate 指纹认证实际调用的地方:daemon.authenticate就调用fingerd这个函数; FingerprintDaemonProxy::init初始化:如进行初始化一个回调等 在FingerprintService就有用到:(注册一个回调给fingerd) public IFingerprintDaemongetFingerprintDaemon() { if (mDaemon == null) { mDaemon =IFingerprintDaemon.Stub.asInterface(ServiceManager.getService(FINGERPRINTD)); if (mDaemon != null) { try { mDaemon.asBinder().linkToDeath(this, 0); mDaemon.init(mDaemonCallback); mHalDeviceId =mDaemon.openHal(); FingerprintDaemonProxy::hal_notify_callback 注册到device驱动中:如FingerprintDaemonProxy::openHal() ---》err =mDevice->set_notify(mDevice, hal_notify_callback); 如:驱动进行指纹的识别动作,根据不同的返回码调用hal_notify_callback这个回调,这个回调最后回调到mDaemon.init(mDaemonCallback);初始化进去的mDaemonCallback(即框架上层的回调) 如authenticate 操作经过指纹汇顶驱动进行匹配后,会回调执行到以下函数。 最后通过callback->onAuthenticated回调反馈给上层处理。 caseFINGERPRINT_AUTHENTICATED: ALOGD("onAuthenticated(fid=%d, gid=%d)", msg->data.authenticated.finger.fid, msg->data.authenticated.finger.gid); if (msg->data.authenticated.finger.fid!= 0) { const uint8_t* hat = reinterpret_cast<const uint8_t*>(&msg->data.authenticated.hat); instance->notifyKeystore(hat,sizeof(msg->data.authenticated.hat)); } callback->onAuthenticated(device, msg->data.authenticated.finger.fid, msg->data.authenticated.finger.gid); break; 那么上层的callback->onAuthenticated是怎么处理的呢? callback实际上是FingerprintService.java中的IFingerprintDaemonCallbackmDaemonCallback = new IFingerprintDaemonCallback.Stub(){ @Override public void onAuthenticated(long deviceId, int fingerId, int groupId) { dispatchAuthenticated(deviceId, fingerId, groupId); } } --------->最后调到:receiver.onAuthenticationSucceeded(mHalDeviceId,fp); receiver实际是:KeyguardUpdateMonitor.java privateFingerprintManager.AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() { @Override public void onAuthenticationSucceeded(AuthenticationResult result) { handleFingerprintAuthenticated(); } }; handleFingerprintAuthenticated 会调到KeyguardUpdateMonitorCallback,而其中的一个KeyguardUpdateMonitorCallback实际就是KeyguardViewMediator.onFingerprintAuthenticated这个函数就实现了解锁功能: KeyguardUpdateMonitorCallback cb =mCallbacks.get(i).get(); cb.onFingerprintAuthenticated(userId,wakeAndUnlocking); ************** public void onFingerprintAuthenticated(int userId, booleanwakeAndUnlocking) { if (wakeAndUnlocking &&mShowing && unlockingWithFingerprintAllowed) { mWakeAndUnlocking = true; mStatusBarKeyguardViewManager.setWakeAndUnlocking(); keyguardDone(true, true); } else if (mShowing &&mDeviceInteractive) { if (wakeAndUnlocking) { mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); } mStatusBarKeyguardViewManager.animateCollapsePanels( FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); } } }; *************** KeyguardViewMediator.onFingerprintAuthenticated这个函数就实现了解锁功能: 黑屏指纹解锁调用:keyguardDone(true,true); 亮屏指纹解锁调用:mStatusBarKeyguardViewManager.animateCollapsePanels( FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); 先讲解:亮屏指纹解锁调用的过程: 1:状态栏的一些处理 :如: PanelView 2:执行mBar.makeExpandedInvisible(); 实现解锁 1)添加mHideExpandedRunnable到sPendingRunnables中 2)postAnimationCallback调用执行sPendingRunnables private Runnable mHideExpandedRunnable = new Runnable() { @Override public void run() { mBar.makeExpandedInvisible(); } }; 上面的mHideExpandedRunnable是由下面函数进行调用的。 private staticvoid postAnimationCallback() { sChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,sAnimationCallbackRunnable, null); } 其中有对于调用的控制最后又doFrame 做每一帧的时候根据条件调用doCallbacks函数,这里会调用到上列的mHideExpandedRunnable。 执行mBar.makeExpandedInvisible();实现解锁的解锁过程: 1)最终它也是调用mViewMediatorCallback.keyguardDone(true);实现的解锁 通过: makeExpandedInvisible --》StatusBarKeyguarViewManager.dismiss(booleanauthenticated)--> showBouncer--->KeyguardBouncer.show(..)--->mKeyguardView.dismiss(authenticated) mKeyguardView.dismiss(authenticated)就是实现解锁的关键方法: KeyguardHostView.dismiss() -->KeyguardSecurityContainer. showNextSecurityScreenOrFinish(....) showNextSecurityScreenOrFinish最终会调到mSecurityCallback.finish(); 而mSecurityCallback是KeyguardHostView.即最终调了KeyguardHostView. finish() if (mViewMediatorCallback != null) { if (deferKeyguardDone) { mViewMediatorCallback.keyguardDonePending(); } else { mViewMediatorCallback.keyguardDone(true); } } *************************************************************************** mViewMediatorCallback实际是定义在KeyguardViewMediator.java中 ViewMediatorCallback mViewMediatorCallback= new ViewMediatorCallback() { public void userActivity() { KeyguardViewMediator.this.userActivity(); } public void keyguardDone(boolean authenticated) { if (!mKeyguardDonePending) { KeyguardViewMediator.this.keyguardDone(authenticated,true); } } 这里终于调到了KeyguardViewMediator.keyguardDone. 那我们从现在开始论述KeyguardViewMediator.keyguardDone.的解锁过程: keyguardDone 实际调用解锁handleHide 最终它会跑到如下的代码进入框架进行解锁流程: private final RunnablemKeyguardGoingAwayRunnable = new Runnable() { @Override public void run() { try { mStatusBarKeyguardViewManager.keyguardGoingAway(); // Don't actually hide theKeyguard at the moment, wait for window // manager until it tells usit's safe to do so with // startKeyguardExitAnimation. ActivityManagerNative.getDefault().keyguardGoingAway( mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock() ||mWakeAndUnlocking, mStatusBarKeyguardViewManager.isGoingToNotificationShade()); } catch (RemoteException e) { Log.e(TAG, "Error whilecalling WindowManager", e); } } }; 其中mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock() ||mWakeAndUnlocking, 可以控制解锁进桌面是否播放动画。keyguardGoingAway先是通过ActivityManagerService调到WindowManagerService的keyguardGoingAway 设置了mAnimator属性后直接进入requestTraversalLocked();进行窗口的变化。 performLayoutAndPlaceSurfacesLocked--》performLayoutAndPlaceSurfacesLockedLoop--》performLayoutAndPlaceSurfacesLockedInner---》 这个过程有很多窗口的layout 等最后跑到scheduleAnimationLocked();函数中。最后进入WindowAnimator的窗口动画中。 scheduleAnimationLocked到animateLocked 的过程: mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);其实它是通过Choreographer机制最后调用mAnimationFrameCallback------Choreographer通过利用Vsync机制执行执行Choreographer.dnFrame从而通过doCallbacks(Choreographer.CALLBACK_ANIMATION,frameTimeNanos);调用到了mAnimationFrameCallback 下面说一下animateLocked主要干了些什么? window动画分为两种:窗口中的动画,Activity切换个动画。 1)updateWindowsLocked 这里需要指出的变量是: // Currentlyrunning animation. boolean mAnimating; if (mAnimating) { mService.scheduleAnimationLocked(); } 它是判断当前是否在有动画在执行:判断规则比较严格,如果窗口还有更多动画,或有Activity动画它都会反复调用scheduleAnimationLocked进行多次执行,这是为了保证窗口的画面的正确性。有时我们能通过判断这个变量拿到窗口动画执行的总时间。 下面通过代码分析认证这个: updateWindowsLocked(displayId); 就是通过这个进行条件判断:winAnimator.stepAnimationLocked(mCurrentTime);里面就是通过判断 窗口是否还有更多动画需要执行,或有Activity动画来返回true或false来赋值mAnimating updateWallpaperLocked(displayId) updateWallpaperLocked同样也会进行判断:winAnimator.mAnimating来赋值mAnimating 如果最终mAnimating是True它会再次执行scheduleAnimationLocked if (mAnimating) { mService.scheduleAnimationLocked(); } 最终这个过程通过mPolicy.startKeyguardExitAnimation(mCurrentTime, 0 /*duration */);跑出框架。mPolicy实际是PhoneWindowManager对象。即最终调用了 public void startKeyguardExitAnimation(longstartTime, long fadeoutDuration) { mKeyguardDelegate.startKeyguardExitAnimation(startTime,fadeoutDuration); } } 然后调到mKeyguardService.startKeyguardExitAnimation(startTime,fadeoutDuration); 即调到了KeyguardViewMediator的handleStartKeyguardExitAnimation 很多时候我们可以认为如果调到handleStartKeyguardExitAnimation那么解锁就完成了,但严格上也不能说它完成了(因为这时候其实窗口还是在变化中,我们无法确定窗口时候已经全部绘画完成),所以这个函数很多时候用来处理解锁完成后的一些事情。 2)updateWallpaperLocked 3:窗口动画的呈现:WinAnimator.prepareSurfaceLocked 1) computeShownFrameLocked(); 计算需要呈现的动画 2)赋值动画变化矩阵,透明度,Z轴到mSurfaceControl中 mSurfaceAlpha = mShownAlpha; mSurfaceControl.setAlpha(mShownAlpha); mSurfaceLayer = mAnimLayer; mSurfaceControl.setLayer(mAnimLayer); mSurfaceControl.setMatrix( mDsDx * w.mHScale,mDtDx * w.mVScale, mDsDy * w.mHScale,mDtDy * w.mVScale); 3)通过surfacefinger绘制surface画布纹理从而实现动画。 showSurfaceRobustlyLocked.mSurfaceControl.show(); 再说一下Choreographer机制: 最后会执行到 调用输入窗口,其他窗口,窗口动画的回调函数 mFrameInfo.markInputHandlingStart(); doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); mFrameInfo.markAnimationsStart(); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); mFrameInfo.markPerformTraversalsStart(); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_COMMIT,frameTimeNanos); 如下面所列都用到这个机制: 1:窗口动画:mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback); 2:View的添加然后窗口创建: 如:应用通过addView来添加布局View - //3 选定了窗口修饰布局文件 ,添加至DecorView对象里,并且指定mcontentParent值
- View in = mLayoutInflater.inflate(layoutResource, null);
- decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
它的工作原理是: ViewRootImp是用户与WMS沟通的桥梁,通过DectorView .addView ViewRootImp.setView----> ViewRootImp. requestLayout-->ViewRootImp. scheduleTraversals最后会执行到: mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); 最后执行到mTraversalRunnable这个回调函数: mTraversalRunnable做了些什么呢? 1) performMeasure View进行大小计算 2) performLayout View进行布局 2) performDraw(); 进行绘画 代码过程如下: doTraversal()-->performTraversals ---》performMeasure ---》performLayout ---》performDraw performDraw的过程比较有意思: performDraw --》draw(fullRedrawNeeded); draw(fullRedrawNeeded);主要作用 1: surface = mSurface;拿到计算后的刚才通过performMeasure ,performLayout 过程后的surface纹理画布 2:drawSoftware(surface, mAttachInfo, xOffset,yOffset, scalingRequired, dirty)通过mView.draw(canvas)遍历绘制DectorView, surface.unlockCanvasAndPost(canvas);sufaceFinger绘制这个suface. 3:判断是否有动画,如果有,走动画的过程。 if(animating) { mFullRedrawNeeded = true; scheduleTraversals(); } |