1 /* 2 * Copyright (C) 2017 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.settings.applications.appinfo; 17 18 import static android.app.Activity.RESULT_CANCELED; 19 import static android.app.Activity.RESULT_OK; 20 21 import android.app.AppOpsManager; 22 import android.app.settings.SettingsEnums; 23 import android.content.Context; 24 import android.os.Bundle; 25 import android.os.UserHandle; 26 import android.os.UserManager; 27 28 import androidx.appcompat.app.AlertDialog; 29 import androidx.preference.Preference; 30 import androidx.preference.Preference.OnPreferenceChangeListener; 31 32 import com.android.settings.R; 33 import com.android.settings.Settings; 34 import com.android.settings.applications.AppInfoWithHeader; 35 import com.android.settings.applications.AppStateInstallAppsBridge; 36 import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState; 37 import com.android.settingslib.RestrictedSwitchPreference; 38 import com.android.settingslib.applications.ApplicationsState.AppEntry; 39 40 public class ExternalSourcesDetails extends AppInfoWithHeader 41 implements OnPreferenceChangeListener { 42 43 private static final String KEY_EXTERNAL_SOURCE_SWITCH = "external_sources_settings_switch"; 44 45 private AppStateInstallAppsBridge mAppBridge; 46 private AppOpsManager mAppOpsManager; 47 private UserManager mUserManager; 48 private RestrictedSwitchPreference mSwitchPref; 49 private InstallAppsState mInstallAppsState; 50 51 @Override onCreate(Bundle savedInstanceState)52 public void onCreate(Bundle savedInstanceState) { 53 super.onCreate(savedInstanceState); 54 55 final Context context = getActivity(); 56 mAppBridge = new AppStateInstallAppsBridge(context, mState, null); 57 mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 58 mUserManager = UserManager.get(context); 59 60 addPreferencesFromResource(R.xml.external_sources_details); 61 mSwitchPref = (RestrictedSwitchPreference) findPreference(KEY_EXTERNAL_SOURCE_SWITCH); 62 mSwitchPref.setOnPreferenceChangeListener(this); 63 } 64 65 @Override onPreferenceChange(Preference preference, Object newValue)66 public boolean onPreferenceChange(Preference preference, Object newValue) { 67 final boolean checked = (Boolean) newValue; 68 if (preference == mSwitchPref) { 69 if (mInstallAppsState != null && checked != mInstallAppsState.canInstallApps()) { 70 if (Settings.ManageAppExternalSourcesActivity.class.getName().equals( 71 getIntent().getComponent().getClassName())) { 72 setResult(checked ? RESULT_OK : RESULT_CANCELED); 73 } 74 setCanInstallApps(checked); 75 refreshUi(); 76 } 77 return true; 78 } 79 return false; 80 } 81 getPreferenceSummary(Context context, AppEntry entry)82 public static CharSequence getPreferenceSummary(Context context, AppEntry entry) { 83 final UserHandle userHandle = UserHandle.getUserHandleForUid(entry.info.uid); 84 final UserManager um = UserManager.get(context); 85 final int userRestrictionSource = um.getUserRestrictionSource( 86 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userHandle) 87 | um.getUserRestrictionSource( 88 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, 89 userHandle); 90 if ((userRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) { 91 return context.getString(R.string.disabled_by_admin); 92 } else if (userRestrictionSource != 0) { 93 return context.getString(R.string.disabled); 94 } 95 final InstallAppsState appsState = new AppStateInstallAppsBridge(context, null, null) 96 .createInstallAppsStateFor(entry.info.packageName, entry.info.uid); 97 return context.getString(appsState.canInstallApps() 98 ? R.string.app_permission_summary_allowed 99 : R.string.app_permission_summary_not_allowed); 100 } 101 setCanInstallApps(boolean newState)102 private void setCanInstallApps(boolean newState) { 103 mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, 104 mPackageInfo.applicationInfo.uid, mPackageName, 105 newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_ERRORED); 106 } 107 108 @Override refreshUi()109 protected boolean refreshUi() { 110 if (mPackageInfo == null || mPackageInfo.applicationInfo == null) { 111 return false; 112 } 113 if (mUserManager.hasBaseUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 114 UserHandle.of(UserHandle.myUserId()))) { 115 mSwitchPref.setChecked(false); 116 mSwitchPref.setSummary(R.string.disabled); 117 mSwitchPref.setEnabled(false); 118 return true; 119 } 120 mSwitchPref.checkRestrictionAndSetDisabled(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 121 if (!mSwitchPref.isDisabledByAdmin()) { 122 mSwitchPref.checkRestrictionAndSetDisabled( 123 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY); 124 } 125 if (mSwitchPref.isDisabledByAdmin()) { 126 return true; 127 } 128 mInstallAppsState = mAppBridge.createInstallAppsStateFor(mPackageName, 129 mPackageInfo.applicationInfo.uid); 130 if (!mInstallAppsState.isPotentialAppSource()) { 131 // Invalid app entry. Should not allow changing permission 132 mSwitchPref.setEnabled(false); 133 return true; 134 } 135 mSwitchPref.setChecked(mInstallAppsState.canInstallApps()); 136 return true; 137 } 138 139 @Override createDialog(int id, int errorCode)140 protected AlertDialog createDialog(int id, int errorCode) { 141 return null; 142 } 143 144 @Override getMetricsCategory()145 public int getMetricsCategory() { 146 return SettingsEnums.MANAGE_EXTERNAL_SOURCES; 147 } 148 } 149