LensPickerActivity.java revision b05b6c6076eaa0d140c95e6594f7e9998f14416a
1/* 2 * Copyright (C) 2015 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 */ 16package com.android.support.car.lenspicker; 17 18import android.app.Activity; 19import android.content.Context; 20import android.content.Intent; 21import android.content.SharedPreferences; 22import android.content.pm.PackageManager; 23import android.content.pm.ResolveInfo; 24import android.graphics.Canvas; 25import android.os.Bundle; 26import android.service.media.MediaBrowserService; 27import android.support.v7.widget.RecyclerView; 28import android.text.TextUtils; 29import android.util.Log; 30import android.view.View; 31 32import com.android.car.view.PagedListView; 33 34import java.util.ArrayList; 35import java.util.HashMap; 36import java.util.List; 37 38/** 39 * An Activity to present the user with a list of applications that can be started for a given 40 * facet. 41 */ 42public class LensPickerActivity extends Activity implements LensPickerSelectionHandler { 43 private static final String TAG = "LensPickerActivity"; 44 private PackageManager mPackageManager; 45 private SharedPreferences mSharedPrefs; 46 47 private String mLastLaunchedFacetId; 48 private String mLastLaunchedPackageName; 49 private Intent mLastLaunchedIntent; 50 51 private PagedListView mPagedListView; 52 53 @Override 54 protected void onCreate(Bundle savedInstanceState) { 55 super.onCreate(savedInstanceState); 56 57 mPackageManager = getPackageManager(); 58 mSharedPrefs = LensPickerUtils.getFacetSharedPrefs(this); 59 60 setContentView(R.layout.lens_list); 61 mPagedListView = (PagedListView) findViewById(R.id.list_view); 62 mPagedListView.setDefaultItemDecoration(new ItemDecoration(this)); 63 // Set this to light mode, since the scroll bar buttons always appear 64 // on top of a dark scrim. 65 mPagedListView.setLightMode(); 66 67 findViewById(R.id.dismiss_area).setOnClickListener(new View.OnClickListener() { 68 @Override 69 public void onClick(View v) { 70 finish(); 71 } 72 }); 73 } 74 75 @Override 76 protected void onResume() { 77 super.onResume(); 78 79 Intent intent = getIntent(); 80 String[] categories = intent.getStringArrayExtra( 81 LensPickerConstants.EXTRA_FACET_CATEGORIES); 82 String[] packages = intent.getStringArrayExtra(LensPickerConstants.EXTRA_FACET_PACKAGES); 83 String facetId = intent.getStringExtra(LensPickerConstants.EXTRA_FACET_ID); 84 85 List<ResolveInfo> resolveInfos = getComponents(packages, categories); 86 87 if (resolveInfos != null && resolveInfos.size() == 1) { 88 // Directly launch the package rather than showing a list of 1. 89 ResolveInfo rInfo = resolveInfos.get(0); 90 String packageName = LensPickerUtils.getPackageName(rInfo); 91 Intent launchIntent = LensPickerUtils.getLaunchIntent(packageName, rInfo, 92 mPackageManager); 93 if (launchIntent != null) { 94 launch(facetId, packageName, launchIntent); 95 } else { 96 Log.e(TAG, "Failed to get launch intent for package" + packageName); 97 } 98 finish(); 99 return; 100 } 101 102 mPagedListView.setAdapter(new LensPickerAdapter(this, resolveInfos, facetId, 103 this /* LensPickerSelectionHandler */)); 104 } 105 106 @Override 107 protected void onPause() { 108 super.onPause(); 109 110 if (mLastLaunchedFacetId == null || mLastLaunchedPackageName == null 111 || mLastLaunchedIntent == null) { 112 return; 113 } 114 115 LensPickerUtils.saveLastLaunchedAppInfo(mSharedPrefs, mLastLaunchedFacetId, 116 mLastLaunchedPackageName, mLastLaunchedIntent); 117 } 118 119 private boolean isReclick(Intent intent, Intent oldIntent) { 120 String oldFacetId = oldIntent.getStringExtra(LensPickerConstants.EXTRA_FACET_ID); 121 String newFacetId = intent.getStringExtra(LensPickerConstants.EXTRA_FACET_ID); 122 return TextUtils.equals(oldFacetId, newFacetId); 123 } 124 125 @Override 126 protected void onNewIntent(Intent intent) { 127 Intent oldIntent = getIntent(); 128 setIntent(intent); 129 if (isReclick(intent, oldIntent)) { 130 finish(); 131 } 132 } 133 134 private ArrayList<ResolveInfo> getComponents(String[] packages, String[] categories) { 135 List<ResolveInfo> packageList = new ArrayList<>(); 136 if (packages != null) { 137 for (int i = 0; i < packages.length; i++) { 138 packageList.addAll(resolvePackage(packages[i])); 139 } 140 } 141 142 if (categories != null) { 143 for (int i = 0; i < categories.length; i++) { 144 packageList.addAll(resolveCategory(categories[i])); 145 146 if (categories[i].equals(Intent.CATEGORY_APP_MUSIC)) { 147 packageList.addAll(resolveMediaBrowserServices()); 148 } 149 } 150 } 151 152 // De-dupe the list based on package names 153 HashMap<String, ResolveInfo> dedupeList = new HashMap<>(); 154 for (ResolveInfo pkg : packageList) { 155 String packageName = LensPickerUtils.getPackageName(pkg); 156 if (!dedupeList.containsKey(packageName) || LensPickerUtils.isMediaService(pkg)) { 157 dedupeList.put(packageName, pkg); 158 } 159 } 160 161 ArrayList<ResolveInfo> filteredPackageList = new ArrayList<>(dedupeList.values()); 162 if (Log.isLoggable(TAG, Log.DEBUG)) { 163 printResolveInfo("before dedupe", packageList); 164 printResolveInfo("after dedupe", filteredPackageList); 165 } 166 167 return filteredPackageList; 168 } 169 170 private List<ResolveInfo> resolvePackage(String packageName) { 171 Intent intent = new Intent(); 172 intent.setPackage(packageName); 173 intent.setAction(Intent.ACTION_MAIN); 174 intent.addCategory(Intent.CATEGORY_LAUNCHER); 175 return mPackageManager.queryIntentActivities(intent, 0); 176 } 177 178 private List<ResolveInfo> resolveCategory(String category) { 179 Intent intent = new Intent(); 180 intent.setAction(Intent.ACTION_MAIN); 181 intent.addCategory(Intent.CATEGORY_LAUNCHER); 182 intent.addCategory(category); 183 return mPackageManager.queryIntentActivities(intent, 0); 184 } 185 186 private List<ResolveInfo> resolveMediaBrowserServices() { 187 Intent intent = new Intent(); 188 intent.setAction(MediaBrowserService.SERVICE_INTERFACE); 189 return mPackageManager.queryIntentServices(intent, PackageManager.GET_RESOLVED_FILTER); 190 } 191 192 private void printResolveInfo(String title, List<ResolveInfo> list) { 193 String names = ""; 194 for (ResolveInfo info : list) { 195 names += " " + LensPickerUtils.getPackageName(info); 196 } 197 Log.d(TAG, title + " resolve info name: " + names); 198 } 199 200 @Override 201 public void onActivitySelected(LensPickerItem item) { 202 Intent launchIntent = item.getLaunchIntent(); 203 launch(item.getFacetId(), launchIntent.getPackage(), launchIntent); 204 finish(); 205 } 206 207 private void launch(String facetId, String packageName, Intent launchIntent) { 208 // Save the information for the application that is about to be launched. 209 mLastLaunchedFacetId = facetId; 210 mLastLaunchedPackageName = packageName; 211 mLastLaunchedIntent = launchIntent; 212 213 LensPickerUtils.launch(this /* context */, mSharedPrefs, facetId, packageName, 214 launchIntent); 215 } 216 217 /** 218 * Default {@link com.android.car.view.PagedListView.Decoration} for the {@link PagedListView} 219 * that removes the dividing lines between items. 220 */ 221 private static class ItemDecoration extends PagedListView.Decoration { 222 public ItemDecoration(Context context) { 223 super(context); 224 } 225 226 @Override 227 public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {} 228 } 229} 230