CarNavigationBarController.java revision c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8
12b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/* 22b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Copyright (C) 2015 The Android Open Source Project 32b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * 42b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Licensed under the Apache License, Version 2.0 (the "License"); 52b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * you may not use this file except in compliance with the License. 62b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * You may obtain a copy of the License at 72b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * 82b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * http://www.apache.org/licenses/LICENSE-2.0 92b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * 102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Unless required by applicable law or agreed to in writing, software 112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * distributed under the License is distributed on an "AS IS" BASIS, 122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * See the License for the specific language governing permissions and 142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * limitations under the License. 152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */ 162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianpackage com.android.systemui.statusbar.car; 172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.content.Context; 192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.content.Intent; 202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.content.pm.PackageManager; 212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.content.pm.ResolveInfo; 222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.content.res.Resources; 232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.content.res.TypedArray; 242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.graphics.drawable.Drawable; 252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.support.v4.util.SimpleArrayMap; 262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.view.View; 272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport android.widget.LinearLayout; 282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport com.android.systemui.R; 292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport com.android.systemui.statusbar.phone.ActivityStarter; 302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport java.net.URISyntaxException; 322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport java.util.ArrayList; 332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianimport java.util.List; 342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/** 362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * A controller to populate data for CarNavigationBarView and handle user interactions. 372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * <p/> 382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can customize 392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * the navigation buttons by updating arrays_car.xml appropriately in an overlay. 402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */ 412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianclass CarNavigationBarController { 422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private static final String EXTRA_FACET_CATEGORIES = "categories"; 432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private static final String EXTRA_FACET_PACKAGES = "packages"; 442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private static final String EXTRA_FACET_ID = "filter_id"; 452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker"; 462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Each facet of the navigation bar maps to a set of package names or categories defined in 482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // arrays_car.xml. Package names for a given facet are delimited by ";" 492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private static final String FACET_FILTER_DEMILITER = ";"; 502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 512b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private Context mContext; 522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private CarNavigationBarView mNavBar; 532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private ActivityStarter mActivityStarter; 542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Set of categories each facet will filter on. 562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private List<String[]> mFacetCategories = new ArrayList<String[]>(); 572b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Set of package names each facet will filter on. 582b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private List<String[]> mFacetPackages = new ArrayList<String[]>(); 592b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private SimpleArrayMap<String, Integer> mFacetCategoryMap 612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian = new SimpleArrayMap<String, Integer>(); 622b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private SimpleArrayMap<String, Integer> mFacetPackageMap 635b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian = new SimpleArrayMap<String, Integer>(); 645b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian 655b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian private List<Intent> mIntents = new ArrayList<Intent>(); 665b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian private List<Intent> mLongPressIntents = new ArrayList<Intent>(); 675b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian 685b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>(); 695b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian 70d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian private int mCurrentFacetIndex; 71d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian private String mCurrentPackageName; 725b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian 732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian public CarNavigationBarController(Context context, 742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian CarNavigationBarView navBar, 752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian ActivityStarter activityStarter) { 762b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mContext = context; 772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mNavBar = navBar; 782b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mActivityStarter = activityStarter; 796d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian bind(); 806d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian } 816d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian 826d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian public void taskChanged(String packageName) { 836d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian mCurrentPackageName = packageName; 842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // If the package name belongs to a filter, then highlight appropriate button in 852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // the navigation bar. 862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (mFacetPackageMap.containsKey(packageName)) { 87b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian setCurrentFacet(mFacetPackageMap.get(packageName)); 882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Check if the package matches any of the categories for the facets 912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian String category = getPackageCategory(packageName); 925b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian if (category != null) { 935b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian setCurrentFacet(mFacetCategoryMap.get(category)); 942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private void bind() { 982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Read up arrays_car.xml and populate the navigation bar here. 992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Resources r = mContext.getResources(); 1002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian TypedArray icons = r.obtainTypedArray(R.array.car_facet_icons); 1012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian TypedArray intents = r.obtainTypedArray(R.array.car_facet_intent_uris); 1022b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian TypedArray longpressIntents = 1032b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian r.obtainTypedArray(R.array.car_facet_longpress_intent_uris); 1042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian TypedArray facetPackageNames = r.obtainTypedArray(R.array.car_facet_package_filters); 1052b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1062b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian TypedArray facetCategories = r.obtainTypedArray(R.array.car_facet_category_filters); 1072b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1082b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (icons.length() != intents.length() 1092b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian || icons.length() != longpressIntents.length() 1102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian || icons.length() != facetPackageNames.length() 1112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian || icons.length() != facetCategories.length()) { 1122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian throw new RuntimeException("car_facet array lengths do not match"); 1132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian for (int i = 0; i < icons.length(); i++) { 1162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Drawable icon = icons.getDrawable(i); 1172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian try { 1182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mIntents.add(i, 1192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Intent.parseUri(intents.getString(i), Intent.URI_INTENT_SCHEME)); 1202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian String longpressUri = longpressIntents.getString(i); 1222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian boolean hasLongpress = !longpressUri.isEmpty(); 1232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (hasLongpress) { 1242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mLongPressIntents.add(i, 1252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Intent.parseUri(longpressUri, Intent.URI_INTENT_SCHEME)); 1262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian CarNavigationButton button = createNavButton(icon, i, hasLongpress); 1292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mNavButtons.add(button); 1302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mNavBar.addButton(button, 1312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian createNavButton(icon, i, hasLongpress) /* lightsOutButton */); 1322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian initFacetFilterMaps(i, 1342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian facetPackageNames.getString(i).split(FACET_FILTER_DEMILITER), 1352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian facetCategories.getString(i).split(FACET_FILTER_DEMILITER)); 1362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } catch (URISyntaxException e) { 1372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian throw new RuntimeException("Malformed intent uri", e); 1382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1415b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian 1422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private void initFacetFilterMaps(int id, String[] packageNames, String[] categories) { 1432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mFacetCategories.add(categories); 1442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian for (int i = 0; i < categories.length; i++) { 1452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mFacetCategoryMap.put(categories[i], id); 1462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mFacetPackages.add(packageNames); 1492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian for (int i = 0; i < packageNames.length; i++) { 1502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mFacetPackageMap.put(packageNames[i], id); 1512b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private String getPackageCategory(String packageName) { 1552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian PackageManager pm = mContext.getPackageManager(); 1562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian int size = mFacetCategories.size(); 1572b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // For each facet, check if the given package name matches one of its categories 1582b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian for (int i = 0; i < size; i++) { 1596d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian String[] categories = mFacetCategories.get(i); 1602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian for (int j = 0; j < categories.length; j++) { 1612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian String category = categories[j]; 1622b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Intent intent = new Intent(); 1632b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.setPackage(packageName); 1642b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.setAction(Intent.ACTION_MAIN); 1656d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian intent.addCategory(category); 1662b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian List<ResolveInfo> list = pm.queryIntentActivities(intent, 0); 1672b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (list.size() > 0) { 1682b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Cache this package name into facetPackageMap, so we won't have to query 1692b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // all categories next time this package name shows up. 1706d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian mFacetPackageMap.put(packageName, mFacetCategoryMap.get(category)); 1712b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return category; 1722b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return null; 1765b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian } 1772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1785b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian /** 1792b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Helper method to check if a given facet has multiple packages associated with it. 1802b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * This can be resource defined package names or package names filtered by facet category. 1812b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */ 1822b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private boolean facetHasMultiplePackages(int index) { 1832b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian PackageManager pm = mContext.getPackageManager(); 1842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Check if the packages defined for the filter actually exists on the device 1862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian String[] packages = mFacetPackages.get(index); 1872b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (packages.length > 1) { 1882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian int count = 0; 1892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian for (int i = 0; i < packages.length; i++) { 1902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian count += pm.getLaunchIntentForPackage(packages[i]) != null ? 1 : 0; 1912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (count > 1) { 1922b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return true; 1932b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 1962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 1972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // If there weren't multiple packages defined for the facet, check the categories 1982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // and see if they resolve to multiple package names 1992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian String categories[] = mFacetCategories.get(index); 2002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian int count = 0; 2025b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian for (int i = 0; i < categories.length; i++) { 2035b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian String category = categories[i]; 2042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Intent intent = new Intent(); 2055b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian intent.setAction(Intent.ACTION_MAIN); 2062b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.addCategory(category); 2072b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian count += pm.queryIntentActivities(intent, 0).size(); 2082b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (count > 1) { 2092b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return true; 2102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return false; 2132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private void setCurrentFacet(int index) { 2162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (index == mCurrentFacetIndex) { 2172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return; 2182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (mNavButtons.get(mCurrentFacetIndex) != null) { 2212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mNavButtons.get(mCurrentFacetIndex) 2222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian .setSelected(false /* selected */, false /* showMoreIcon */); 2232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (mNavButtons.get(index) != null) { 2262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mNavButtons.get(index).setSelected(true /* selected */, 2272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian facetHasMultiplePackages(index) /* showMoreIcon */); 2282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian mCurrentFacetIndex = index; 2302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private CarNavigationButton createNavButton(Drawable icon, final int id, 2332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian boolean longClickEnabled) { 2342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian CarNavigationButton button = (CarNavigationButton) View.inflate(mContext, 2352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian R.layout.car_navigation_button, null); 2362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian button.setResources(icon); 2372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian LinearLayout.LayoutParams lp = 2382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1); 2392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian button.setLayoutParams(lp); 2402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian button.setOnClickListener(new View.OnClickListener() { 2422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian @Override 2432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian public void onClick(View v) { 2442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian onFacetClicked(id); 2452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian }); 2472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (longClickEnabled) { 2492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian button.setLongClickable(true); 2502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian button.setOnLongClickListener(new View.OnLongClickListener() { 251b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian @Override 2522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian public boolean onLongClick(View v) { 2532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian onFacetLongClicked(id); 2542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return true; 2552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian }); 257d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian } else { 258d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian button.setLongClickable(false); 2592b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 261b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian return button; 262b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian } 263b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian 2642b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private void startActivity(Intent intent) { 265d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian if (mActivityStarter != null && intent != null) { 266d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian mActivityStarter.startActivity(intent, true); 2672b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2682b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2692b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2702b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private void onFacetClicked(int index) { 2712b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian Intent intent = mIntents.get(index); 2722b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian String packageName = intent.getPackage(); 2732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (packageName == null) { 2752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return; 2762b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2782b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // Don't launch the lens picker if it's already running and the 2792b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // user clicks the same facet 2802b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian if (packageName.equals(mCurrentPackageName) && index == mCurrentFacetIndex) { 2812b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian return; 2822b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2832b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.putExtra(EXTRA_FACET_CATEGORIES, mFacetCategories.get(index)); 2852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.putExtra(EXTRA_FACET_PACKAGES, mFacetPackages.get(index)); 2862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // The facet is identified by the index in which it was added to the nav bar. 2872b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // This value can be used to determine which facet was selected 2882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.putExtra(EXTRA_FACET_ID, Integer.toString(index)); 2892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // If the current facet is clicked, we want to launch the picker by default 2912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian // rather than the "preferred/last run" app. 2922b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian intent.putExtra(EXTRA_FACET_LAUNCH_PICKER, index == mCurrentFacetIndex); 2932b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian setCurrentFacet(index); 2952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian startActivity(intent); 2962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 2972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian 2982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian private void onFacetLongClicked(int index) { 2992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian setCurrentFacet(index); 3002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian startActivity(mLongPressIntents.get(index)); 3012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian } 3022b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian} 3032b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian