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 17 package com.android.settings.applications; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.pm.ResolveInfo; 23 import android.net.Uri; 24 import android.os.Handler; 25 import android.os.UserHandle; 26 import android.text.TextUtils; 27 import android.util.AttributeSet; 28 import android.util.Log; 29 import com.android.internal.content.PackageMonitor; 30 import com.android.settings.AppListPreference; 31 import com.android.settings.R; 32 33 import java.util.ArrayList; 34 import java.util.List; 35 36 public class DefaultBrowserPreference extends AppListPreference { 37 38 private static final String TAG = "DefaultBrowserPref"; 39 40 private static final long DELAY_UPDATE_BROWSER_MILLIS = 500; 41 42 private final Handler mHandler = new Handler(); 43 44 final private PackageManager mPm; 45 46 public DefaultBrowserPreference(Context context, AttributeSet attrs) { 47 super(context, attrs); 48 49 mPm = context.getPackageManager(); 50 refreshBrowserApps(); 51 } 52 53 @Override 54 public void onAttached() { 55 super.onAttached(); 56 updateDefaultBrowserPreference(); 57 mPackageMonitor.register(getContext(), getContext().getMainLooper(), false); 58 } 59 60 @Override 61 public void onDetached() { 62 mPackageMonitor.unregister(); 63 super.onDetached(); 64 } 65 66 @Override 67 protected boolean persistString(String newValue) { 68 69 if (newValue == null) { 70 return false; 71 } 72 final CharSequence packageName = (CharSequence) newValue; 73 if (TextUtils.isEmpty(packageName)) { 74 return false; 75 } 76 boolean result = mPm.setDefaultBrowserPackageNameAsUser( 77 packageName.toString(), mUserId); 78 if (result) { 79 setSummary("%s"); 80 } 81 return result && super.persistString(newValue); 82 } 83 84 public void refreshBrowserApps() { 85 List<String> browsers = resolveBrowserApps(); 86 87 setPackageNames(browsers.toArray(new String[browsers.size()]), null); 88 } 89 90 private void updateDefaultBrowserPreference() { 91 refreshBrowserApps(); 92 93 final PackageManager pm = getContext().getPackageManager(); 94 95 String packageName = pm.getDefaultBrowserPackageNameAsUser(mUserId); 96 if (!TextUtils.isEmpty(packageName)) { 97 // Check if the default Browser package is still there 98 Intent intent = new Intent(); 99 intent.setPackage(packageName); 100 intent.setAction(Intent.ACTION_VIEW); 101 intent.addCategory(Intent.CATEGORY_BROWSABLE); 102 intent.setData(Uri.parse("http:")); 103 104 ResolveInfo info = mPm.resolveActivityAsUser(intent, 0, mUserId); 105 if (info != null) { 106 setValue(packageName); 107 setSummary("%s"); 108 } else { 109 setSummary(R.string.default_browser_title_none); 110 } 111 } else { 112 setSummary(R.string.default_browser_title_none); 113 Log.d(TAG, "Cannot set empty default Browser value!"); 114 } 115 } 116 117 private List<String> resolveBrowserApps() { 118 List<String> result = new ArrayList<>(); 119 120 // Create an Intent that will match ALL Browser Apps 121 Intent intent = new Intent(); 122 intent.setAction(Intent.ACTION_VIEW); 123 intent.addCategory(Intent.CATEGORY_BROWSABLE); 124 intent.setData(Uri.parse("http:")); 125 126 // Resolve that intent and check that the handleAllWebDataURI boolean is set 127 List<ResolveInfo> list = mPm.queryIntentActivitiesAsUser(intent, PackageManager.MATCH_ALL, 128 mUserId); 129 130 final int count = list.size(); 131 for (int i=0; i<count; i++) { 132 ResolveInfo info = list.get(i); 133 if (info.activityInfo == null || result.contains(info.activityInfo.packageName) 134 || !info.handleAllWebDataURI) { 135 continue; 136 } 137 138 result.add(info.activityInfo.packageName); 139 } 140 141 return result; 142 } 143 144 private final Runnable mUpdateRunnable = new Runnable() { 145 @Override 146 public void run() { 147 updateDefaultBrowserPreference(); 148 } 149 }; 150 151 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 152 @Override 153 public void onPackageAdded(String packageName, int uid) { 154 sendUpdate(); 155 } 156 157 @Override 158 public void onPackageAppeared(String packageName, int reason) { 159 sendUpdate(); 160 } 161 162 @Override 163 public void onPackageDisappeared(String packageName, int reason) { 164 sendUpdate(); 165 } 166 167 @Override 168 public void onPackageRemoved(String packageName, int uid) { 169 sendUpdate(); 170 } 171 172 private void sendUpdate() { 173 mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_BROWSER_MILLIS); 174 } 175 }; 176 177 public static boolean hasBrowserPreference(String pkg, Context context) { 178 Intent intent = new Intent(); 179 intent.setAction(Intent.ACTION_VIEW); 180 intent.addCategory(Intent.CATEGORY_BROWSABLE); 181 intent.setData(Uri.parse("http:")); 182 intent.setPackage(pkg); 183 final List<ResolveInfo> resolveInfos = 184 context.getPackageManager().queryIntentActivities(intent, 0); 185 return resolveInfos != null && resolveInfos.size() != 0; 186 } 187 188 public static boolean isBrowserDefault(String pkg, Context context) { 189 String defaultPackage = context.getPackageManager() 190 .getDefaultBrowserPackageNameAsUser(UserHandle.myUserId()); 191 return defaultPackage != null && defaultPackage.equals(pkg); 192 } 193 } 194