Add brightness dialog to SystemUI

Change-Id: If31406c9144bb2583876f08dd54b259d1dfa3601
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 434946c..fb0b896 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2489,6 +2489,14 @@
     public static final String ACTION_QUICK_CLOCK =
             "android.intent.action.QUICK_CLOCK";
 
+    /**
+     * Broadcast Action: This is broadcast when a user action should request the
+     * brightness setting dialog.
+     * @hide
+     */
+    public static final String ACTION_SHOW_BRIGHTNESS_DIALOG =
+            "android.intent.action.SHOW_BRIGHTNESS_DIALOG";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent categories (see addCategory()).
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index f7b1d78..b547d99 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -27,7 +27,7 @@
         android:paddingRight="10dp"
         android:src="@drawable/ic_qs_brightness_auto_off"
         />
-    <com.android.systemui.statusbar.policy.ToggleSlider
+    <com.android.systemui.settings.ToggleSlider
         android:id="@+id/brightness_slider"
         android:layout_width="0dp"
         android:layout_height="40dp"
diff --git a/packages/SystemUI/res/layout/system_bar_settings_view.xml b/packages/SystemUI/res/layout/system_bar_settings_view.xml
index 3e959d5..4987dd9 100644
--- a/packages/SystemUI/res/layout/system_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout/system_bar_settings_view.xml
@@ -100,7 +100,7 @@
                 style="@style/SystemBarPanelSettingsIcon"
                 android:src="@drawable/ic_sysbar_brightness"
                 />
-        <com.android.systemui.statusbar.policy.ToggleSlider
+        <com.android.systemui.settings.ToggleSlider
                 android:id="@+id/brightness"
                 android:layout_width="0dp"
                 android:layout_height="fill_parent"
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 427fe91..1f3e942 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -44,6 +44,7 @@
             0, // system bar or status bar, filled in below.
             com.android.systemui.power.PowerUI.class,
             com.android.systemui.media.RingtonePlayer.class,
+            com.android.systemui.settings.SettingsUI.class,
         };
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
new file mode 100644
index 0000000..fdeead1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+
+import java.util.ArrayList;
+
+public class BrightnessController implements ToggleSlider.Listener {
+    private static final String TAG = "StatusBar.BrightnessController";
+
+    private final int mMinimumBacklight;
+    private final int mMaximumBacklight;
+
+    private final Context mContext;
+    private final ImageView mIcon;
+    private final ToggleSlider mControl;
+    private final boolean mAutomaticAvailable;
+    private final IPowerManager mPower;
+    private final CurrentUserTracker mUserTracker;
+    private final Handler mHandler;
+    private final BrightnessObserver mBrightnessObserver;
+
+    private ArrayList<BrightnessStateChangeCallback> mChangeCallbacks =
+            new ArrayList<BrightnessStateChangeCallback>();
+
+    public interface BrightnessStateChangeCallback {
+        public void onBrightnessLevelChanged();
+    }
+
+    /** ContentObserver to watch brightness **/
+    private class BrightnessObserver extends ContentObserver {
+
+        private final Uri BRIGHTNESS_MODE_URI =
+                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE);
+        private final Uri BRIGHTNESS_URI =
+                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
+
+        public BrightnessObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onChange(selfChange, null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (selfChange) return;
+            if (BRIGHTNESS_MODE_URI.equals(uri)) {
+                updateMode();
+            } else if (BRIGHTNESS_URI.equals(uri)) {
+                updateSlider();
+            } else {
+                updateMode();
+                updateSlider();
+            }
+            for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
+                cb.onBrightnessLevelChanged();
+            }
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(
+                    BRIGHTNESS_MODE_URI,
+                    false, this, UserHandle.USER_ALL);
+            cr.registerContentObserver(
+                    BRIGHTNESS_URI,
+                    false, this, UserHandle.USER_ALL);
+        }
+
+        public void stopObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+        }
+
+    }
+
+    public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
+        mContext = context;
+        mIcon = icon;
+        mControl = control;
+        mHandler = new Handler();
+        mUserTracker = new CurrentUserTracker(mContext) {
+            @Override
+            public void onUserSwitched(int newUserId) {
+                updateMode();
+                updateSlider();
+            }
+        };
+        mBrightnessObserver = new BrightnessObserver(mHandler);
+        mBrightnessObserver.startObserving();
+
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mMinimumBacklight = pm.getMinimumScreenBrightnessSetting();
+        mMaximumBacklight = pm.getMaximumScreenBrightnessSetting();
+
+        mAutomaticAvailable = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_automatic_brightness_available);
+        mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
+
+        // Update the slider and mode before attaching the listener so we don't receive the
+        // onChanged notifications for the initial values.
+        updateMode();
+        updateSlider();
+
+        control.setOnChangedListener(this);
+    }
+
+    public void addStateChangedCallback(BrightnessStateChangeCallback cb) {
+        mChangeCallbacks.add(cb);
+    }
+
+    public boolean removeStateChangedCallback(BrightnessStateChangeCallback cb) {
+        return mChangeCallbacks.remove(cb);
+    }
+
+    @Override
+    public void onInit(ToggleSlider control) {
+        // Do nothing
+    }
+
+    /** Unregister all call backs, both to and from the controller */
+    public void unregisterCallbacks() {
+        mBrightnessObserver.stopObserving();
+        mChangeCallbacks.clear();
+        mUserTracker.stopTracking();
+    }
+
+    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) {
+        setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
+                : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+        updateIcon(automatic);
+        if (!automatic) {
+            final int val = value + mMinimumBacklight;
+            setBrightness(val);
+            if (!tracking) {
+                AsyncTask.execute(new Runnable() {
+                        public void run() {
+                            Settings.System.putIntForUser(mContext.getContentResolver(),
+                                    Settings.System.SCREEN_BRIGHTNESS, val,
+                                    UserHandle.USER_CURRENT);
+                        }
+                    });
+            }
+        }
+
+        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
+            cb.onBrightnessLevelChanged();
+        }
+    }
+
+    private void setMode(int mode) {
+        Settings.System.putIntForUser(mContext.getContentResolver(),
+                Settings.System.SCREEN_BRIGHTNESS_MODE, mode,
+                mUserTracker.getCurrentUserId());
+    }
+
+    private void setBrightness(int brightness) {
+        try {
+            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    private void updateIcon(boolean automatic) {
+        if (mIcon != null) {
+            mIcon.setImageResource(automatic ?
+                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
+                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
+        }
+    }
+
+    /** Fetch the brightness mode from the system settings and update the icon */
+    private void updateMode() {
+        if (mAutomaticAvailable) {
+            int automatic;
+            try {
+                automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS_MODE,
+                        UserHandle.USER_CURRENT);
+            } catch (SettingNotFoundException snfe) {
+                automatic = 0;
+            }
+            mControl.setChecked(automatic != 0);
+            updateIcon(automatic != 0);
+        } else {
+            mControl.setChecked(false);
+            updateIcon(false /*automatic*/);
+        }
+    }
+
+    /** Fetch the brightness from the system settings and update the slider */
+    private void updateSlider() {
+        int value;
+        try {
+            value = Settings.System.getIntForUser(mContext.getContentResolver(),
+                    Settings.System.SCREEN_BRIGHTNESS,
+                    UserHandle.USER_CURRENT);
+        } catch (SettingNotFoundException ex) {
+            value = mMaximumBacklight;
+        }
+        mControl.setMax(mMaximumBacklight - mMinimumBacklight);
+        mControl.setValue(value - mMinimumBacklight);
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
new file mode 100644
index 0000000..1b05084
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import com.android.systemui.R;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import java.lang.Runnable;
+
+/** A dialog that provides controls for adjusting the screen brightness. */
+public class BrightnessDialog extends Dialog implements
+        BrightnessController.BrightnessStateChangeCallback {
+
+    private static final String TAG = "BrightnessDialog";
+    private static final boolean DEBUG = false;
+
+    protected Handler mHandler = new Handler();
+
+    private BrightnessController mBrightnessController;
+    private final int mBrightnessDialogLongTimeout;
+    private final int mBrightnessDialogShortTimeout;
+
+    private final Runnable mDismissDialogRunnable = new Runnable() {
+        public void run() {
+            if (BrightnessDialog.this.isShowing()) {
+                BrightnessDialog.this.dismiss();
+            }
+        };
+    };
+
+
+    public BrightnessDialog(Context ctx) {
+        super(ctx);
+        Resources r = ctx.getResources();
+        mBrightnessDialogLongTimeout =
+                r.getInteger(R.integer.quick_settings_brightness_dialog_long_timeout);
+        mBrightnessDialogShortTimeout =
+                r.getInteger(R.integer.quick_settings_brightness_dialog_short_timeout);
+    }
+
+
+    /**
+     * Create the brightness dialog and any resources that are used for the
+     * entire lifetime of the dialog.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Window window = getWindow();
+        window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        window.getAttributes().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        window.requestFeature(Window.FEATURE_NO_TITLE);
+
+        setContentView(R.layout.quick_settings_brightness_dialog);
+        setCanceledOnTouchOutside(true);
+    }
+
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mBrightnessController = new BrightnessController(getContext(),
+                (ImageView) findViewById(R.id.brightness_icon),
+                (ToggleSlider) findViewById(R.id.brightness_slider));
+        dismissBrightnessDialog(mBrightnessDialogLongTimeout);
+        mBrightnessController.addStateChangedCallback(this);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mBrightnessController.unregisterCallbacks();
+        removeAllBrightnessDialogCallbacks();
+    }
+
+    public void onBrightnessLevelChanged() {
+        dismissBrightnessDialog(mBrightnessDialogShortTimeout);
+    }
+
+    private void dismissBrightnessDialog(int timeout) {
+        removeAllBrightnessDialogCallbacks();
+        mHandler.postDelayed(mDismissDialogRunnable, timeout);
+    }
+
+    private void removeAllBrightnessDialogCallbacks() {
+        mHandler.removeCallbacks(mDismissDialogRunnable);
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
new file mode 100644
index 0000000..122f81e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public abstract class CurrentUserTracker extends BroadcastReceiver {
+
+    private Context mContext;
+    private int mCurrentUserId;
+
+    public CurrentUserTracker(Context context) {
+        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
+        context.registerReceiver(this, filter);
+        mCurrentUserId = ActivityManager.getCurrentUser();
+        mContext = context;
+    }
+
+    public int getCurrentUserId() {
+        return mCurrentUserId;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+            int oldUserId = mCurrentUserId;
+            mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+            if (oldUserId != mCurrentUserId) {
+                onUserSwitched(mCurrentUserId);
+            }
+        }
+    }
+
+    public void stopTracking() {
+        mContext.unregisterReceiver(this);
+    }
+
+    public abstract void onUserSwitched(int newUserId);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java b/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
new file mode 100644
index 0000000..f65123a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.util.Slog;
+
+import com.android.systemui.SystemUI;
+
+public class SettingsUI extends SystemUI {
+    private static final String TAG = "SettingsUI";
+    private static final boolean DEBUG = false;
+
+    private final Handler mHandler = new Handler();
+    private BrightnessDialog mBrightnessDialog;
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG)) {
+                if (DEBUG) Slog.d(TAG, "showing brightness dialog");
+
+                if (mBrightnessDialog == null) {
+                    mBrightnessDialog = new BrightnessDialog(mContext);
+                    mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                        @Override
+                        public void onDismiss(DialogInterface dialog) {
+                            mBrightnessDialog = null;
+                        }
+                    });
+                }
+
+                if (!mBrightnessDialog.isShowing()) {
+                    mBrightnessDialog.show();
+                }
+
+            } else {
+                Slog.w(TAG, "unknown intent: " + intent);
+            }
+        }
+    };
+
+    public void start() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
+        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.print("mBrightnessDialog=");
+        pw.println(mBrightnessDialog == null ? "null" : mBrightnessDialog.toString());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
rename to packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
index 39f8fcc..c7c361c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2013 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.settings;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -31,7 +31,7 @@
 
 import com.android.systemui.R;
 
-public class ToggleSlider extends RelativeLayout 
+public class ToggleSlider extends RelativeLayout
         implements CompoundButton.OnCheckedChangeListener, SeekBar.OnSeekBarChangeListener {
     private static final String TAG = "StatusBar.ToggleSlider";
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 4ff3862..60e22c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -27,10 +27,8 @@
 import com.android.systemui.statusbar.phone.QuickSettingsModel.WifiState;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
-import com.android.systemui.statusbar.policy.BrightnessController;
 import com.android.systemui.statusbar.policy.LocationController;
 import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.ToggleSlider;
 
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
@@ -70,7 +68,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.widget.ImageView;
@@ -100,13 +97,8 @@
     private BluetoothAdapter mBluetoothAdapter;
     private WifiManager mWifiManager;
 
-    private BrightnessController mBrightnessController;
     private BluetoothController mBluetoothController;
 
-    private Dialog mBrightnessDialog;
-    private int mBrightnessDialogShortTimeout;
-    private int mBrightnessDialogLongTimeout;
-
     private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask;
 
     private LevelListDrawable mBatteryLevels;
@@ -146,10 +138,6 @@
         mBatteryLevels = (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery);
         mChargingBatteryLevels =
                 (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery_charging);
-        mBrightnessDialogLongTimeout =
-                r.getInteger(R.integer.quick_settings_brightness_dialog_long_timeout);
-        mBrightnessDialogShortTimeout =
-                r.getInteger(R.integer.quick_settings_brightness_dialog_short_timeout);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
@@ -352,7 +340,6 @@
                 TextView tv = (TextView) view.findViewById(R.id.brightness_textview);
                 tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
                 tv.setText(state.label);
-                dismissBrightnessDialog(mBrightnessDialogShortTimeout);
             }
         });
         parent.addView(brightnessTile);
@@ -776,72 +763,12 @@
         }
         ((QuickSettingsContainerView)mContainerView).updateResources();
         mContainerView.requestLayout();
-
-        // Reset the dialog
-        boolean isBrightnessDialogVisible = false;
-        if (mBrightnessDialog != null) {
-            removeAllBrightnessDialogCallbacks();
-
-            isBrightnessDialogVisible = mBrightnessDialog.isShowing();
-            mBrightnessDialog.dismiss();
-        }
-        mBrightnessDialog = null;
-        if (isBrightnessDialogVisible) {
-            showBrightnessDialog();
-        }
     }
 
-    private void removeAllBrightnessDialogCallbacks() {
-        mHandler.removeCallbacks(mDismissBrightnessDialogRunnable);
-    }
-
-    private Runnable mDismissBrightnessDialogRunnable = new Runnable() {
-        public void run() {
-            if (mBrightnessDialog != null && mBrightnessDialog.isShowing()) {
-                mBrightnessDialog.dismiss();
-            }
-            removeAllBrightnessDialogCallbacks();
-        };
-    };
 
     private void showBrightnessDialog() {
-        if (mBrightnessDialog == null) {
-            mBrightnessDialog = new Dialog(mContext);
-            mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
-            mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog);
-            mBrightnessDialog.setCanceledOnTouchOutside(true);
-
-            mBrightnessController = new BrightnessController(mContext,
-                    (ImageView) mBrightnessDialog.findViewById(R.id.brightness_icon),
-                    (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
-            mBrightnessController.addStateChangedCallback(mModel);
-            mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
-                @Override
-                public void onDismiss(DialogInterface dialog) {
-                    mBrightnessController = null;
-                }
-            });
-
-            mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-            mBrightnessDialog.getWindow().getAttributes().privateFlags |=
-                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-        }
-        if (!mBrightnessDialog.isShowing()) {
-            try {
-                WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
-            } catch (RemoteException e) {
-            }
-            mBrightnessDialog.show();
-            dismissBrightnessDialog(mBrightnessDialogLongTimeout);
-        }
-    }
-
-    private void dismissBrightnessDialog(int timeout) {
-        removeAllBrightnessDialogCallbacks();
-        if (mBrightnessDialog != null) {
-            mHandler.postDelayed(mDismissBrightnessDialogRunnable, timeout);
-        }
+        Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
+        mContext.sendBroadcast(intent);
     }
 
     private void showBugreportDialog() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 1037137..435ea4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -42,9 +42,9 @@
 
 import com.android.internal.view.RotationPolicy;
 import com.android.systemui.R;
+import com.android.systemui.settings.CurrentUserTracker;
+import com.android.systemui.settings.BrightnessController.BrightnessStateChangeCallback;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
-import com.android.systemui.statusbar.policy.BrightnessController.BrightnessStateChangeCallback;
-import com.android.systemui.statusbar.policy.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
 
@@ -239,10 +239,12 @@
         mContext = context;
         mHandler = new Handler();
         mUserTracker = new CurrentUserTracker(mContext) {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                super.onReceive(context, intent);
-                onUserSwitched();
+            public void onUserSwitched(int newUserId) {
+                mBrightnessObserver.startObserving();
+                onRotationLockChanged();
+                onBrightnessLevelChanged();
+                onNextAlarmChanged();
+                onBugreportChanged();
             }
         };
 
@@ -705,13 +707,4 @@
     void refreshBrightnessTile() {
         onBrightnessLevelChanged();
     }
-
-    // User switch: need to update visuals of all tiles known to have per-user state
-    void onUserSwitched() {
-        mBrightnessObserver.startObserving();
-        onRotationLockChanged();
-        onBrightnessLevelChanged();
-        onNextAlarmChanged();
-        onBugreportChanged();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
deleted file mode 100644
index e18b28a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.statusbar.policy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.AsyncTask;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.util.Slog;
-import android.view.IWindowManager;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-
-import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
-
-import java.util.ArrayList;
-
-public class BrightnessController implements ToggleSlider.Listener {
-    private static final String TAG = "StatusBar.BrightnessController";
-
-    private final int mMinimumBacklight;
-    private final int mMaximumBacklight;
-
-    private final Context mContext;
-    private final ImageView mIcon;
-    private final ToggleSlider mControl;
-    private final boolean mAutomaticAvailable;
-    private final IPowerManager mPower;
-    private final CurrentUserTracker mUserTracker;
-
-    private ArrayList<BrightnessStateChangeCallback> mChangeCallbacks =
-            new ArrayList<BrightnessStateChangeCallback>();
-
-    public interface BrightnessStateChangeCallback {
-        public void onBrightnessLevelChanged();
-    }
-
-    public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
-        mContext = context;
-        mIcon = icon;
-        mControl = control;
-        mUserTracker = new CurrentUserTracker(mContext);
-
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mMinimumBacklight = pm.getMinimumScreenBrightnessSetting();
-        mMaximumBacklight = pm.getMaximumScreenBrightnessSetting();
-
-        mAutomaticAvailable = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_automatic_brightness_available);
-        mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
-
-        control.setOnChangedListener(this);
-    }
-
-    public void addStateChangedCallback(BrightnessStateChangeCallback cb) {
-        mChangeCallbacks.add(cb);
-    }
-
-    @Override
-    public void onInit(ToggleSlider control) {
-        if (mAutomaticAvailable) {
-            int automatic;
-            try {
-                automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
-                        Settings.System.SCREEN_BRIGHTNESS_MODE,
-                        mUserTracker.getCurrentUserId());
-            } catch (SettingNotFoundException snfe) {
-                automatic = 0;
-            }
-            control.setChecked(automatic != 0);
-            updateIcon(automatic != 0);
-        } else {
-            control.setChecked(false);
-            updateIcon(false /*automatic*/);
-            //control.hideToggle();
-        }
-        
-        int value;
-        try {
-            value = Settings.System.getIntForUser(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS,
-                    mUserTracker.getCurrentUserId());
-        } catch (SettingNotFoundException ex) {
-            value = mMaximumBacklight;
-        }
-
-        control.setMax(mMaximumBacklight - mMinimumBacklight);
-        control.setValue(value - mMinimumBacklight);
-    }
-
-    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) {
-        setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
-                : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
-        updateIcon(automatic);
-        if (!automatic) {
-            final int val = value + mMinimumBacklight;
-            setBrightness(val);
-            if (!tracking) {
-                AsyncTask.execute(new Runnable() {
-                        public void run() {
-                            Settings.System.putIntForUser(mContext.getContentResolver(),
-                                    Settings.System.SCREEN_BRIGHTNESS, val,
-                                    mUserTracker.getCurrentUserId());
-                        }
-                    });
-            }
-        }
-
-        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
-            cb.onBrightnessLevelChanged();
-        }
-    }
-
-    private void setMode(int mode) {
-        Settings.System.putIntForUser(mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_MODE, mode,
-                mUserTracker.getCurrentUserId());
-    }
-    
-    private void setBrightness(int brightness) {
-        try {
-            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
-        } catch (RemoteException ex) {
-        }        
-    }
-
-    private void updateIcon(boolean automatic) {
-        if (mIcon != null) {
-            mIcon.setImageResource(automatic ?
-                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
-                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
index 6fee4323..70f9ac8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
@@ -27,6 +27,8 @@
 import android.view.IWindowManager;
 import android.widget.CompoundButton;
 
+import com.android.systemui.settings.ToggleSlider;
+
 public class VolumeController implements ToggleSlider.Listener {
     private static final String TAG = "StatusBar.VolumeController";
     private static final int STREAM = AudioManager.STREAM_NOTIFICATION;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
index f71842e..e0dcbcd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
@@ -30,11 +30,11 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.settings.BrightnessController;
+import com.android.systemui.settings.ToggleSlider;
 import com.android.systemui.statusbar.policy.AirplaneModeController;
 import com.android.systemui.statusbar.policy.AutoRotateController;
-import com.android.systemui.statusbar.policy.BrightnessController;
 import com.android.systemui.statusbar.policy.DoNotDisturbController;
-import com.android.systemui.statusbar.policy.ToggleSlider;
 import com.android.systemui.statusbar.policy.VolumeController;
 
 public class SettingsView extends LinearLayout implements View.OnClickListener {