SettingsAppWidgetProvider.java revision 94ea6e21c337225f01856b65318d34fbaa044ac4
103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff/*
203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Copyright (C) 2009 The Android Open Source Project
303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff *
403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Licensed under the Apache License, Version 2.0 (the "License");
503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * you may not use this file except in compliance with the License.
603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * You may obtain a copy of the License at
703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff *
803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff *      http://www.apache.org/licenses/LICENSE-2.0
903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff *
1003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Unless required by applicable law or agreed to in writing, software
1103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * distributed under the License is distributed on an "AS IS" BASIS,
1203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * See the License for the specific language governing permissions and
1403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * limitations under the License.
1503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */
1603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
1703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffpackage com.android.settings.widget;
1803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
1903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.app.PendingIntent;
2003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.appwidget.AppWidgetManager;
2103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.appwidget.AppWidgetProvider;
22d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport android.bluetooth.BluetoothAdapter;
2303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.ComponentName;
2403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.ContentResolver;
2503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.Context;
2603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.IContentService;
2703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.Intent;
2803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.pm.PackageManager;
2903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.location.LocationManager;
3003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.net.ConnectivityManager;
3103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.net.Uri;
3203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.net.wifi.WifiManager;
33cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwoodimport android.os.IPowerManager;
3403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.os.RemoteException;
3503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.os.ServiceManager;
3603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.provider.Settings;
3703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.util.Log;
3803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.widget.RemoteViews;
39e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriffimport android.widget.Toast;
4003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport com.android.settings.R;
4103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport com.android.settings.bluetooth.LocalBluetoothManager;
4203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
4303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff/**
4403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Provides control of power-related settings from a widget.
4503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */
4603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffpublic class SettingsAppWidgetProvider extends AppWidgetProvider {
4703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    static final String TAG = "SettingsAppWidgetProvider";
4803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
4903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    static final ComponentName THIS_APPWIDGET =
5003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            new ComponentName("com.android.settings",
5103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                    "com.android.settings.widget.SettingsAppWidgetProvider");
5203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
5394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static LocalBluetoothManager sLocalBluetoothManager = null;
5403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
5503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int BUTTON_WIFI = 0;
5603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int BUTTON_BRIGHTNESS = 1;
5703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int BUTTON_SYNC = 2;
5803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int BUTTON_GPS = 3;
5903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int BUTTON_BLUETOOTH = 4;
6003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
6194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    // This widget keeps track of two sets of states:
6294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    // "3-state": STATE_DISABLED, STATE_ENABLED, STATE_INTERMEDIATE
6394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    // "5-state": STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON, STATE_TURNING_OFF, STATE_UNKNOWN
6403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int STATE_DISABLED = 0;
6503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int STATE_ENABLED = 1;
6694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final int STATE_TURNING_ON = 2;
6794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final int STATE_TURNING_OFF = 3;
6894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final int STATE_UNKNOWN = 4;
6994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final int STATE_INTERMEDIATE = 5;
7094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
7103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
7203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
7303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Minimum and maximum brightnesses.  Don't go to 0 since that makes the display unusable
7403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
7503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
7603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
7703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f);
7803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
7994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final StateTracker sWifiState = new WifiStateTracker();
8094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final StateTracker sBluetoothState = new BluetoothStateTracker();
8194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
8294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    /**
8394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * The state machine for Wifi and Bluetooth toggling, tracking
8494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * reality versus the user's intent.
8594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     *
8694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * This is necessary because reality moves relatively slowly
8794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * (turning on & off radio drivers), compared to user's
8894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * expectations.
8994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     */
9094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private abstract static class StateTracker {
9194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        // Is the state in the process of changing?
9294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private boolean mInTransition = false;
9394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private Boolean mActualState = null;  // initially not set
9494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private Boolean mIntendedState = null;  // initially not set
9594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
9694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        // Did a toggle request arrive while a state update was
9794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        // already in-flight?  If so, the mIntendedState needs to be
9894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        // requested when the other one is done, unless we happened to
9994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        // arrive at that state already.
10094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private boolean mDeferredStateChangeRequestNeeded = false;
10194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
10294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
10394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * User pressed a button to change the state.  Something
10494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * should immediately appear to the user afterwards, even if
10594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * we effectively do nothing.  Their press must be heard.
10694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
10794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public final void toggleState(Context context) {
10894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            int currentState = getTriState(context);
10994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            boolean newState = false;
11094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (currentState) {
11194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_ENABLED:
11294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    newState = false;
11394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
11494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_DISABLED:
11594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    newState = true;
11694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
11794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_INTERMEDIATE:
11894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    if (mIntendedState != null) {
11994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                        newState = !mIntendedState;
12094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    }
12194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
12294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
12394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            mIntendedState = newState;
12494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (mInTransition) {
12594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // We don't send off a transition request if we're
12694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // already transitioning.  Makes our state tracking
12794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // easier, and is probably nicer on lower levels.
12894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // (even though they should be able to take it...)
12994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                mDeferredStateChangeRequestNeeded = true;
13094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            } else {
13194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                mInTransition = true;
13294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                boolean showToast = newState;  // only show Toast on the up transition
13394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                requestStateChange(context, newState, showToast);
13494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
13594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
13694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
13794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
13894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Update internal state from a broadcast state change.
13994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
14094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public abstract void onActualStateChange(Context context, Intent intent);
14194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
14294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
14394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Sets the value that we're now in.  To be called from onActualStateChange.
14494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         *
14594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * @param newState one of STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON,
14694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         *                 STATE_TURNING_OFF, STATE_UNKNOWN
14794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
14894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        protected final void setCurrentState(Context context, int newState) {
14994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            boolean wasInTransition = mInTransition;
15094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (newState) {
15194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_DISABLED:
15294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mInTransition = false;
15394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mActualState = false;
15494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
15594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_ENABLED:
15694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mInTransition = false;
15794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mActualState = true;
15894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
15994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_TURNING_ON:
16094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mInTransition = true;
16194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mActualState = false;
16294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
16394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_TURNING_OFF:
16494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mInTransition = true;
16594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mActualState = true;
16694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    break;
16794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
16894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
16994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (wasInTransition && !mInTransition) {
17094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (mDeferredStateChangeRequestNeeded) {
17194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    Log.v(TAG, "processing deferred state change");
17294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    if (mActualState != null && mIntendedState != null &&
17394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                        mIntendedState.equals(mActualState)) {
17494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                        Log.v(TAG, "... but intended state matches, so no changes.");
17594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    } else if (mIntendedState != null) {
17694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                        mInTransition = true;
17794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                        requestStateChange(context, mIntendedState, false /* no toast */);
17894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    }
17994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    mDeferredStateChangeRequestNeeded = false;
18094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
18194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
18294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
18394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
18494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
18594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
18694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * If we're in a transition mode, this returns true if we're
18794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * transitioning towards being enabled.
18894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
18994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public final boolean isTurningOn() {
19094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            return mIntendedState != null && mIntendedState;
19194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
19294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
19394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
19494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Returns simplified 3-state value from underlying 5-state.
19594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         *
19694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * @param context
19794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE
19894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
19994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public final int getTriState(Context context) {
20094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (getActualState(context)) {
20194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_DISABLED:
20294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_DISABLED;
20394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case STATE_ENABLED:
20494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_ENABLED;
20594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                default:
20694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_INTERMEDIATE;
20794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
20894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
20994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
21094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
21194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Gets underlying actual state.
21294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         *
21394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * @param context
21494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * @return STATE_ENABLED, STATE_DISABLED, STATE_ENABLING, STATE_DISABLING,
21594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         *         or or STATE_UNKNOWN.
21694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
21794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public abstract int getActualState(Context context);
21894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
21994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
22094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Actually make the desired change to the underlying radio
22194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * API.
22294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
22394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        protected abstract void requestStateChange(Context context,
22494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                                   boolean desiredState, boolean withToast);
22594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    }
22694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
22794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    /**
22894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * Subclass of StateTracker to get/set Wifi state.
22994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     */
23094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final class WifiStateTracker extends StateTracker {
23194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
23294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public int getActualState(Context context) {
23394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
23494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (wifiManager != null) {
23594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return wifiStateToFiveState(wifiManager.getWifiState());
23694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
23794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            return STATE_UNKNOWN;
23894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
23994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
24094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
24194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        protected void requestStateChange(Context context,
24294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                          boolean desiredState, boolean withToast) {
24394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
24494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (wifiManager == null) {
24594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                Log.d(TAG, "No wifiManager.");
24694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
24794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
24894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (withToast) {
24994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show();
25094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
25194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            wifiManager.setWifiEnabled(desiredState);
25294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
25394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
25494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
25594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public void onActualStateChange(Context context, Intent intent) {
25694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
25794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
25894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
25994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
26094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            setCurrentState(context, wifiStateToFiveState(wifiState));
26194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
26294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
26394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
26494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Converts WifiManager's state values into our
26594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Wifi/Bluetooth-common state values.
26694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
26794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private static int wifiStateToFiveState(int wifiState) {
26894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (wifiState) {
26994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_DISABLED:
27094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_DISABLED;
27194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_ENABLED:
27294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_ENABLED;
27394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_DISABLING:
27494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_OFF;
27594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_ENABLING:
27694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_ON;
27794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                default:
27894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_UNKNOWN;
27994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
28094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
28194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    }
28294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
28394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    /**
28494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * Subclass of StateTracker to get/set Bluetooth state.
28594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     */
28694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final class BluetoothStateTracker extends StateTracker {
28794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
28894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
28994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public int getActualState(Context context) {
29094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (sLocalBluetoothManager == null) {
29194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                sLocalBluetoothManager = LocalBluetoothManager.getInstance(context);
29294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (sLocalBluetoothManager == null) {
29394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_UNKNOWN;  // On emulator?
29494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
29594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
29694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            return bluetoothStateToFiveState(sLocalBluetoothManager.getBluetoothState());
29794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
29894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
29994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
30094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        protected void requestStateChange(Context context,
30194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                          boolean desiredState, boolean withToast) {
30294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (sLocalBluetoothManager == null) {
30394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                Log.d(TAG, "No LocalBluetoothManager");
30494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
30594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
30694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (withToast) {
30794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                Toast.makeText(context,
30894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                               R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show();
30994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
31094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            sLocalBluetoothManager.setBluetoothEnabled(desiredState);
31194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
31294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
31394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
31494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public void onActualStateChange(Context context, Intent intent) {
31594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
31694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
31794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
31894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
31994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            setCurrentState(context, bluetoothStateToFiveState(bluetoothState));
32094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
32194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
32294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
32394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Converts BluetoothAdapter's state values into our
32494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Wifi/Bluetooth-common state values.
32594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
32694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private static int bluetoothStateToFiveState(int bluetoothState) {
32794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (bluetoothState) {
32894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_OFF:
32994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_DISABLED;
33094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_ON:
33194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_ENABLED;
33294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_TURNING_ON:
33394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_ON;
33494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_TURNING_OFF:
33594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_OFF;
33694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                default:
33794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_UNKNOWN;
33894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
33994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
34094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    }
34194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
34294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
34303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
34403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
34503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            int[] appWidgetIds) {
34603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        // Update each requested appWidgetId
34703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        RemoteViews view = buildUpdate(context, -1);
34803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
34903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        for (int i = 0; i < appWidgetIds.length; i++) {
35003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            appWidgetManager.updateAppWidget(appWidgetIds[i], view);
35103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
35203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
35303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
35403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
35503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onEnabled(Context context) {
35603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        PackageManager pm = context.getPackageManager();
35703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        pm.setComponentEnabledSetting(
35803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                new ComponentName("com.android.settings", ".widget.SettingsAppWidgetProvider"),
35903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
36003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.DONT_KILL_APP);
36103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
36203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
36303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
36403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onDisabled(Context context) {
36503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        Class clazz = com.android.settings.widget.SettingsAppWidgetProvider.class;
36603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        PackageManager pm = context.getPackageManager();
36703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        pm.setComponentEnabledSetting(
36803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                new ComponentName("com.android.settings", ".widget.SettingsAppWidgetProvider"),
36903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
37003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.DONT_KILL_APP);
37103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
37203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
37303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
37403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Load image for given widget and build {@link RemoteViews} for it.
37503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
37603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    static RemoteViews buildUpdate(Context context, int appWidgetId) {
37703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        RemoteViews views = new RemoteViews(context.getPackageName(),
37803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                R.layout.widget);
37903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_wifi, getLaunchPendingIntent(context, appWidgetId,
38003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                BUTTON_WIFI));
38103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_brightness,
38203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context,
38303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        appWidgetId, BUTTON_BRIGHTNESS));
38403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_sync,
38503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context,
38603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        appWidgetId, BUTTON_SYNC));
38703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_gps,
38803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context, appWidgetId, BUTTON_GPS));
38903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_bluetooth,
39003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context,
39103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        appWidgetId, BUTTON_BLUETOOTH));
39203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
39303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        updateButtons(views, context);
39403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return views;
39503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
39603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
39703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
39803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Updates the widget when something changes, or when a button is pushed.
39903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
40003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
40103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
40203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public static void updateWidget(Context context) {
40303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        RemoteViews views = buildUpdate(context, -1);
40403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        // Update specific list of appWidgetIds if given, otherwise default to all
40503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        final AppWidgetManager gm = AppWidgetManager.getInstance(context);
40603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        gm.updateAppWidget(THIS_APPWIDGET, views);
40703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
40803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
40903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
41003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Updates the buttons based on the underlying states of wifi, etc.
41103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
41203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param views   The RemoteViews to update.
41303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
41403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
41503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static void updateButtons(RemoteViews views, Context context) {
41694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        switch (sWifiState.getTriState(context)) {
41703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_DISABLED:
41894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_wifi,
41994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_wifi_off);
42094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_wifi,
42194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_off_l);
42203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
42303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_ENABLED:
42494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_wifi,
42594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_wifi_on);
42694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_wifi,
42794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_on_l);
42803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
42903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_INTERMEDIATE:
43094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // In the transitional state, the bottom green bar
43194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // shows the tri-state (on, off, transitioning), but
43294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // the top dark-gray-or-bright-white logo shows the
43394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // user's intent.  This is much easier to see in
43494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // sunlight.
43594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (sWifiState.isTurningOn()) {
43694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_wifi,
43794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_wifi_on);
43894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_wifi,
43994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_mid_l);
44094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                } else {
44194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_wifi,
44294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_wifi_off);
44394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_wifi,
44494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_off_l);
44594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
44603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
44703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
4485c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        if (getBrightnessMode(context)) {
44994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.img_brightness,
45094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.ic_appwidget_settings_brightness_auto);
45194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.ind_brightness,
45294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.appwidget_settings_ind_on_r);
4535c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        } else if (getBrightness(context)) {
45494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.img_brightness,
45594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.ic_appwidget_settings_brightness_on);
45694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.ind_brightness,
45794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.appwidget_settings_ind_on_r);
45803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } else {
45994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.img_brightness,
46094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.ic_appwidget_settings_brightness_off);
46194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.ind_brightness,
46294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.appwidget_settings_ind_off_r);
46303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
464ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (getSync(context)) {
465c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_on);
466c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_sync, R.drawable.appwidget_settings_ind_on_c);
46703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } else {
468c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_off);
469c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_sync, R.drawable.appwidget_settings_ind_off_c);
47003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
47103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        if (getGpsState(context)) {
472c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_on);
473c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_on_c);
47403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } else {
475c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_off);
476c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_off_c);
47703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
47894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        switch (sBluetoothState.getTriState(context)) {
47903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_DISABLED:
48094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_bluetooth,
48194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_bluetooth_off);
48294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_bluetooth,
48394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_off_c);
48403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
48503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_ENABLED:
48694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_bluetooth,
48794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_bluetooth_on);
48894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_bluetooth,
48994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_on_c);
49003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
49103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_INTERMEDIATE:
49294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // In the transitional state, the bottom green bar
49394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // shows the tri-state (on, off, transitioning), but
49494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // the top dark-gray-or-bright-white logo shows the
49594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // user's intent.  This is much easier to see in
49694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // sunlight.
49794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (sBluetoothState.isTurningOn()) {
49894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_bluetooth,
49994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_bluetooth_on);
50094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_bluetooth,
50194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_mid_c);
50294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                } else {
50394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_bluetooth,
50494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_bluetooth_off);
50594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_bluetooth,
50694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_off_c);
50794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
50803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
50903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
51003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
51103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
51203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
51303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Creates PendingIntent to notify the widget of a button click.
51403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
51503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
51603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param appWidgetId
51703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return
51803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
519e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff    private static PendingIntent getLaunchPendingIntent(Context context, int appWidgetId,
520e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff            int buttonId) {
52103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        Intent launchIntent = new Intent();
52203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        launchIntent.setClass(context, SettingsAppWidgetProvider.class);
52303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        launchIntent.addCategory(Intent.CATEGORY_ALTERNATIVE);
52403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        launchIntent.setData(Uri.parse("custom:" + buttonId));
52503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        PendingIntent pi = PendingIntent.getBroadcast(context, 0 /* no requestCode */,
52603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                launchIntent, 0 /* no flags */);
52703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return pi;
52803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
52903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
53003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
53103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Receives and processes a button pressed intent or state change.
53203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
53303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
53403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param intent  Indicates the pressed button.
53503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
53603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
53703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onReceive(Context context, Intent intent) {
53803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        super.onReceive(context, intent);
53994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
54094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            sWifiState.onActualStateChange(context, intent);
54194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
54294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            sBluetoothState.onActualStateChange(context, intent);
54394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        } else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) {
54403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Uri data = intent.getData();
54503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            int buttonId = Integer.parseInt(data.getSchemeSpecificPart());
54603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            if (buttonId == BUTTON_WIFI) {
54794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                sWifiState.toggleState(context);
54803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_BRIGHTNESS) {
54903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                toggleBrightness(context);
55003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_SYNC) {
551ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh                toggleSync(context);
55203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_GPS) {
55303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                toggleGps(context);
55403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_BLUETOOTH) {
55594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                sBluetoothState.toggleState(context);
55603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            }
55703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
55894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
55903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        // State changes fall through
56003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        updateWidget(context);
56103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
56203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
56303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
56403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Gets the state of background data.
56503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
56603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
56703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return true if enabled
56803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
56903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static boolean getBackgroundDataState(Context context) {
570e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff        ConnectivityManager connManager =
571e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
57203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return connManager.getBackgroundDataSetting();
57303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
57403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
57503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
576ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * Gets the state of auto-sync.
577ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     *
578ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * @param context
579ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * @return true if enabled
580ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     */
581ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    private static boolean getSync(Context context) {
582ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean backgroundData = getBackgroundDataState(context);
583ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean sync = ContentResolver.getMasterSyncAutomatically();
584ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        return backgroundData && sync;
585ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    }
586ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
587ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    /**
588ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * Toggle auto-sync
58903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
59003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
59103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
592ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    private void toggleSync(Context context) {
593e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff        ConnectivityManager connManager =
594e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
595ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean backgroundData = getBackgroundDataState(context);
596ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean sync = ContentResolver.getMasterSyncAutomatically();
597ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
598ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // four cases to handle:
599ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // setting toggled from off to on:
600ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 1. background data was off, sync was off: turn on both
601ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (!backgroundData && !sync) {
602ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            connManager.setBackgroundDataSetting(true);
603ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            ContentResolver.setMasterSyncAutomatically(true);
604ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
605ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
606ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 2. background data was off, sync was on: turn on background data
607ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (!backgroundData && sync) {
608ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            connManager.setBackgroundDataSetting(true);
609ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
610ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
611ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 3. background data was on, sync was off: turn on sync
612ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (backgroundData && !sync) {
613ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            ContentResolver.setMasterSyncAutomatically(true);
614ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
615ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
616ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // setting toggled from on to off:
617ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 4. background data was on, sync was on: turn off sync
618ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (backgroundData && sync) {
619ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            ContentResolver.setMasterSyncAutomatically(false);
620ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
62103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
62203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
62303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
62403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Gets the state of GPS location.
62503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
62603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
62703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return true if enabled.
62803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
62903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static boolean getGpsState(Context context) {
63003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        ContentResolver resolver = context.getContentResolver();
63103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return Settings.Secure.isLocationProviderEnabled(resolver, LocationManager.GPS_PROVIDER);
63203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
63303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
63403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
63503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Toggles the state of GPS.
63603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
63703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
63803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
63903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private void toggleGps(Context context) {
64003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        ContentResolver resolver = context.getContentResolver();
64103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        boolean enabled = getGpsState(context);
642e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff        Settings.Secure.setLocationProviderEnabled(resolver, LocationManager.GPS_PROVIDER,
643e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff                !enabled);
64403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
64503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
64603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
64703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Gets state of brightness.
64803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
64903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
65003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return true if more than moderately bright.
65103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
65203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static boolean getBrightness(Context context) {
65303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        try {
654cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            IPowerManager power = IPowerManager.Stub.asInterface(
655cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood                    ServiceManager.getService("power"));
656cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            if (power != null) {
65703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                int brightness = Settings.System.getInt(context.getContentResolver(),
65803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        Settings.System.SCREEN_BRIGHTNESS);
65903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                return brightness > 100;
66003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            }
66103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } catch (Exception e) {
66203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Log.d(TAG, "getBrightness: " + e);
66303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
66403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return false;
66503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
66603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
66703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
6685c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     * Gets state of brightness mode.
6695c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     *
6705c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     * @param context
6715c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     * @return true if auto brightness is on.
6725c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     */
6735c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik    private static boolean getBrightnessMode(Context context) {
6745c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        try {
6755c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            IPowerManager power = IPowerManager.Stub.asInterface(
6765c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    ServiceManager.getService("power"));
6775c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            if (power != null) {
6785c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                int brightnessMode = Settings.System.getInt(context.getContentResolver(),
6795c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                        Settings.System.SCREEN_BRIGHTNESS_MODE);
6805c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
6815c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            }
6825c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        } catch (Exception e) {
6835c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            Log.d(TAG, "getBrightnessMode: " + e);
6845c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        }
6855c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        return false;
6865c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik    }
6875c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik
6885c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik    /**
68903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Increases or decreases the brightness.
69003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
69103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
69203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
69303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private void toggleBrightness(Context context) {
69403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        try {
695cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            IPowerManager power = IPowerManager.Stub.asInterface(
696cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood                    ServiceManager.getService("power"));
697cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            if (power != null) {
69803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                ContentResolver cr = context.getContentResolver();
69903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                int brightness = Settings.System.getInt(cr,
70003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        Settings.System.SCREEN_BRIGHTNESS);
7015c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
7025c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                //Only get brightness setting if available
7035c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                if (context.getResources().getBoolean(
7045c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                        com.android.internal.R.bool.config_automatic_brightness_available)) {
7055c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightnessMode = Settings.System.getInt(cr,
7065c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                            Settings.System.SCREEN_BRIGHTNESS_MODE);
7075c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                }
7085c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik
7095c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM
71003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                // Technically, not a toggle...
7115c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
7125c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightness = MINIMUM_BACKLIGHT;
7135c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
7145c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                } else if (brightness < DEFAULT_BACKLIGHT) {
71503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                    brightness = DEFAULT_BACKLIGHT;
71603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                } else if (brightness < MAXIMUM_BACKLIGHT) {
71703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                    brightness = MAXIMUM_BACKLIGHT;
71803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                } else {
7195c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
7205bc5cedc7ae2808ed487d90ff86caedc722021dbErik                    brightness = MINIMUM_BACKLIGHT;
72103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                }
7225c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik
723c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                if (context.getResources().getBoolean(
724c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                        com.android.internal.R.bool.config_automatic_brightness_available)) {
7255c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    // Set screen brightness mode (automatic or manual)
726c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                    Settings.System.putInt(context.getContentResolver(),
727c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                            Settings.System.SCREEN_BRIGHTNESS_MODE,
7285c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                            brightnessMode);
7295bc5cedc7ae2808ed487d90ff86caedc722021dbErik                } else {
7305bc5cedc7ae2808ed487d90ff86caedc722021dbErik                    // Make sure we set the brightness if automatic mode isn't available
7315bc5cedc7ae2808ed487d90ff86caedc722021dbErik                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
7325c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                }
7335c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) {
734d80d19996a4b9ec3bfe1a9127af0df154f0e6770Ken Shirriff                    power.setBacklightBrightness(brightness);
7355c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness);
736c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                }
73703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            }
73803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } catch (RemoteException e) {
73903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Log.d(TAG, "toggleBrightness: " + e);
74003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } catch (Settings.SettingNotFoundException e) {
74103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Log.d(TAG, "toggleBrightness: " + e);
74203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
74303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
74403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff}
745