1a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne/*
2a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * Copyright (C) 2011 The Android Open Source Project
3a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne *
4a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * Licensed under the Apache License, Version 2.0 (the "License");
5a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * you may not use this file except in compliance with the License.
6a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * You may obtain a copy of the License at
7a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne *
8a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne *      http://www.apache.org/licenses/LICENSE-2.0
9a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne *
10a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * Unless required by applicable law or agreed to in writing, software
11a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * distributed under the License is distributed on an "AS IS" BASIS,
12a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * See the License for the specific language governing permissions and
14a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne * limitations under the License.
15a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne */
16a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne
1783ab7c932e59fd23799f5db723e80d411918a9a5Lifu Tangpackage com.android.settings.location;
18a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne
199d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monkimport android.app.Activity;
20ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Banimport android.app.admin.DevicePolicyManager;
2132e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tangimport android.content.BroadcastReceiver;
22ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Banimport android.content.ComponentName;
2332e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tangimport android.content.Context;
24a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunneimport android.content.Intent;
2532e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tangimport android.content.IntentFilter;
2632e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tangimport android.location.SettingInjectorService;
27263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglioimport android.os.Bundle;
2886c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Banimport android.os.UserHandle;
2986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Banimport android.os.UserManager;
309d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monkimport android.provider.Settings;
3139b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference;
3239b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceCategory;
3339b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceGroup;
3439b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceScreen;
35e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neillimport android.util.Log;
36cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tangimport android.view.Menu;
37cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tangimport android.view.MenuInflater;
38cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tangimport android.view.MenuItem;
39d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tangimport android.widget.Switch;
409d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent;
41f313a75e262026f7d33969b0aa174686692f6aafTony Mantlerimport com.android.settings.DimmableIconPreference;
4283ab7c932e59fd23799f5db723e80d411918a9a5Lifu Tangimport com.android.settings.R;
43263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglioimport com.android.settings.SettingsActivity;
4486c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Banimport com.android.settings.Utils;
45f313a75e262026f7d33969b0aa174686692f6aafTony Mantlerimport com.android.settings.applications.InstalledAppDetails;
469d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monkimport com.android.settings.dashboard.SummaryLoader;
47304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglioimport com.android.settings.widget.SwitchBar;
489c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils;
490d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shankaimport com.android.settingslib.RestrictedSwitchPreference;
50f313a75e262026f7d33969b0aa174686692f6aafTony Mantlerimport com.android.settingslib.location.RecentLocationApps;
5183ab7c932e59fd23799f5db723e80d411918a9a5Lifu Tang
52f313a75e262026f7d33969b0aa174686692f6aafTony Mantlerimport java.util.ArrayList;
5325518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tangimport java.util.Collections;
5425518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tangimport java.util.Comparator;
5525518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tangimport java.util.List;
5625518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang
579c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
589c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka
59a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne/**
6067dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * System location settings (Settings > Location). The screen has three parts:
6167dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * <ul>
6267dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *     <li>Platform location controls</li>
6367dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *     <ul>
6467dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         <li>In switch bar: location master switch. Used to toggle
6567dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         {@link android.provider.Settings.Secure#LOCATION_MODE} between
6667dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         {@link android.provider.Settings.Secure#LOCATION_MODE_OFF} and another location mode.
6767dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         </li>
6867dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         <li>Mode preference: only available if the master switch is on, selects between
6967dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         {@link android.provider.Settings.Secure#LOCATION_MODE} of
7067dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         {@link android.provider.Settings.Secure#LOCATION_MODE_HIGH_ACCURACY},
7167dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         {@link android.provider.Settings.Secure#LOCATION_MODE_BATTERY_SAVING}, or
7267dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *         {@link android.provider.Settings.Secure#LOCATION_MODE_SENSORS_ONLY}.</li>
7367dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *     </ul>
7467dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *     <li>Recent location requests: automatically populated by {@link RecentLocationApps}</li>
7567dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *     <li>Location services: multi-app settings provided from outside the Android framework. Each
7667dc554030302f0b975939cf62099dbe79af5aacTom O'Neill *     is injected by a system-partition app via the {@link SettingInjectorService} API.</li>
7767dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * </ul>
7867dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * <p>
7967dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * Note that as of KitKat, the {@link SettingInjectorService} is the preferred method for OEMs to
8067dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * add their own settings to this page, rather than directly modifying the framework code. Among
8167dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * other things, this simplifies integration with future changes to the default (AOSP)
8267dc554030302f0b975939cf62099dbe79af5aacTom O'Neill * implementation.
83a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne */
84e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tangpublic class LocationSettings extends LocationSettingsBase
85304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio        implements SwitchBar.OnSwitchChangeListener {
86e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neill
87e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neill    private static final String TAG = "LocationSettings";
88e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neill
8986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    /**
90ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban     * Key for managed profile location switch preference. Shown only
91ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban     * if there is a managed profile.
9286c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban     */
93ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban    private static final String KEY_MANAGED_PROFILE_SWITCH = "managed_profile_location_switch";
9488afb32fc6422139dcf8340aa88f3de9112a1485Lifu Tang    /** Key for preference screen "Mode" */
95d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang    private static final String KEY_LOCATION_MODE = "location_mode";
9688afb32fc6422139dcf8340aa88f3de9112a1485Lifu Tang    /** Key for preference category "Recent location requests" */
97e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
9888afb32fc6422139dcf8340aa88f3de9112a1485Lifu Tang    /** Key for preference category "Location services" */
995ab9fa432d17fe72c74a25770a26d405635cc0f6Lifu Tang    private static final String KEY_LOCATION_SERVICES = "location_services";
100a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne
101cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    private static final int MENU_SCANNING = Menu.FIRST;
102cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang
103304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio    private SwitchBar mSwitchBar;
104e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    private Switch mSwitch;
10542fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang    private boolean mValidListener = false;
10686c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    private UserHandle mManagedProfile;
1070d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka    private RestrictedSwitchPreference mManagedProfileSwitch;
10808a4c33a409f7cc693527de138179f80bf07be9cLifu Tang    private Preference mLocationMode;
109d3a77665ef13755cf463dff27f50d78c16e595d8Lifu Tang    private PreferenceCategory mCategoryRecentLocationRequests;
11032e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang    /** Receives UPDATE_INTENT  */
11132e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang    private BroadcastReceiver mReceiver;
11272bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang    private SettingsInjector injector;
11386c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    private UserManager mUm;
114c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang
115a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne    @Override
1168a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    protected int getMetricsCategory() {
1179d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren        return MetricsEvent.LOCATION;
1188a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    }
1198a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
1208a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    @Override
121263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio    public void onActivityCreated(Bundle savedInstanceState) {
122263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio        super.onActivityCreated(savedInstanceState);
123263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio
124263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio        final SettingsActivity activity = (SettingsActivity) getActivity();
12586c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
126263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio
1274148f17616173a0bb475ed3b09ed90fc17540cc6Lifu Tang        setHasOptionsMenu(true);
128304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio        mSwitchBar = activity.getSwitchBar();
129304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio        mSwitch = mSwitchBar.getSwitch();
130138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        mSwitchBar.show();
131138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    }
132138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio
133138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    @Override
134138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio    public void onDestroyView() {
135138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        super.onDestroyView();
136138ff8c0457c6e1345015973668d652fa17c7c3bFabrice Di Meglio        mSwitchBar.hide();
137263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio    }
138263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio
139263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio    @Override
140d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang    public void onResume() {
141d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang        super.onResume();
142d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang        createPreferenceHierarchy();
14342fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang        if (!mValidListener) {
14442fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang            mSwitchBar.addOnSwitchChangeListener(this);
14542fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang            mValidListener = true;
14642fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang        }
147a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne    }
148a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne
149e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    @Override
150e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    public void onPause() {
15132e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang        try {
15232e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang            getActivity().unregisterReceiver(mReceiver);
15332e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang        } catch (RuntimeException e) {
15432e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang            // Ignore exceptions caused by race condition
15542fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang            if (Log.isLoggable(TAG, Log.VERBOSE)) {
15642fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang                Log.v(TAG, "Swallowing " + e);
15742fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang            }
15842fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang        }
15942fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang        if (mValidListener) {
16042fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang            mSwitchBar.removeOnSwitchChangeListener(this);
16142fa97345717d1a2421b173877284a0d6eca55e4Lifu Tang            mValidListener = false;
16232e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang        }
163e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        super.onPause();
164e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    }
165e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
16625518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang    private void addPreferencesSorted(List<Preference> prefs, PreferenceGroup container) {
16725518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        // If there's some items to display, sort the items and add them to the container.
16825518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        Collections.sort(prefs, new Comparator<Preference>() {
16925518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang            @Override
17025518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang            public int compare(Preference lhs, Preference rhs) {
17125518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang                return lhs.getTitle().toString().compareTo(rhs.getTitle().toString());
17225518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang            }
17325518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        });
17425518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        for (Preference entry : prefs) {
17525518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang            container.addPreference(entry);
17625518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        }
17725518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang    }
17825518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang
179a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne    private PreferenceScreen createPreferenceHierarchy() {
180263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio        final SettingsActivity activity = (SettingsActivity) getActivity();
181a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne        PreferenceScreen root = getPreferenceScreen();
182a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne        if (root != null) {
183a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne            root.removeAll();
184a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne        }
185a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne        addPreferencesFromResource(R.xml.location_settings);
186a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne        root = getPreferenceScreen();
187a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne
18886c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        setupManagedProfileCategory(root);
18908a4c33a409f7cc693527de138179f80bf07be9cLifu Tang        mLocationMode = root.findPreference(KEY_LOCATION_MODE);
190d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang        mLocationMode.setOnPreferenceClickListener(
191d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                new Preference.OnPreferenceClickListener() {
192d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                    @Override
193d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                    public boolean onPreferenceClick(Preference preference) {
194c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang                        activity.startPreferencePanel(
195d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                                LocationMode.class.getName(), null,
196d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                                R.string.location_mode_screen_title, null, LocationSettings.this,
197d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                                0);
198d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                        return true;
199d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                    }
200d5fbbc4e49727f98188aeb89e32146c7fe546c75Lifu Tang                });
20125518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang
202d3a77665ef13755cf463dff27f50d78c16e595d8Lifu Tang        mCategoryRecentLocationRequests =
203e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang                (PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS);
204f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        RecentLocationApps recentApps = new RecentLocationApps(activity);
205f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        List<RecentLocationApps.Request> recentLocationRequests = recentApps.getAppList();
206f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        List<Preference> recentLocationPrefs = new ArrayList<>(recentLocationRequests.size());
207f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        for (final RecentLocationApps.Request request : recentLocationRequests) {
208f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            DimmableIconPreference pref = new DimmableIconPreference(getPrefContext(),
209f313a75e262026f7d33969b0aa174686692f6aafTony Mantler                    request.contentDescription);
210f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            pref.setIcon(request.icon);
211f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            pref.setTitle(request.label);
212f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            if (request.isHighBattery) {
213f313a75e262026f7d33969b0aa174686692f6aafTony Mantler                pref.setSummary(R.string.location_high_battery_use);
214f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            } else {
215f313a75e262026f7d33969b0aa174686692f6aafTony Mantler                pref.setSummary(R.string.location_low_battery_use);
216f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            }
217f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            pref.setOnPreferenceClickListener(
218f313a75e262026f7d33969b0aa174686692f6aafTony Mantler                    new PackageEntryClickedListener(request.packageName, request.userHandle));
219f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            recentLocationPrefs.add(pref);
220f313a75e262026f7d33969b0aa174686692f6aafTony Mantler
221f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        }
22225518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        if (recentLocationRequests.size() > 0) {
223f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            addPreferencesSorted(recentLocationPrefs, mCategoryRecentLocationRequests);
22425518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        } else {
22525518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang            // If there's no item to display, add a "No recent apps" item.
22639b467482d1bf256a111c757e9b7621c6f523271Jason Monk            Preference banner = new Preference(getPrefContext());
22708a4c33a409f7cc693527de138179f80bf07be9cLifu Tang            banner.setLayoutResource(R.layout.location_list_no_item);
22808a4c33a409f7cc693527de138179f80bf07be9cLifu Tang            banner.setTitle(R.string.location_no_recent_apps);
22908a4c33a409f7cc693527de138179f80bf07be9cLifu Tang            banner.setSelectable(false);
230d3a77665ef13755cf463dff27f50d78c16e595d8Lifu Tang            mCategoryRecentLocationRequests.addPreference(banner);
23125518c3b45827537b2b2c2b35fdc86bc8bd60502Lifu Tang        }
23288afb32fc6422139dcf8340aa88f3de9112a1485Lifu Tang
23386c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        boolean lockdownOnLocationAccess = false;
23486c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // Checking if device policy has put a location access lock-down on the managed
23586c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // profile. If managed profile has lock-down on location access then its
23686c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // injected location services must not be shown.
23786c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        if (mManagedProfile != null
23886c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban                && mUm.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile)) {
23986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban            lockdownOnLocationAccess = true;
24086c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        }
24186c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        addLocationServices(activity, root, lockdownOnLocationAccess);
242421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill
243421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill        refreshLocationMode();
244421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill        return root;
245421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill    }
246421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill
24786c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    private void setupManagedProfileCategory(PreferenceScreen root) {
24886c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // Looking for a managed profile. If there are no managed profiles then we are removing the
24986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // managed profile category.
25086c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        mManagedProfile = Utils.getManagedProfile(mUm);
25186c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        if (mManagedProfile == null) {
25286c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban            // There is no managed profile
253ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            root.removePreference(root.findPreference(KEY_MANAGED_PROFILE_SWITCH));
254ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            mManagedProfileSwitch = null;
25586c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        } else {
2560d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            mManagedProfileSwitch = (RestrictedSwitchPreference)root
257ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                    .findPreference(KEY_MANAGED_PROFILE_SWITCH);
258ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            mManagedProfileSwitch.setOnPreferenceClickListener(null);
25986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        }
26086c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    }
26186c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban
262ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban    private void changeManagedProfileLocationAccessStatus(boolean mainSwitchOn) {
263ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        if (mManagedProfileSwitch == null) {
26486c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban            return;
26586c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        }
266ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        mManagedProfileSwitch.setOnPreferenceClickListener(null);
2670d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka        final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
2680d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka                UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile.getIdentifier());
2699e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka        final boolean isRestrictedByBase = isManagedProfileRestrictedByBase();
2709e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka        if (!isRestrictedByBase && admin != null) {
2710d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            mManagedProfileSwitch.setDisabledByAdmin(admin);
272ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            mManagedProfileSwitch.setChecked(false);
273ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        } else {
2740d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            boolean enabled = mainSwitchOn;
2750d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            mManagedProfileSwitch.setEnabled(enabled);
2760d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka
2770d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            int summaryResId = R.string.switch_off_text;
2780d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            if (!enabled) {
2790d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka                mManagedProfileSwitch.setChecked(false);
2800d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            } else {
2819e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka                mManagedProfileSwitch.setChecked(!isRestrictedByBase);
2829e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka                summaryResId = (isRestrictedByBase ?
2830d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka                        R.string.switch_off_text : R.string.switch_on_text);
2840d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka                mManagedProfileSwitch.setOnPreferenceClickListener(
2850d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka                        mManagedProfileSwitchClickListener);
2860d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            }
2870d9ac3469b5bd9c680e4f3d72dae7767a60ce8a9Sudheer Shanka            mManagedProfileSwitch.setSummary(summaryResId);
288ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        }
28986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    }
29086c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban
291421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill    /**
292421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill     * Add the settings injected by external apps into the "App Settings" category. Hides the
293421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill     * category if there are no injected settings.
294421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill     *
295421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill     * Reloads the settings whenever receives
29672bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang     * {@link SettingInjectorService#ACTION_INJECTED_SETTING_CHANGED}.
297421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill     */
29886c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban    private void addLocationServices(Context context, PreferenceScreen root,
29986c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban            boolean lockdownOnLocationAccess) {
3005ab9fa432d17fe72c74a25770a26d405635cc0f6Lifu Tang        PreferenceCategory categoryLocationServices =
3015ab9fa432d17fe72c74a25770a26d405635cc0f6Lifu Tang                (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES);
30272bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        injector = new SettingsInjector(context);
30386c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // If location access is locked down by device policy then we only show injected settings
30486c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        // for the primary profile.
30586c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        List<Preference> locationServices = injector.getInjectedSettings(lockdownOnLocationAccess ?
30686c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban                UserHandle.myUserId() : UserHandle.USER_CURRENT);
30732e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang
30832e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang        mReceiver = new BroadcastReceiver() {
30932e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang            @Override
31032e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang            public void onReceive(Context context, Intent intent) {
311e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neill                if (Log.isLoggable(TAG, Log.DEBUG)) {
312e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neill                    Log.d(TAG, "Received settings change intent: " + intent);
313e17ce5fb73efe8046f9d806a6fbb9a5abb5b0e87Tom O'Neill                }
31432e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang                injector.reloadStatusMessages();
31532e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang            }
31632e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang        };
317421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill
318421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill        IntentFilter filter = new IntentFilter();
319421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill        filter.addAction(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED);
320421dccd5dd8cdec03bbc704b142f3ca2396f7e40Tom O'Neill        context.registerReceiver(mReceiver, filter);
32132e016b5fae1f4caf673ff1f062869dce0e94757Lifu Tang
3225ab9fa432d17fe72c74a25770a26d405635cc0f6Lifu Tang        if (locationServices.size() > 0) {
3235ab9fa432d17fe72c74a25770a26d405635cc0f6Lifu Tang            addPreferencesSorted(locationServices, categoryLocationServices);
32408a4c33a409f7cc693527de138179f80bf07be9cLifu Tang        } else {
32508a4c33a409f7cc693527de138179f80bf07be9cLifu Tang            // If there's no item to display, remove the whole category.
3265ab9fa432d17fe72c74a25770a26d405635cc0f6Lifu Tang            root.removePreference(categoryLocationServices);
32708a4c33a409f7cc693527de138179f80bf07be9cLifu Tang        }
328a6a8a1479b970d8a84395453703348fe42d17438Gilles Debunne    }
3298442db24a1f75e67ea658e7fd29708ef3fa4af1bAmith Yamasani
33038223dc4585bb8f11125c90082789db78881e97dAmith Yamasani    @Override
331cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
332cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang        menu.add(0, MENU_SCANNING, 0, R.string.location_menu_scanning);
333cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang        // The super class adds "Help & Feedback" menu item.
334cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang        super.onCreateOptionsMenu(menu, inflater);
335cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    }
336cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang
337cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    @Override
338cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    public boolean onOptionsItemSelected(MenuItem item) {
339cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang        final SettingsActivity activity = (SettingsActivity) getActivity();
340cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang        switch (item.getItemId()) {
341cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang            case MENU_SCANNING:
342cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang                activity.startPreferencePanel(
343cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang                        ScanningSettings.class.getName(), null,
344cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang                        R.string.location_scanning_screen_title, null, LocationSettings.this,
345cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang                        0);
346cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang                return true;
347cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang            default:
348cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang                return super.onOptionsItemSelected(item);
349cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang        }
350cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    }
351cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang
352cb193d55e17fc7cfdb195eea9b6c4b4c7af66b4bLifu Tang    @Override
35338223dc4585bb8f11125c90082789db78881e97dAmith Yamasani    public int getHelpResource() {
35438223dc4585bb8f11125c90082789db78881e97dAmith Yamasani        return R.string.help_url_location_access;
35538223dc4585bb8f11125c90082789db78881e97dAmith Yamasani    }
3568442db24a1f75e67ea658e7fd29708ef3fa4af1bAmith Yamasani
3579d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    private static int getLocationString(int mode) {
358e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        switch (mode) {
359263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            case android.provider.Settings.Secure.LOCATION_MODE_OFF:
3609d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                return R.string.location_mode_location_off_title;
361263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
3629d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                return R.string.location_mode_sensors_only_title;
363263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
3649d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                return R.string.location_mode_battery_saving_title;
365263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
3669d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                return R.string.location_mode_high_accuracy_title;
3679d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        }
3689d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        return 0;
3699d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    }
3709d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk
3719d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    @Override
3729d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    public void onModeChanged(int mode, boolean restricted) {
3739d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        int modeDescription = getLocationString(mode);
3749d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        if (modeDescription != 0) {
3759d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            mLocationMode.setSummary(modeDescription);
376e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        }
377e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
3789294fdb6f8803eab64dc26d05dcdede419644115Lifu Tang        // Restricted user can't change the location mode, so disable the master switch. But in some
3799294fdb6f8803eab64dc26d05dcdede419644115Lifu Tang        // corner cases, the location might still be enabled. In such case the master switch should
3809294fdb6f8803eab64dc26d05dcdede419644115Lifu Tang        // be disabled but checked.
38186c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban        final boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF);
3829c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
3839c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka                UserManager.DISALLOW_SHARE_LOCATION, UserHandle.myUserId());
3849e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka        boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
3859e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka                UserManager.DISALLOW_SHARE_LOCATION, UserHandle.myUserId());
386387ecc6931c36a068efeaf6cc916307317d07c10Lifu Tang        // Disable the whole switch bar instead of the switch itself. If we disabled the switch
387387ecc6931c36a068efeaf6cc916307317d07c10Lifu Tang        // only, it would be re-enabled again if the switch bar is not disabled.
3889e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka        if (!hasBaseUserRestriction && admin != null) {
3899c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            mSwitchBar.setDisabledByAdmin(admin);
3909c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        } else {
3919c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka            mSwitchBar.setEnabled(!restricted);
3929c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka        }
3939294fdb6f8803eab64dc26d05dcdede419644115Lifu Tang        mLocationMode.setEnabled(enabled && !restricted);
394d3a77665ef13755cf463dff27f50d78c16e595d8Lifu Tang        mCategoryRecentLocationRequests.setEnabled(enabled);
395e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
396e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        if (enabled != mSwitch.isChecked()) {
397e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            // set listener to null so that that code below doesn't trigger onCheckedChanged()
398e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            if (mValidListener) {
399304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio                mSwitchBar.removeOnSwitchChangeListener(this);
400e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            }
401e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            mSwitch.setChecked(enabled);
402e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            if (mValidListener) {
403304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio                mSwitchBar.addOnSwitchChangeListener(this);
404e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang            }
405e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        }
40686c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban
407ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        changeManagedProfileLocationAccessStatus(enabled);
40886c877e9b66165bb46432de6172d1fdc6b2808feZoltan Szatmary-Ban
40972bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        // As a safety measure, also reloads on location mode change to ensure the settings are
41072bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        // up-to-date even if an affected app doesn't send the setting changed broadcast.
41172bafff2b817a47da4c4c649c746ca72251cc9a4Lifu Tang        injector.reloadStatusMessages();
412e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    }
413e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang
414e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    /**
415e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang     * Listens to the state change of the location master switch.
416e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang     */
417e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang    @Override
418304100350372f0bda4836e62bc6f55aad85c068dFabrice Di Meglio    public void onSwitchChanged(Switch switchView, boolean isChecked) {
419e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        if (isChecked) {
420ee0db4c35bd4284102e6a59a4426c85b463b7841Lifu Tang            setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_PREVIOUS);
421e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        } else {
422263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_OFF);
423e63142329060fabe105a8fd939cb637d530ae4a3Lifu Tang        }
4248442db24a1f75e67ea658e7fd29708ef3fa4af1bAmith Yamasani    }
425f313a75e262026f7d33969b0aa174686692f6aafTony Mantler
426ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban    private boolean isManagedProfileRestrictedByBase() {
427ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        if (mManagedProfile == null) {
428ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            return false;
429ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        }
430ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban        return mUm.hasBaseUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile);
431ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban    }
432ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban
433ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban    private Preference.OnPreferenceClickListener mManagedProfileSwitchClickListener =
434ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            new Preference.OnPreferenceClickListener() {
435ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                @Override
436ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                public boolean onPreferenceClick(Preference preference) {
437ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                    final boolean switchState = mManagedProfileSwitch.isChecked();
438ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                    mUm.setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION,
439ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                            !switchState, mManagedProfile);
440ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                    mManagedProfileSwitch.setSummary(switchState ?
441ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                            R.string.switch_on_text : R.string.switch_off_text);
442ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                    return true;
443ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban                }
444ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban            };
445ad0ca96fcd271d1e07fd4b9a36ed6a7ea35971afZoltan Szatmary-Ban
446f313a75e262026f7d33969b0aa174686692f6aafTony Mantler    private class PackageEntryClickedListener
447f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            implements Preference.OnPreferenceClickListener {
448f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        private String mPackage;
449f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        private UserHandle mUserHandle;
450f313a75e262026f7d33969b0aa174686692f6aafTony Mantler
451f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        public PackageEntryClickedListener(String packageName, UserHandle userHandle) {
452f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            mPackage = packageName;
453f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            mUserHandle = userHandle;
454f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        }
455f313a75e262026f7d33969b0aa174686692f6aafTony Mantler
456f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        @Override
457f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        public boolean onPreferenceClick(Preference preference) {
458f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            // start new fragment to display extended information
459f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            Bundle args = new Bundle();
460f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
4618b886c4649e04b3bc0fbc50de0cd82bdbb11b9b1Jason Monk            ((SettingsActivity) getActivity()).startPreferencePanelAsUser(
462f313a75e262026f7d33969b0aa174686692f6aafTony Mantler                    InstalledAppDetails.class.getName(), args,
463f313a75e262026f7d33969b0aa174686692f6aafTony Mantler                    R.string.application_info_label, null, mUserHandle);
464f313a75e262026f7d33969b0aa174686692f6aafTony Mantler            return true;
465f313a75e262026f7d33969b0aa174686692f6aafTony Mantler        }
466f313a75e262026f7d33969b0aa174686692f6aafTony Mantler    }
4679d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk
4689d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
4699d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk
4709d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        private final Context mContext;
4719d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        private final SummaryLoader mSummaryLoader;
4729d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk
4739d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        public SummaryProvider(Context context, SummaryLoader summaryLoader) {
4749d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            mContext = context;
4759d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            mSummaryLoader = summaryLoader;
4769d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        }
4779d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk
4789d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        @Override
4799d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        public void setListening(boolean listening) {
4809d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            if (listening) {
4819d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                int mode = Settings.Secure.getInt(mContext.getContentResolver(),
4829d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                        Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
4839d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                if (mode != Settings.Secure.LOCATION_MODE_OFF) {
4849d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                    mSummaryLoader.setSummary(this, mContext.getString(R.string.location_on_summary,
4859d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                            mContext.getString(getLocationString(mode))));
4869d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                } else {
4879d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                    mSummaryLoader.setSummary(this,
4889d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                            mContext.getString(R.string.location_off_summary));
4899d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                }
4909d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            }
4919d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        }
4929d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    }
4939d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk
4949d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
4959d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            = new SummaryLoader.SummaryProviderFactory() {
4969d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        @Override
4979d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
4989d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk                                                                   SummaryLoader summaryLoader) {
4999d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk            return new SummaryProvider(activity, summaryLoader);
5009d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk        }
5019d80eeabe7807b5ff0a60bd40d3a1a84f681ea37Jason Monk    };
5028442db24a1f75e67ea658e7fd29708ef3fa4af1bAmith Yamasani}
503