1 /* 2 * Copyright (C) 2019 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 17 package com.android.settingslib.drawer; 18 19 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT; 20 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY; 21 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE; 22 23 import android.content.ContentProvider; 24 import android.content.ContentValues; 25 import android.content.Context; 26 import android.content.pm.ProviderInfo; 27 import android.database.Cursor; 28 import android.net.Uri; 29 import android.os.Bundle; 30 import android.text.TextUtils; 31 import android.util.Log; 32 33 import java.util.ArrayList; 34 import java.util.LinkedHashMap; 35 import java.util.List; 36 import java.util.Map; 37 38 /** 39 * An abstract class for injecting switches to Settings. 40 */ 41 public abstract class SwitchesProvider extends ContentProvider { 42 private static final String TAG = "SwitchesProvider"; 43 44 public static final String METHOD_GET_SWITCH_DATA = "getSwitchData"; 45 public static final String METHOD_GET_PROVIDER_ICON = "getProviderIcon"; 46 public static final String METHOD_GET_DYNAMIC_TITLE = "getDynamicTitle"; 47 public static final String METHOD_GET_DYNAMIC_SUMMARY = "getDynamicSummary"; 48 public static final String METHOD_IS_CHECKED = "isChecked"; 49 public static final String METHOD_ON_CHECKED_CHANGED = "onCheckedChanged"; 50 51 public static final String EXTRA_SWITCH_DATA = "switch_data"; 52 public static final String EXTRA_SWITCH_CHECKED_STATE = "checked_state"; 53 public static final String EXTRA_SWITCH_SET_CHECKED_ERROR = "set_checked_error"; 54 public static final String EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE = "set_checked_error_message"; 55 56 private String mAuthority; 57 private final Map<String, SwitchController> mControllerMap = new LinkedHashMap<>(); 58 private final List<Bundle> mSwitchDataList = new ArrayList<>(); 59 60 /** 61 * Get a list of {@link SwitchController} for this provider. 62 */ createSwitchControllers()63 protected abstract List<SwitchController> createSwitchControllers(); 64 65 @Override attachInfo(Context context, ProviderInfo info)66 public void attachInfo(Context context, ProviderInfo info) { 67 mAuthority = info.authority; 68 Log.i(TAG, mAuthority); 69 super.attachInfo(context, info); 70 } 71 72 @Override onCreate()73 public boolean onCreate() { 74 final List<SwitchController> controllers = createSwitchControllers(); 75 if (controllers == null || controllers.isEmpty()) { 76 throw new IllegalArgumentException(); 77 } 78 79 controllers.forEach(controller -> { 80 final String key = controller.getSwitchKey(); 81 if (TextUtils.isEmpty(key)) { 82 throw new NullPointerException("Switch key cannot be null: " 83 + controller.getClass().getSimpleName()); 84 } else if (mControllerMap.containsKey(key)) { 85 throw new IllegalArgumentException("Switch key " + key + " is duplicated by: " 86 + controller.getClass().getSimpleName()); 87 } 88 89 controller.setAuthority(mAuthority); 90 mControllerMap.put(key, controller); 91 if (!(controller instanceof PrimarySwitchController)) { 92 mSwitchDataList.add(controller.getBundle()); 93 } 94 }); 95 return true; 96 } 97 98 @Override call(String method, String uriString, Bundle extras)99 public Bundle call(String method, String uriString, Bundle extras) { 100 final Bundle bundle = new Bundle(); 101 final String key = extras != null 102 ? extras.getString(META_DATA_PREFERENCE_KEYHINT) 103 : null; 104 if (TextUtils.isEmpty(key)) { 105 if (METHOD_GET_SWITCH_DATA.equals(method)) { 106 bundle.putParcelableList(EXTRA_SWITCH_DATA, mSwitchDataList); 107 return bundle; 108 } 109 return null; 110 } 111 112 final SwitchController controller = mControllerMap.get(key); 113 if (controller == null) { 114 return null; 115 } 116 117 switch (method) { 118 case METHOD_GET_SWITCH_DATA: 119 if (!(controller instanceof PrimarySwitchController)) { 120 return controller.getBundle(); 121 } 122 break; 123 case METHOD_GET_PROVIDER_ICON: 124 if (controller instanceof ProviderIcon) { 125 return ((ProviderIcon) controller).getProviderIcon(); 126 } 127 break; 128 case METHOD_GET_DYNAMIC_TITLE: 129 if (controller instanceof DynamicTitle) { 130 bundle.putString(META_DATA_PREFERENCE_TITLE, 131 ((DynamicTitle) controller).getDynamicTitle()); 132 return bundle; 133 } 134 break; 135 case METHOD_GET_DYNAMIC_SUMMARY: 136 if (controller instanceof DynamicSummary) { 137 bundle.putString(META_DATA_PREFERENCE_SUMMARY, 138 ((DynamicSummary) controller).getDynamicSummary()); 139 return bundle; 140 } 141 break; 142 case METHOD_IS_CHECKED: 143 bundle.putBoolean(EXTRA_SWITCH_CHECKED_STATE, controller.isChecked()); 144 return bundle; 145 case METHOD_ON_CHECKED_CHANGED: 146 return onCheckedChanged(extras.getBoolean(EXTRA_SWITCH_CHECKED_STATE), controller); 147 } 148 return null; 149 } 150 onCheckedChanged(boolean checked, SwitchController controller)151 private Bundle onCheckedChanged(boolean checked, SwitchController controller) { 152 final boolean success = controller.onCheckedChanged(checked); 153 final Bundle bundle = new Bundle(); 154 bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, !success); 155 if (success) { 156 if (controller instanceof DynamicSummary) { 157 controller.notifySummaryChanged(getContext()); 158 } 159 } else { 160 bundle.putString(EXTRA_SWITCH_SET_CHECKED_ERROR_MESSAGE, 161 controller.getErrorMessage(checked)); 162 } 163 return bundle; 164 } 165 166 @Override query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)167 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 168 String sortOrder) { 169 throw new UnsupportedOperationException(); 170 } 171 172 @Override getType(Uri uri)173 public String getType(Uri uri) { 174 throw new UnsupportedOperationException(); 175 } 176 177 @Override insert(Uri uri, ContentValues values)178 public Uri insert(Uri uri, ContentValues values) { 179 throw new UnsupportedOperationException(); 180 } 181 182 @Override delete(Uri uri, String selection, String[] selectionArgs)183 public int delete(Uri uri, String selection, String[] selectionArgs) { 184 throw new UnsupportedOperationException(); 185 } 186 187 @Override update(Uri uri, ContentValues values, String selection, String[] selectionArgs)188 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 189 throw new UnsupportedOperationException(); 190 } 191 } 192