Loading src/com/android/settings/applications/AppStateInstallAppsBridge.java +3 −4 Original line number Diff line number Diff line Loading @@ -123,9 +123,8 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { } } public int getSummary() { return canInstallApps() ? R.string.external_source_trusted : R.string.external_source_untrusted; public boolean isPotentialAppSource() { return appOpMode != AppOpsManager.MODE_DEFAULT || permissionRequested; } @Override Loading @@ -150,7 +149,7 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { return false; } InstallAppsState state = (InstallAppsState) info.extraInfo; return (state.appOpMode != AppOpsManager.MODE_DEFAULT) || state.permissionRequested; return state.isPotentialAppSource(); } }; } src/com/android/settings/applications/ExternalSourcesDetails.java +13 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener; import com.android.settings.R; import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; public class ExternalSourcesDetails extends AppInfoWithHeader implements OnPreferenceChangeListener { Loading Loading @@ -74,6 +75,18 @@ public class ExternalSourcesDetails extends AppInfoWithHeader return false; } static CharSequence getPreferenceSummary(Context context, AppEntry entry) { final InstallAppsState appsState; if (entry.extraInfo instanceof InstallAppsState) { appsState = (InstallAppsState) entry.extraInfo; } else { appsState = new AppStateInstallAppsBridge(context, null, null) .createInstallAppsStateFor(entry.info.packageName, entry.info.uid); } return context.getString(appsState.canInstallApps() ? R.string.external_source_trusted : R.string.external_source_untrusted); } private void setCanInstallApps(boolean newState) { mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, mPackageInfo.applicationInfo.uid, mPackageName, Loading src/com/android/settings/applications/InstalledAppDetails.java +28 −1 Original line number Diff line number Diff line Loading @@ -977,7 +977,9 @@ public class InstalledAppDetails extends AppInfoBase PictureInPictureSettings.checkPackageHasPictureInPictureActivities( packageInfoWithActivities.packageName, packageInfoWithActivities.activities); if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities) { boolean isPotentialAppSource = isPotentialAppSource(); if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities || isPotentialAppSource) { PreferenceCategory category = new PreferenceCategory(getPrefContext()); category.setTitle(R.string.advanced_apps); screen.addPreference(category); Loading Loading @@ -1027,11 +1029,32 @@ public class InstalledAppDetails extends AppInfoBase }); category.addPreference(pref); } if (isPotentialAppSource) { Preference pref = new Preference(getPrefContext()); pref.setTitle(R.string.install_other_apps); pref.setKey("install_other_apps"); pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { startAppInfoFragment(ExternalSourcesDetails.class, getString(R.string.install_other_apps)); return true; } }); category.addPreference(pref); } } addAppInstallerInfoPref(screen); } private boolean isPotentialAppSource() { AppStateInstallAppsBridge.InstallAppsState appState = new AppStateInstallAppsBridge(getContext(), null, null) .createInstallAppsStateFor(mPackageName, mPackageInfo.applicationInfo.uid); return appState.isPotentialAppSource(); } private void addAppInstallerInfoPref(PreferenceScreen screen) { String installerPackageName = null; try { Loading Loading @@ -1117,6 +1140,10 @@ public class InstalledAppDetails extends AppInfoBase if (pref != null) { pref.setSummary(WriteSettingsDetails.getSummary(getContext(), mAppEntry)); } pref = findPreference("install_other_apps"); if (pref != null) { pref.setSummary(ExternalSourcesDetails.getPreferenceSummary(getContext(), mAppEntry)); } } public static void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon, Loading src/com/android/settings/applications/ManageApplications.java +2 −2 Original line number Diff line number Diff line Loading @@ -1373,8 +1373,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment break; case LIST_TYPE_MANAGE_SOURCES: holder.summary .setText(((InstallAppsState) holder.entry.extraInfo).getSummary()); holder.summary.setText(ExternalSourcesDetails.getPreferenceSummary(mContext, holder.entry)); break; default: Loading tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.settings.applications; import static com.google.common.truth.Truth.assertThat; import android.app.AppOpsManager; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class AppStateInstallAppsBridgeTest { @Test public void testInstallAppsStateCanInstallApps() { AppStateInstallAppsBridge.InstallAppsState appState = new AppStateInstallAppsBridge .InstallAppsState(); assertThat(appState.canInstallApps()).isFalse(); appState.permissionGranted = true; appState.permissionRequested = true; assertThat(appState.canInstallApps()).isTrue(); appState.appOpMode = AppOpsManager.MODE_ERRORED; assertThat(appState.canInstallApps()).isFalse(); } @Test public void testInstallAppsStateIsPotentialAppSource() { AppStateInstallAppsBridge.InstallAppsState appState = new AppStateInstallAppsBridge .InstallAppsState(); assertThat(appState.isPotentialAppSource()).isFalse(); appState.appOpMode = AppOpsManager.MODE_ERRORED; assertThat(appState.isPotentialAppSource()).isTrue(); appState.permissionRequested = true; appState.appOpMode = AppOpsManager.MODE_DEFAULT; assertThat(appState.isPotentialAppSource()).isTrue(); } } Loading
src/com/android/settings/applications/AppStateInstallAppsBridge.java +3 −4 Original line number Diff line number Diff line Loading @@ -123,9 +123,8 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { } } public int getSummary() { return canInstallApps() ? R.string.external_source_trusted : R.string.external_source_untrusted; public boolean isPotentialAppSource() { return appOpMode != AppOpsManager.MODE_DEFAULT || permissionRequested; } @Override Loading @@ -150,7 +149,7 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge { return false; } InstallAppsState state = (InstallAppsState) info.extraInfo; return (state.appOpMode != AppOpsManager.MODE_DEFAULT) || state.permissionRequested; return state.isPotentialAppSource(); } }; }
src/com/android/settings/applications/ExternalSourcesDetails.java +13 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener; import com.android.settings.R; import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; public class ExternalSourcesDetails extends AppInfoWithHeader implements OnPreferenceChangeListener { Loading Loading @@ -74,6 +75,18 @@ public class ExternalSourcesDetails extends AppInfoWithHeader return false; } static CharSequence getPreferenceSummary(Context context, AppEntry entry) { final InstallAppsState appsState; if (entry.extraInfo instanceof InstallAppsState) { appsState = (InstallAppsState) entry.extraInfo; } else { appsState = new AppStateInstallAppsBridge(context, null, null) .createInstallAppsStateFor(entry.info.packageName, entry.info.uid); } return context.getString(appsState.canInstallApps() ? R.string.external_source_trusted : R.string.external_source_untrusted); } private void setCanInstallApps(boolean newState) { mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, mPackageInfo.applicationInfo.uid, mPackageName, Loading
src/com/android/settings/applications/InstalledAppDetails.java +28 −1 Original line number Diff line number Diff line Loading @@ -977,7 +977,9 @@ public class InstalledAppDetails extends AppInfoBase PictureInPictureSettings.checkPackageHasPictureInPictureActivities( packageInfoWithActivities.packageName, packageInfoWithActivities.activities); if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities) { boolean isPotentialAppSource = isPotentialAppSource(); if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities || isPotentialAppSource) { PreferenceCategory category = new PreferenceCategory(getPrefContext()); category.setTitle(R.string.advanced_apps); screen.addPreference(category); Loading Loading @@ -1027,11 +1029,32 @@ public class InstalledAppDetails extends AppInfoBase }); category.addPreference(pref); } if (isPotentialAppSource) { Preference pref = new Preference(getPrefContext()); pref.setTitle(R.string.install_other_apps); pref.setKey("install_other_apps"); pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { startAppInfoFragment(ExternalSourcesDetails.class, getString(R.string.install_other_apps)); return true; } }); category.addPreference(pref); } } addAppInstallerInfoPref(screen); } private boolean isPotentialAppSource() { AppStateInstallAppsBridge.InstallAppsState appState = new AppStateInstallAppsBridge(getContext(), null, null) .createInstallAppsStateFor(mPackageName, mPackageInfo.applicationInfo.uid); return appState.isPotentialAppSource(); } private void addAppInstallerInfoPref(PreferenceScreen screen) { String installerPackageName = null; try { Loading Loading @@ -1117,6 +1140,10 @@ public class InstalledAppDetails extends AppInfoBase if (pref != null) { pref.setSummary(WriteSettingsDetails.getSummary(getContext(), mAppEntry)); } pref = findPreference("install_other_apps"); if (pref != null) { pref.setSummary(ExternalSourcesDetails.getPreferenceSummary(getContext(), mAppEntry)); } } public static void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon, Loading
src/com/android/settings/applications/ManageApplications.java +2 −2 Original line number Diff line number Diff line Loading @@ -1373,8 +1373,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment break; case LIST_TYPE_MANAGE_SOURCES: holder.summary .setText(((InstallAppsState) holder.entry.extraInfo).getSummary()); holder.summary.setText(ExternalSourcesDetails.getPreferenceSummary(mContext, holder.entry)); break; default: Loading
tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.settings.applications; import static com.google.common.truth.Truth.assertThat; import android.app.AppOpsManager; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class AppStateInstallAppsBridgeTest { @Test public void testInstallAppsStateCanInstallApps() { AppStateInstallAppsBridge.InstallAppsState appState = new AppStateInstallAppsBridge .InstallAppsState(); assertThat(appState.canInstallApps()).isFalse(); appState.permissionGranted = true; appState.permissionRequested = true; assertThat(appState.canInstallApps()).isTrue(); appState.appOpMode = AppOpsManager.MODE_ERRORED; assertThat(appState.canInstallApps()).isFalse(); } @Test public void testInstallAppsStateIsPotentialAppSource() { AppStateInstallAppsBridge.InstallAppsState appState = new AppStateInstallAppsBridge .InstallAppsState(); assertThat(appState.isPotentialAppSource()).isFalse(); appState.appOpMode = AppOpsManager.MODE_ERRORED; assertThat(appState.isPotentialAppSource()).isTrue(); appState.permissionRequested = true; appState.appOpMode = AppOpsManager.MODE_DEFAULT; assertThat(appState.isPotentialAppSource()).isTrue(); } }