diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java index 3e2b9276fee9b..5ea73bde9f5c1 100644 --- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java @@ -101,6 +101,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final String TAG = "WindowManager"; static final boolean DEBUG = false; static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; + static final boolean DEBUG_LAYOUT = false; static final boolean SHOW_STARTING_ANIMATIONS = true; static final boolean SHOW_PROCESSES_ON_ALT_MENU = false; @@ -992,6 +993,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { // If the status bar is hidden, we don't want to cause // windows behind it to scroll. mDockTop = mContentTop = mCurTop = mStatusBar.getFrameLw().bottom; + if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mDockBottom=" + + mDockBottom + " mContentBottom=" + + mContentBottom + " mCurBottom=" + mCurBottom); } } } @@ -1152,11 +1156,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; } + if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle() + + ": sim=#" + Integer.toHexString(sim) + + " 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 + - ": pf=" + pf.toShortString() + " df=" + df.toShortString() + ": sim=#" + Integer.toHexString(sim) + + " pf=" + pf.toShortString() + " df=" + df.toShortString() + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); } } @@ -1176,6 +1186,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mCurBottom > top) { mCurBottom = top; } + if (DEBUG_LAYOUT) Log.v(TAG, "Input method: mDockBottom=" + + mDockBottom + " mContentBottom=" + + mContentBottom + " mCurBottom=" + mCurBottom); } } diff --git a/policy/com/android/internal/policy/impl/ShutdownThread.java b/policy/com/android/internal/policy/impl/ShutdownThread.java index 994b1d50bdf9c..c61d60b524266 100644 --- a/policy/com/android/internal/policy/impl/ShutdownThread.java +++ b/policy/com/android/internal/policy/impl/ShutdownThread.java @@ -19,6 +19,8 @@ package com.android.internal.policy.impl; import android.app.ProgressDialog; import android.app.AlertDialog; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.IBluetoothDevice; import android.content.Context; import android.content.DialogInterface; import android.os.RemoteException; @@ -35,9 +37,12 @@ final class ShutdownThread extends Thread { private static final String TAG = "ShutdownThread"; private static final int MAX_NUM_PHONE_STATE_READS = 16; private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500; - private static final ITelephony sPhone = + private static final ITelephony sPhone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone")); - + private static final IBluetoothDevice sBluetooth = + IBluetoothDevice.Stub.asInterface(ServiceManager.getService(Context.BLUETOOTH_SERVICE)); + + // state tracking private static Object sIsStartedGuard = new Object(); private static boolean sIsStarted = false; @@ -62,7 +67,7 @@ final class ShutdownThread extends Thread { return; } } - + Log.d(TAG, "Notifying thread to start radio shutdown"); if (confirm) { @@ -106,31 +111,61 @@ final class ShutdownThread extends Thread { sInstance.start(); } - /** - * Makes sure we handle the shutdown gracefully. - * Shuts off power regardless of radio state if the alloted time has passed. + /** + * Makes sure we handle the shutdown gracefully. + * Shuts off power regardless of radio and bluetooth state if the alloted time has passed. */ public void run() { - //shutdown the phone radio if possible. - if (sPhone != null) { - try { - //shutdown radio - sPhone.setRadio(false); + boolean bluetoothOff; + boolean radioOff; - for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++){ - // poll radio up to 64 times, with a 0.5 sec delay between each call, - // totaling 32 sec. - if (!sPhone.isRadioOn()) { - Log.d(TAG, "Radio shutdown complete."); - break; - } - SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC); - } - } catch (RemoteException ex) { - Log.e(TAG, "RemoteException caught from failed radio shutdown.", ex); + try { + bluetoothOff = sBluetooth == null || + sBluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF; + if (!bluetoothOff) { + sBluetooth.disable(false); // disable but don't persist new state } + } catch (RemoteException ex) { + Log.e(TAG, "RemoteException during bluetooth shutdown", ex); + bluetoothOff = true; } - + + try { + radioOff = sPhone == null || !sPhone.isRadioOn(); + if (!radioOff) { + sPhone.setRadio(false); + } + } catch (RemoteException ex) { + Log.e(TAG, "RemoteException during radio shutdown", ex); + radioOff = true; + } + + // Wait a max of 32 seconds for clean shutdown + for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) { + if (!bluetoothOff) { + try { + bluetoothOff = + sBluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF; + } catch (RemoteException ex) { + Log.e(TAG, "RemoteException during bluetooth shutdown", ex); + bluetoothOff = true; + } + } + if (!radioOff) { + try { + radioOff = !sPhone.isRadioOn(); + } catch (RemoteException ex) { + Log.e(TAG, "RemoteException during radio shutdown", ex); + radioOff = true; + } + } + if (radioOff && bluetoothOff) { + Log.d(TAG, "Radio and Bluetooth shutdown complete."); + break; + } + SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC); + } + //shutdown power Log.d(TAG, "Shutting down power."); Power.shutdown();