1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import android.os.IBinder; 20 import android.os.Process; 21 import android.os.RemoteException; 22 import android.os.UserHandle; 23 import android.view.Display; 24 import android.view.InputChannel; 25 import android.view.WindowManager; 26 import com.android.server.input.InputApplicationHandle; 27 import com.android.server.input.InputWindowHandle; 28 29 import java.io.PrintWriter; 30 31 class InputConsumerImpl implements IBinder.DeathRecipient { 32 final WindowManagerService mService; 33 final InputChannel mServerChannel, mClientChannel; 34 final InputApplicationHandle mApplicationHandle; 35 final InputWindowHandle mWindowHandle; 36 37 final IBinder mToken; 38 final String mName; 39 final int mClientPid; 40 final UserHandle mClientUser; 41 InputConsumerImpl(WindowManagerService service, IBinder token, String name, InputChannel inputChannel, int clientPid, UserHandle clientUser)42 InputConsumerImpl(WindowManagerService service, IBinder token, String name, 43 InputChannel inputChannel, int clientPid, UserHandle clientUser) { 44 mService = service; 45 mToken = token; 46 mName = name; 47 mClientPid = clientPid; 48 mClientUser = clientUser; 49 50 InputChannel[] channels = InputChannel.openInputChannelPair(name); 51 mServerChannel = channels[0]; 52 if (inputChannel != null) { 53 channels[1].transferTo(inputChannel); 54 channels[1].dispose(); 55 mClientChannel = inputChannel; 56 } else { 57 mClientChannel = channels[1]; 58 } 59 mService.mInputManager.registerInputChannel(mServerChannel, null); 60 61 mApplicationHandle = new InputApplicationHandle(null); 62 mApplicationHandle.name = name; 63 mApplicationHandle.dispatchingTimeoutNanos = 64 WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 65 66 mWindowHandle = new InputWindowHandle(mApplicationHandle, null, null, 67 Display.DEFAULT_DISPLAY); 68 mWindowHandle.name = name; 69 mWindowHandle.inputChannel = mServerChannel; 70 mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; 71 mWindowHandle.layer = getLayerLw(mWindowHandle.layoutParamsType); 72 mWindowHandle.layoutParamsFlags = 0; 73 mWindowHandle.dispatchingTimeoutNanos = 74 WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 75 mWindowHandle.visible = true; 76 mWindowHandle.canReceiveKeys = false; 77 mWindowHandle.hasFocus = false; 78 mWindowHandle.hasWallpaper = false; 79 mWindowHandle.paused = false; 80 mWindowHandle.ownerPid = Process.myPid(); 81 mWindowHandle.ownerUid = Process.myUid(); 82 mWindowHandle.inputFeatures = 0; 83 mWindowHandle.scaleFactor = 1.0f; 84 } 85 linkToDeathRecipient()86 void linkToDeathRecipient() { 87 if (mToken == null) { 88 return; 89 } 90 91 try { 92 mToken.linkToDeath(this, 0); 93 } catch (RemoteException e) { 94 // Client died, do nothing 95 } 96 } 97 unlinkFromDeathRecipient()98 void unlinkFromDeathRecipient() { 99 if (mToken == null) { 100 return; 101 } 102 103 mToken.unlinkToDeath(this, 0); 104 } 105 layout(int dw, int dh)106 void layout(int dw, int dh) { 107 mWindowHandle.touchableRegion.set(0, 0, dw, dh); 108 mWindowHandle.frameLeft = 0; 109 mWindowHandle.frameTop = 0; 110 mWindowHandle.frameRight = dw; 111 mWindowHandle.frameBottom = dh; 112 } 113 getLayerLw(int windowType)114 private int getLayerLw(int windowType) { 115 return mService.mPolicy.getWindowLayerFromTypeLw(windowType) 116 * WindowManagerService.TYPE_LAYER_MULTIPLIER 117 + WindowManagerService.TYPE_LAYER_OFFSET; 118 } 119 disposeChannelsLw()120 void disposeChannelsLw() { 121 mService.mInputManager.unregisterInputChannel(mServerChannel); 122 mClientChannel.dispose(); 123 mServerChannel.dispose(); 124 unlinkFromDeathRecipient(); 125 } 126 127 @Override binderDied()128 public void binderDied() { 129 synchronized (mService.getWindowManagerLock()) { 130 // Clean up the input consumer 131 mService.mInputMonitor.destroyInputConsumer(mName); 132 unlinkFromDeathRecipient(); 133 } 134 } 135 dump(PrintWriter pw, String name, String prefix)136 void dump(PrintWriter pw, String name, String prefix) { 137 pw.println(prefix + " name=" + name + " pid=" + mClientPid + " user=" + mClientUser); 138 } 139 } 140