windows i0s android,Android之基础建设之IWindow跟IWindowSession

本文主要围绕Android的基础建设,详细展示了IWindow和IWindowSession的代码实现。包括IWindow的各类方法,如resized、dispatchAppVisibility等,以及IWindowSession的相关方法,如add、remove、relayout等,体现了其在Android系统中的重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android之基础建设之IWindow和IWindowSession

static class W extends IWindow.Stub {

private final WeakReference mViewRoot;

public W(ViewRoot viewRoot, Context context) {

mViewRoot = new WeakReference(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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值