CarNavigationBarController.java revision c0d7058b14c24cd07912f5629c26b39b7b4673d5
11c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan/* 21c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * Copyright (C) 2015 The Android Open Source Project 31c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * 41c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * Licensed under the Apache License, Version 2.0 (the "License"); 51c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * you may not use this file except in compliance with the License. 61c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * You may obtain a copy of the License at 71c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * 81c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * http://www.apache.org/licenses/LICENSE-2.0 91c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * 101c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * Unless required by applicable law or agreed to in writing, software 111c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * distributed under the License is distributed on an "AS IS" BASIS, 121c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * See the License for the specific language governing permissions and 141c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * limitations under the License. 151c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan */ 161c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanpackage com.android.systemui.statusbar.car; 171c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 181c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.content.Context; 191c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.content.Intent; 201c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.content.pm.PackageManager; 211c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.content.pm.ResolveInfo; 221c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.content.res.Resources; 231c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.content.res.TypedArray; 241c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.graphics.drawable.Drawable; 251c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.support.v4.util.SimpleArrayMap; 261c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.view.View; 271c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport android.widget.LinearLayout; 28c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson 291c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport com.android.systemui.R; 301c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport com.android.systemui.statusbar.phone.ActivityStarter; 311c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 321c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport java.net.URISyntaxException; 331c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport java.util.ArrayList; 3404a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsevimport java.util.Arrays; 351c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanimport java.util.List; 361c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 371c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan/** 381c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * A controller to populate data for CarNavigationBarView and handle user interactions. 391c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * <p/> 401c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can customize 411c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * the navigation buttons by updating arrays_car.xml appropriately in an overlay. 421c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan */ 431c6d0589f1c6429ca84402227cd5954479cf66edVictor Chanclass CarNavigationBarController { 44c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan private static final String EXTRA_FACET_CATEGORIES = "categories"; 45c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan private static final String EXTRA_FACET_PACKAGES = "packages"; 46c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan private static final String EXTRA_FACET_ID = "filter_id"; 47c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker"; 481c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 491c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Each facet of the navigation bar maps to a set of package names or categories defined in 501c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // arrays_car.xml. Package names for a given facet are delimited by ";" 511c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private static final String FACET_FILTER_DEMILITER = ";"; 521c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 531c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private Context mContext; 541c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private CarNavigationBarView mNavBar; 551c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private ActivityStarter mActivityStarter; 561c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 571c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Set of categories each facet will filter on. 581c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private List<String[]> mFacetCategories = new ArrayList<String[]>(); 591c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Set of package names each facet will filter on. 601c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private List<String[]> mFacetPackages = new ArrayList<String[]>(); 611c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 621c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private SimpleArrayMap<String, Integer> mFacetCategoryMap 631c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan = new SimpleArrayMap<String, Integer>(); 641c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private SimpleArrayMap<String, Integer> mFacetPackageMap 651c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan = new SimpleArrayMap<String, Integer>(); 661c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 6704a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev private List<Intent> mIntents; 6804a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev private List<Intent> mLongPressIntents; 691c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 701c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>(); 711c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 721c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private int mCurrentFacetIndex; 73c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan private String mCurrentPackageName; 741c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 751c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan public CarNavigationBarController(Context context, 761c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan CarNavigationBarView navBar, 771c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan ActivityStarter activityStarter) { 781c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mContext = context; 791c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mNavBar = navBar; 801c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mActivityStarter = activityStarter; 811c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan bind(); 821c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 831c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 841c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan public void taskChanged(String packageName) { 85c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan mCurrentPackageName = packageName; 861c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // If the package name belongs to a filter, then highlight appropriate button in 871c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // the navigation bar. 881c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (mFacetPackageMap.containsKey(packageName)) { 891c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan setCurrentFacet(mFacetPackageMap.get(packageName)); 901c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 911c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 921c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Check if the package matches any of the categories for the facets 931c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String category = getPackageCategory(packageName); 941c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (category != null) { 951c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan setCurrentFacet(mFacetCategoryMap.get(category)); 961c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 971c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 981c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 991c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private void bind() { 1001c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Read up arrays_car.xml and populate the navigation bar here. 1011c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan Resources r = mContext.getResources(); 1021c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan TypedArray icons = r.obtainTypedArray(R.array.car_facet_icons); 1031c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan TypedArray intents = r.obtainTypedArray(R.array.car_facet_intent_uris); 1041c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan TypedArray longpressIntents = 1051c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan r.obtainTypedArray(R.array.car_facet_longpress_intent_uris); 1061c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan TypedArray facetPackageNames = r.obtainTypedArray(R.array.car_facet_package_filters); 1071c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1081c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan TypedArray facetCategories = r.obtainTypedArray(R.array.car_facet_category_filters); 1091c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1101c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (icons.length() != intents.length() 1111c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan || icons.length() != longpressIntents.length() 1121c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan || icons.length() != facetPackageNames.length() 1131c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan || icons.length() != facetCategories.length()) { 1141c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan throw new RuntimeException("car_facet array lengths do not match"); 1151c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1161c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 11704a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev mIntents = createEmptyIntentList(icons.length()); 11804a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev mLongPressIntents = createEmptyIntentList(icons.length()); 11904a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev 1201c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int i = 0; i < icons.length(); i++) { 1211c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan Drawable icon = icons.getDrawable(i); 1221c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan try { 12304a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev mIntents.set(i, 1241c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan Intent.parseUri(intents.getString(i), Intent.URI_INTENT_SCHEME)); 1251c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1261c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String longpressUri = longpressIntents.getString(i); 1271c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan boolean hasLongpress = !longpressUri.isEmpty(); 1281c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (hasLongpress) { 12904a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev mLongPressIntents.set(i, 1301c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan Intent.parseUri(longpressUri, Intent.URI_INTENT_SCHEME)); 1311c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1321c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1331c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan CarNavigationButton button = createNavButton(icon, i, hasLongpress); 1341c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mNavButtons.add(button); 135c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan mNavBar.addButton(button, 136c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan createNavButton(icon, i, hasLongpress) /* lightsOutButton */); 1371c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1381c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan initFacetFilterMaps(i, 1391c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan facetPackageNames.getString(i).split(FACET_FILTER_DEMILITER), 1401c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan facetCategories.getString(i).split(FACET_FILTER_DEMILITER)); 1411c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } catch (URISyntaxException e) { 1421c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan throw new RuntimeException("Malformed intent uri", e); 1431c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1441c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1451c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1461c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 147c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan private void initFacetFilterMaps(int id, String[] packageNames, String[] categories) { 1481c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mFacetCategories.add(categories); 1491c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int i = 0; i < categories.length; i++) { 1501c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mFacetCategoryMap.put(categories[i], id); 1511c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1521c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1531c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mFacetPackages.add(packageNames); 1541c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int i = 0; i < packageNames.length; i++) { 1551c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mFacetPackageMap.put(packageNames[i], id); 1561c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1571c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1581c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1591c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private String getPackageCategory(String packageName) { 1601c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan PackageManager pm = mContext.getPackageManager(); 1611c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan int size = mFacetCategories.size(); 1621c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // For each facet, check if the given package name matches one of its categories 1631c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int i = 0; i < size; i++) { 1641c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String[] categories = mFacetCategories.get(i); 1651c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int j = 0; j < categories.length; j++) { 1661c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String category = categories[j]; 1671c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan Intent intent = new Intent(); 1681c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan intent.setPackage(packageName); 1691c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan intent.setAction(Intent.ACTION_MAIN); 1701c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan intent.addCategory(category); 1711c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan List<ResolveInfo> list = pm.queryIntentActivities(intent, 0); 1721c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (list.size() > 0) { 1731c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Cache this package name into facetPackageMap, so we won't have to query 1741c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // all categories next time this package name shows up. 1751c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mFacetPackageMap.put(packageName, mFacetCategoryMap.get(category)); 1761c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return category; 1771c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1781c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1791c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1801c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return null; 1811c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1821c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1831c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan /** 1841c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * Helper method to check if a given facet has multiple packages associated with it. 1851c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan * This can be resource defined package names or package names filtered by facet category. 1861c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan */ 1871c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private boolean facetHasMultiplePackages(int index) { 1881c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan PackageManager pm = mContext.getPackageManager(); 1891c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 1901c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // Check if the packages defined for the filter actually exists on the device 1911c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String[] packages = mFacetPackages.get(index); 1921c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (packages.length > 1) { 1931c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan int count = 0; 1941c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int i = 0; i < packages.length; i++) { 1951c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan count += pm.getLaunchIntentForPackage(packages[i]) != null ? 1 : 0; 1961c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (count > 1) { 1971c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return true; 1981c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 1991c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2001c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2011c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2021c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // If there weren't multiple packages defined for the facet, check the categories 2031c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan // and see if they resolve to multiple package names 2041c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String categories[] = mFacetCategories.get(index); 2051c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2061c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan int count = 0; 2071c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan for (int i = 0; i < categories.length; i++) { 2081c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan String category = categories[i]; 2091c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan Intent intent = new Intent(); 2101c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan intent.setAction(Intent.ACTION_MAIN); 2111c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan intent.addCategory(category); 2121c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan count += pm.queryIntentActivities(intent, 0).size(); 2131c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (count > 1) { 2141c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return true; 2151c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2161c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2171c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return false; 2181c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2191c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2201c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private void setCurrentFacet(int index) { 2211c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (index == mCurrentFacetIndex) { 2221c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return; 2231c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2241c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2251c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (mNavButtons.get(mCurrentFacetIndex) != null) { 2261c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mNavButtons.get(mCurrentFacetIndex) 2271c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan .setSelected(false /* selected */, false /* showMoreIcon */); 2281c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2291c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2301c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (mNavButtons.get(index) != null) { 2311c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mNavButtons.get(index).setSelected(true /* selected */, 2321c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan facetHasMultiplePackages(index) /* showMoreIcon */); 2331c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2341c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mCurrentFacetIndex = index; 2351c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2361c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2371c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private CarNavigationButton createNavButton(Drawable icon, final int id, 2381c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan boolean longClickEnabled) { 2391c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan CarNavigationButton button = (CarNavigationButton) View.inflate(mContext, 2401c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan R.layout.car_navigation_button, null); 2411c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan button.setResources(icon); 2421c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan LinearLayout.LayoutParams lp = 2431c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1); 2441c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan button.setLayoutParams(lp); 2451c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2461c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan button.setOnClickListener(new View.OnClickListener() { 2471c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan @Override 2481c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan public void onClick(View v) { 2491c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan onFacetClicked(id); 2501c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2511c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan }); 2521c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2531c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (longClickEnabled) { 2541c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan button.setLongClickable(true); 2551c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan button.setOnLongClickListener(new View.OnLongClickListener() { 2561c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan @Override 2571c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan public boolean onLongClick(View v) { 2581c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan onFacetLongClicked(id); 2591c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return true; 2601c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2611c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan }); 2621c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } else { 2631c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan button.setLongClickable(false); 2641c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 265c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan 2661c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan return button; 2671c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2681c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2691c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private void startActivity(Intent intent) { 2701c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan if (mActivityStarter != null && intent != null) { 2711c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan mActivityStarter.startActivity(intent, true); 2721c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2731c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 2741c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 2751c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private void onFacetClicked(int index) { 276c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan Intent intent = mIntents.get(index); 277c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan String packageName = intent.getPackage(); 278c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan 279c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan if (packageName == null) { 280c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan return; 281c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan } 282c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan 283c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan // Don't launch the lens picker if it's already running and the 284c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan // user clicks the same facet 285c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan if (packageName.equals(mCurrentPackageName) && index == mCurrentFacetIndex) { 286c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan return; 287c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan } 288c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan 289c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan intent.putExtra(EXTRA_FACET_CATEGORIES, mFacetCategories.get(index)); 290c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan intent.putExtra(EXTRA_FACET_PACKAGES, mFacetPackages.get(index)); 291c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan // The facet is identified by the index in which it was added to the nav bar. 292c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan // This value can be used to determine which facet was selected 293c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan intent.putExtra(EXTRA_FACET_ID, Integer.toString(index)); 294c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan 295c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan // If the current facet is clicked, we want to launch the picker by default 296c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan // rather than the "preferred/last run" app. 297c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan intent.putExtra(EXTRA_FACET_LAUNCH_PICKER, index == mCurrentFacetIndex); 298c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan 299c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan setCurrentFacet(index); 300c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan startActivity(intent); 3011c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 3021c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan 3031c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan private void onFacetLongClicked(int index) { 304c0ca9e5a3fa09ac8f6adc861d508b58c7fffd0f8Victor Chan setCurrentFacet(index); 3051c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan startActivity(mLongPressIntents.get(index)); 3061c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan } 30704a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev 30804a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev private List<Intent> createEmptyIntentList(int size) { 30904a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev return Arrays.asList(new Intent[size]); 31004a22a26d61866add8a85ca50a623a5d8e4d4bb6Pavel Maltsev } 3111c6d0589f1c6429ca84402227cd5954479cf66edVictor Chan} 312