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.Stubimplements 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);}}@Overridepublic 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 callerif (!(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);}@Overridepublic String toString() {return mStringName;}}?