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