1e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang/*
2e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * Copyright (C) 2011 The Android Open Source Project
3e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang *
4e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * Licensed under the Apache License, Version 2.0 (the "License");
5e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * you may not use this file except in compliance with the License.
6e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * You may obtain a copy of the License at
7e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang *
8e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang *      http://www.apache.org/licenses/LICENSE-2.0
9e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang *
10e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * Unless required by applicable law or agreed to in writing, software
11e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * distributed under the License is distributed on an "AS IS" BASIS,
12e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * See the License for the specific language governing permissions and
14e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * limitations under the License.
15e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang */
16e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
17e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tangpackage com.android.settings.location;
18e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
1972bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tangimport android.content.BroadcastReceiver;
20e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tangimport android.content.Context;
211673fbc029d569b6424914db48e571b52091b4fcLifu Tangimport android.content.Intent;
2272bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tangimport android.content.IntentFilter;
2372bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tangimport android.location.LocationManager;
24007994279c6d9e41fe35a6804eb4ca753d139969Lifu Tangimport android.os.Bundle;
25e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tangimport android.os.UserManager;
26e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tangimport android.provider.Settings;
27f06dc3216318672d5a30d58c0cfcb4142dbab2c2Tom O'Neillimport android.util.Log;
28e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
29007994279c6d9e41fe35a6804eb4ca753d139969Lifu Tangimport com.android.settings.SettingsPreferenceFragment;
30e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
31e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang/**
32e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * A base class that listens to location settings change and modifies location
33e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang * settings.
34e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang */
3572bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tangpublic abstract class LocationSettingsBase extends SettingsPreferenceFragment {
36f06dc3216318672d5a30d58c0cfcb4142dbab2c2Tom O'Neill    private static final String TAG = "LocationSettingsBase";
371673fbc029d569b6424914db48e571b52091b4fcLifu Tang    /** Broadcast intent action when the location mode is about to change. */
381673fbc029d569b6424914db48e571b52091b4fcLifu Tang    private static final String MODE_CHANGING_ACTION =
391673fbc029d569b6424914db48e571b52091b4fcLifu Tang            "com.android.settings.location.MODE_CHANGING";
401673fbc029d569b6424914db48e571b52091b4fcLifu Tang    private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
411673fbc029d569b6424914db48e571b52091b4fcLifu Tang    private static final String NEW_MODE_KEY = "NEW_MODE";
42e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
431673fbc029d569b6424914db48e571b52091b4fcLifu Tang    private int mCurrentMode;
4472bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang    private BroadcastReceiver mReceiver;
45e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
4696f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    /**
4796f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang     * Whether the fragment is actively running.
4896f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang     */
4996f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    private boolean mActive = false;
5096f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang
51e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    @Override
52007994279c6d9e41fe35a6804eb4ca753d139969Lifu Tang    public void onCreate(Bundle icicle) {
53007994279c6d9e41fe35a6804eb4ca753d139969Lifu Tang        super.onCreate(icicle);
5472bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        mReceiver = new BroadcastReceiver() {
5572bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            @Override
5672bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            public void onReceive(Context context, Intent intent) {
5772bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang                if (Log.isLoggable(TAG, Log.DEBUG)) {
5872bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang                    Log.d(TAG, "Received location mode change intent: " + intent);
5972bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang                }
6072bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang                refreshLocationMode();
6172bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            }
6272bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        };
63e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    }
64e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
6596f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    @Override
6696f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    public void onResume() {
6796f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang        super.onResume();
6896f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang        mActive = true;
6972bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        IntentFilter filter = new IntentFilter();
7072bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        filter.addAction(LocationManager.MODE_CHANGED_ACTION);
7172bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        getActivity().registerReceiver(mReceiver, filter);
7296f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    }
7396f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang
7496f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    @Override
7596f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    public void onPause() {
7672bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        try {
7772bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            getActivity().unregisterReceiver(mReceiver);
7872bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        } catch (RuntimeException e) {
7972bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            // Ignore exceptions caused by race condition
8072bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        }
8196f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang        super.onPause();
8296f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang        mActive = false;
8396f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang    }
8496f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang
85e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    /** Called when location mode has changed. */
864fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang    public abstract void onModeChanged(int mode, boolean restricted);
87e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
884fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang    private boolean isRestricted() {
89e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
904fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang        return um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
914fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang    }
924fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang
934fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang    public void setLocationMode(int mode) {
944fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang        if (isRestricted()) {
954fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang            // Location toggling disabled by user restriction. Read the current location mode to
964fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang            // update the location master switch.
97f06dc3216318672d5a30d58c0cfcb4142dbab2c2Tom O'Neill            if (Log.isLoggable(TAG, Log.INFO)) {
98f06dc3216318672d5a30d58c0cfcb4142dbab2c2Tom O'Neill                Log.i(TAG, "Restricted user, not setting location mode");
99f06dc3216318672d5a30d58c0cfcb4142dbab2c2Tom O'Neill            }
1004fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang            mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
1014fb17c1c9847d8a1a7c2386f3f28b91616e73f4bLifu Tang                    Settings.Secure.LOCATION_MODE_OFF);
10296f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang            if (mActive) {
10396f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang                onModeChanged(mode, true);
10496f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang            }
105e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            return;
106e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        }
1071673fbc029d569b6424914db48e571b52091b4fcLifu Tang        Intent intent = new Intent(MODE_CHANGING_ACTION);
1081673fbc029d569b6424914db48e571b52091b4fcLifu Tang        intent.putExtra(CURRENT_MODE_KEY, mCurrentMode);
1091673fbc029d569b6424914db48e571b52091b4fcLifu Tang        intent.putExtra(NEW_MODE_KEY, mode);
1108a4c53ac2bbd2eca81a8725212d4d61672fbfdefLifu Tang        getActivity().sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
11193259c14f3aca4739e2cf7691cb0416ded509d8dTom O'Neill        Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, mode);
112e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        refreshLocationMode();
113e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    }
114e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
115e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    public void refreshLocationMode() {
11696f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang        if (mActive) {
11796f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang            int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
11896f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang                    Settings.Secure.LOCATION_MODE_OFF);
1191673fbc029d569b6424914db48e571b52091b4fcLifu Tang            mCurrentMode = mode;
12072bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            if (Log.isLoggable(TAG, Log.INFO)) {
12172bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang                Log.i(TAG, "Location mode has been changed");
12272bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang            }
12396f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang            onModeChanged(mode, isRestricted());
12496f95212b819ba196b609e2e1e2bc2fcc682933eLifu Tang        }
125e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    }
126e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang}
127