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