1 /*
2  * Copyright (C) 2016 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 package com.android.settings.users;
17 
18 import android.app.ActivityManager;
19 import android.app.Dialog;
20 import android.app.settings.SettingsEnums;
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.os.Bundle;
25 import android.os.Process;
26 import android.os.UserHandle;
27 import android.os.UserManager;
28 import android.util.Log;
29 
30 import androidx.appcompat.app.AlertDialog;
31 import androidx.fragment.app.Fragment;
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceFragmentCompat;
34 import androidx.preference.TwoStatePreference;
35 
36 import com.android.settings.R;
37 import com.android.settings.core.PreferenceControllerMixin;
38 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
39 import com.android.settingslib.core.AbstractPreferenceController;
40 
41 public class AutoSyncDataPreferenceController extends AbstractPreferenceController
42         implements PreferenceControllerMixin {
43 
44     private static final String TAG = "AutoSyncDataController";
45     private static final String TAG_CONFIRM_AUTO_SYNC_CHANGE = "confirmAutoSyncChange";
46     private static final String KEY_AUTO_SYNC_ACCOUNT = "auto_sync_account_data";
47 
48     protected final UserManager mUserManager;
49     private final PreferenceFragmentCompat mParentFragment;
50 
51     protected UserHandle mUserHandle;
52 
AutoSyncDataPreferenceController(Context context, PreferenceFragmentCompat parent)53     public AutoSyncDataPreferenceController(Context context, PreferenceFragmentCompat parent) {
54         super(context);
55         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
56         mParentFragment = parent;
57         mUserHandle = Process.myUserHandle();
58     }
59 
60     @Override
updateState(Preference preference)61     public void updateState(Preference preference) {
62         TwoStatePreference switchPreference = (TwoStatePreference) preference;
63         switchPreference.setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser(
64                 mUserHandle.getIdentifier()));
65     }
66 
67     @Override
handlePreferenceTreeClick(Preference preference)68     public boolean handlePreferenceTreeClick(Preference preference) {
69         if (getPreferenceKey().equals(preference.getKey())) {
70             TwoStatePreference switchPreference = (TwoStatePreference) preference;
71             boolean checked = switchPreference.isChecked();
72             switchPreference.setChecked(!checked);
73             if (ActivityManager.isUserAMonkey()) {
74                 Log.d(TAG, "ignoring monkey's attempt to flip sync state");
75             } else {
76                 ConfirmAutoSyncChangeFragment
77                         .newInstance(checked, mUserHandle.getIdentifier(), getPreferenceKey())
78                         .show(mParentFragment);
79             }
80             return true;
81         }
82         return false;
83     }
84 
85     @Override
isAvailable()86     public boolean isAvailable() {
87         return !mUserManager.isManagedProfile()
88                 && (mUserManager.isRestrictedProfile()
89                 || mUserManager.getProfiles(UserHandle.myUserId()).size() == 1);
90     }
91 
92     @Override
getPreferenceKey()93     public String getPreferenceKey() {
94         return KEY_AUTO_SYNC_ACCOUNT;
95     }
96 
97     /**
98      * Dialog to inform user about changing auto-sync setting
99      */
100     public static class ConfirmAutoSyncChangeFragment extends InstrumentedDialogFragment implements
101             DialogInterface.OnClickListener {
102         private static final String ARG_ENABLING = "enabling";
103         private static final String ARG_USER_ID = "userId";
104         private static final String ARG_KEY = "key";
105 
newInstance(boolean enabling, int userId, String key)106         static ConfirmAutoSyncChangeFragment newInstance(boolean enabling, int userId, String key) {
107             ConfirmAutoSyncChangeFragment dialogFragment = new ConfirmAutoSyncChangeFragment();
108             Bundle arguments = new Bundle();
109             arguments.putBoolean(ARG_ENABLING, enabling);
110             arguments.putInt(ARG_USER_ID, userId);
111             arguments.putString(ARG_KEY, key);
112             dialogFragment.setArguments(arguments);
113             return dialogFragment;
114         }
115 
show(PreferenceFragmentCompat parent)116         void show(PreferenceFragmentCompat parent) {
117             if (!parent.isAdded()) {
118                 return;
119             }
120             setTargetFragment(parent, 0);
121             show(parent.getParentFragmentManager(), TAG_CONFIRM_AUTO_SYNC_CHANGE);
122         }
123 
124         @Override
onCreateDialog(Bundle savedInstanceState)125         public Dialog onCreateDialog(Bundle savedInstanceState) {
126             final Context context = getActivity();
127             final AlertDialog.Builder builder = new AlertDialog.Builder(context);
128             if (!requireArguments().getBoolean(ARG_ENABLING)) {
129                 builder.setTitle(R.string.data_usage_auto_sync_off_dialog_title);
130                 builder.setMessage(R.string.data_usage_auto_sync_off_dialog);
131             } else {
132                 builder.setTitle(R.string.data_usage_auto_sync_on_dialog_title);
133                 builder.setMessage(R.string.data_usage_auto_sync_on_dialog);
134             }
135 
136             builder.setPositiveButton(android.R.string.ok, this);
137             builder.setNegativeButton(android.R.string.cancel, null);
138 
139             return builder.create();
140         }
141 
142         @Override
getMetricsCategory()143         public int getMetricsCategory() {
144             return SettingsEnums.DIALOG_CONFIRM_AUTO_SYNC_CHANGE;
145         }
146 
147         @Override
onClick(DialogInterface dialog, int which)148         public void onClick(DialogInterface dialog, int which) {
149             if (which == DialogInterface.BUTTON_POSITIVE) {
150                 Bundle arguments = requireArguments();
151                 boolean enabling = arguments.getBoolean(ARG_ENABLING);
152                 ContentResolver.setMasterSyncAutomaticallyAsUser(enabling,
153                         arguments.getInt(ARG_USER_ID));
154                 Fragment targetFragment = getTargetFragment();
155                 if (targetFragment instanceof PreferenceFragmentCompat) {
156                     Preference preference =
157                             ((PreferenceFragmentCompat) targetFragment).findPreference(
158                                     arguments.getString(ARG_KEY));
159                     if (preference instanceof TwoStatePreference) {
160                         ((TwoStatePreference) preference).setChecked(enabling);
161                     }
162                 }
163             }
164         }
165     }
166 
167 }
168