Android4.4之Keyguard

1. KeyguardSecurityCallback接口

KeyguardSecurityCallback.java

public interface KeyguardSecurityCallback {
    void dismiss(boolean securityVerified);
    void userActivity(long timeout);
    boolean isVerifyUnlockOnly();
    void reportSuccessfulUnlockAttempt();
    void reportFailedUnlockAttempt();
    int getFailedAttempts();
    void showBackupSecurity();
    void setOnDismissAction(OnDismissAction action);
    boolean hasOnDismissAction();
    void updateKeyguardLayerVisibility(boolean visible);
    void updateClipChildren(boolean clipChildren);
    void updateWidgetContainerInteractive(boolean disable) ;
}
这个接口只有两个实现,其中一个是空实现,在KeyguardHostView.java中

mCallback 和 mNullCallback

。。。。。。

KeyguardHostView.java

private void showSecurityScreen(SecurityMode securityMode)

    KeyguardSecurityView newView = getSecurityView(securityMode);

    newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
    newView.setKeyguardCallback(mCallback);


private void updateSecurityView(View view)

    if (view instanceof KeyguardSecurityView) {
        KeyguardSecurityView ksv = (KeyguardSecurityView) view;
        ksv.setKeyguardCallback(mCallback);
        ksv.setLockPatternUtils(mLockPatternUtils);
        if (mViewStateManager.isBouncing()) {
            ksv.showBouncer(0);
        } else {
            ksv.hideBouncer(0);
        }
    }


2. ViewMediatorCallback接口

在KeyguardViewMediator.java中定义

public interface ViewMediatorCallback {
    void userActivity();
    void userActivity(long millis);
    void keyguardDone(boolean authenticated);
    void keyguardDoneDrawing();
    void setNeedsInput(boolean needsInput);
    void onUserActivityTimeoutChanged();
    void keyguardDonePending();
    void keyguardGone();
}

public void keyguardGone() {
    if (mKeyguardDisplayManager != null) {
        mKeyguardDisplayManager.hide();
    }
}

//handleShow
if (mKeyguardDisplayManager != null) {
    mKeyguardDisplayManager.show();
}

public void keyguardDonePending() {
    mKeyguardDonePending = true;
}
public void keyguardDone(boolean authenticated, boolean wakeup) {
    synchronized (this) {
        mKeyguardDonePending = false;
    }
    Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0, wakeup ? 1 : 0);
    mHandler.sendMessage(msg);
}
private void handleKeyguardDone(boolean authenticated, boolean wakeup) {
    if (authenticated) {
        mUpdateMonitor.clearFailedUnlockAttempts();
    }

    handleHide();
    sendUserPresentBroadcast();
}
private void handleHide() {
    synchronized (KeyguardViewMediator.this) {
        /// M: skip hide if not showing
        if (!mShowing) return;
        if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
            playSounds(false);
        }
        mKeyguardViewManager.hide();
        mShowing = false;
        mKeyguardDonePending = false;
        updateActivityLockScreenState();
        adjustStatusBarLocked();
    }
}

public void setNeedsInput(boolean needsInput) {
    mKeyguardViewManager.setNeedsInput(needsInput);
}

public void onUserActivityTimeoutChanged() {
    mKeyguardViewManager.updateUserActivityTimeout();
} 

这个接口只有一个实现,也在KeyguardViewMediator.java中定义:

。。。。。。

这个实例最终传递给KeyguardViewManager的mViewMediatorCallback变量

KeyguardViewManager除了自己要使用这个Callback外,它还会把这个callback传递给KeyguardHostView

mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);

public abstract class KeyguardViewBase extends FrameLayout {

    protected KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;

    public void setViewMediatorCallback(KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
        mViewMediatorCallback = viewMediatorCallback;
    }
}

public class KeyguardHostView extends KeyguardViewBase

3. 关于这两个接口中的userActivity方法

KeyguardSecurityCallback接口中有:

void userActivity(long timeout);

//唯一的非空实现mCallback,这里可以看到它其实调用的是KeyguardHostView的mViewMediatorCallback
//而这里的mViewMediatorCallback其实也只有唯一的一个实现,就是在KeyguardViewMediator中的实现
public void userActivity(long timeout) {
    if (mViewMediatorCallback != null) {
        mViewMediatorCallback.userActivity(timeout);
    }
}
ViewMediatorCallback接口中有:
void userActivity();
void userActivity(long millis);

//ViewMediatorCallback接口唯一的实现mViewMediatorCallback,在KeyguardViewMediator中
//这两个方法的实现其实调用了KeyguardViewMediator对应的两个方法
public void userActivity() {
    KeyguardViewMediator.this.userActivity();
}

public void userActivity(long holdMs) {
    KeyguardViewMediator.this.userActivity(holdMs);
}

//KeyguardViewMediator对应的两个方法如下:
private void userActivity() {
    userActivity(AWAKE_INTERVAL_DEFAULT_MS);
}

//归根到底,最终调用的都是下面这个方法,而下面这个方法完全忽略了holdMs这个参数,
//它的实现调用了PowerManager的userActivity(SystemClock.uptimeMillis(), false)
//从注释也可以看到,We ignore the hold time.  Eventually we should remove it
//所以,在锁屏模块中看到的所有userActivity方法,可以完全忽略其中的参数,
//最终调用的都是PowerManager的userActivity(SystemClock.uptimeMillis(), false)
public void userActivity(long holdMs) {
    // We ignore the hold time.  Eventually we should remove it.
    // Instead, the keyguard window has an explicit user activity timeout set on it.
    mPM.userActivity(SystemClock.uptimeMillis(), false);
}

4. 关于KeyguardSecurityContainer和KeyguardSecurityViewFlipper

<com.android.keyguard.KeyguardSecurityContainer
    android:id="@+id/keyguard_security_container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clipChildren="false"
    android:clipToPadding="false"
    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
    androidprv:layout_childType="challenge"
    android:padding="0dp"
    android:gravity="bottom|center_horizontal">
    <com.android.keyguard.KeyguardSecurityViewFlipper
        android:id="@+id/view_flipper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:paddingTop="@dimen/keyguard_security_view_margin"
        android:gravity="center">
    </com.android.keyguard.KeyguardSecurityViewFlipper>
</com.android.keyguard.KeyguardSecurityContainer>

关于KeyguardSecurityViewFlipper

public class KeyguardSecurityViewFlipper extends ViewFlipper implements KeyguardSecurityView

首先,它是一个ViewFlipper,关于ViewFlipper,开发文档中有如下描述:

Simple ViewAnimator that will animate between two or more views that have been added to it.

Only one child is shown at a time.

If requested, can automatically flip between each child at a regular interval.

但是在锁屏模块中并没有使用它的自动切换的功能,而是手动地切换:mSecurityViewContainer.setDisplayedChild(i);

至于它其中一共有几个child,这需要打log来看了,不过估计会有多个child。


其次,它也是一个KeyguardSecurityView,它的十个抽象方法这里都一一实现了。

它的实现方式非常简单,从hierarchyviewer的view结构图中我们知道KeyguardSecurityViewFlipper下面包含的view(或者child)都是KeyguardSecurityView,因此它的实现方式就是:

//getDisplayedChild方法得到当前显示的子view的index(不是R.id,对应的是0、1、2......)
KeyguardSecurityView getSecurityView() {
    View child = getChildAt(getDisplayedChild());
    if (child instanceof KeyguardSecurityView) {
        return (KeyguardSecurityView) child;
    }
    return null;
}

//直接调用child的方法来实现接口
public void reset() {
    KeyguardSecurityView ksv = getSecurityView();
    if (ksv != null) {
        ksv.reset();
    }
}

//showBouncer和hideBouncer的实现与其它八个方法的实现有差别
//其它几个:只有当前显示的子view才有实现,否则实现为空
//这两个:不管子view是否正在显示,都会调用子view的showBouncer和hideBouncer方法,但是duration不一样(若不是正在显示,则duration为0)
public void showBouncer(int duration) {
    KeyguardSecurityView active = getSecurityView();
    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        if (child instanceof KeyguardSecurityView) {
            KeyguardSecurityView ksv = (KeyguardSecurityView) child;
            ksv.showBouncer(ksv == active ? duration : 0);
        }
    }
}

这个类的实例只有一个,在KeyguardHostView.java中定义,并把它传递给了KeyguardViewStateManager的mKeyguardSecurityContainer变量:
//onFinishInflate方法
mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(fliperId);
mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);

public class KeyguardSecurityContainer extends FrameLayout {

    //这里要在所有的子view中查找KeyguardSecurityViewFlipper,不过它应该只有一个子view
    KeyguardSecurityViewFlipper getFlipper() {
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child instanceof KeyguardSecurityViewFlipper) {
                return (KeyguardSecurityViewFlipper) child;
            }
        }
        return null;
    }

    //这里的实现其实也是调用子view的方法
    //showBouncer、hideBouncer和setClipChildrenForNewEventView方法的实现都是一样的
    public void showBouncer(int duration) {
        KeyguardSecurityViewFlipper flipper = getFlipper();
        if (flipper != null) {
            flipper.showBouncer(duration);
        }
    }
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值