1 /* 2 * Copyright (C) 2014 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.phone; 18 19 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; 20 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; 21 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; 22 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; 23 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS; 24 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE; 25 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK; 26 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID; 27 import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS; 28 import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS; 29 import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS; 30 31 import android.content.Context; 32 import android.database.Cursor; 33 import android.database.MatrixCursor; 34 import android.os.Binder; 35 import android.os.UserManager; 36 import android.provider.SearchIndexableResource; 37 import android.provider.SearchIndexablesContract.RawData; 38 import android.provider.SearchIndexablesProvider; 39 import android.support.annotation.VisibleForTesting; 40 import android.telephony.euicc.EuiccManager; 41 42 public class PhoneSearchIndexablesProvider extends SearchIndexablesProvider { 43 private static final String TAG = "PhoneSearchIndexablesProvider"; 44 private UserManager mUserManager; 45 46 private static SearchIndexableResource[] INDEXABLE_RES = new SearchIndexableResource[] { 47 new SearchIndexableResource(1, R.xml.network_setting_fragment, 48 MobileNetworkSettings.class.getName(), 49 R.mipmap.ic_launcher_phone), 50 }; 51 52 @Override 53 public boolean onCreate() { 54 mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); 55 return true; 56 } 57 58 @Override 59 public Cursor queryXmlResources(String[] projection) { 60 MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS); 61 final int count = INDEXABLE_RES.length; 62 for (int n = 0; n < count; n++) { 63 Object[] ref = new Object[7]; 64 ref[COLUMN_INDEX_XML_RES_RANK] = INDEXABLE_RES[n].rank; 65 ref[COLUMN_INDEX_XML_RES_RESID] = INDEXABLE_RES[n].xmlResId; 66 ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = null; 67 ref[COLUMN_INDEX_XML_RES_ICON_RESID] = INDEXABLE_RES[n].iconResId; 68 ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = "android.intent.action.MAIN"; 69 ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = "com.android.phone"; 70 ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = INDEXABLE_RES[n].className; 71 cursor.addRow(ref); 72 } 73 return cursor; 74 } 75 76 @Override 77 public Cursor queryRawData(String[] projection) { 78 MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS); 79 Context context = getContext(); 80 String title = context.getString(R.string.carrier_settings_euicc); 81 cursor.newRow() 82 .add(RawData.COLUMN_RANK, 0) 83 .add(RawData.COLUMN_TITLE, title) 84 .add( 85 RawData.COLUMN_KEYWORDS, 86 context.getString(R.string.keywords_carrier_settings_euicc)) 87 .add(RawData.COLUMN_SCREEN_TITLE, title) 88 .add(RawData.COLUMN_KEY, "esim_list_profile") 89 .add( 90 RawData.COLUMN_INTENT_ACTION, 91 EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS) 92 .add( 93 RawData.COLUMN_INTENT_TARGET_PACKAGE, 94 context.getPackageName()); 95 return cursor; 96 } 97 98 @Override 99 public Cursor queryNonIndexableKeys(String[] projection) { 100 final long uidToken = Binder.clearCallingIdentity(); 101 try { 102 MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS); 103 104 if (!mUserManager.isAdminUser()) { 105 final String[] values = new String[]{"preferred_network_mode_key", 106 "button_roaming_key", "cdma_lte_data_service_key", "enhanced_4g_lte", 107 "button_apn_key", "button_carrier_sel_key", "carrier_settings_key", 108 "cdma_system_select_key", "esim_list_profile", "mobile_data_enable", 109 "data_usage_summary", "wifi_calling_key", "video_calling_key"}; 110 for (String nik : values) { 111 cursor.addRow(createNonIndexableRow(nik)); 112 } 113 } else { 114 if (isEuiccSettingsHidden()) { 115 cursor.addRow(createNonIndexableRow("esim_list_profile" /* key */)); 116 } 117 if (isEnhanced4gLteHidden()) { 118 cursor.addRow(createNonIndexableRow("enhanced_4g_lte" /* key */)); 119 } 120 } 121 122 // enabled_networks button and preferred_network_mode button share the same title 123 // "Preferred network type"and are mutual exclusive. Thus we remove one from search 124 // result to avoid duplicate search result. 125 // TODO: b/63381516 all hidden buttons should dynamically be removed from search result. 126 cursor.addRow(createNonIndexableRow("enabled_networks_key" /* key */)); 127 cursor.addRow(createNonIndexableRow("carrier_settings_euicc_key" /* key */)); 128 cursor.addRow(createNonIndexableRow("advanced_options" /* key */)); 129 return cursor; 130 } finally { 131 Binder.restoreCallingIdentity(uidToken); 132 } 133 } 134 135 @VisibleForTesting boolean isEuiccSettingsHidden() { 136 return !MobileNetworkSettings.showEuiccSettings(getContext()); 137 } 138 139 @VisibleForTesting boolean isEnhanced4gLteHidden() { 140 return MobileNetworkSettings.hideEnhanced4gLteSettings(getContext()); 141 } 142 143 private Object[] createNonIndexableRow(String key) { 144 final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length]; 145 ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = key; 146 return ref; 147 } 148 } 149