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