自由窗口框架分析

自由窗口模式

构建了新的服务SmtPCManagerService

该服务的构建是在SystemServer.java中,也就是在system_server进程中

SmtPCManagerService(Contextcontext,ActivityManagerServiceams,InputManagerServiceims)

从启动Activity开始:

Activity.java

Activity.attach()->构建PhoneWindow

PhoneWindow.java

PhoneWindow(Context context,Window preservedWindow,

ActivityConfigCallback activityConfigCallback)

在PhoneWindow的构造方法中,会通过preservedWindow获取到DecorView实例

setContentView

addContentView

getDecorView

getCircularProgressBar

getHorizontalProgressBar

getRightIconView

getLeftIconView

上述方法都会调用到installDecor方法,调用依据就是mContentParent是否为空

,而mContentParent = generateLayout(mDecor)

installDecor()

1) DecorView.onConfigurationChanged(Configuration newConfig) -> createDecorCaptionView (会根据stack号决定是否创建DecorCaptionView)

2) PhoneWIndow.generateLayout(执行requestFeature,setFlags等操作,inflate decorview)->DecorView.onResourcesLoaded(根据不同的features得到不同的资源索引,随后加载view,根据时候存在DecorCaptionView执行不同的addView) -> createDecorCaptionView

->inflateDecorCaptionView(加载xml文件,<com.android.internal.widget.SmtDecorCaptionView)

->创建SmtDecorCaptionView(继承于DecorCaptionView,内部逻辑与DecorCaptionView大同小异)

SmtDecorCaptionView.java

1)setPhoneWindow,会在Activity.attach构建PhoneWindow时调用,控制一些视图的显示

2) 关于事件的监听

首先SmtDecorCaptionView 继承于DecorCaptionView extendsViewGroupimplementsView.OnTouchListener,

GestureDetector.OnGestureListener

那么

a、onInterceptTouchEvent ( 根据view的getHitRect获取到点击范围,判断点击的view,并进行拦截,拦截了之后就意味着,事件不会再传递到下层View,会在SmtDecorCaptionView的onTouchEvent中处理事件)

b、onTouchEvent( 实际将event传递给了GestureDetector进行处理,返回、最小化、结束的点击事件就是在onSingleTapUp方法中处理的)

c、onTouch ->View.OnTouchListener(

当点击的是非特殊事件的位置时,会执行检测是否执行拖动操作,满足拖动操作的条件->

回调到View.startMovingExtendScreenTask->mAttachInfo.mSession.startMovingExtendScreenTask)

dispatchAttachedToWindow - > View.AttachInfo ->WindowManagerGlobal.getWindowSession() -> WindowManagerService.openSession ->Session.startMovingExtendScreenTask

->WindowManagerService.startMovingExtendScreenTask

boolean startMovingExtendScreenTask(IWindow window, float startX, float startY) {
    WindowState win = null;
    synchronized (mWindowMap) {
        win = windowForClientLocked(null, window, false);
        // win shouldn't be null here, pass it down to startPositioningLocked
        // to get warning if it's null.
        if (!startExtendScreenPositioningLocked(
                    win, false /*resize*/, false /*preserveOrientation*/, startX, startY)) {
            return false;
        }

        if(mSmtTaskPositioners.size() >= 1) {
            return true;
        }
    }
    try {
        mActivityManager.setFocusedTask(win.getTask().mTaskId);
    } catch(RemoteException e) {}
    return true;
}

-->windowForClientLocked

-->startExtendScreenPositioningLocked

-->mActivityManager.setFocusedTask

startExtendScreenPositioningLocked

private boolean startExtendScreenPositioningLocked(WindowState win, boolean resize,
        boolean preserveOrientation, float startX, float startY) {
    if (DEBUG_TASK_POSITIONING)
        Slog.d(TAG_WM, "startExtendScreenPositioningLocked: "
                        + "win=" + win + ", resize=" + resize + ", preserveOrientation="
                        + preserveOrientation + ", {" + startX + ", " + startY + "}");
    if(mSmtTaskPositioners.size() >=2) {
        return false;
    }
    if (win == null || win.getAppToken() == null) {
        Slog.w(TAG_WM, "startExtendScreenPositioningLocked: Bad window " + win);
        return false;
    }
    if (win.mInputChannel == null) {
        Slog.wtf(TAG_WM, "startExtendScreenPositioningLocked: " + win + " has no input channel, "
                + " probably being removed");
        return false;
    }

    final DisplayContent displayContent = win.getDisplayContent();
    if (displayContent == null) {
        Slog.w(TAG_WM, "startExtendScreenPositioningLocked: Invalid display content " + win);
        return false;
    }
    if(mSmtTaskPositioners.get(win) != null) {
         Slog.w(TAG_WM, "startExtendScreenPositioningLocked: Invalid window " + win);
        return false;
    }
    Display display = displayContent.getDisplay();
    SmtTaskPositioner taskPositioner = new SmtTaskPositioner(this);
    taskPositioner.register(display);
    mSmtTaskPositioners.put(win, taskPositioner);

    mInputMonitor.updateInputWindowsLw(true /*force*/);

    // We need to grab the touch focus so that the touch events during the
    // resizing/scrolling are not sent to the app. 'win' is the main window
    // of the app, it may not have focus since there might be other windows
    // on top (eg. a dialog window).
    WindowState transferFocusFromWin = win;
    if (mCurrentFocus != null && mCurrentFocus != win
            && mCurrentFocus.mAppToken == win.mAppToken) {
        transferFocusFromWin = mCurrentFocus;
    }
    if (!mInputManager.transferTouchFocus(
            transferFocusFromWin.mInputChannel, taskPositioner.mServerChannel)) {
        Slog.e(TAG_WM, "startExtendScreenPositioningLocked: Unable to transfer touch focus");
        taskPositioner.unregister();
        mSmtTaskPositioners.remove(win);
        taskPositioner = null;
        mInputMonitor.updateInputWindowsLw(true /*force*/);
        return false;
    }

    taskPositioner.startDrag(win, resize, preserveOrientation, startX, startY);
    return true;
}

results for ""

    No results matching ""