diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-10-07 15:12:17 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-10-07 15:12:17 -0700 |
commit | ba8ecd206cc6f175767f952d380c88f70ece04cf (patch) | |
tree | f463b4123ae906ac81eb16460aa8443ecefa12d9 /services/java/com | |
parent | 270928bd4a1db1dc0d989f4e9897a81ab865e30e (diff) | |
parent | df89e65bf0fcc651d20b208c8d8d0b848fb43418 (diff) | |
download | frameworks_base-ba8ecd206cc6f175767f952d380c88f70ece04cf.zip frameworks_base-ba8ecd206cc6f175767f952d380c88f70ece04cf.tar.gz frameworks_base-ba8ecd206cc6f175767f952d380c88f70ece04cf.tar.bz2 |
Merge "Fix how we hide and show the nav bar."
Diffstat (limited to 'services/java/com')
5 files changed, 211 insertions, 34 deletions
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index bab9f8a..a9ff6c5 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -117,11 +117,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub // ================================================================================ // From IStatusBarService // ================================================================================ - public void userActivity() { - if (mBar != null) try { - mBar.userActivity(); - } catch (RemoteException ex) {} - } public void expand() { enforceExpandStatusBar(); diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java index f2e7485..25cc259 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/java/com/android/server/wm/DragState.java @@ -32,7 +32,6 @@ import android.view.InputQueue; import android.view.Surface; import android.view.View; import android.view.WindowManager; -import android.view.WindowManagerPolicy; import java.util.ArrayList; diff --git a/services/java/com/android/server/wm/FakeWindowImpl.java b/services/java/com/android/server/wm/FakeWindowImpl.java new file mode 100644 index 0000000..0e72f7d --- /dev/null +++ b/services/java/com/android/server/wm/FakeWindowImpl.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import android.os.Looper; +import android.os.Process; +import android.util.Slog; +import android.view.InputChannel; +import android.view.InputHandler; +import android.view.InputQueue; +import android.view.WindowManagerPolicy; + +public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow { + final WindowManagerService mService; + final InputChannel mServerChannel, mClientChannel; + final InputApplicationHandle mApplicationHandle; + final InputWindowHandle mWindowHandle; + final int mWindowLayer; + + boolean mTouchFullscreen; + + public FakeWindowImpl(WindowManagerService service, Looper looper, InputHandler inputHandler, + String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys, + boolean hasFocus, boolean touchFullscreen) { + mService = service; + + InputChannel[] channels = InputChannel.openInputChannelPair(name); + mServerChannel = channels[0]; + mClientChannel = channels[1]; + mService.mInputManager.registerInputChannel(mServerChannel, null); + InputQueue.registerInputChannel(mClientChannel, inputHandler, looper.getQueue()); + + mApplicationHandle = new InputApplicationHandle(null); + mApplicationHandle.name = name; + mApplicationHandle.dispatchingTimeoutNanos = + WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; + + mWindowHandle = new InputWindowHandle(mApplicationHandle, null); + mWindowHandle.name = name; + mWindowHandle.inputChannel = mServerChannel; + mWindowLayer = getLayerLw(windowType); + mWindowHandle.layer = mWindowLayer; + mWindowHandle.layoutParamsFlags = layoutParamsFlags; + mWindowHandle.layoutParamsType = windowType; + mWindowHandle.dispatchingTimeoutNanos = + WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; + mWindowHandle.visible = true; + mWindowHandle.canReceiveKeys = canReceiveKeys; + mWindowHandle.hasFocus = hasFocus; + mWindowHandle.hasWallpaper = false; + mWindowHandle.paused = false; + mWindowHandle.ownerPid = Process.myPid(); + mWindowHandle.ownerUid = Process.myUid(); + mWindowHandle.inputFeatures = 0; + mWindowHandle.scaleFactor = 1.0f; + + mTouchFullscreen = touchFullscreen; + } + + void layout(int dw, int dh) { + if (mTouchFullscreen) { + mWindowHandle.touchableRegion.set(0, 0, dw, dh); + } else { + mWindowHandle.touchableRegion.setEmpty(); + } + mWindowHandle.frameLeft = 0; + mWindowHandle.frameTop = 0; + mWindowHandle.frameRight = dw; + mWindowHandle.frameBottom = dh; + } + + @Override + public void dismiss() { + synchronized (mService.mWindowMap) { + if (mService.removeFakeWindowLocked(this)) { + mService.mInputManager.unregisterInputChannel(mServerChannel); + InputQueue.unregisterInputChannel(mClientChannel); + mClientChannel.dispose(); + mServerChannel.dispose(); + } + } + } + + private int getLayerLw(int windowType) { + return mService.mPolicy.windowTypeToLayerLw(windowType) + * WindowManagerService.TYPE_LAYER_MULTIPLIER + + WindowManagerService.TYPE_LAYER_OFFSET; + } +} diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java index 573a7d4..9a559e0 100644 --- a/services/java/com/android/server/wm/InputMonitor.java +++ b/services/java/com/android/server/wm/InputMonitor.java @@ -169,6 +169,11 @@ final class InputMonitor { } } + final int NFW = mService.mFakeWindows.size(); + for (int i = 0; i < NFW; i++) { + addInputWindowHandleLw(mService.mFakeWindows.get(i).mWindowHandle); + } + final int N = windows.size(); for (int i = N - 1; i >= 0; i--) { final WindowState child = windows.get(i); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 540c518..73a9601 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -118,6 +118,7 @@ import android.view.WindowManager; import android.view.WindowManagerImpl; import android.view.WindowManagerPolicy; import android.view.WindowManager.LayoutParams; +import android.view.WindowManagerPolicy.FakeWindow; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Transformation; @@ -142,7 +143,7 @@ import java.util.List; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub - implements Watchdog.Monitor { + implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { static final String TAG = "WindowManager"; static final boolean DEBUG = false; static final boolean DEBUG_ADD_REMOVE = false; @@ -352,6 +353,12 @@ public class WindowManagerService extends IWindowManager.Stub final ArrayList<WindowState> mWindows = new ArrayList<WindowState>(); /** + * Fake windows added to the window manager. Note: ordered from top to + * bottom, opposite of mWindows. + */ + final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>(); + + /** * Windows that are being resized. Used so we can tell the client about * the resize after closing the transaction in which we resized the * underlying surface. @@ -442,7 +449,9 @@ public class WindowManagerService extends IWindowManager.Stub int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; int mLayoutSeq = 0; - + + int mLastStatusBarVisibility = 0; + // State while inside of layoutAndPlaceSurfacesLocked(). boolean mFocusMayChange; @@ -702,7 +711,7 @@ public class WindowManagerService extends IWindowManager.Stub android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); - mPolicy.init(mContext, mService, mPM); + mPolicy.init(mContext, mService, mService, mPM); synchronized (this) { mRunning = true; @@ -6368,8 +6377,6 @@ public class WindowManagerService extends IWindowManager.Stub // Ignore if process has died. } } - - mPolicy.focusChanged(lastFocus, newFocus); } } break; @@ -7184,6 +7191,11 @@ public class WindowManagerService extends IWindowManager.Stub final int dw = mCurDisplayWidth; final int dh = mCurDisplayHeight; + final int NFW = mFakeWindows.size(); + for (int i=0; i<NFW; i++) { + mFakeWindows.get(i).layout(dw, dh); + } + final int N = mWindows.size(); int i; @@ -8835,6 +8847,7 @@ public class WindowManagerService extends IWindowManager.Stub final WindowState oldFocus = mCurrentFocus; mCurrentFocus = newFocus; mLosingFocus.remove(newFocus); + int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus); final WindowState imWindow = mInputMethodWindow; if (newFocus != imWindow && oldFocus != imWindow) { @@ -8845,13 +8858,22 @@ public class WindowManagerService extends IWindowManager.Stub } if (mode == UPDATE_FOCUS_PLACING_SURFACES) { performLayoutLockedInner(true /*initial*/, updateInputWindows); + focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) { // Client will do the layout, but we need to assign layers // for handleNewWindowLocked() below. assignLayersLocked(); } } - + + if ((focusChanged&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) { + // The change in focus caused us to need to do a layout. Okay. + mLayoutNeeded = true; + if (mode == UPDATE_FOCUS_PLACING_SURFACES) { + performLayoutLockedInner(true /*initial*/, updateInputWindows); + } + } + if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) { // If we defer assigning layers, then the caller is responsible for // doing this part. @@ -9097,33 +9119,82 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void statusBarVisibilityChanged(int visibility) { + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Caller does not hold permission " + + android.Manifest.permission.STATUS_BAR); + } + + synchronized (mWindowMap) { + mLastStatusBarVisibility = visibility; + visibility = mPolicy.adjustSystemUiVisibilityLw(visibility); + updateStatusBarVisibilityLocked(visibility); + } + } + + void updateStatusBarVisibilityLocked(int visibility) { mInputManager.setSystemUiVisibility(visibility); + final int N = mWindows.size(); + for (int i = 0; i < N; i++) { + WindowState ws = mWindows.get(i); + try { + int curValue = ws.mSystemUiVisibility; + int diff = curValue ^ visibility; + // We are only interested in differences of one of the + // clearable flags... + diff &= View.SYSTEM_UI_CLEARABLE_FLAGS; + // ...if it has actually been cleared. + diff &= ~visibility; + int newValue = (curValue&~diff) | (visibility&diff); + if (newValue != curValue) { + ws.mSeq++; + ws.mSystemUiVisibility = newValue; + } + if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) { + ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq, + visibility, newValue, diff); + } + } catch (RemoteException e) { + // so sorry + } + } + } + + @Override + public void reevaluateStatusBarVisibility() { + synchronized (mWindowMap) { + int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility); + updateStatusBarVisibilityLocked(visibility); + performLayoutAndPlaceSurfacesLocked(); + } + } + @Override + public FakeWindow addFakeWindow(Looper looper, InputHandler inputHandler, + String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys, + boolean hasFocus, boolean touchFullscreen) { synchronized (mWindowMap) { - final int N = mWindows.size(); - for (int i = 0; i < N; i++) { - WindowState ws = mWindows.get(i); - try { - int curValue = ws.mSystemUiVisibility; - int diff = curValue ^ visibility; - // We are only interested in differences of one of the - // clearable flags... - diff &= View.SYSTEM_UI_CLEARABLE_FLAGS; - // ...if it has actually been cleared. - diff &= ~visibility; - int newValue = (curValue&~diff) | (visibility&diff); - if (newValue != curValue) { - ws.mSeq++; - ws.mSystemUiVisibility = newValue; - } - if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) { - ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq, - visibility, newValue, diff); - } - } catch (RemoteException e) { - // so sorry + FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputHandler, name, windowType, + layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen); + int i=0; + while (i<mFakeWindows.size()) { + if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) { + break; } } + mFakeWindows.add(i, fw); + mInputMonitor.updateInputWindowsLw(true); + return fw; + } + } + + boolean removeFakeWindowLocked(FakeWindow window) { + synchronized (mWindowMap) { + if (mFakeWindows.remove(window)) { + mInputMonitor.updateInputWindowsLw(true); + return true; + } + return false; } } @@ -9387,6 +9458,10 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mInTouchMode="); pw.print(mInTouchMode); pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); if (dumpAll) { + if (mLastStatusBarVisibility != 0) { + pw.print(" mLastStatusBarVisibility=0x"); + pw.println(Integer.toHexString(mLastStatusBarVisibility)); + } if (mInputMethodWindow != null) { pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow); } |