From 87be4e504149485983491a51e0109cbc929385e6 Mon Sep 17 00:00:00 2001 From: Yanuar Harry Date: Tue, 5 Mar 2013 01:00:29 +0700 Subject: [PATCH] trying to fix navbar show/hide --- core/java/android/view/View.java | 2 +- .../policy/impl/PhoneWindowManager.java | 265 ++++++++---------- .../android/server/WindowManagerService.java | 2 +- 3 files changed, 126 insertions(+), 143 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f265dd50..f027b818 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -9786,7 +9786,7 @@ public void setOverScrollMode(int overScrollMode) { * A Property wrapper around the alpha functionality handled by the * {@link View#setAlpha(float)} and {@link View#getAlpha()} methods. */ - static Property ALPHA = new FloatProperty("alpha") { + public static Property ALPHA = new FloatProperty("alpha") { @Override public void setValue(View object, float value) { object.setAlpha(value); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index ddd13a07..870e2569 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -240,8 +240,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mSafeMode; WindowState mStatusBar = null; + boolean mStatusBarCanHide = true; + int mScreenMarginBottom = 0; final ArrayList mStatusBarPanels = new ArrayList(); WindowState mNavigationBar = null; + int mNavigationBarHeight = 0; WindowState mKeyguard = null; KeyguardViewMediator mKeyguardMediator = null; @@ -384,6 +387,7 @@ public void handleMotion(MotionEvent event, Runnable finishedCallback) { static final Rect mTmpNavigationFrame = new Rect(); WindowState mTopFullscreenOpaqueWindowState; + boolean mTopIsFullscreen; boolean mForceStatusBar; boolean mHideLockScreen; boolean mDismissKeyguard; @@ -543,16 +547,6 @@ public void onOrientationChanged(int rotation) { } MyOrientationListener mOrientationListener; - IStatusBarService getStatusBarService() { - synchronized (mServiceAquireLock) { - if (mStatusBarService == null) { - mStatusBarService = IStatusBarService.Stub.asInterface( - ServiceManager.getService("statusbar")); - } - return mStatusBarService; - } - } - boolean useSensorForOrientationLp(int appOrientation) { // The app says use the sensor. if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR @@ -711,19 +705,7 @@ void showGlobalActionsDialog() { // poke the wake lock so they have some time to see the dialog. mKeyguardMediator.pokeWakelock(); if (mNaviShow && mNaviShowAll) { - mHandler.post(new Runnable() { - @Override - public void run() { - try { - IStatusBarService statusbar = getStatusBarService(); - if (statusbar != null) { - statusbar.showNaviBar(false); - } - } catch (RemoteException ex) { - // re-acquire status bar service next time it is needed. - mStatusBarService = null; - } - }}); + shouldShowNavbar(false); } } } @@ -1580,9 +1562,6 @@ public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) mContext.enforceCallingOrSelfPermission( android.Manifest.permission.STATUS_BAR_SERVICE, "PhoneWindowManager"); - if (mNavigationBar != null) { - return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; - } mNavigationBar = win; break; case TYPE_NAVIGATION_BAR_PANEL: @@ -2001,36 +1980,43 @@ public void beginLayoutLw(int displayWidth, int displayHeight) { mDockBottom = mContentBottom = mCurBottom = displayHeight; mDockLayer = 0x10000000; mNavRotate = (displayWidth > displayHeight); + mNavigationBarHeight = mNavRotate ? getStatBarSize() : getNavBarSize(); + + // 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 = 0; + pf.top = df.top = vf.top = 0; + pf.right = df.right = vf.right = displayWidth; + pf.bottom = df.bottom = vf.bottom = displayHeight; - // 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 = 0; - pf.top = df.top = vf.top = 0; - pf.right = df.right = vf.right = displayWidth; - pf.bottom = df.bottom = vf.bottom = displayHeight; + final boolean navVisible = (mNaviShow && mNaviShowAll && mNaviShowAll2); // decide where the status bar goes ahead of time if (mStatusBar != null) { if (mNavigationBar != null) { - final boolean navVisible = (mNavigationBar.isVisibleLw() && mNaviShow && mNaviShowAll && mNaviShowAll2); - final int mNavigationBarHeight = mNavRotate ? getStatBarSize() : getNavBarSize(); mTmpNavigationFrame.set(0, (displayHeight-mNavigationBarHeight), displayWidth, displayHeight); if (navVisible) { - mDockBottom = mContentBottom = mCurBottom = mTmpNavigationFrame.top; + mDockBottom = mTmpNavigationFrame.top; } else { mTmpNavigationFrame.offset(0, mNavigationBarHeight); } + // 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; mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame); if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); - } else { - mDockBottom = mContentBottom = mCurBottom = displayHeight; } + if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", + mDockLeft, mDockTop, mDockRight, mDockBottom)); - if(mBottomBar && !mNaviShow){ + if (mBottomBar && !mNaviShow) { final int statusbar_height = getStatBarSize(); //setting status bar's top, to bottom of the screen, minus status bar height pf.top = df.top = vf.top = (displayHeight-statusbar_height); @@ -2044,10 +2030,14 @@ public void beginLayoutLw(int displayWidth, int displayHeight) { // windows behind it to scroll. if(mBottomBar && (!mNaviShow || !mNaviShowAll || !mNaviShowAll2)) { //setting activites bottoms, to top of status bar - mDockBottom = mContentBottom = mCurBottom = r.top; + mDockBottom = r.top; } else { - mDockTop = mContentTop = mCurTop = r.bottom; + mDockTop = r.bottom; } + mContentTop = mCurTop = mDockTop; + mContentBottom = mCurBottom = mDockBottom; + mContentLeft = mCurLeft = mDockLeft; + mContentRight = mCurRight = mDockRight; if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mDockBottom=" + mDockBottom + " mContentBottom=" + mContentBottom + " mCurBottom=" + mCurBottom); @@ -2055,7 +2045,7 @@ public void beginLayoutLw(int displayWidth, int displayHeight) { } } - void setAttachedWindowFrames(WindowState win, int fl, int sim, + void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect cf, Rect vf) { if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { // Here's a special case: if this attached window is a panel that is @@ -2076,7 +2066,7 @@ void setAttachedWindowFrames(WindowState win, int fl, int sim, // window is positioned within that content. Otherwise we can use // the display frame and let the attached window take care of // positioning its content appropriately. - if ((sim & SOFT_INPUT_MASK_ADJUST) != SOFT_INPUT_ADJUST_RESIZE) { + if (adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.set(attached.getDisplayFrameLw()); } else { // If the window is resizing, then we want to base the content @@ -2113,13 +2103,6 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, return; } - if (false) { - if ("com.google.android.youtube".equals(attrs.packageName) - && attrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { - Log.i(TAG, "GOTCHA!"); - } - } - final int fl = attrs.flags; final int sim = attrs.softInputMode; @@ -2138,6 +2121,8 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, attrs.gravity = Gravity.BOTTOM; mDockLayer = win.getSurfaceLayer(); } else { + final int adjust = sim & SOFT_INPUT_MASK_ADJUST; + if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR)) == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { @@ -2162,7 +2147,7 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, pf.right = df.right = mRestrictedScreenLeft+mRestrictedScreenWidth; pf.bottom = df.bottom = hasNavBar ? mDockBottom : mRestrictedScreenTop+mRestrictedScreenHeight; } - if ((sim & SOFT_INPUT_MASK_ADJUST) != SOFT_INPUT_ADJUST_RESIZE) { + if (adjust != SOFT_INPUT_ADJUST_RESIZE) { cf.left = mDockLeft; cf.top = mDockTop; cf.right = mDockRight; @@ -2185,11 +2170,13 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { pf.left = df.left = cf.left = mUnrestrictedScreenLeft; pf.top = df.top = cf.top = mUnrestrictedScreenTop; - pf.right = df.right = cf.right - = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; - pf.bottom = df.bottom = cf.bottom - = hasNavBar ? mDockBottom : mUnrestrictedScreenTop+mUnrestrictedScreenHeight; - } else if (attrs.type == TYPE_SECURE_SYSTEM_OVERLAY) { + pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth; + pf.bottom = df.bottom = cf.bottom = hasNavBar + ? mDockBottom + : mUnrestrictedScreenTop+mUnrestrictedScreenHeight; + } else if ((attrs.type == TYPE_SECURE_SYSTEM_OVERLAY + || attrs.type == TYPE_BOOT_PROGRESS) + && ((fl & FLAG_FULLSCREEN) != 0)) { // Fullscreen secure system overlays get what they ask for. pf.left = df.left = mUnrestrictedScreenLeft; pf.top = df.top = mUnrestrictedScreenTop; @@ -2216,7 +2203,7 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, } else if (attached != null) { // A child window should be placed inside of the same visible // frame that its parent had. - setAttachedWindowFrames(win, fl, sim, attached, false, pf, df, cf, vf); + setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf); } else { // Otherwise, a normal window must be placed inside the content // of all screen decorations. @@ -2254,16 +2241,6 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, + " pf=" + pf.toShortString() + " df=" + df.toShortString() + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); - if (false) { - if ("com.google.android.youtube".equals(attrs.packageName) - && attrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { - if (true || localLOGV) Log.v(TAG, "Computing frame of " + win + - ": sim=#" + Integer.toHexString(sim) - + " pf=" + pf.toShortString() + " df=" + df.toShortString() - + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); - } - } - win.computeFrameLw(pf, df, cf, vf); // Dock windows carve out the bottom of the screen, so normal windows @@ -2347,16 +2324,34 @@ public void run() { if (!mNaviShowAll2) { Settings.System.putInt(mContext.getContentResolver(), Settings.System.NAVI_BUTTONS, 0); - mHandler.postDelayed(mShowsNavbar, 25); + mHandler.postDelayed(mShowsNavbar, 10); } } }; + private void shouldShowNavbar(final boolean what) { + mHandler.post(new Runnable() { + @Override + public void run() { + if (mStatusBarService != null) { + try { + mStatusBarService.showNaviBar(what); + } catch (RemoteException ex) {} + } + }}); + } + /** {@inheritDoc} */ public int finishAnimationLw() { mNaviShowAll = (Settings.System.getInt(mContext.getContentResolver(), Settings.System.NAVI_BUTTONS, 1) == 1); + updateSystemUiservice(); + int changes = 0; + boolean topIsFullscreen = false; + final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null) + ? mTopFullscreenOpaqueWindowState.getAttrs() + : null; if (mStatusBar != null) { if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar @@ -2365,72 +2360,44 @@ public int finishAnimationLw() { if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; } else if (mTopFullscreenOpaqueWindowState != null) { - WindowManager.LayoutParams lp = - mTopFullscreenOpaqueWindowState.getAttrs(); - boolean hideStatusBar = - (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; - if (hideStatusBar || mShowStatBar) { - if (DEBUG_LAYOUT) Log.v(TAG, "Hiding status bar"); - if (mStatusBar.hideLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT; - - mHandler.post(new Runnable() { - @Override - public void run() { - try { - IStatusBarService statusbar = getStatusBarService(); - if (statusbar != null) { - statusbar.collapse(); - } - } catch (RemoteException ex) { - // re-acquire status bar service next time it is needed. - mStatusBarService = null; - } - }}); - } else if (DEBUG_LAYOUT) { - if (DEBUG_LAYOUT) Log.v(TAG, "Preventing status bar from hiding by policy"); - } + topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; + + if (topIsFullscreen) { if (mNaviShow && mNaviShowAll) { mNaviShowAll2 = false; - mHandler.post(new Runnable() { - @Override - public void run() { - try { - IStatusBarService statusbar = getStatusBarService(); - if (statusbar != null) { - statusbar.showNaviBar(false); + shouldShowNavbar(false); + } + if (mStatusBarCanHide || mShowStatBar) { + if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar"); + if (mStatusBar.hideLw(true)) { + changes |= FINISH_LAYOUT_REDO_LAYOUT; + + mHandler.post(new Runnable() { + @Override + public void run() { + if (mStatusBarService != null) { + try { + mStatusBarService.collapse(); + } catch (RemoteException ex) {} } - } catch (RemoteException ex) { - // re-acquire status bar service next time it is needed. - mStatusBarService = null; - } - }}); + }}); + } + } else { + if (DEBUG_LAYOUT) Log.v(TAG, "Preventing status bar from hiding by policy"); } } else { - if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); - if (mStatusBar.showLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT; - } + if (DEBUG_LAYOUT) Log.v(TAG, "** SHOWING status bar"); if (mNaviShow && mNaviShowAll) { - mHandler.postDelayed(mHidesNavbar, 50); - mHandler.post(new Runnable() { - @Override - public void run() { - try { - IStatusBarService statusbar = getStatusBarService(); - if (statusbar != null) { - statusbar.showNaviBar(true); - } - } catch (RemoteException ex) { - // re-acquire status bar service next time it is needed. - mStatusBarService = null; - } - }}); + mHandler.post(mHidesNavbar); + shouldShowNavbar(true); } + if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; } } } + mTopIsFullscreen = topIsFullscreen; + // Hide the key guard if a visible window explicitly specifies that it wants to be displayed // when the screen is locked if (mKeyguard != null) { @@ -2477,23 +2444,29 @@ public boolean allowAppAnimationsLw() { // behind it. return false; } - if (mStatusBar != null && mStatusBar.isVisibleLw()) { - Rect rect = new Rect(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 (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()) { + Rect rect = new Rect(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; + } } } return true; @@ -3795,6 +3768,16 @@ public boolean allowKeyRepeat() { return mScreenOnEarly; } + private void updateSystemUiservice() { + mHandler.post(new Runnable() { + public void run() { + if (mStatusBarService == null) { + mStatusBarService = IStatusBarService.Stub.asInterface( + ServiceManager.getService("statusbar")); + } + }}); + } + /* * mtwebster - Added functions for allowing adjustable haptic feedback in * certain global areas of phone diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index d723cb9f..c7eacd7e 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -9041,7 +9041,7 @@ private final void performLayoutAndPlaceSurfacesLockedInner( continue; } } else { - Slog.w(TAG, "Layout repeat skipped after too many iterations"); + //Slog.w(TAG, "Layout repeat skipped after too many iterations"); changes = 0; }