diff options
author | Dianne Hackborn <hackbod@google.com> | 2012-04-05 11:47:02 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-05 11:47:02 -0700 |
commit | 5459c43b83c3a9d0406f01deffaadd2ef458518c (patch) | |
tree | 9193ba676d54cf522aec320b089692c9fcecbbd8 | |
parent | 5b4a57973c85afb2f5ec833dc2c202111399b871 (diff) | |
parent | f87d19621dc2a30232bba1f51862a0b671eb9729 (diff) | |
download | frameworks_base-5459c43b83c3a9d0406f01deffaadd2ef458518c.zip frameworks_base-5459c43b83c3a9d0406f01deffaadd2ef458518c.tar.gz frameworks_base-5459c43b83c3a9d0406f01deffaadd2ef458518c.tar.bz2 |
Merge "Clean up status bar, system bar, navigation bar management."
25 files changed, 452 insertions, 410 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 14cd48f..eb030de 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -62,8 +62,8 @@ interface IWindowManager void setForcedDisplaySize(int longDimen, int shortDimen); void clearForcedDisplaySize(); - // Is device configured with a hideable status bar or a tablet system bar? - boolean canStatusBarHide(); + // Is the device configured to have a full system bar for larger screens? + boolean hasSystemNavBar(); // These can only be called when injecting events to your own window, // or by holding the INJECT_EVENTS permission. These methods may block @@ -171,8 +171,10 @@ interface IWindowManager * @param alwaysSendConfiguration Flag to force a new configuration to * be evaluated. This can be used when there are other parameters in * configuration that are changing. + * @param forceRelayout If true, the window manager will always do a relayout + * of its windows even if the rotation hasn't changed. */ - void updateRotation(boolean alwaysSendConfiguration); + void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout); /** * Retrieve the current screen orientation, constants as per diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index b9924c7..9d06145 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -315,7 +315,7 @@ public class ViewConfiguration { if (!sHasPermanentMenuKeySet) { IWindowManager wm = Display.getWindowManager(); try { - sHasPermanentMenuKey = wm.canStatusBarHide() && !wm.hasNavigationBar(); + sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar(); sHasPermanentMenuKeySet = true; } catch (RemoteException ex) { sHasPermanentMenuKey = false; diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 75267bb..cf9cafc 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -326,6 +326,11 @@ public interface WindowManagerPolicy { * Returns true if {@link #hideLw} was last called for the window. */ public boolean showLw(boolean doAnimation); + + /** + * Check whether the process hosting this window is currently alive. + */ + public boolean isAlive(); } /** @@ -447,7 +452,7 @@ public interface WindowManagerPolicy { * Called by window manager once it has the initial, default native * display dimensions. */ - public void setInitialDisplaySize(int width, int height); + public void setInitialDisplaySize(Display display, int width, int height); /** * Check permissions when adding a window. @@ -514,10 +519,10 @@ public interface WindowManagerPolicy { public int getMaxWallpaperLayer(); /** - * Return true if the policy allows the status bar to hide. Otherwise, - * it is a tablet-style system bar. + * Return true if the policy desires a full unified system nav bar. Otherwise, + * it is a phone-style status bar with optional nav bar. */ - public boolean canStatusBarHide(); + public boolean hasSystemNavBar(); /** * Return the display width available after excluding any screen diff --git a/core/res/res/anim/dock_bottom_enter.xml b/core/res/res/anim/dock_bottom_enter.xml new file mode 100644 index 0000000..7a2e94b --- /dev/null +++ b/core/res/res/anim/dock_bottom_enter.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 2012, 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. +*/ +--> + +<!-- Animation for when a dock window at the bottom of the screen is entering. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/decelerate_quad"> + <translate android:fromYDelta="75%" android:toYDelta="0" + android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/dock_bottom_exit.xml b/core/res/res/anim/dock_bottom_exit.xml new file mode 100644 index 0000000..c2fd15c --- /dev/null +++ b/core/res/res/anim/dock_bottom_exit.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 2012, 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. +*/ +--> + +<!-- Animation for when a dock window at the bottom of the screen is exiting. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/accelerate_quad"> + <translate android:fromYDelta="0" android:toYDelta="75%" + android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/dock_left_enter.xml b/core/res/res/anim/dock_left_enter.xml new file mode 100644 index 0000000..b057f67 --- /dev/null +++ b/core/res/res/anim/dock_left_enter.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 2012, 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. +*/ +--> + +<!-- Animation for when a dock window at the left of the screen is entering. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/decelerate_quad"> + <translate android:fromXDelta="-75%" android:toXDelta="0" + android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/dock_left_exit.xml b/core/res/res/anim/dock_left_exit.xml new file mode 100644 index 0000000..576b1aa --- /dev/null +++ b/core/res/res/anim/dock_left_exit.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 2012, 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. +*/ +--> + +<!-- Animation for when a dock window at the right of the screen is exiting. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/accelerate_quad"> + <translate android:fromXDelta="0" android:toXDelta="-75%" + android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/dock_right_enter.xml b/core/res/res/anim/dock_right_enter.xml new file mode 100644 index 0000000..e1bd190 --- /dev/null +++ b/core/res/res/anim/dock_right_enter.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 2012, 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. +*/ +--> + +<!-- Animation for when a dock window at the right of the screen is entering. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/decelerate_quad"> + <translate android:fromXDelta="75%" android:toXDelta="0" + android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/dock_right_exit.xml b/core/res/res/anim/dock_right_exit.xml new file mode 100644 index 0000000..6d778fa --- /dev/null +++ b/core/res/res/anim/dock_right_exit.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* Copyright 2012, 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. +*/ +--> + +<!-- Animation for when a dock window at the right of the screen is exiting. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/accelerate_quad"> + <translate android:fromXDelta="0" android:toXDelta="75%" + android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/packages/SystemUI/res/anim/status_bar_enter.xml b/core/res/res/anim/dock_top_enter.xml index f1c1301..f2e4cae 100644 --- a/packages/SystemUI/res/anim/status_bar_enter.xml +++ b/core/res/res/anim/dock_top_enter.xml @@ -1,8 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* //device/apps/common/res/anim/options_panel_enter.xml -** -** Copyright 2007, The Android Open Source Project +/* Copyright 2007, 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. @@ -18,10 +16,11 @@ */ --> +<!-- Animation for when a dock window at the top of the screen is entering. --> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/decelerate_quad"> - <translate android:fromYDelta="-75%" android:toYDelta="0" + <translate android:fromYDelta="-75%" android:toYDelta="0" android:duration="@android:integer/config_mediumAnimTime"/> - <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/packages/SystemUI/res/anim/status_bar_exit.xml b/core/res/res/anim/dock_top_exit.xml index 46462e2..7373695 100644 --- a/packages/SystemUI/res/anim/status_bar_exit.xml +++ b/core/res/res/anim/dock_top_exit.xml @@ -1,8 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* //device/apps/common/res/anim/options_panel_exit.xml -** -** Copyright 2007, The Android Open Source Project +/* Copyright 2007, 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. @@ -18,10 +16,11 @@ */ --> +<!-- Animation for when a dock window at the top of the screen is exiting. --> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/accelerate_quad"> - <translate android:fromYDelta="0" android:toYDelta="-75%" + <translate android:fromYDelta="0" android:toYDelta="-75%" android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/> - <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 6d6b86b..0442be8 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -32,11 +32,9 @@ <dimen name="toast_y_offset">64dip</dimen> <!-- Height of the status bar --> <dimen name="status_bar_height">25dip</dimen> - <!-- Height of the system bar (combined status + navigation, used on large screens) --> - <dimen name="system_bar_height">48dip</dimen> - <!-- Height of the horizontal navigation bar on devices that require it --> + <!-- Height of the bottom navigation / system bar. --> <dimen name="navigation_bar_height">48dp</dimen> - <!-- Width of the vertical navigation bar on devices that require it --> + <!-- Width of the navigation bar when it is placed vertically on the screen --> <dimen name="navigation_bar_width">42dp</dimen> <!-- Height of notification icons in the status bar --> <dimen name="status_bar_icon_size">24dip</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 31b444a..f010a02 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1128,6 +1128,14 @@ <!-- From android.policy --> <java-symbol type="anim" name="app_starting_exit" /> <java-symbol type="anim" name="lock_screen_behind_enter" /> + <java-symbol type="anim" name="dock_top_enter" /> + <java-symbol type="anim" name="dock_top_exit" /> + <java-symbol type="anim" name="dock_bottom_enter" /> + <java-symbol type="anim" name="dock_bottom_exit" /> + <java-symbol type="anim" name="dock_left_enter" /> + <java-symbol type="anim" name="dock_left_exit" /> + <java-symbol type="anim" name="dock_right_enter" /> + <java-symbol type="anim" name="dock_right_exit" /> <java-symbol type="array" name="config_keyboardTapVibePattern" /> <java-symbol type="array" name="config_longPressVibePattern" /> <java-symbol type="array" name="config_safeModeDisabledVibePattern" /> @@ -1153,7 +1161,6 @@ <java-symbol type="dimen" name="navigation_bar_height" /> <java-symbol type="dimen" name="navigation_bar_width" /> <java-symbol type="dimen" name="status_bar_height" /> - <java-symbol type="dimen" name="system_bar_height" /> <java-symbol type="drawable" name="ic_jog_dial_sound_off" /> <java-symbol type="drawable" name="ic_jog_dial_sound_on" /> <java-symbol type="drawable" name="ic_jog_dial_unlock" /> diff --git a/packages/SystemUI/res/anim/status_bar_in.xml b/packages/SystemUI/res/anim/status_bar_in.xml deleted file mode 100644 index 79fe5f1..0000000 --- a/packages/SystemUI/res/anim/status_bar_in.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2010 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. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" - > - <translate android:fromYDelta="100%p" android:toYDelta="0" - android:duration="@android:integer/config_longAnimTime" - android:interpolator="@anim/hydraulic_brake_interpolator" - /> - <alpha android:fromAlpha="0.5" android:toAlpha="1.0" - android:duration="@android:integer/config_longAnimTime" - /> -</set> diff --git a/packages/SystemUI/res/anim/status_bar_out.xml b/packages/SystemUI/res/anim/status_bar_out.xml deleted file mode 100644 index 80863cf..0000000 --- a/packages/SystemUI/res/anim/status_bar_out.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2010 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. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" - > - <translate android:toYDelta="100%p" android:fromYDelta="0" - android:duration="@android:integer/config_longAnimTime" - android:interpolator="@anim/hydraulic_brake_interpolator" - /> - <alpha android:toAlpha="0.5" android:fromAlpha="1.0" - android:duration="@android:integer/config_longAnimTime" - /> -</set> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index dc5c540..02411d4 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -67,8 +67,6 @@ <!-- Standard animations for hiding and showing the status bar. --> <style name="Animation.StatusBar"> - <item name="android:windowEnterAnimation">@anim/status_bar_enter</item> - <item name="android:windowExitAnimation">@anim/status_bar_exit</item> </style> <style name="Animation.StatusBar.IntruderAlert"> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index d7a5056..1ae15be 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -69,9 +69,9 @@ public class SystemUIService extends Service { IWindowManager wm = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); try { - SERVICES[0] = wm.canStatusBarHide() - ? R.string.config_statusBarComponent - : R.string.config_systemBarComponent; + SERVICES[0] = wm.hasSystemNavBar() + ? R.string.config_systemBarComponent + : R.string.config_statusBarComponent; } catch (RemoteException e) { Slog.w(TAG, "Failing checking whether status bar can hide", e); } 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 12c05ed..5ba72c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1766,11 +1766,6 @@ public class PhoneStatusBar extends BaseStatusBar { // HWComposer is unable to handle SW-rendered RGBX_8888 layers. PixelFormat.RGB_565); - // the status bar should be in an overlay if possible - final Display defaultDisplay - = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags. The status bar occupies // very little screen real-estate and is updated fairly frequently. By using CPU rendering // for the status bar, we prevent the GPU from having to wake up just to do these small @@ -1779,9 +1774,7 @@ public class PhoneStatusBar extends BaseStatusBar { lp.gravity = getStatusBarGravity(); lp.setTitle("StatusBar"); lp.packageName = mContext.getPackageName(); - lp.windowAnimations = R.style.Animation_StatusBar; WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp); - } void addExpandedWindow() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java deleted file mode 100644 index 3e9a9d8..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.systemui.statusbar.tablet; - -import java.util.ArrayList; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Resources; -import android.util.DisplayMetrics; -import android.util.Slog; -import android.view.Display; -import android.view.WindowManager; -import android.view.WindowManagerImpl; -import android.view.WindowManagerPolicy; - -public class HeightReceiver extends BroadcastReceiver { - private static final String TAG = "StatusBar.HeightReceiver"; - - public interface OnBarHeightChangedListener { - public void onBarHeightChanged(int height); - } - - Context mContext; - ArrayList<OnBarHeightChangedListener> mListeners = new ArrayList<OnBarHeightChangedListener>(); - WindowManager mWindowManager; - int mHeight; - boolean mPlugged; - - public HeightReceiver(Context context) { - mContext = context; - mWindowManager = WindowManagerImpl.getDefault(); - } - - public void addOnBarHeightChangedListener(OnBarHeightChangedListener l) { - mListeners.add(l); - l.onBarHeightChanged(mHeight); - } - - public void removeOnBarHeightChangedListener(OnBarHeightChangedListener l) { - mListeners.remove(l); - } - - @Override - public void onReceive(Context context, Intent intent) { - final boolean plugged - = intent.getBooleanExtra(WindowManagerPolicy.EXTRA_HDMI_PLUGGED_STATE, false); - setPlugged(plugged); - } - - public void registerReceiver() { - final IntentFilter filter = new IntentFilter(); - filter.addAction(WindowManagerPolicy.ACTION_HDMI_PLUGGED); - final Intent val = mContext.registerReceiver(this, filter); - onReceive(mContext, val); - } - - private void setPlugged(boolean plugged) { - mPlugged = plugged; - updateHeight(); - } - - public void updateHeight() { - final Resources res = mContext.getResources(); - - int height = -1; - if (mPlugged) { - final DisplayMetrics metrics = new DisplayMetrics(); - Display display = mWindowManager.getDefaultDisplay(); - display.getRealMetrics(metrics); - - //Slog.i(TAG, "updateHeight: display metrics=" + metrics); - final int shortSide = Math.min(metrics.widthPixels, metrics.heightPixels); - final int externalShortSide = Math.min(display.getRawExternalWidth(), - display.getRawExternalHeight()); - height = shortSide - externalShortSide; - } - - final int minHeight - = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); - if (height < minHeight) { - height = minHeight; - } - Slog.i(TAG, "Resizing status bar plugged=" + mPlugged + " height=" - + height + " old=" + mHeight); - mHeight = height; - - final int N = mListeners.size(); - for (int i=0; i<N; i++) { - mListeners.get(i).onBarHeightChanged(height); - } - } - - public int getHeight() { - return mHeight; - } -} - diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 7325a37..49b1a14 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -87,7 +87,6 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.Prefs; public class TabletStatusBar extends BaseStatusBar implements - HeightReceiver.OnBarHeightChangedListener, InputMethodsPanel.OnHardKeyboardEnabledChangeListener, RecentsPanelView.OnRecentsPanelVisibilityChangedListener { public static final boolean DEBUG = false; @@ -162,7 +161,6 @@ public class TabletStatusBar extends BaseStatusBar implements ViewGroup mPile; - HeightReceiver mHeightReceiver; BatteryController mBatteryController; BluetoothController mBluetoothController; LocationController mLocationController; @@ -204,12 +202,11 @@ public class TabletStatusBar extends BaseStatusBar implements private void addStatusBarWindow() { final View sb = makeStatusBarView(); - final int height = getStatusBarHeight(); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, - height, - WindowManager.LayoutParams.TYPE_STATUS_BAR, + ViewGroup.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, @@ -218,20 +215,14 @@ public class TabletStatusBar extends BaseStatusBar implements // HWComposer is unable to handle SW-rendered RGBX_8888 layers. PixelFormat.RGB_565); - // the status bar should be in an overlay if possible - final Display defaultDisplay - = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags. The status bar occupies // very little screen real-estate and is updated fairly frequently. By using CPU rendering // for the status bar, we prevent the GPU from having to wake up just to do these small // updates, which should help keep power consumption down. lp.gravity = getStatusBarGravity(); - lp.setTitle("StatusBar"); + lp.setTitle("SystemBar"); lp.packageName = mContext.getPackageName(); - lp.windowAnimations = R.style.Animation_StatusBar; WindowManagerImpl.getDefault().addView(sb, lp); } @@ -414,7 +405,6 @@ public class TabletStatusBar extends BaseStatusBar implements @Override protected void onConfigurationChanged(Configuration newConfig) { - mHeightReceiver.updateHeight(); // display size may have changed loadDimens(); mNotificationPanelParams.height = getNotificationPanelHeight(); WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel, @@ -426,7 +416,7 @@ public class TabletStatusBar extends BaseStatusBar implements final Resources res = mContext.getResources(); mNaturalBarHeight = res.getDimensionPixelSize( - com.android.internal.R.dimen.system_bar_height); + com.android.internal.R.dimen.navigation_bar_height); int newIconSize = res.getDimensionPixelSize( com.android.internal.R.dimen.system_bar_icon_size); @@ -478,10 +468,6 @@ public class TabletStatusBar extends BaseStatusBar implements mWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); - // This guy will listen for HDMI plugged broadcasts so we can resize the - // status bar as appropriate. - mHeightReceiver = new HeightReceiver(mContext); - mHeightReceiver.registerReceiver(); loadDimens(); final TabletStatusBarView sb = (TabletStatusBarView)View.inflate( @@ -637,8 +623,6 @@ public class TabletStatusBar extends BaseStatusBar implements // set the initial view visibility setAreThereNotifications(); - mHeightReceiver.addOnBarHeightChangedListener(this); - // receive broadcasts IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); @@ -674,7 +658,9 @@ public class TabletStatusBar extends BaseStatusBar implements } public int getStatusBarHeight() { - return mHeightReceiver.getHeight(); + return mStatusBarView != null ? mStatusBarView.getHeight() + : mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height); } protected int getStatusBarGravity() { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index fb1e106..c3cac6e 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -1,5 +1,4 @@ /* - * Copyright (C) 2006 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. @@ -72,6 +71,7 @@ import android.util.EventLog; import android.util.Log; import android.util.Slog; import android.util.SparseArray; +import android.view.Display; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.IApplicationToken; @@ -299,11 +299,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mHeadless; boolean mSafeMode; WindowState mStatusBar = null; - boolean mStatusBarCanHide; + boolean mHasSystemNavBar; int mStatusBarHeight; final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>(); WindowState mNavigationBar = null; boolean mHasNavigationBar = false; + boolean mCanHideNavigationBar = false; + boolean mNavigationBarOnBottom = true; int mNavigationBarWidth = 0, mNavigationBarHeight = 0; WindowState mKeyguard = null; @@ -329,6 +331,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mSystemReady; boolean mSystemBooted; boolean mHdmiPlugged; + int mExternalDisplayWidth; + int mExternalDisplayHeight; int mUiMode; int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED; int mLidOpenRotation; @@ -464,6 +468,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.) int mIncallPowerBehavior; + Display mDisplay; + int mLandscapeRotation = 0; // default landscape rotation int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation int mPortraitRotation = 0; // default portrait rotation @@ -927,10 +933,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - public void setInitialDisplaySize(int width, int height) { - int shortSize; + public void setInitialDisplaySize(Display display, int width, int height) { + mDisplay = display; + + int shortSize, longSize; if (width > height) { shortSize = height; + longSize = width; mLandscapeRotation = Surface.ROTATION_0; mSeascapeRotation = Surface.ROTATION_180; if (mContext.getResources().getBoolean( @@ -943,6 +952,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } else { shortSize = width; + longSize = height; mPortraitRotation = Surface.ROTATION_0; mUpsideDownRotation = Surface.ROTATION_180; if (mContext.getResources().getBoolean( @@ -955,36 +965,61 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + mExternalDisplayWidth = mDisplay.getRawExternalWidth(); + mExternalDisplayHeight = mDisplay.getRawExternalHeight(); + + mStatusBarHeight = mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.status_bar_height); + mNavigationBarHeight = mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height); + mNavigationBarWidth = mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_width); + // Determine whether the status bar can hide based on the size // of the screen. We assume sizes > 600dp are tablets where we // will use the system bar. int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / DisplayMetrics.DENSITY_DEVICE; - mStatusBarCanHide = shortSizeDp < 600; - mStatusBarHeight = mContext.getResources().getDimensionPixelSize( - mStatusBarCanHide - ? com.android.internal.R.dimen.status_bar_height - : com.android.internal.R.dimen.system_bar_height); - - mHasNavigationBar = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_showNavigationBar); - // Allow a system property to override this. Used by the emulator. - // See also hasNavigationBar(). - String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); - if (! "".equals(navBarOverride)) { - if (navBarOverride.equals("1")) mHasNavigationBar = false; - else if (navBarOverride.equals("0")) mHasNavigationBar = true; - } - - mNavigationBarHeight = mHasNavigationBar - ? mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.navigation_bar_height) - : 0; - mNavigationBarWidth = mHasNavigationBar - ? mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.navigation_bar_width) - : 0; + mHasSystemNavBar = shortSizeDp > 600; + + if (!mHasSystemNavBar) { + mHasNavigationBar = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_showNavigationBar); + // Allow a system property to override this. Used by the emulator. + // See also hasNavigationBar(). + String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); + if (! "".equals(navBarOverride)) { + if (navBarOverride.equals("1")) mHasNavigationBar = false; + else if (navBarOverride.equals("0")) mHasNavigationBar = true; + } + } else { + mHasNavigationBar = false; + } + + if (mHasSystemNavBar) { + // The system bar is always at the bottom. If you are watching + // a video in landscape, we don't need to hide it if we can still + // show a 16:9 aspect ratio with it. + int longSizeDp = longSize + * DisplayMetrics.DENSITY_DEFAULT + / DisplayMetrics.DENSITY_DEVICE; + int barHeightDp = mNavigationBarHeight + * DisplayMetrics.DENSITY_DEFAULT + / DisplayMetrics.DENSITY_DEVICE; + int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp; + // We have computed the aspect ratio with the bar height taken + // out to be 16:aspect. If this is less than 9, then hiding + // the navigation bar will provide more useful space for wide + // screen movies. + mCanHideNavigationBar = aspect < 9; + } else if (mHasNavigationBar) { + // The navigation bar is at the right in landscape; it seems always + // useful to hide it for showing a video. + mCanHideNavigationBar = true; + } else { + mCanHideNavigationBar = false; + } if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) { mHdmiRotation = mPortraitRotation; @@ -1318,13 +1353,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { return STATUS_BAR_LAYER; } - public boolean canStatusBarHide() { - return mStatusBarCanHide; + public boolean hasSystemNavBar() { + return mHasSystemNavBar; } public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) { // Assumes that the navigation bar appears on the side of the display in landscape. - if (fullWidth > fullHeight) { + if (mHasNavigationBar && fullWidth > fullHeight) { return fullWidth - mNavigationBarWidth; } return fullWidth; @@ -1333,8 +1368,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) { // Assumes the navigation bar appears on the bottom of the display in portrait. return fullHeight - - (mStatusBarCanHide ? 0 : mStatusBarHeight) - - ((fullWidth > fullHeight) ? 0 : mNavigationBarHeight); + - (mHasSystemNavBar ? mNavigationBarHeight : 0) + - ((mHasNavigationBar && fullWidth > fullHeight) ? 0 : mNavigationBarHeight); } public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) { @@ -1348,7 +1383,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // exclude it since applications can't generally use that part of the // screen. return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation) - - (mStatusBarCanHide ? mStatusBarHeight : 0); + - (mHasSystemNavBar ? 0 : mStatusBarHeight); } public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) { @@ -1357,6 +1392,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) { return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR + && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER; } @@ -1495,10 +1531,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.STATUS_BAR_SERVICE, "PhoneWindowManager"); - // TODO: Need to handle the race condition of the status bar proc - // dying and coming back before the removeWindowLw cleanup has happened. if (mStatusBar != null) { - return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; + if (mStatusBar.isAlive()) { + return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; + } } mStatusBar = win; break; @@ -1506,6 +1542,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.STATUS_BAR_SERVICE, "PhoneWindowManager"); + if (mNavigationBar != null) { + if (mNavigationBar.isAlive()) { + return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; + } + } mNavigationBar = win; if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar); break; @@ -1550,7 +1591,28 @@ public class PhoneWindowManager implements WindowManagerPolicy { public int selectAnimationLw(WindowState win, int transit) { if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win + ": transit=" + transit); - if (transit == TRANSIT_PREVIEW_DONE) { + if (win == mStatusBar) { + if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) { + return R.anim.dock_top_exit; + } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { + return R.anim.dock_top_enter; + } + } else if (win == mNavigationBar) { + // This can be on either the bottom or the right. + if (mNavigationBarOnBottom) { + if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) { + return R.anim.dock_bottom_exit; + } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { + return R.anim.dock_bottom_enter; + } + } else { + if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) { + return R.anim.dock_right_exit; + } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { + return R.anim.dock_right_enter; + } + } + } if (transit == TRANSIT_PREVIEW_DONE) { if (win.hasAppShownWindows()) { if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT"); return com.android.internal.R.anim.app_starting_exit; @@ -2036,7 +2098,8 @@ 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)) { int availRight, availBottom; - if ((attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { + if (mCanHideNavigationBar && + (attrs.systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; } else { @@ -2082,8 +2145,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { pf.right = df.right = vf.right = mDockRight; pf.bottom = df.bottom = vf.bottom = mDockBottom; - final boolean navVisible = (mNavigationBar == null || mNavigationBar.isVisibleLw()) && - (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; + // For purposes of putting out fake window up to steal focus, we will + // drive nav being hidden only by whether it is requested. + boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; // When the navigation bar isn't visible, we put up a fake // input window to catch all touch events. This way we can @@ -2101,57 +2165,71 @@ public class PhoneWindowManager implements WindowManagerPolicy { 0, false, false, true); } - // decide where the status bar goes ahead of time - if (mStatusBar != null) { - if (mNavigationBar != null) { - // Force the navigation bar to its appropriate place and - // size. We need to do this directly, instead of relying on - // it to bubble up from the nav bar, because this needs to - // change atomically with screen rotations. - if (displayWidth < displayHeight) { - // Portrait screen; nav bar goes on bottom. - mTmpNavigationFrame.set(0, displayHeight-mNavigationBarHeight, - displayWidth, displayHeight); - mStableBottom = mTmpNavigationFrame.top; - if (navVisible) { - mDockBottom = mTmpNavigationFrame.top; - mRestrictedScreenHeight = mDockBottom - mDockTop; - } else { - // We currently want to hide the navigation UI. Do this by just - // moving it off the screen, so it can still receive input events - // to know when to be re-shown. - mTmpNavigationFrame.offset(0, mNavigationBarHeight); + // For purposes of positioning and showing the nav bar, if we have + // decided that it can't be hidden (because of the screen aspect ratio), + // then take that into account. + navVisible |= !mCanHideNavigationBar; + + if (mNavigationBar != null) { + // Force the navigation bar to its appropriate place and + // size. We need to do this directly, instead of relying on + // it to bubble up from the nav bar, because this needs to + // change atomically with screen rotations. + mNavigationBarOnBottom = !mHasNavigationBar || displayWidth < displayHeight; + if (mNavigationBarOnBottom) { + // It's a system nav bar or a portrait screen; nav bar goes on bottom. + int top = displayHeight - mNavigationBarHeight; + if (mHdmiPlugged) { + if (top > mExternalDisplayHeight) { + top = mExternalDisplayHeight; } + } + mTmpNavigationFrame.set(0, top, displayWidth, displayHeight); + mStableBottom = mTmpNavigationFrame.top; + if (navVisible) { + mNavigationBar.showLw(true); + mDockBottom = mTmpNavigationFrame.top; + mRestrictedScreenHeight = mDockBottom - mDockTop; } else { - // Landscape screen; nav bar goes to the right. - mTmpNavigationFrame.set(displayWidth-mNavigationBarWidth, 0, - displayWidth, displayHeight); - mStableRight = mTmpNavigationFrame.left; - if (navVisible) { - mDockRight = mTmpNavigationFrame.left; - mRestrictedScreenWidth = mDockRight - mDockLeft; - } else { - // We currently want to hide the navigation UI. Do this by just - // moving it off the screen, so it can still receive input events - // to know when to be re-shown. - mTmpNavigationFrame.offset(mNavigationBarWidth, 0); + // We currently want to hide the navigation UI. + mNavigationBar.hideLw(true); + } + } else { + // Landscape screen; nav bar goes to the right. + int left = displayWidth - mNavigationBarWidth; + if (mHdmiPlugged) { + if (left > mExternalDisplayWidth) { + left = mExternalDisplayWidth; } } - // Make sure the content and current rectangles are updated to - // account for the restrictions from the navigation bar. - mContentTop = mCurTop = mDockTop; - mContentBottom = mCurBottom = mDockBottom; - mContentLeft = mCurLeft = mDockLeft; - mContentRight = mCurRight = mDockRight; - // And compute the final frame. - mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, - mTmpNavigationFrame, mTmpNavigationFrame); - if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); + mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight); + mStableRight = mTmpNavigationFrame.left; + if (navVisible) { + mNavigationBar.showLw(true); + mDockRight = mTmpNavigationFrame.left; + mRestrictedScreenWidth = mDockRight - mDockLeft; + } else { + // We currently want to hide the navigation UI. + mNavigationBar.hideLw(true); + } } - if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", - mDockLeft, mDockTop, mDockRight, mDockBottom)); + // Make sure the content and current rectangles are updated to + // account for the restrictions from the navigation bar. + mContentTop = mCurTop = mDockTop; + mContentBottom = mCurBottom = mDockBottom; + mContentLeft = mCurLeft = mDockLeft; + mContentRight = mCurRight = mDockRight; + // And compute the final frame. + mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, + mTmpNavigationFrame, mTmpNavigationFrame); + if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); + } + if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", + mDockLeft, mDockTop, mDockRight, mDockBottom)); - // apply navigation bar insets + // decide where the status bar goes ahead of time + if (mStatusBar != null) { + // apply any navigation bar insets pf.left = df.left = vf.left = mDockLeft; pf.top = df.top = vf.top = mDockTop; pf.right = df.right = vf.right = mDockRight; @@ -2161,57 +2239,29 @@ public class PhoneWindowManager implements WindowManagerPolicy { final Rect r = mStatusBar.getFrameLw(); // Compute the stable dimensions whether or not the status bar is hidden. - if (mStatusBarCanHide) { - if (mDockTop == r.top) mStableTop = r.bottom; - else if (mDockBottom == r.bottom) mStableBottom = r.top; - } else { - if (mStableTop == r.top) { - mStableTop = r.bottom; - } else if (mStableBottom == r.bottom) { - mStableBottom = r.top; - } - } + if (mDockTop == r.top) mStableTop = r.bottom; + else if (mDockBottom == r.bottom) mStableBottom = r.top; + // If the status bar is hidden, we don't want to cause + // windows behind it to scroll. if (mStatusBar.isVisibleLw()) { - // If the status bar is hidden, we don't want to cause - // windows behind it to scroll. - if (mStatusBarCanHide) { - // Status bar may go away, so the screen area it occupies - // is available to apps but just covering them when the - // 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; - 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. - if (mRestrictedScreenTop == r.top) { - mRestrictedScreenTop = r.bottom; - mRestrictedScreenHeight -= (r.bottom-r.top); - } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) { - mRestrictedScreenHeight -= (r.bottom-r.top); - } + // Status bar may go away, so the screen area it occupies + // is available to apps but just covering them when the + // 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; + mContentLeft = mCurLeft = mDockLeft; + mContentRight = mCurRight = mDockRight; - mContentTop = mCurTop = mDockTop = mRestrictedScreenTop; - mContentBottom = mCurBottom = mDockBottom - = mRestrictedScreenTop + mRestrictedScreenHeight; - if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: (" - + mRestrictedScreenLeft + "," - + mRestrictedScreenTop + "," - + (mRestrictedScreenLeft + mRestrictedScreenWidth) + "," - + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")"); - } + 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)); } } } @@ -2333,7 +2383,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { "Laying out status bar window: (%d,%d - %d,%d)", pf.left, pf.top, pf.right, pf.bottom)); } - } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 + } else if (mCanHideNavigationBar + && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { // Asking for layout as if the nav bar is hidden, lets the @@ -2426,7 +2477,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; pf.bottom = df.bottom = cf.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight; - } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 + } else if (mCanHideNavigationBar + && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { // Asking for layout as if the nav bar is hidden, lets the @@ -2623,19 +2675,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the // case though. if (topIsFullscreen) { - if (mStatusBarCanHide) { - if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar"); - if (mStatusBar.hideLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT; - - mHandler.post(new Runnable() { public void run() { - if (mStatusBarService != null) { - try { - mStatusBarService.collapse(); - } catch (RemoteException ex) {} - } - }}); - } + if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar"); + if (mStatusBar.hideLw(true)) { + changes |= FINISH_LAYOUT_REDO_LAYOUT; + + mHandler.post(new Runnable() { public void run() { + if (mStatusBarService != null) { + try { + mStatusBarService.collapse(); + } catch (RemoteException ex) {} + } + }}); } else if (DEBUG_LAYOUT) { Log.v(TAG, "Preventing status bar from hiding by policy"); } @@ -2699,30 +2749,24 @@ public class PhoneWindowManager implements WindowManagerPolicy { // behind it. return false; } - if (false) { - // Don't do this on the tablet, since the system bar never completely - // covers the screen, and with all its transparency this will - // incorrectly think it does cover it when it doesn't. We'll revisit - // this later when we re-do the phone status bar. - if (mStatusBar != null && mStatusBar.isVisibleLw()) { - RectF rect = new RectF(mStatusBar.getShownFrameLw()); - for (int i=mStatusBarPanels.size()-1; i>=0; i--) { - WindowState w = mStatusBarPanels.get(i); - if (w.isVisibleLw()) { - rect.union(w.getShownFrameLw()); - } - } - final int insetw = mRestrictedScreenWidth/10; - final int inseth = mRestrictedScreenHeight/10; - if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw, - mRestrictedScreenHeight-inseth)) { - // All of the status bar windows put together cover the - // screen, so the app can't be seen. (Note this test doesn't - // work if the rects of these windows are at off offsets or - // sizes, causing gaps in the rect union we have computed.) - return false; + if (mStatusBar != null && mStatusBar.isVisibleLw()) { + RectF rect = new RectF(mStatusBar.getShownFrameLw()); + for (int i=mStatusBarPanels.size()-1; i>=0; i--) { + WindowState w = mStatusBarPanels.get(i); + if (w.isVisibleLw()) { + rect.union(w.getShownFrameLw()); } } + final int insetw = mRestrictedScreenWidth/10; + final int inseth = mRestrictedScreenHeight/10; + if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw, + mRestrictedScreenHeight-inseth)) { + // All of the status bar windows put together cover the + // screen, so the app can't be seen. (Note this test doesn't + // work if the rects of these windows are at odd offsets or + // sizes, causing gaps in the rect union we have computed.) + return false; + } } return true; } @@ -2776,7 +2820,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { void setHdmiPlugged(boolean plugged) { if (mHdmiPlugged != plugged) { mHdmiPlugged = plugged; - updateRotation(true); + if (plugged && mDisplay != null) { + mExternalDisplayWidth = mDisplay.getRawExternalWidth(); + mExternalDisplayHeight = mDisplay.getRawExternalHeight(); + } + updateRotation(true, true); Intent intent = new Intent(ACTION_HDMI_PLUGGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged); @@ -3871,7 +3919,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { void updateRotation(boolean alwaysSendConfiguration) { try { //set orientation on WindowManager - mWindowManager.updateRotation(alwaysSendConfiguration); + mWindowManager.updateRotation(alwaysSendConfiguration, false); + } catch (RemoteException e) { + // Ignore + } + } + + void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { + try { + //set orientation on WindowManager + mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout); } catch (RemoteException e) { // Ignore } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 7eca401..654cfdf 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5109,7 +5109,7 @@ public class WindowManagerService extends IWindowManager.Stub mPolicy.enableScreenAfterBoot(); // Make sure the last requested orientation has been applied. - updateRotationUnchecked(false); + updateRotationUnchecked(false, false); } public void showBootMessage(final CharSequence msg, final boolean always) { @@ -5383,7 +5383,7 @@ public class WindowManagerService extends IWindowManager.Stub mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation == -1 ? mRotation : rotation); - updateRotationUnchecked(false); + updateRotationUnchecked(false, false); } /** @@ -5399,7 +5399,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation); mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used - updateRotationUnchecked(false); + updateRotationUnchecked(false, false); } /** @@ -5409,8 +5409,8 @@ public class WindowManagerService extends IWindowManager.Stub * such that the current rotation might need to be updated, such as when the * device is docked or rotated into a new posture. */ - public void updateRotation(boolean alwaysSendConfiguration) { - updateRotationUnchecked(alwaysSendConfiguration); + public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { + updateRotationUnchecked(alwaysSendConfiguration, forceRelayout); } /** @@ -5440,8 +5440,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void updateRotationUnchecked( - boolean alwaysSendConfiguration) { + public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) { if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked(" + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")"); @@ -5449,6 +5448,10 @@ public class WindowManagerService extends IWindowManager.Stub boolean changed; synchronized(mWindowMap) { changed = updateRotationUncheckedLocked(false); + if (!changed || forceRelayout) { + mLayoutNeeded = true; + performLayoutAndPlaceSurfacesLocked(); + } } if (changed || alwaysSendConfiguration) { @@ -6641,7 +6644,7 @@ public class WindowManagerService extends IWindowManager.Stub mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY, mDisplay.getRawWidth(), mDisplay.getRawHeight(), mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight()); - mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight); + mPolicy.setInitialDisplaySize(mDisplay, mInitialDisplayWidth, mInitialDisplayHeight); } try { @@ -7361,7 +7364,7 @@ public class WindowManagerService extends IWindowManager.Stub mBaseDisplayWidth = width; mBaseDisplayHeight = height; } - mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight); + mPolicy.setInitialDisplaySize(mDisplay, mBaseDisplayWidth, mBaseDisplayHeight); mLayoutNeeded = true; @@ -7393,8 +7396,8 @@ public class WindowManagerService extends IWindowManager.Stub } } - public boolean canStatusBarHide() { - return mPolicy.canStatusBarHide(); + public boolean hasSystemNavBar() { + return mPolicy.hasSystemNavBar(); } // ------------------------------------------------------------- diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 05797a4..a4708d3 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -870,6 +870,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return true; } + @Override public boolean hideLw(boolean doAnimation) { return hideLw(doAnimation, true); } @@ -912,6 +913,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { return true; } + @Override + public boolean isAlive() { + return mClient.asBinder().isBinderAlive(); + } + private static void applyInsets(Region outRegion, Rect frame, Rect inset) { outRegion.set( frame.left + inset.left, frame.top + inset.top, diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index c3ac22c..58f65be 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -412,7 +412,7 @@ public class WindowManagerPermissionTests extends TestCase { @SmallTest public void testSET_ORIENTATION() { try { - mWm.updateRotation(true); + mWm.updateRotation(true, false); mWm.getSwitchState(0); fail("IWindowManager.updateRotation did not throw SecurityException as" + " expected"); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java index 8b1d41a..0755670 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java @@ -88,7 +88,7 @@ public class BridgeWindowManager implements IWindowManager { // ---- unused implementation of IWindowManager ---- @Override - public boolean canStatusBarHide() throws RemoteException { + public boolean hasSystemNavBar() throws RemoteException { // TODO Auto-generated method stub return false; } @@ -468,9 +468,8 @@ public class BridgeWindowManager implements IWindowManager { } @Override - public void updateRotation(boolean arg0) throws RemoteException { + public void updateRotation(boolean arg0, boolean arg1) throws RemoteException { // TODO Auto-generated method stub - } @Override |