diff options
| author | 2011-05-04 11:26:38 -0700 | |
|---|---|---|
| committer | 2011-05-04 11:26:38 -0700 | |
| commit | 0c19aaaebb5baf78857e2e18ebe7fb37b7e1cf8e (patch) | |
| tree | 23a20876a43b62c67c94d7e7b579201a0671f894 | |
| parent | 65b96059766a12454236712931d66bffb311729c (diff) | |
| parent | 8956dbbc5f292d8b79072ae73b25f2114c8c7479 (diff) | |
Merge "On-screen navigation bar (separate from the status bar)."
8 files changed, 407 insertions, 34 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 8a18aaf7c7ce..9395d5cfef2a 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -388,6 +388,12 @@ public interface WindowManager extends ViewManager { public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18; /** + * Window type: Navigation bar (when distinct from status bar) + * @hide + */ + public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19; + + /** * End of types of system windows. */ public static final int LAST_SYSTEM_WINDOW = 2999; diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml new file mode 100644 index 000000000000..eba44802440c --- /dev/null +++ b/packages/SystemUI/res/layout/navigation_bar.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 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. +*/ +--> + +<com.android.systemui.statusbar.phone.NavigationBarView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" + android:layout_height="match_parent" + android:layout_width="match_parent" + > + + <LinearLayout android:id="@+id/rot0" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:paddingLeft="8dip" + android:paddingRight="8dip" + android:background="#FF000000" + android:orientation="horizontal" + > + + <!-- navigation controls --> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:src="@drawable/ic_sysbar_back" + systemui:keyCode="4" + android:layout_weight="1" + /> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:src="@drawable/ic_sysbar_home" + systemui:keyCode="3" + android:layout_weight="1" + /> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:src="@drawable/ic_sysbar_menu" + systemui:keyCode="82" + android:layout_weight="1" + /> + </LinearLayout> + + <LinearLayout android:id="@+id/rot90" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:background="#FF000000" + android:orientation="vertical" + android:visibility="gone" + > + + <!-- navigation controls --> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_menu" + systemui:keyCode="82" + android:layout_weight="1" + /> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_home" + systemui:keyCode="3" + android:layout_weight="1" + /> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_back" + systemui:keyCode="4" + android:layout_weight="1" + /> + </LinearLayout> + + <LinearLayout android:id="@+id/rot270" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:background="#FF000000" + android:orientation="vertical" + android:visibility="gone" + > + + <!-- navigation controls --> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_back" + systemui:keyCode="4" + android:layout_weight="1" + /> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_home" + systemui:keyCode="3" + android:layout_weight="1" + /> + <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_menu" + systemui:keyCode="82" + android:layout_weight="1" + /> + </LinearLayout> +</com.android.systemui.statusbar.phone.NavigationBarView> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml new file mode 100644 index 000000000000..bcc8da1f8595 --- /dev/null +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * 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. +*/ +--> +<resources> + <!-- thickness (width) of the navigation bar on phones that require it --> + <dimen name="navigation_bar_size">42dp</dimen> +</resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 88cd43c74da0..a2577cb738c1 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -31,5 +31,7 @@ <!-- Width of scrollable area in recents --> <dimen name="status_bar_recents_width">356dp</dimen> + <!-- thickness (height) of the navigation bar on phones that require it --> + <dimen name="navigation_bar_size">42dp</dimen> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java new file mode 100644 index 000000000000..ec169e558306 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008 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.systemui.statusbar.phone; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.Display; +import android.view.KeyEvent; +import android.view.View; +import android.view.Surface; +import android.view.WindowManager; +import android.widget.LinearLayout; +import android.content.res.Configuration; + +import com.android.systemui.R; + +public class NavigationBarView extends LinearLayout { + final Display mDisplay; + View[] mRotatedViews = new View[4]; + + public NavigationBarView(Context context, AttributeSet attrs) { + super(context, attrs); + mDisplay = ((WindowManager)context.getSystemService( + Context.WINDOW_SERVICE)).getDefaultDisplay(); + } + + public void onFinishInflate() { + mRotatedViews[Surface.ROTATION_0] = + mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0); + + mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90); + + mRotatedViews[Surface.ROTATION_270] = findViewById(R.id.rot270); + } + + public void reorient() { + final int rot = mDisplay.getRotation(); + for (int i=0; i<4; i++) { + mRotatedViews[i].setVisibility(View.GONE); + } + mRotatedViews[rot].setVisibility(View.VISIBLE); + + android.util.Log.d("NavigationBarView", "reorient(): rot=" + mDisplay.getRotation()); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 5755f32de2fd..b4adde6e8060 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -45,6 +45,7 @@ import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; +import android.view.Surface; import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; @@ -141,6 +142,9 @@ public class PhoneStatusBar extends StatusBar { // for immersive activities private View mIntruderAlertView; + // on-screen navigation buttons + private NavigationBarView mNavigationBarView; + // the tracker view TrackingView mTrackingView; WindowManager.LayoutParams mTrackingParams; @@ -199,7 +203,9 @@ public class PhoneStatusBar extends StatusBar { super.start(); - addIntruderView(); + addNavigationBar(); + + //addIntruderView(); // Lastly, call to the icon policy to install/update all the icons. mIconPolicy = new PhoneStatusBarPolicy(mContext); @@ -223,6 +229,9 @@ public class PhoneStatusBar extends StatusBar { mIntruderAlertView.setVisibility(View.GONE); mIntruderAlertView.setClickable(true); + mNavigationBarView = + (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null); + PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context, R.layout.status_bar, null); sb.mService = this; @@ -292,6 +301,58 @@ public class PhoneStatusBar extends StatusBar { return res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); } + // For small-screen devices (read: phones) that lack hardware navigation buttons + private void addNavigationBar() { + mNavigationBarView.reorient(); + WindowManagerImpl.getDefault().addView( + mNavigationBarView, getNavigationBarLayoutParams()); + } + + private void repositionNavigationBar() { + mNavigationBarView.reorient(); + WindowManagerImpl.getDefault().updateViewLayout( + mNavigationBarView, getNavigationBarLayoutParams()); + } + + private WindowManager.LayoutParams getNavigationBarLayoutParams() { + final int rotation = mDisplay.getRotation(); + final boolean sideways = + (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270); + + final Resources res = mContext.getResources(); + final int size = res.getDimensionPixelSize(R.dimen.navigation_bar_size); + + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + sideways ? size : ViewGroup.LayoutParams.MATCH_PARENT, + sideways ? ViewGroup.LayoutParams.MATCH_PARENT : size, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, + 0 + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + PixelFormat.TRANSLUCENT); + + lp.setTitle("NavigationBar"); + switch (rotation) { + case Surface.ROTATION_90: + // device has been turned 90deg counter-clockwise + lp.gravity = Gravity.RIGHT | Gravity.FILL_VERTICAL; + break; + case Surface.ROTATION_270: + // device has been turned 90deg clockwise + lp.gravity = Gravity.LEFT | Gravity.FILL_VERTICAL; + break; + default: + lp.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL; + break; + } + lp.windowAnimations = 0; + + return lp; + } + private void addIntruderView() { final int height = getStatusBarHeight(); @@ -1529,6 +1590,7 @@ public class PhoneStatusBar extends StatusBar { animateCollapse(); } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { + repositionNavigationBar(); updateResources(); } } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index a37ccc7d0a7e..8a29419e4c74 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -111,6 +111,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_POINTER; +import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import android.view.WindowManagerImpl; import android.view.WindowManagerPolicy; import android.view.KeyCharacterMap.FallbackAction; @@ -175,14 +176,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { // responsible for power management when displayed. static final int KEYGUARD_LAYER = 15; static final int KEYGUARD_DIALOG_LAYER = 16; + // the navigation bar, if available, shows atop most things + static final int NAVIGATION_BAR_LAYER = 17; // the drag layer: input for drag-and-drop is associated with this window, // which sits above all other focusable windows - static final int DRAG_LAYER = 17; + static final int DRAG_LAYER = 18; // things in here CAN NOT take focus, but are shown on top of everything else. - static final int SYSTEM_OVERLAY_LAYER = 18; - static final int SECURE_SYSTEM_OVERLAY_LAYER = 19; + static final int SYSTEM_OVERLAY_LAYER = 19; + static final int SECURE_SYSTEM_OVERLAY_LAYER = 20; // the (mouse) pointer layer - static final int POINTER_LAYER = 20; + static final int POINTER_LAYER = 21; static final int APPLICATION_MEDIA_SUBLAYER = -2; static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; @@ -228,6 +231,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mStatusBar = null; boolean mStatusBarCanHide; final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>(); + WindowState mNavigationBar = null; + WindowState mKeyguard = null; KeyguardViewMediator mKeyguardMediator; GlobalActions mGlobalActions; @@ -1037,6 +1042,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return DRAG_LAYER; case TYPE_POINTER: return POINTER_LAYER; + case TYPE_NAVIGATION_BAR: + return NAVIGATION_BAR_LAYER; } Log.e(TAG, "Unknown window type: " + type); return APPLICATION_LAYER; @@ -1214,6 +1221,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.bool.config_statusBarCanHide); break; + case TYPE_NAVIGATION_BAR: + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.STATUS_BAR_SERVICE, + "PhoneWindowManager"); + mNavigationBar = win; + if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar); + break; case TYPE_STATUS_BAR_PANEL: mContext.enforceCallingOrSelfPermission( android.Manifest.permission.STATUS_BAR_SERVICE, @@ -1240,9 +1254,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void removeWindowLw(WindowState win) { if (mStatusBar == win) { mStatusBar = null; - } - else if (mKeyguard == win) { + } else if (mKeyguard == win) { mKeyguard = null; + } else if (mNavigationBar == win) { + mNavigationBar = null; } else { mStatusBarPanels.remove(win); } @@ -1609,17 +1624,48 @@ public class PhoneWindowManager implements WindowManagerPolicy { mDockBottom = mContentBottom = mCurBottom = displayHeight; mDockLayer = 0x10000000; + // start with the current dock rect, which will be (0,0,displayWidth,displayHeight) + final Rect pf = mTmpParentFrame; + final Rect df = mTmpDisplayFrame; + final Rect vf = mTmpVisibleFrame; + pf.left = df.left = vf.left = mDockLeft; + pf.top = df.top = vf.top = mDockTop; + pf.right = df.right = vf.right = mDockRight; + pf.bottom = df.bottom = vf.bottom = mDockBottom; + // decide where the status bar goes ahead of time if (mStatusBar != null) { - final Rect pf = mTmpParentFrame; - final Rect df = mTmpDisplayFrame; - final Rect vf = mTmpVisibleFrame; - pf.left = df.left = vf.left = 0; - pf.top = df.top = vf.top = 0; - pf.right = df.right = vf.right = displayWidth; - pf.bottom = df.bottom = vf.bottom = displayHeight; - + Rect navr = null; + if (mNavigationBar != null) { + mNavigationBar.computeFrameLw(pf, df, vf, vf); + if (mNavigationBar.isVisibleLw()) { + navr = mNavigationBar.getFrameLw(); + + if (navr.top == 0) { + // Navigation bar is vertical + if (mDockLeft == navr.left) { + mDockLeft = navr.right; + } else if (mDockRight == navr.right) { + mDockRight = navr.left; + } + } else { + // Navigation bar horizontal, at bottom + if (mDockBottom == navr.bottom) { + mDockBottom = navr.top; + } + } + } + } + if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + navr); + + // apply navigation bar insets + pf.left = df.left = vf.left = mDockLeft; + pf.top = df.top = vf.top = mDockTop; + pf.right = df.right = vf.right = mDockRight; + pf.bottom = df.bottom = vf.bottom = mDockBottom; + mStatusBar.computeFrameLw(pf, df, vf, vf); + if (mStatusBar.isVisibleLw()) { // If the status bar is hidden, we don't want to cause // windows behind it to scroll. @@ -1630,14 +1676,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { // status bar is visible. if (mDockTop == r.top) mDockTop = r.bottom; else if (mDockBottom == r.bottom) mDockBottom = r.top; + mContentTop = mCurTop = mDockTop; mContentBottom = mCurBottom = mDockBottom; - if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mDockTop=" + mDockTop - + " mContentTop=" + mContentTop - + " mCurTop=" + mCurTop - + " mDockBottom=" + mDockBottom - + " mContentBottom=" + mContentBottom - + " mCurBottom=" + mCurBottom); + mContentLeft = mCurLeft = mDockLeft; + mContentRight = mCurRight = mDockRight; + + if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " + + String.format( + "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]", + mDockLeft, mDockTop, mDockRight, mDockBottom, + mContentLeft, mContentTop, mContentRight, mContentBottom, + mCurLeft, mCurTop, mCurRight, mCurBottom)); } else { // Status bar can't go away; the part of the screen it // covers does not exist for anything behind it. @@ -1647,12 +1697,32 @@ public class PhoneWindowManager implements WindowManagerPolicy { } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) { mRestrictedScreenHeight -= (r.bottom-r.top); } + + if (navr != null) { + if (navr.top == 0) { + // Navigation bar is vertical + if (mRestrictedScreenLeft == navr.left) { + mRestrictedScreenLeft = navr.right; + mRestrictedScreenWidth -= (navr.right - navr.left); + } else if ((mRestrictedScreenLeft+mRestrictedScreenWidth) == navr.right) { + mRestrictedScreenWidth -= (navr.right - navr.left); + } + } else { + // Navigation bar horizontal, at bottom + if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) { + mRestrictedScreenHeight -= (navr.bottom-navr.top); + } + } + } + mContentTop = mCurTop = mDockTop = mRestrictedScreenTop; mContentBottom = mCurBottom = mDockBottom = mRestrictedScreenTop + mRestrictedScreenHeight; - if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mRestrictedScreenTop=" - + mRestrictedScreenTop - + " mRestrictedScreenHeight=" + mRestrictedScreenHeight); + if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: (" + + mRestrictedScreenLeft + "," + + mRestrictedScreenTop + "," + + (mRestrictedScreenLeft + mRestrictedScreenWidth) + "," + + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")"); } } } @@ -1722,6 +1792,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { final Rect cf = mTmpContentFrame; final Rect vf = mTmpVisibleFrame; + final boolean hasNavBar = (mNavigationBar != null && mNavigationBar.isVisibleLw()); + if (attrs.type == TYPE_INPUT_METHOD) { pf.left = df.left = cf.left = vf.left = mDockLeft; pf.top = df.top = cf.top = vf.top = mDockTop; @@ -1735,6 +1807,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR)) == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { + if (DEBUG_LAYOUT) + Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + + "): IN_SCREEN, INSET_DECOR, !FULLSCREEN"); // This is the case for a normal activity window: we want it // to cover all of the screen space, and it can take care of // moving its contents to account for screen decorations that @@ -1744,15 +1819,26 @@ public class PhoneWindowManager implements WindowManagerPolicy { // frame is the same as the one we are attached to. setAttachedWindowFrames(win, fl, sim, attached, true, pf, df, cf, vf); } else { - if (attrs.type == TYPE_STATUS_BAR_PANEL) { + if (attrs.type == TYPE_STATUS_BAR_PANEL + || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { // Status bar panels are the only windows who can go on top of // the status bar. They are protected by the STATUS_BAR_SERVICE // permission, so they have the same privileges as the status // bar itself. - pf.left = df.left = mUnrestrictedScreenLeft; + // + // However, they should still dodge the navigation bar if it exists. A + // straightforward way to do this is to only allow the status bar panels to + // extend to the extrema of the allowable region for the IME dock. + + pf.left = df.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft; pf.top = df.top = mUnrestrictedScreenTop; - pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; - pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight; + pf.right = df.right = hasNavBar + ? mDockRight + : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; + pf.bottom = df.bottom = hasNavBar + ? mDockBottom + : mUnrestrictedScreenTop+mUnrestrictedScreenHeight; + } else { pf.left = df.left = mRestrictedScreenLeft; pf.top = df.top = mRestrictedScreenTop; @@ -1780,15 +1866,21 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0) { + if (DEBUG_LAYOUT) + Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN"); // A window that has requested to fill the entire screen just // gets everything, period. - if (attrs.type == TYPE_STATUS_BAR_PANEL) { - pf.left = df.left = cf.left = mUnrestrictedScreenLeft; + if (attrs.type == TYPE_STATUS_BAR_PANEL + || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { + pf.left = df.left = cf.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft; pf.top = df.top = cf.top = mUnrestrictedScreenTop; - pf.right = df.right = cf.right - = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; - pf.bottom = df.bottom = cf.bottom - = mUnrestrictedScreenTop+mUnrestrictedScreenHeight; + pf.right = df.right = cf.right = hasNavBar + ? mDockRight + : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; + pf.bottom = df.bottom = cf.bottom = hasNavBar + ? mDockBottom + : mUnrestrictedScreenTop+mUnrestrictedScreenHeight; + } else { pf.left = df.left = cf.left = mRestrictedScreenLeft; pf.top = df.top = cf.top = mRestrictedScreenTop; @@ -1805,10 +1897,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { vf.set(cf); } } else if (attached != null) { + if (DEBUG_LAYOUT) + Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached); // A child window should be placed inside of the same visible // frame that its parent had. setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf); } else { + if (DEBUG_LAYOUT) + Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window"); // Otherwise, a normal window must be placed inside the content // of all screen decorations. pf.left = mContentLeft; @@ -1844,6 +1940,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle() + ": sim=#" + Integer.toHexString(sim) + + " attach=" + attached + " type=" + attrs.type + + String.format(" flags=0x%08x", fl) + " pf=" + pf.toShortString() + " df=" + df.toShortString() + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h index f04fb020fff7..208353d22f2f 100644 --- a/services/input/InputWindow.h +++ b/services/input/InputWindow.h @@ -119,6 +119,7 @@ struct InputWindow { TYPE_DRAG = FIRST_SYSTEM_WINDOW+16, TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17, TYPE_POINTER = FIRST_SYSTEM_WINDOW+18, + TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19, LAST_SYSTEM_WINDOW = 2999, }; |