1 /* 2 * Copyright (C) 2021 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.settings.homepage; 18 19 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_HIGHLIGHTABLE_MENU_KEY; 20 import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY; 21 22 import android.annotation.XmlRes; 23 import android.content.Context; 24 import android.os.Bundle; 25 import android.text.TextUtils; 26 import android.util.ArrayMap; 27 import android.util.Log; 28 29 import com.android.settings.core.PreferenceXmlParserUtils; 30 import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag; 31 32 import org.xmlpull.v1.XmlPullParserException; 33 34 import java.io.IOException; 35 import java.util.List; 36 import java.util.Map; 37 38 /** 39 * Class for mapping highlightable menu keys and preference keys 40 */ 41 public class HighlightableMenu { 42 private static final String TAG = "HighlightableMenu"; 43 44 /** 45 * Map from highlightable menu key to preference key. 46 */ 47 private static final Map<String, String> MENU_TO_PREFERENCE_KEY_MAP; 48 49 /** 50 * Map from old menu key to current key string id. 51 */ 52 private static final Map<String, Integer> MENU_KEY_COMPAT_MAP; 53 54 private static boolean sXmlParsed; 55 56 static { 57 MENU_TO_PREFERENCE_KEY_MAP = new ArrayMap<>(); 58 MENU_KEY_COMPAT_MAP = new ArrayMap<>(); 59 60 // Manual mapping for platform compatibility, e.g. 61 // MENU_KEY_COMPAT_MAP.put("top_level_apps_and_notifs", R.string.menu_key_apps); 62 } 63 64 /** Parses the highlightable menu keys from xml */ fromXml(Context context, @XmlRes int xmlResId)65 public static synchronized void fromXml(Context context, @XmlRes int xmlResId) { 66 if (sXmlParsed) { 67 return; 68 } 69 70 Log.d(TAG, "parsing highlightable menu from xml"); 71 final List<Bundle> preferenceMetadata; 72 try { 73 preferenceMetadata = PreferenceXmlParserUtils.extractMetadata(context, xmlResId, 74 MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_HIGHLIGHTABLE_MENU_KEY); 75 } catch (IOException | XmlPullParserException e) { 76 Log.e(TAG, "Failed to parse preference xml for getting highlightable menu keys", e); 77 return; 78 } 79 80 for (Bundle metadata : preferenceMetadata) { 81 final String menuKey = metadata.getString(METADATA_HIGHLIGHTABLE_MENU_KEY); 82 if (TextUtils.isEmpty(menuKey)) { 83 continue; 84 } 85 final String prefKey = metadata.getString(METADATA_KEY); 86 if (TextUtils.isEmpty(prefKey)) { 87 Log.w(TAG, "Highlightable menu requires android:key but it's missing in xml: " 88 + menuKey); 89 continue; 90 } 91 MENU_TO_PREFERENCE_KEY_MAP.put(menuKey, prefKey); 92 } 93 94 if (MENU_TO_PREFERENCE_KEY_MAP.isEmpty()) { 95 return; 96 } 97 98 sXmlParsed = true; 99 MENU_KEY_COMPAT_MAP.forEach((compatMenuKey, keyId) -> { 100 final String prefKey = lookupPreferenceKey(context.getString(keyId)); 101 if (prefKey != null) { 102 MENU_TO_PREFERENCE_KEY_MAP.put(compatMenuKey, prefKey); 103 } 104 }); 105 } 106 107 /** Manually adds a preference as the menu key for Injection */ addMenuKey(String key)108 public static synchronized void addMenuKey(String key) { 109 Log.d(TAG, "add menu key: " + key); 110 MENU_TO_PREFERENCE_KEY_MAP.put(key, key); 111 } 112 113 /** Looks up the preference key by a specified menu key */ lookupPreferenceKey(String menuKey)114 public static String lookupPreferenceKey(String menuKey) { 115 return MENU_TO_PREFERENCE_KEY_MAP.get(menuKey); 116 } 117 } 118