`
daojin
  • 浏览: 691762 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Android之基础建设之IWindow和IWindowSession

 
阅读更多
static class W extends IWindow.Stub {
        private final WeakReference<ViewRoot> mViewRoot;

        public W(ViewRoot viewRoot, Context context) {
            mViewRoot = new WeakReference<ViewRoot>(viewRoot);
        }

        public void resized(int w, int h, Rect coveredInsets,
                Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
            final ViewRoot viewRoot = mViewRoot.get();
            if (viewRoot != null) {
                viewRoot.dispatchResized(w, h, coveredInsets,
                        visibleInsets, reportDraw, newConfig);
            }
        }

        public void dispatchAppVisibility(boolean visible) {
            final ViewRoot viewRoot = mViewRoot.get();
            if (viewRoot != null) {
                viewRoot.dispatchAppVisibility(visible);
            }
        }

        public void dispatchGetNewSurface() {
            final ViewRoot viewRoot = mViewRoot.get();
            if (viewRoot != null) {
                viewRoot.dispatchGetNewSurface();
            }
        }

        public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
            final ViewRoot viewRoot = mViewRoot.get();
            if (viewRoot != null) {
                viewRoot.windowFocusChanged(hasFocus, inTouchMode);
            }
        }

        private static int checkCallingPermission(String permission) {
            if (!Process.supportsProcesses()) {
                return PackageManager.PERMISSION_GRANTED;
            }

            try {
                return ActivityManagerNative.getDefault().checkPermission(
                        permission, Binder.getCallingPid(), Binder.getCallingUid());
            } catch (RemoteException e) {
                return PackageManager.PERMISSION_DENIED;
            }
        }

        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
            final ViewRoot viewRoot = mViewRoot.get();
            if (viewRoot != null) {
                final View view = viewRoot.mView;
                if (view != null) {
                    if (checkCallingPermission(Manifest.permission.DUMP) !=
                            PackageManager.PERMISSION_GRANTED) {
                        throw new SecurityException("Insufficient permissions to invoke"
                                + " executeCommand() from pid=" + Binder.getCallingPid()
                                + ", uid=" + Binder.getCallingUid());
                    }

                    OutputStream clientStream = null;
                    try {
                        clientStream = new ParcelFileDescriptor.AutoCloseOutputStream(out);
                        ViewDebug.dispatchCommand(view, command, parameters, clientStream);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (clientStream != null) {
                            try {
                                clientStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
        
        public void closeSystemDialogs(String reason) {
            final ViewRoot viewRoot = mViewRoot.get();
            if (viewRoot != null) {
                viewRoot.dispatchCloseSystemDialogs(reason);
            }
        }
        
        public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
                boolean sync) {
            if (sync) {
                try {
                    sWindowSession.wallpaperOffsetsComplete(asBinder());
                } catch (RemoteException e) {
                }
            }
        }
        
        public void dispatchWallpaperCommand(String action, int x, int y,
                int z, Bundle extras, boolean sync) {
            if (sync) {
                try {
                    sWindowSession.wallpaperCommandComplete(asBinder(), null);
                } catch (RemoteException e) {
                }
            }
        }
    }
 
写道
private final class Session extends IWindowSession.Stub
implements IBinder.DeathRecipient {
final IInputMethodClient mClient;
final IInputContext mInputContext;
final int mUid;
final int mPid;
final String mStringName;
SurfaceSession mSurfaceSession;
int mNumWindow = 0;
boolean mClientDead = false;

public Session(IInputMethodClient client, IInputContext inputContext) {
mClient = client;
mInputContext = inputContext;
mUid = Binder.getCallingUid();
mPid = Binder.getCallingPid();
StringBuilder sb = new StringBuilder();
sb.append("Session{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" uid ");
sb.append(mUid);
sb.append("}");
mStringName = sb.toString();

synchronized (mWindowMap) {
if (mInputMethodManager == null && mHaveInputMethods) {
IBinder b = ServiceManager.getService(
Context.INPUT_METHOD_SERVICE);
mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
}
}
long ident = Binder.clearCallingIdentity();
try {
// Note: it is safe to call in to the input method manager
// here because we are not holding our lock.
if (mInputMethodManager != null) {
mInputMethodManager.addClient(client, inputContext,
mUid, mPid);
} else {
client.setUsingInputMethod(false);
}
client.asBinder().linkToDeath(this, 0);
} catch (RemoteException e) {
// The caller has died, so we can just forget about this.
try {
if (mInputMethodManager != null) {
mInputMethodManager.removeClient(client);
}
} catch (RemoteException ee) {
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
try {
return super.onTransact(code, data, reply, flags);
} catch (RuntimeException e) {
// Log all 'real' exceptions thrown to the caller
if (!(e instanceof SecurityException)) {
Slog.e(TAG, "Window Session Crash", e);
}
throw e;
}
}

public void binderDied() {
// Note: it is safe to call in to the input method manager
// here because we are not holding our lock.
try {
if (mInputMethodManager != null) {
mInputMethodManager.removeClient(mClient);
}
} catch (RemoteException e) {
}
synchronized(mWindowMap) {
mClient.asBinder().unlinkToDeath(this, 0);
mClientDead = true;
killSessionLocked();
}
}

public int add(IWindow window, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
return addWindow(this, window, attrs, viewVisibility, outContentInsets,
outInputChannel);
}

public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets) {
return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
}

public void remove(IWindow window) {
removeWindow(this, window);
}

public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
boolean insetsPending, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
//Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
int res = relayoutWindow(this, window, attrs,
requestedWidth, requestedHeight, viewFlags, insetsPending,
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
//Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
return res;
}

public void setTransparentRegion(IWindow window, Region region) {
setTransparentRegionWindow(this, window, region);
}

public void setInsets(IWindow window, int touchableInsets,
Rect contentInsets, Rect visibleInsets) {
setInsetsWindow(this, window, touchableInsets, contentInsets,
visibleInsets);
}

public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
getWindowDisplayFrame(this, window, outDisplayFrame);
}

public void finishDrawing(IWindow window) {
if (localLOGV) Slog.v(
TAG, "IWindow finishDrawing called for " + window);
finishDrawingWindow(this, window);
}

public void setInTouchMode(boolean mode) {
synchronized(mWindowMap) {
mInTouchMode = mode;
}
}

public boolean getInTouchMode() {
synchronized(mWindowMap) {
return mInTouchMode;
}
}

public boolean performHapticFeedback(IWindow window, int effectId,
boolean always) {
synchronized(mWindowMap) {
long ident = Binder.clearCallingIdentity();
try {
return mPolicy.performHapticFeedbackLw(
windowForClientLocked(this, window, true),
effectId, always);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}

public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
synchronized(mWindowMap) {
long ident = Binder.clearCallingIdentity();
try {
setWindowWallpaperPositionLocked(
windowForClientLocked(this, window, true),
x, y, xStep, yStep);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}

public void wallpaperOffsetsComplete(IBinder window) {
WindowManagerService.this.wallpaperOffsetsComplete(window);
}

public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
int z, Bundle extras, boolean sync) {
synchronized(mWindowMap) {
long ident = Binder.clearCallingIdentity();
try {
return sendWindowWallpaperCommandLocked(
windowForClientLocked(this, window, true),
action, x, y, z, extras, sync);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}

public void wallpaperCommandComplete(IBinder window, Bundle result) {
WindowManagerService.this.wallpaperCommandComplete(window, result);
}

void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Slog.v(
TAG, "First window added to " + this + ", creating SurfaceSession");
mSurfaceSession = new SurfaceSession();
if (SHOW_TRANSACTIONS) Slog.i(
TAG, " NEW SURFACE SESSION " + mSurfaceSession);
mSessions.add(this);
}
mNumWindow++;
}

void windowRemovedLocked() {
mNumWindow--;
killSessionLocked();
}

void killSessionLocked() {
if (mNumWindow <= 0 && mClientDead) {
mSessions.remove(this);
if (mSurfaceSession != null) {
if (localLOGV) Slog.v(
TAG, "Last window removed from " + this
+ ", destroying " + mSurfaceSession);
if (SHOW_TRANSACTIONS) Slog.i(
TAG, " KILL SURFACE SESSION " + mSurfaceSession);
try {
mSurfaceSession.kill();
} catch (Exception e) {
Slog.w(TAG, "Exception thrown when killing surface session "
+ mSurfaceSession + " in session " + this
+ ": " + e.toString());
}
mSurfaceSession = null;
}
}
}

void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
pw.print(" mClientDead="); pw.print(mClientDead);
pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
}

@Override
public String toString() {
return mStringName;
}
}
 
分享到:
评论

相关推荐

    Android 核心分析(13) -----Android GWES之Android窗口管理.doc

    这篇文档主要探讨了Android GWES(Global Workspace Environment System)中的窗口管理机制,特别是涉及到Window、DecorView、View、IWindow、ISession以及WindowState等核心组件之间的关系。 1. **基本构架原理** ...

    Android 4.2 Input 研究分析

    ### Android 4.2 Input 研究分析 #### 前言 本文将深入剖析 Android 4.2 版本中的输入事件处理机制。...这些基础知识对于开发高质量的应用程序至关重要,同时也为深入研究 Android 内部工作机制提供了坚实的基础。

    Android_Surface系统的实现

    - **IWindowSession 和 IWindow 接口:**这些是标准的AIDL接口,用于ViewRoot与WMS之间的通信。IWindowSession用于跨进程通信,而IWindow则被WMS用于调用ViewRoot内部的W类来处理按键消息等任务。 - **...

    深入理解Android卷 III 的SampleWindow

    在Android系统中,窗口(Window)是应用程序与用户交互的最基础单元。每个应用界面,无论是Activity、Dialog还是PopupWindow,都是由一个或多个窗口构成的。SampleWindow作为示例,帮助开发者理解窗口对象如何创建、...

    安卓核心分析之输入

    ### 安卓核心分析之输入:深入理解Android输入法框架 #### 一、输入路径的一般原理与设计 Android输入系统的设计围绕着按键、鼠标消息的处理展开,旨在确保从设备接收用户输入到最终送达焦点窗口的过程高效且有序...

    decoratorMode.rar

    在Qt中使用装饰模式可以为UI组件或其他复杂对象提供动态的扩展性,例如,我们可能有一个基础的窗口类,然后通过装饰类为其添加如动画、阴影、边框等附加特性。 装饰模式的核心思想是定义一个抽象组件接口,所有真实...

    C#抽象工厂模式.zip

    抽象产品如`IButton`和`IWindow`,具体产品如`WindowsButton`和`LinuxButton`。 ```csharp // 抽象工厂 public interface IGUIFactory { IButton CreateButton(); IWindow CreateWindow(); } // 具体工厂 public...

    为richtext制作的ppt

    - `Win_Delete(IWindow * po)` 用于释放窗体占用的资源,如接口指针和内存分配。这是为了确保程序运行的效率和内存管理的有效性。 4. **窗体重绘** - `Win_Redraw(IWindow * po)` 与API的`redraw()`函数类似,但...

    扩展RationalFunctionalTester的对象识别技术[整理].pdf

    《扩展Rational Functional ...通过深入理解RFT的对象模型,灵活运用静态和动态识别方法,结合IWindow接口,以及利用辅助工具,测试人员能够克服各种复杂的GUI识别问题,提升测试质量和效率,确保软件的质量和稳定性。

    RAP Helloworld

    **正文** "RAP Helloworld" 是一个初学者入门级别的程序,...总的来说,"RAP Helloworld" 是一个很好的起点,它引导你进入 RAP 的世界,通过实际操作来学习和理解这个框架,从而为构建高效、互动的 Web 应用奠定基础。

    银行业务调度系统(做的项目)

    - **窗口接口(IWindow)**:定义窗口的基本行为,如叫号、开始业务处理、结束业务处理等,让不同类型的窗口实现该接口。 - **客户接口(ICustomer)**:定义客户的基本属性和行为,如客户服务类型、所需时间等。 ...

    C#工厂模式

    **工厂模式**是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在对象创建时提供了一种封装和解耦的机制。工厂模式的核心思想是将对象的创建过程封装到一个单独的工厂类中,使得客户端代码无需关心具体...

    Monkey源码分析

    - **injectEvent的完整流程**:从调用WM.injectKeyEvent()开始,经过WM.dispatchKey()到达窗口状态(WindowState)对象,最终通过IWindow接口完成事件的传递。 #### 设计亮点与改进思路 - **设计亮点**:Monkey的...

    C#面向对象设计模式纵横谈(3):Abstract Factory 抽象工厂模式(创建型模式)

    例如,`WindowsButton`和`WindowsWindow`实现了`IButton`和`IWindow`接口,分别代表Windows平台上的按钮和窗口;同理,`MacButton`和`MacWindow`对应Mac平台。 抽象工厂模式的运作过程如下: 1. **客户端代码**:...

    kibana-API:Kibana-API是Kibana的扩展,可让您从应用程序中访问仪表板管理板并动态更改可视化效果

    我建议您逐步阅读所有内容,但是如果您没有耐心,请转到“演示版postMessage 该插件使用Window.postMessage()方法( )在应用程序和kibana iframe之间进行连接var iframe = document.getElementById('Iframe');...

    iframe是如何使用的?.docx

    尽管关于其高能耗和安全性的争议存在,但`iframe`因其独特的优势,在某些场景下仍然被广泛使用。以下是对`iframe`使用、属性、交互方式以及优缺点的详细解释。 **使用方法** 要使用`iframe`,首先在HTML文档中插入`...

    C#面向对象设计模式纵横谈(3):Abstract Factory 抽象工厂模式(创建型模式) (Level 300)

    抽象工厂模式是面向对象设计模式中的创建型模式之一,它为创建一组相关或相互依赖的对象提供了一个统一的接口,使得客户端无需关注这些对象的具体实现细节。在C#中,抽象工厂模式的应用尤为广泛,尤其在多平台开发...

    as3做的一个窗体系统demo

    IWindow接口:定义所有窗口,并且Window实现了该接口 Module类:模块基类 PopModule类:弹出型环境类,继承Module PopWindow类:弹出型窗口,继承Window Window类:窗口基类 WindowEvent类:窗口事件类 Windows...

    高通brew SDK中mediaplayer研究

    例如,`QINTERFACE`宏用于定义接口结构体和方法,如`IWindow`接口的定义。`QINTERFACE`宏的展开揭示了接口的基本框架,包括使能/禁用窗口、重绘窗口、处理路由到窗口的事件以及释放窗口资源等方法的声明。 通过对宏...

Global site tag (gtag.js) - Google Analytics