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.Looper;
20 import android.os.Process;
21 import android.view.Display;
22 import android.view.InputChannel;
23 import android.view.InputEventReceiver;
24 import android.view.WindowManager;
25 import android.view.WindowManagerPolicy;
26 
27 import com.android.server.input.InputApplicationHandle;
28 import com.android.server.input.InputWindowHandle;
29 
30 public final class InputConsumerImpl implements WindowManagerPolicy.InputConsumer {
31     final WindowManagerService mService;
32     final InputChannel mServerChannel, mClientChannel;
33     final InputApplicationHandle mApplicationHandle;
34     final InputWindowHandle mWindowHandle;
35     final InputEventReceiver mInputEventReceiver;
36     final int mWindowLayer;
37 
InputConsumerImpl(WindowManagerService service, Looper looper, InputEventReceiver.Factory inputEventReceiverFactory)38     public InputConsumerImpl(WindowManagerService service, Looper looper,
39             InputEventReceiver.Factory inputEventReceiverFactory) {
40         String name = "input consumer";
41         mService = service;
42 
43         InputChannel[] channels = InputChannel.openInputChannelPair(name);
44         mServerChannel = channels[0];
45         mClientChannel = channels[1];
46         mService.mInputManager.registerInputChannel(mServerChannel, null);
47 
48         mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
49                 mClientChannel, looper);
50 
51         mApplicationHandle = new InputApplicationHandle(null);
52         mApplicationHandle.name = name;
53         mApplicationHandle.dispatchingTimeoutNanos =
54                 WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
55 
56         mWindowHandle = new InputWindowHandle(mApplicationHandle, null, Display.DEFAULT_DISPLAY);
57         mWindowHandle.name = name;
58         mWindowHandle.inputChannel = mServerChannel;
59         mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
60         mWindowLayer = getLayerLw(mWindowHandle.layoutParamsType);
61         mWindowHandle.layer = mWindowLayer;
62         mWindowHandle.layoutParamsFlags = 0;
63         mWindowHandle.dispatchingTimeoutNanos =
64                 WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
65         mWindowHandle.visible = true;
66         mWindowHandle.canReceiveKeys = false;
67         mWindowHandle.hasFocus = false;
68         mWindowHandle.hasWallpaper = false;
69         mWindowHandle.paused = false;
70         mWindowHandle.ownerPid = Process.myPid();
71         mWindowHandle.ownerUid = Process.myUid();
72         mWindowHandle.inputFeatures = 0;
73         mWindowHandle.scaleFactor = 1.0f;
74     }
75 
layout(int dw, int dh)76     void layout(int dw, int dh) {
77         mWindowHandle.touchableRegion.set(0, 0, dw, dh);
78         mWindowHandle.frameLeft = 0;
79         mWindowHandle.frameTop = 0;
80         mWindowHandle.frameRight = dw;
81         mWindowHandle.frameBottom = dh;
82     }
83 
84     @Override
dismiss()85     public void dismiss() {
86         synchronized (mService.mWindowMap) {
87             if (mService.removeInputConsumer()) {
88                 mInputEventReceiver.dispose();
89                 mService.mInputManager.unregisterInputChannel(mServerChannel);
90                 mClientChannel.dispose();
91                 mServerChannel.dispose();
92             }
93         }
94     }
95 
getLayerLw(int windowType)96     private int getLayerLw(int windowType) {
97         return mService.mPolicy.windowTypeToLayerLw(windowType)
98                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
99                 + WindowManagerService.TYPE_LAYER_OFFSET;
100     }
101 }
102