LensPickerActivity.java revision bfee8559eaca4b3ce0625bc55cc9eb76108e42c2
12465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer/* 22465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * Copyright (C) 2015 The Android Open Source Project 32465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * 42465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License"); 52465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * you may not use this file except in compliance with the License. 62465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * You may obtain a copy of the License at 72465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * 82465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * http://www.apache.org/licenses/LICENSE-2.0 92465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * 102465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * Unless required by applicable law or agreed to in writing, software 112465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS, 122465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * See the License for the specific language governing permissions and 142465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * limitations under the License. 152465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer */ 162465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerpackage com.android.support.car.lenspicker; 172465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 182465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.app.Activity; 192465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.content.Intent; 202465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.content.SharedPreferences; 212465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.content.pm.PackageManager; 222465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.content.pm.ResolveInfo; 2361448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauerimport android.content.pm.ResolveInfo.DisplayNameComparator; 242465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.os.Bundle; 252465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.service.media.MediaBrowserService; 262465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.text.TextUtils; 272465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport android.util.Log; 28bfee8559eaca4b3ce0625bc55cc9eb76108e42c2Anthony Chen 29bfee8559eaca4b3ce0625bc55cc9eb76108e42c2Anthony Chenimport androidx.car.widget.DayNightStyle; 30bfee8559eaca4b3ce0625bc55cc9eb76108e42c2Anthony Chenimport androidx.car.widget.PagedListView; 312465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 322465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport java.util.ArrayList; 3361448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauerimport java.util.Collections; 342465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport java.util.HashMap; 352465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerimport java.util.List; 362465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 372465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer/** 382465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * An Activity to present the user with a list of applications that can be started for a given 392465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer * facet. 402465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer */ 412465f273eb12ef26ae921ac82058534b71974178Rakesh Iyerpublic class LensPickerActivity extends Activity implements LensPickerSelectionHandler { 422465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private static final String TAG = "LensPickerActivity"; 432465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private PackageManager mPackageManager; 442465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private SharedPreferences mSharedPrefs; 452465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 462465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private String mLastLaunchedFacetId; 472465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private String mLastLaunchedPackageName; 482465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private Intent mLastLaunchedIntent; 492465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 502465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private PagedListView mPagedListView; 512465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 522465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer @Override 532465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer protected void onCreate(Bundle savedInstanceState) { 542465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer super.onCreate(savedInstanceState); 552465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 562465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mPackageManager = getPackageManager(); 572465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mSharedPrefs = LensPickerUtils.getFacetSharedPrefs(this); 582465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 592465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer setContentView(R.layout.lens_list); 602465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mPagedListView = (PagedListView) findViewById(R.id.list_view); 612465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer // Set this to light mode, since the scroll bar buttons always appear 622465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer // on top of a dark scrim. 63bfee8559eaca4b3ce0625bc55cc9eb76108e42c2Anthony Chen mPagedListView.setDayNightStyle(DayNightStyle.ALWAYS_LIGHT); 642465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 65bfee8559eaca4b3ce0625bc55cc9eb76108e42c2Anthony Chen findViewById(R.id.dismiss_area).setOnClickListener(v -> finish()); 662465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 672465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 682465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer @Override 692465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer protected void onResume() { 702465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer super.onResume(); 712465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 722465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent intent = getIntent(); 732465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String[] categories = intent.getStringArrayExtra( 742465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer LensPickerConstants.EXTRA_FACET_CATEGORIES); 752465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String[] packages = intent.getStringArrayExtra(LensPickerConstants.EXTRA_FACET_PACKAGES); 762465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String facetId = intent.getStringExtra(LensPickerConstants.EXTRA_FACET_ID); 772465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 782465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer List<ResolveInfo> resolveInfos = getComponents(packages, categories); 792465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 802465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (resolveInfos != null && resolveInfos.size() == 1) { 812465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer // Directly launch the package rather than showing a list of 1. 822465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer ResolveInfo rInfo = resolveInfos.get(0); 832465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String packageName = LensPickerUtils.getPackageName(rInfo); 842465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent launchIntent = LensPickerUtils.getLaunchIntent(packageName, rInfo, 85b05b6c6076eaa0d140c95e6594f7e9998f14416aRakesh Iyer mPackageManager); 862465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (launchIntent != null) { 872465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer launch(facetId, packageName, launchIntent); 882465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } else { 892465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Log.e(TAG, "Failed to get launch intent for package" + packageName); 902465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 912465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer finish(); 922465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return; 932465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 942465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 952465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mPagedListView.setAdapter(new LensPickerAdapter(this, resolveInfos, facetId, 962465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer this /* LensPickerSelectionHandler */)); 972465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 982465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 992465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer @Override 1002465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer protected void onPause() { 1012465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer super.onPause(); 1022465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1032465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (mLastLaunchedFacetId == null || mLastLaunchedPackageName == null 1042465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer || mLastLaunchedIntent == null) { 1052465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return; 1062465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1072465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1082465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer LensPickerUtils.saveLastLaunchedAppInfo(mSharedPrefs, mLastLaunchedFacetId, 1092465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mLastLaunchedPackageName, mLastLaunchedIntent); 1102465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1112465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1122465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private boolean isReclick(Intent intent, Intent oldIntent) { 1132465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String oldFacetId = oldIntent.getStringExtra(LensPickerConstants.EXTRA_FACET_ID); 1142465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String newFacetId = intent.getStringExtra(LensPickerConstants.EXTRA_FACET_ID); 1152465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return TextUtils.equals(oldFacetId, newFacetId); 1162465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1172465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1182465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer @Override 1192465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer protected void onNewIntent(Intent intent) { 1202465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent oldIntent = getIntent(); 1212465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer setIntent(intent); 1222465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (isReclick(intent, oldIntent)) { 1232465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer finish(); 1242465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1252465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1262465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1272465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private ArrayList<ResolveInfo> getComponents(String[] packages, String[] categories) { 1282465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer List<ResolveInfo> packageList = new ArrayList<>(); 1292465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (packages != null) { 1302465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer for (int i = 0; i < packages.length; i++) { 1312465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer packageList.addAll(resolvePackage(packages[i])); 1322465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1332465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1342465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1352465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (categories != null) { 1362465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer for (int i = 0; i < categories.length; i++) { 1372465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer packageList.addAll(resolveCategory(categories[i])); 1382465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1392465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (categories[i].equals(Intent.CATEGORY_APP_MUSIC)) { 1402465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer packageList.addAll(resolveMediaBrowserServices()); 1412465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1422465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1432465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1442465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1452465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer // De-dupe the list based on package names 1462465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer HashMap<String, ResolveInfo> dedupeList = new HashMap<>(); 1472465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer for (ResolveInfo pkg : packageList) { 1482465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String packageName = LensPickerUtils.getPackageName(pkg); 1492465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (!dedupeList.containsKey(packageName) || LensPickerUtils.isMediaService(pkg)) { 1502465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer dedupeList.put(packageName, pkg); 1512465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1522465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1532465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1542465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer ArrayList<ResolveInfo> filteredPackageList = new ArrayList<>(dedupeList.values()); 1552465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer if (Log.isLoggable(TAG, Log.DEBUG)) { 1562465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer printResolveInfo("before dedupe", packageList); 1572465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer printResolveInfo("after dedupe", filteredPackageList); 1582465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1592465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 16061448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauer // If presenting a category, alphabetize the list based on name. 16161448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauer if (categories != null) { 16261448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauer Collections.sort(filteredPackageList, new DisplayNameComparator(mPackageManager)); 16361448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauer } 16461448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauer 16561448e336b72d426e78d0d1bedb1a29fa10e42b2Nicholas Sauer 1662465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return filteredPackageList; 1672465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1682465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1692465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private List<ResolveInfo> resolvePackage(String packageName) { 1702465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent intent = new Intent(); 1712465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.setPackage(packageName); 1722465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.setAction(Intent.ACTION_MAIN); 1732465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.addCategory(Intent.CATEGORY_LAUNCHER); 1742465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return mPackageManager.queryIntentActivities(intent, 0); 1752465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1762465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1772465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private List<ResolveInfo> resolveCategory(String category) { 1782465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent intent = new Intent(); 1792465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.setAction(Intent.ACTION_MAIN); 1802465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.addCategory(Intent.CATEGORY_LAUNCHER); 1812465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.addCategory(category); 1822465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return mPackageManager.queryIntentActivities(intent, 0); 1832465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1842465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1852465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private List<ResolveInfo> resolveMediaBrowserServices() { 1862465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent intent = new Intent(); 1872465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer intent.setAction(MediaBrowserService.SERVICE_INTERFACE); 1882465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer return mPackageManager.queryIntentServices(intent, PackageManager.GET_RESOLVED_FILTER); 1892465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1902465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1912465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private void printResolveInfo(String title, List<ResolveInfo> list) { 1922465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer String names = ""; 1932465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer for (ResolveInfo info : list) { 1942465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer names += " " + LensPickerUtils.getPackageName(info); 1952465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1962465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Log.d(TAG, title + " resolve info name: " + names); 1972465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 1982465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 1992465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer @Override 2002465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer public void onActivitySelected(LensPickerItem item) { 2012465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer Intent launchIntent = item.getLaunchIntent(); 2022465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer launch(item.getFacetId(), launchIntent.getPackage(), launchIntent); 2032465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer finish(); 2042465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 2052465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 2062465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer private void launch(String facetId, String packageName, Intent launchIntent) { 2072465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer // Save the information for the application that is about to be launched. 2082465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mLastLaunchedFacetId = facetId; 2092465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mLastLaunchedPackageName = packageName; 2102465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer mLastLaunchedIntent = launchIntent; 2112465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer 2122465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer LensPickerUtils.launch(this /* context */, mSharedPrefs, facetId, packageName, 2132465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer launchIntent); 2142465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer } 2152465f273eb12ef26ae921ac82058534b71974178Rakesh Iyer} 216