Home | History | Annotate | Download | only in wm
      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 
     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 
     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 
     98     void unlinkFromDeathRecipient() {
     99         if (mToken == null) {
    100             return;
    101         }
    102 
    103         mToken.unlinkToDeath(this, 0);
    104     }
    105 
    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 
    114     private int getLayerLw(int windowType) {
    115         return mService.mPolicy.getWindowLayerFromTypeLw(windowType)
    116                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
    117                 + WindowManagerService.TYPE_LAYER_OFFSET;
    118     }
    119 
    120     void disposeChannelsLw() {
    121         mService.mInputManager.unregisterInputChannel(mServerChannel);
    122         mClientChannel.dispose();
    123         mServerChannel.dispose();
    124         unlinkFromDeathRecipient();
    125     }
    126 
    127     @Override
    128     public void binderDied() {
    129         synchronized (mService.getWindowManagerLock()) {
    130             // Clean up the input consumer
    131             mService.mInputMonitor.destroyInputConsumer(mName);
    132             unlinkFromDeathRecipient();
    133         }
    134     }
    135 
    136     void dump(PrintWriter pw, String name, String prefix) {
    137         pw.println(prefix + "  name=" + name + " pid=" + mClientPid + " user=" + mClientUser);
    138     }
    139 }
    140