SettingsAppWidgetProvider.java revision a6a74e222a994e29a1daa7178943a1fc9dd06c47
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            }
251a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff            /**
252a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff             * Disable tethering if enabling Wifi
253a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff             */
254a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff            int wifiApState = wifiManager.getWifiApState();
255a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff            if (desiredState && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
256a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff                        (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
257a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff                wifiManager.setWifiApEnabled(null, false);
258a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff            }
259a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff
26094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            wifiManager.setWifiEnabled(desiredState);
26194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
26294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
26394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
26494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public void onActualStateChange(Context context, Intent intent) {
26594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
26694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
26794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
26894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
26994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            setCurrentState(context, wifiStateToFiveState(wifiState));
27094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
27194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
27294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
27394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Converts WifiManager's state values into our
27494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Wifi/Bluetooth-common state values.
27594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
27694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private static int wifiStateToFiveState(int wifiState) {
27794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (wifiState) {
27894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_DISABLED:
27994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_DISABLED;
28094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_ENABLED:
28194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_ENABLED;
28294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_DISABLING:
28394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_OFF;
28494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case WifiManager.WIFI_STATE_ENABLING:
28594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_ON;
28694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                default:
28794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_UNKNOWN;
28894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
28994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
29094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    }
29194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
29294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    /**
29394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     * Subclass of StateTracker to get/set Bluetooth state.
29494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick     */
29594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    private static final class BluetoothStateTracker extends StateTracker {
29694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
29794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
29894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public int getActualState(Context context) {
29994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (sLocalBluetoothManager == null) {
30094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                sLocalBluetoothManager = LocalBluetoothManager.getInstance(context);
30194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (sLocalBluetoothManager == null) {
30294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_UNKNOWN;  // On emulator?
30394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
30494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
30594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            return bluetoothStateToFiveState(sLocalBluetoothManager.getBluetoothState());
30694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
30794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
30894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
30994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        protected void requestStateChange(Context context,
31094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                          boolean desiredState, boolean withToast) {
31194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (sLocalBluetoothManager == null) {
31294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                Log.d(TAG, "No LocalBluetoothManager");
31394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
31494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
31594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (withToast) {
31694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                Toast.makeText(context,
31794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                               R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show();
31894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
31994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            sLocalBluetoothManager.setBluetoothEnabled(desiredState);
32094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
32194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
32294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        @Override
32394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        public void onActualStateChange(Context context, Intent intent) {
32494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
32594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                return;
32694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
32794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
32894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            setCurrentState(context, bluetoothStateToFiveState(bluetoothState));
32994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
33094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
33194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        /**
33294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Converts BluetoothAdapter's state values into our
33394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         * Wifi/Bluetooth-common state values.
33494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick         */
33594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        private static int bluetoothStateToFiveState(int bluetoothState) {
33694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            switch (bluetoothState) {
33794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_OFF:
33894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_DISABLED;
33994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_ON:
34094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_ENABLED;
34194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_TURNING_ON:
34294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_ON;
34394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                case BluetoothAdapter.STATE_TURNING_OFF:
34494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_TURNING_OFF;
34594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                default:
34694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    return STATE_UNKNOWN;
34794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            }
34894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        }
34994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick    }
35094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
35194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
35203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
35303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
35403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            int[] appWidgetIds) {
35503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        // Update each requested appWidgetId
35603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        RemoteViews view = buildUpdate(context, -1);
35703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
35803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        for (int i = 0; i < appWidgetIds.length; i++) {
35903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            appWidgetManager.updateAppWidget(appWidgetIds[i], view);
36003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
36103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
36203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
36303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
36403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onEnabled(Context context) {
36503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        PackageManager pm = context.getPackageManager();
36603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        pm.setComponentEnabledSetting(
36703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                new ComponentName("com.android.settings", ".widget.SettingsAppWidgetProvider"),
36803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
36903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.DONT_KILL_APP);
37003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
37103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
37203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
37303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onDisabled(Context context) {
37403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        Class clazz = com.android.settings.widget.SettingsAppWidgetProvider.class;
37503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        PackageManager pm = context.getPackageManager();
37603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        pm.setComponentEnabledSetting(
37703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                new ComponentName("com.android.settings", ".widget.SettingsAppWidgetProvider"),
37803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
37903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                PackageManager.DONT_KILL_APP);
38003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
38103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
38203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
38303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Load image for given widget and build {@link RemoteViews} for it.
38403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
38503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    static RemoteViews buildUpdate(Context context, int appWidgetId) {
38603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        RemoteViews views = new RemoteViews(context.getPackageName(),
38703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                R.layout.widget);
38803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_wifi, getLaunchPendingIntent(context, appWidgetId,
38903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                BUTTON_WIFI));
39003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_brightness,
39103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context,
39203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        appWidgetId, BUTTON_BRIGHTNESS));
39303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_sync,
39403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context,
39503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        appWidgetId, BUTTON_SYNC));
39603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_gps,
39703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context, appWidgetId, BUTTON_GPS));
39803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        views.setOnClickPendingIntent(R.id.btn_bluetooth,
39903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                getLaunchPendingIntent(context,
40003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        appWidgetId, BUTTON_BLUETOOTH));
40103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
40203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        updateButtons(views, context);
40303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return views;
40403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
40503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
40603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
40703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Updates the widget when something changes, or when a button is pushed.
40803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
40903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
41003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
41103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public static void updateWidget(Context context) {
41203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        RemoteViews views = buildUpdate(context, -1);
41303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        // Update specific list of appWidgetIds if given, otherwise default to all
41403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        final AppWidgetManager gm = AppWidgetManager.getInstance(context);
41503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        gm.updateAppWidget(THIS_APPWIDGET, views);
41603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
41703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
41803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
41903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Updates the buttons based on the underlying states of wifi, etc.
42003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
42103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param views   The RemoteViews to update.
42203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
42303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
42403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static void updateButtons(RemoteViews views, Context context) {
42594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        switch (sWifiState.getTriState(context)) {
42603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_DISABLED:
42794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_wifi,
42894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_wifi_off);
42994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_wifi,
43094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_off_l);
43103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
43203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_ENABLED:
43394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_wifi,
43494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_wifi_on);
43594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_wifi,
43694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_on_l);
43703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
43803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_INTERMEDIATE:
43994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // In the transitional state, the bottom green bar
44094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // shows the tri-state (on, off, transitioning), but
44194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // the top dark-gray-or-bright-white logo shows the
44294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // user's intent.  This is much easier to see in
44394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // sunlight.
44494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (sWifiState.isTurningOn()) {
44594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_wifi,
44694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_wifi_on);
44794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_wifi,
44894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_mid_l);
44994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                } else {
45094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_wifi,
45194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_wifi_off);
45294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_wifi,
45394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_off_l);
45494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
45503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
45603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
4575c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        if (getBrightnessMode(context)) {
45894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.img_brightness,
45994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.ic_appwidget_settings_brightness_auto);
46094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.ind_brightness,
46194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.appwidget_settings_ind_on_r);
4625c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        } else if (getBrightness(context)) {
46394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.img_brightness,
46494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.ic_appwidget_settings_brightness_on);
46594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.ind_brightness,
46694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.appwidget_settings_ind_on_r);
46703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } else {
46894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.img_brightness,
46994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.ic_appwidget_settings_brightness_off);
47094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            views.setImageViewResource(R.id.ind_brightness,
47194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                       R.drawable.appwidget_settings_ind_off_r);
47203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
473ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (getSync(context)) {
474c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_on);
475c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_sync, R.drawable.appwidget_settings_ind_on_c);
47603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } else {
477c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_off);
478c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_sync, R.drawable.appwidget_settings_ind_off_c);
47903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
48003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        if (getGpsState(context)) {
481c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_on);
482c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_on_c);
48303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } else {
484c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_off);
485c151e45d8c8054516448e58280de63f180b790d5Mike Cleron            views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_off_c);
48603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
48794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        switch (sBluetoothState.getTriState(context)) {
48803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_DISABLED:
48994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_bluetooth,
49094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_bluetooth_off);
49194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_bluetooth,
49294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_off_c);
49303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
49403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_ENABLED:
49594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.img_bluetooth,
49694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.ic_appwidget_settings_bluetooth_on);
49794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                views.setImageViewResource(R.id.ind_bluetooth,
49894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                           R.drawable.appwidget_settings_ind_on_c);
49903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
50003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            case STATE_INTERMEDIATE:
50194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // In the transitional state, the bottom green bar
50294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // shows the tri-state (on, off, transitioning), but
50394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // the top dark-gray-or-bright-white logo shows the
50494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // user's intent.  This is much easier to see in
50594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                // sunlight.
50694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                if (sBluetoothState.isTurningOn()) {
50794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_bluetooth,
50894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_bluetooth_on);
50994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_bluetooth,
51094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_mid_c);
51194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                } else {
51294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.img_bluetooth,
51394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.ic_appwidget_settings_bluetooth_off);
51494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                    views.setImageViewResource(R.id.ind_bluetooth,
51594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                                               R.drawable.appwidget_settings_ind_off_c);
51694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                }
51703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                break;
51803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
51903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
52003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
52103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
52203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Creates PendingIntent to notify the widget of a button click.
52303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
52403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
52503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param appWidgetId
52603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return
52703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
528e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff    private static PendingIntent getLaunchPendingIntent(Context context, int appWidgetId,
529e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff            int buttonId) {
53003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        Intent launchIntent = new Intent();
53103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        launchIntent.setClass(context, SettingsAppWidgetProvider.class);
53203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        launchIntent.addCategory(Intent.CATEGORY_ALTERNATIVE);
53303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        launchIntent.setData(Uri.parse("custom:" + buttonId));
53403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        PendingIntent pi = PendingIntent.getBroadcast(context, 0 /* no requestCode */,
53503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                launchIntent, 0 /* no flags */);
53603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return pi;
53703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
53803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
53903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
54003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Receives and processes a button pressed intent or state change.
54103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
54203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
54303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param intent  Indicates the pressed button.
54403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
54503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    @Override
54603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    public void onReceive(Context context, Intent intent) {
54703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        super.onReceive(context, intent);
54894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
54994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            sWifiState.onActualStateChange(context, intent);
55094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
55194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick            sBluetoothState.onActualStateChange(context, intent);
55294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick        } else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) {
55303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Uri data = intent.getData();
55403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            int buttonId = Integer.parseInt(data.getSchemeSpecificPart());
55503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            if (buttonId == BUTTON_WIFI) {
55694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                sWifiState.toggleState(context);
55703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_BRIGHTNESS) {
55803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                toggleBrightness(context);
55903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_SYNC) {
560ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh                toggleSync(context);
56103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_GPS) {
56203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                toggleGps(context);
56303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            } else if (buttonId == BUTTON_BLUETOOTH) {
56494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick                sBluetoothState.toggleState(context);
56503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            }
56603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
56794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick
56803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        // State changes fall through
56903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        updateWidget(context);
57003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
57103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
57203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
57303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Gets the state of background data.
57403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
57503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
57603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return true if enabled
57703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
57803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static boolean getBackgroundDataState(Context context) {
579e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff        ConnectivityManager connManager =
580e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
58103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return connManager.getBackgroundDataSetting();
58203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
58303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
58403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
585ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * Gets the state of auto-sync.
586ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     *
587ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * @param context
588ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * @return true if enabled
589ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     */
590ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    private static boolean getSync(Context context) {
591ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean backgroundData = getBackgroundDataState(context);
592ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean sync = ContentResolver.getMasterSyncAutomatically();
593ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        return backgroundData && sync;
594ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    }
595ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
596ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    /**
597ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh     * Toggle auto-sync
59803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
59903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
60003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
601ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh    private void toggleSync(Context context) {
602e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff        ConnectivityManager connManager =
603e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
604ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean backgroundData = getBackgroundDataState(context);
605ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        boolean sync = ContentResolver.getMasterSyncAutomatically();
606ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
607ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // four cases to handle:
608ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // setting toggled from off to on:
609ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 1. background data was off, sync was off: turn on both
610ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (!backgroundData && !sync) {
611ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            connManager.setBackgroundDataSetting(true);
612ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            ContentResolver.setMasterSyncAutomatically(true);
613ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
614ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
615ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 2. background data was off, sync was on: turn on background data
616ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (!backgroundData && sync) {
617ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            connManager.setBackgroundDataSetting(true);
618ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
619ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
620ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 3. background data was on, sync was off: turn on sync
621ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (backgroundData && !sync) {
622ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            ContentResolver.setMasterSyncAutomatically(true);
623ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
624ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh
625ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // setting toggled from on to off:
626ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        // 4. background data was on, sync was on: turn off sync
627ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        if (backgroundData && sync) {
628ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh            ContentResolver.setMasterSyncAutomatically(false);
629ae57dbd618decb8cdc942756e283fadef659b2b6Debajit Ghosh        }
63003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
63103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
63203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
63303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Gets the state of GPS location.
63403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
63503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
63603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return true if enabled.
63703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
63803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static boolean getGpsState(Context context) {
63903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        ContentResolver resolver = context.getContentResolver();
64003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return Settings.Secure.isLocationProviderEnabled(resolver, LocationManager.GPS_PROVIDER);
64103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
64203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
64303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
64403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Toggles the state of GPS.
64503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
64603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
64703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
64803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private void toggleGps(Context context) {
64903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        ContentResolver resolver = context.getContentResolver();
65003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        boolean enabled = getGpsState(context);
651e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff        Settings.Secure.setLocationProviderEnabled(resolver, LocationManager.GPS_PROVIDER,
652e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff                !enabled);
65303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
65403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
65503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
65603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Gets state of brightness.
65703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
65803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
65903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @return true if more than moderately bright.
66003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
66103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private static boolean getBrightness(Context context) {
66203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        try {
663cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            IPowerManager power = IPowerManager.Stub.asInterface(
664cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood                    ServiceManager.getService("power"));
665cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            if (power != null) {
66603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                int brightness = Settings.System.getInt(context.getContentResolver(),
66703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        Settings.System.SCREEN_BRIGHTNESS);
66803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                return brightness > 100;
66903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            }
67003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } catch (Exception e) {
67103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Log.d(TAG, "getBrightness: " + e);
67203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
67303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        return false;
67403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
67503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff
67603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    /**
6775c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     * Gets state of brightness mode.
6785c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     *
6795c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     * @param context
6805c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     * @return true if auto brightness is on.
6815c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik     */
6825c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik    private static boolean getBrightnessMode(Context context) {
6835c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        try {
6845c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            IPowerManager power = IPowerManager.Stub.asInterface(
6855c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    ServiceManager.getService("power"));
6865c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            if (power != null) {
6875c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                int brightnessMode = Settings.System.getInt(context.getContentResolver(),
6885c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                        Settings.System.SCREEN_BRIGHTNESS_MODE);
6895c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
6905c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            }
6915c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        } catch (Exception e) {
6925c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik            Log.d(TAG, "getBrightnessMode: " + e);
6935c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        }
6945c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik        return false;
6955c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik    }
6965c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik
6975c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik    /**
69803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * Increases or decreases the brightness.
69903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     *
70003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     * @param context
70103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff     */
70203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    private void toggleBrightness(Context context) {
70303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        try {
704cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            IPowerManager power = IPowerManager.Stub.asInterface(
705cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood                    ServiceManager.getService("power"));
706cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood            if (power != null) {
70703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                ContentResolver cr = context.getContentResolver();
70803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                int brightness = Settings.System.getInt(cr,
70903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                        Settings.System.SCREEN_BRIGHTNESS);
7105c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
7115c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                //Only get brightness setting if available
7125c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                if (context.getResources().getBoolean(
7135c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                        com.android.internal.R.bool.config_automatic_brightness_available)) {
7145c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightnessMode = Settings.System.getInt(cr,
7155c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                            Settings.System.SCREEN_BRIGHTNESS_MODE);
7165c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                }
7175c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik
7185c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM
71903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                // Technically, not a toggle...
7205c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
7215c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightness = MINIMUM_BACKLIGHT;
7225c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
7235c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                } else if (brightness < DEFAULT_BACKLIGHT) {
72403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                    brightness = DEFAULT_BACKLIGHT;
72503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                } else if (brightness < MAXIMUM_BACKLIGHT) {
72603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                    brightness = MAXIMUM_BACKLIGHT;
72703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                } else {
7285c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
7295bc5cedc7ae2808ed487d90ff86caedc722021dbErik                    brightness = MINIMUM_BACKLIGHT;
73003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff                }
7315c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik
732c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                if (context.getResources().getBoolean(
733c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                        com.android.internal.R.bool.config_automatic_brightness_available)) {
7345c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    // Set screen brightness mode (automatic or manual)
735c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                    Settings.System.putInt(context.getContentResolver(),
736c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                            Settings.System.SCREEN_BRIGHTNESS_MODE,
7375c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                            brightnessMode);
7385bc5cedc7ae2808ed487d90ff86caedc722021dbErik                } else {
7395bc5cedc7ae2808ed487d90ff86caedc722021dbErik                    // Make sure we set the brightness if automatic mode isn't available
7405bc5cedc7ae2808ed487d90ff86caedc722021dbErik                    brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
7415c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                }
7425c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) {
743d80d19996a4b9ec3bfe1a9127af0df154f0e6770Ken Shirriff                    power.setBacklightBrightness(brightness);
7445c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik                    Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness);
745c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff                }
74603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            }
74703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } catch (RemoteException e) {
74803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Log.d(TAG, "toggleBrightness: " + e);
74903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        } catch (Settings.SettingNotFoundException e) {
75003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff            Log.d(TAG, "toggleBrightness: " + e);
75103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff        }
75203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff    }
75303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff}
754