1 /* 2 * Copyright (C) 2019 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.car.settings.applications.managedomainurls; 18 19 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 20 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 21 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 22 23 import android.car.drivingstate.CarUxRestrictions; 24 import android.content.Context; 25 import android.content.pm.ApplicationInfo; 26 import android.content.pm.PackageManager; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.preference.ListPreference; 30 31 import com.android.car.settings.R; 32 import com.android.car.settings.common.FragmentController; 33 import com.android.car.settings.common.Logger; 34 35 /** 36 * Business logic to define how the app should handle related domain links (whether related domain 37 * links should be opened always, never, or after asking). 38 */ 39 public class AppLinkStatePreferenceController extends 40 AppLaunchSettingsBasePreferenceController<ListPreference> { 41 42 private static final Logger LOG = new Logger(AppLinkStatePreferenceController.class); 43 44 private boolean mHasDomainUrls; 45 AppLinkStatePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)46 public AppLinkStatePreferenceController(Context context, String preferenceKey, 47 FragmentController fragmentController, CarUxRestrictions uxRestrictions) { 48 super(context, preferenceKey, fragmentController, uxRestrictions); 49 } 50 51 @VisibleForTesting AppLinkStatePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, PackageManager packageManager)52 AppLinkStatePreferenceController(Context context, String preferenceKey, 53 FragmentController fragmentController, CarUxRestrictions uxRestrictions, 54 PackageManager packageManager) { 55 super(context, preferenceKey, fragmentController, uxRestrictions, packageManager); 56 } 57 58 @Override getPreferenceType()59 protected Class<ListPreference> getPreferenceType() { 60 return ListPreference.class; 61 } 62 63 @Override onCreateInternal()64 protected void onCreateInternal() { 65 mHasDomainUrls = 66 (getAppEntry().info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) 67 != 0; 68 } 69 70 @Override updateState(ListPreference preference)71 protected void updateState(ListPreference preference) { 72 if (isBrowserApp()) { 73 preference.setEnabled(false); 74 } else { 75 preference.setEnabled(mHasDomainUrls); 76 77 preference.setEntries(new CharSequence[]{ 78 getContext().getString(R.string.app_link_open_always), 79 getContext().getString(R.string.app_link_open_ask), 80 getContext().getString(R.string.app_link_open_never), 81 }); 82 preference.setEntryValues(new CharSequence[]{ 83 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS), 84 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK), 85 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER), 86 }); 87 88 if (mHasDomainUrls) { 89 int state = mPm.getIntentVerificationStatusAsUser(getPackageName(), 90 getCurrentUserId()); 91 preference.setValueIndex(linkStateToIndex(state)); 92 } 93 } 94 } 95 96 @Override handlePreferenceChanged(ListPreference preference, Object newValue)97 protected boolean handlePreferenceChanged(ListPreference preference, Object newValue) { 98 if (isBrowserApp()) { 99 // We shouldn't get into this state, but if we do make sure 100 // not to cause any permanent mayhem. 101 return false; 102 } 103 104 int newState = Integer.parseInt((String) newValue); 105 int priorState = mPm.getIntentVerificationStatusAsUser(getPackageName(), 106 getCurrentUserId()); 107 if (priorState == newState) { 108 return false; 109 } 110 111 boolean success = mPm.updateIntentVerificationStatusAsUser(getPackageName(), newState, 112 getCurrentUserId()); 113 if (success) { 114 // Read back the state to see if the change worked. 115 int updatedState = mPm.getIntentVerificationStatusAsUser(getPackageName(), 116 getCurrentUserId()); 117 success = (newState == updatedState); 118 } else { 119 LOG.e("Couldn't update intent verification status!"); 120 } 121 return success; 122 } 123 linkStateToIndex(int state)124 private int linkStateToIndex(int state) { 125 switch (state) { 126 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: 127 return getPreference().findIndexOfValue( 128 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS)); 129 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: 130 return getPreference().findIndexOfValue( 131 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)); 132 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK: 133 default: 134 return getPreference().findIndexOfValue( 135 Integer.toString(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK)); 136 } 137 } 138 } 139