AppLaunchSettings.java revision 49b6103b56d777cb41f280e0dc636f738f6ba56d
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 17package com.android.settings.applications; 18 19import android.app.AlertDialog; 20import android.content.IntentFilter; 21import android.content.pm.ApplicationInfo; 22import android.content.pm.IntentFilterVerificationInfo; 23import android.content.pm.PackageManager; 24import android.os.Bundle; 25import android.os.UserHandle; 26import android.preference.Preference; 27import android.preference.Preference.OnPreferenceChangeListener; 28import android.util.ArraySet; 29import android.util.Log; 30import android.view.View; 31import android.view.View.OnClickListener; 32 33import com.android.internal.logging.MetricsLogger; 34import com.android.settings.DropDownPreference; 35import com.android.settings.R; 36import com.android.settings.Utils; 37 38import java.util.List; 39 40import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 41import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 42import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 43import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 44 45public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener, 46 Preference.OnPreferenceChangeListener { 47 private static final String TAG = "AppLaunchSettings"; 48 49 private static final String KEY_APP_LINK_STATE = "app_link_state"; 50 private static final String KEY_SUPPORTED_DOMAIN_URLS = "app_launch_supported_domain_urls"; 51 private static final String KEY_CLEAR_DEFAULTS = "app_launch_clear_defaults"; 52 53 private PackageManager mPm; 54 55 private boolean mHasDomainUrls; 56 private DropDownPreference mAppLinkState; 57 private AppDomainsPreference mAppDomainUrls; 58 private ClearDefaultsPreference mClearDefaultsPreference; 59 60 @Override 61 public void onCreate(Bundle savedInstanceState) { 62 super.onCreate(savedInstanceState); 63 64 addPreferencesFromResource(R.xml.installed_app_launch_settings); 65 66 mPm = getActivity().getPackageManager(); 67 68 mHasDomainUrls = 69 (mAppEntry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 70 List<IntentFilterVerificationInfo> iviList = mPm.getIntentFilterVerifications(mPackageName); 71 72 List<IntentFilter> filters = mPm.getAllIntentFilters(mPackageName); 73 74 mAppDomainUrls = (AppDomainsPreference) findPreference(KEY_SUPPORTED_DOMAIN_URLS); 75 CharSequence[] entries = getEntries(mPackageName, iviList, filters); 76 mAppDomainUrls.setTitles(entries); 77 mAppDomainUrls.setValues(new int[entries.length]); 78 79 mClearDefaultsPreference = (ClearDefaultsPreference) findPreference(KEY_CLEAR_DEFAULTS); 80 81 buildStateDropDown(); 82 } 83 84 private void buildStateDropDown() { 85 mAppLinkState = (DropDownPreference) findPreference(KEY_APP_LINK_STATE); 86 87 // Designed order of states in the dropdown: 88 // 89 // * always 90 // * ask 91 // * never 92 mAppLinkState.setEntries(new CharSequence[] { 93 getString(R.string.app_link_open_always), 94 getString(R.string.app_link_open_ask), 95 getString(R.string.app_link_open_never), 96 }); 97 mAppLinkState.setEntryValues(new CharSequence[] { 98 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS), 99 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK), 100 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER), 101 }); 102 103 mAppLinkState.setEnabled(mHasDomainUrls); 104 if (mHasDomainUrls) { 105 // Present 'undefined' as 'ask' because the OS treats them identically for 106 // purposes of the UI (and does the right thing around pending domain 107 // verifications that might arrive after the user chooses 'ask' in this UI). 108 final int state = mPm.getIntentVerificationStatus(mPackageName, UserHandle.myUserId()); 109 mAppLinkState.setValue( 110 Integer.toString((state == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) 111 ? INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK 112 : state)); 113 114 // Set the callback only after setting the initial selected item 115 mAppLinkState.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 116 @Override 117 public boolean onPreferenceChange(Preference preference, Object newValue) { 118 return updateAppLinkState(Integer.parseInt((String) newValue)); 119 } 120 }); 121 } 122 } 123 124 private boolean updateAppLinkState(final int newState) { 125 final int userId = UserHandle.myUserId(); 126 final int priorState = mPm.getIntentVerificationStatus(mPackageName, userId); 127 128 if (priorState == newState) { 129 return false; 130 } 131 132 boolean success = mPm.updateIntentVerificationStatus(mPackageName, newState, userId); 133 if (success) { 134 // Read back the state to see if the change worked 135 final int updatedState = mPm.getIntentVerificationStatus(mPackageName, userId); 136 success = (newState == updatedState); 137 } else { 138 Log.e(TAG, "Couldn't update intent verification status!"); 139 } 140 return success; 141 } 142 143 private CharSequence[] getEntries(String packageName, List<IntentFilterVerificationInfo> iviList, 144 List<IntentFilter> filters) { 145 ArraySet<String> result = Utils.getHandledDomains(mPm, packageName); 146 return result.toArray(new CharSequence[result.size()]); 147 } 148 149 @Override 150 protected boolean refreshUi() { 151 mClearDefaultsPreference.setPackageName(mPackageName); 152 mClearDefaultsPreference.setAppEntry(mAppEntry); 153 return true; 154 } 155 156 @Override 157 protected AlertDialog createDialog(int id, int errorCode) { 158 // No dialogs for preferred launch settings. 159 return null; 160 } 161 162 @Override 163 public void onClick(View v) { 164 // Nothing to do 165 } 166 167 @Override 168 public boolean onPreferenceChange(Preference preference, Object newValue) { 169 // actual updates are handled by the app link dropdown callback 170 return true; 171 } 172 173 @Override 174 protected int getMetricsCategory() { 175 return MetricsLogger.APPLICATIONS_APP_LAUNCH; 176 } 177} 178