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 */ 16 package com.android.car.pm; 17 18 import android.annotation.Nullable; 19 import android.content.Context; 20 import android.content.pm.ActivityInfo; 21 import android.content.pm.PackageInfo; 22 import android.content.pm.PackageManager; 23 import android.content.pm.PackageManager.NameNotFoundException; 24 import android.os.Bundle; 25 import android.util.Log; 26 27 import com.android.car.CarLog; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /** 33 * Read App meta data and look for Distraction Optimization(DO) tags. 34 * An app can tag a distraction optimized activity to be DO by adding the following meta-data 35 * to that <activity> element: 36 * 37 * <pre>{@code 38 * <activity> 39 * <meta-data android:name="distractionOptimized" android:value="true"/> 40 * </activity> 41 * }</pre> 42 * 43 */ 44 public class CarAppMetadataReader { 45 /** Name of the meta-data attribute of the Activity that denotes distraction optimized */ 46 private static final String DO_METADATA_ATTRIBUTE = "distractionOptimized"; 47 48 /** 49 * Parses the given package and returns Distraction Optimized information, if present. 50 * 51 * @return Array of DO activity names in the given package 52 */ 53 @Nullable findDistractionOptimizedActivitiesAsUser(Context context, String packageName, int userId)54 public static String[] findDistractionOptimizedActivitiesAsUser(Context context, 55 String packageName, int userId) throws NameNotFoundException { 56 final PackageManager pm = context.getPackageManager(); 57 58 // Check if any of the activities in the package are DO by checking all the 59 // <activity> elements. 60 PackageInfo pkgInfo = 61 pm.getPackageInfoAsUser( 62 packageName, PackageManager.GET_ACTIVITIES 63 | PackageManager.GET_META_DATA 64 | PackageManager.MATCH_DIRECT_BOOT_AWARE 65 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 66 userId); 67 if (pkgInfo == null) { 68 return null; 69 } 70 71 ActivityInfo[] activities = pkgInfo.activities; 72 if (activities == null) { 73 if (Log.isLoggable(CarLog.TAG_PACKAGE, Log.DEBUG)) { 74 Log.d(CarLog.TAG_PACKAGE, "Null Activities for " + packageName); 75 } 76 return null; 77 } 78 List<String> optimizedActivityList = new ArrayList(); 79 for (ActivityInfo activity : activities) { 80 Bundle mData = activity.metaData; 81 if (mData != null && mData.getBoolean(DO_METADATA_ATTRIBUTE, false)) { 82 if (Log.isLoggable(CarLog.TAG_PACKAGE, Log.DEBUG)) { 83 Log.d(CarLog.TAG_PACKAGE, 84 "DO Activity:" + activity.packageName + "/" + activity.name); 85 } 86 optimizedActivityList.add(activity.name); 87 } 88 } 89 if (optimizedActivityList.isEmpty()) { 90 return null; 91 } 92 return optimizedActivityList.toArray(new String[optimizedActivityList.size()]); 93 } 94 } 95