1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings.location;
18
19import android.app.LoaderManager.LoaderCallbacks;
20import android.content.Context;
21import android.content.CursorLoader;
22import android.content.Intent;
23import android.content.Loader;
24import android.database.Cursor;
25import android.os.Bundle;
26import android.os.UserManager;
27import android.provider.Settings;
28import android.util.Log;
29
30import com.android.settings.SettingsPreferenceFragment;
31
32/**
33 * A base class that listens to location settings change and modifies location
34 * settings.
35 */
36public abstract class LocationSettingsBase extends SettingsPreferenceFragment
37        implements LoaderCallbacks<Cursor> {
38    private static final String TAG = "LocationSettingsBase";
39    /** Broadcast intent action when the location mode is about to change. */
40    private static final String MODE_CHANGING_ACTION =
41            "com.android.settings.location.MODE_CHANGING";
42    private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
43    private static final String NEW_MODE_KEY = "NEW_MODE";
44
45    private static final int LOADER_ID_LOCATION_MODE = 1;
46    private int mCurrentMode;
47
48    /**
49     * Whether the fragment is actively running.
50     */
51    private boolean mActive = false;
52
53    @Override
54    public void onCreate(Bundle icicle) {
55        super.onCreate(icicle);
56        getLoaderManager().initLoader(LOADER_ID_LOCATION_MODE, null, this);
57    }
58
59    @Override
60    public void onResume() {
61        super.onResume();
62        mActive = true;
63    }
64
65    @Override
66    public void onPause() {
67        super.onPause();
68        mActive = false;
69    }
70
71    /** Called when location mode has changed. */
72    public abstract void onModeChanged(int mode, boolean restricted);
73
74    private boolean isRestricted() {
75        final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
76        return um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
77    }
78
79    public void setLocationMode(int mode) {
80        if (isRestricted()) {
81            // Location toggling disabled by user restriction. Read the current location mode to
82            // update the location master switch.
83            if (Log.isLoggable(TAG, Log.INFO)) {
84                Log.i(TAG, "Restricted user, not setting location mode");
85            }
86            mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
87                    Settings.Secure.LOCATION_MODE_OFF);
88            if (mActive) {
89                onModeChanged(mode, true);
90            }
91            return;
92        }
93        Intent intent = new Intent(MODE_CHANGING_ACTION);
94        intent.putExtra(CURRENT_MODE_KEY, mCurrentMode);
95        intent.putExtra(NEW_MODE_KEY, mode);
96        getActivity().sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
97        Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, mode);
98        refreshLocationMode();
99    }
100
101    public void refreshLocationMode() {
102        if (mActive) {
103            int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
104                    Settings.Secure.LOCATION_MODE_OFF);
105            mCurrentMode = mode;
106            onModeChanged(mode, isRestricted());
107        }
108    }
109
110    @Override
111    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
112        switch (id) {
113            case LOADER_ID_LOCATION_MODE:
114                return new CursorLoader(getActivity(), Settings.Secure.CONTENT_URI, null,
115                        "(" + Settings.System.NAME + "=?)",
116                        new String[] { Settings.Secure.LOCATION_MODE }, null);
117            default:
118                return null;
119        }
120    }
121
122    @Override
123    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
124        refreshLocationMode();
125    }
126
127    @Override
128    public void onLoaderReset(Loader<Cursor> loader) {
129        // Nothing to do here.
130    }
131}
132