Merge "Add controllers for default app shortcut preferences."

This commit is contained in:
TreeHugger Robot
2017-12-08 02:20:11 +00:00
committed by Android (Google) Code Review
28 changed files with 961 additions and 211 deletions

View File

@@ -105,6 +105,33 @@
android:title="@string/sms_application_title"
android:summary="@string/summary_placeholder" />
<!-- Advanced apps settings -->
<PreferenceCategory
android:key="advanced_app_info"
android:title="@string/advanced_apps">
<Preference
android:key="system_alert_window"
android:title="@string/draw_overlay"
android:summary="@string/summary_placeholder" />
<Preference
android:key="write_settings_apps"
android:title="@string/write_settings"
android:summary="@string/summary_placeholder" />
<Preference
android:key="picture_in_picture"
android:title="@string/picture_in_picture_app_detail_title"
android:summary="@string/summary_placeholder" />
<Preference
android:key="install_other_apps"
android:title="@string/install_other_apps"
android:summary="@string/summary_placeholder" />
</PreferenceCategory>
<Preference
android:key="app_version"
android:selectable="false"

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="draw_overlay_permission_detail_settings"
android:title="@string/draw_overlay">
<SwitchPreference
android:key="app_ops_settings_switch"
android:title="@string/permit_draw_overlay"/>
<Preference
android:key="app_ops_settings_preference"
android:title="@string/app_overlay_permission_preference"/>
<Preference
android:summary="@string/allow_overlay_description"
android:selectable="false"/>
</PreferenceScreen>

View File

@@ -15,7 +15,6 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/install_other_apps">
<com.android.settingslib.RestrictedSwitchPreference

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="picture_in_picture_permission_detail_settings"
android:title="@string/picture_in_picture_app_detail_title">
<SwitchPreference
android:key="app_ops_settings_switch"
android:title="@string/picture_in_picture_app_detail_switch"/>
<Preference
android:summary="@string/picture_in_picture_app_detail_summary"
android:selectable="false"/>
</PreferenceScreen>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="write_system_settings_permission_detail_settings"
android:title="@string/write_settings">
<SwitchPreference
android:key="app_ops_settings_switch"
android:title="@string/permit_write_settings"/>
<Preference
android:key="app_ops_settings_preference"
android:title="@string/write_settings_preference"/>
<Preference
android:summary="@string/write_settings_description"
android:selectable="false"/>
</PreferenceScreen>

View File

@@ -18,7 +18,6 @@ package com.android.settings.applications;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.Manifest.permission;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
@@ -47,7 +46,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
@@ -58,7 +56,6 @@ import android.view.MenuItem;
import android.view.View;
import android.webkit.IWebViewUpdateService;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.DeviceAdminAdd;
import com.android.settings.R;
@@ -78,11 +75,10 @@ import com.android.settings.applications.appinfo.DefaultEmergencyShortcutPrefere
import com.android.settings.applications.appinfo.DefaultHomeShortcutPreferenceController;
import com.android.settings.applications.appinfo.DefaultPhoneShortcutPreferenceController;
import com.android.settings.applications.appinfo.DefaultSmsShortcutPreferenceController;
import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
import com.android.settings.applications.defaultapps.DefaultEmergencyPreferenceController;
import com.android.settings.applications.defaultapps.DefaultHomePreferenceController;
import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
import com.android.settings.applications.appinfo.DrawOverlayDetailPreferenceController;
import com.android.settings.applications.appinfo.ExternalSourceDetailPreferenceController;
import com.android.settings.applications.appinfo.PictureInPictureDetailPreferenceController;
import com.android.settings.applications.appinfo.WriteSystemSettingsPreferenceController;
import com.android.settings.applications.instantapps.InstantAppButtonsController;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
@@ -90,6 +86,7 @@ import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settings.widget.EntityHeaderController;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.applications.AppUtils;
@@ -97,7 +94,6 @@ import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.wrapper.PackageManagerWrapper;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -149,6 +145,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
public static final String ARG_PACKAGE_UID = "uid";
protected static final boolean localLOGV = false;
private static final String KEY_ADVANCED_APP_INFO_CATEGORY = "advanced_app_info";
private EnforcedAdmin mAppsControlDisallowedAdmin;
private boolean mAppsControlDisallowedBySystem;
@@ -358,11 +355,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
if (!refreshUi()) {
setIntentAndFinish(true, true);
}
if (mFinishing) {
return;
}
updateDynamicPrefs();
}
@Override
@@ -404,6 +396,17 @@ public class AppInfoDashboardFragment extends DashboardFragment
controllers.add(new DefaultEmergencyShortcutPreferenceController(context, packageName));
controllers.add(new DefaultSmsShortcutPreferenceController(context, packageName));
final List<AbstractPreferenceController> advancedAppInfoControllers = new ArrayList<>();
advancedAppInfoControllers.add(new DrawOverlayDetailPreferenceController(context, this));
advancedAppInfoControllers.add(new WriteSystemSettingsPreferenceController(context, this));
advancedAppInfoControllers.add(
new PictureInPictureDetailPreferenceController(context, this, packageName));
advancedAppInfoControllers.add(
new ExternalSourceDetailPreferenceController(context, this, packageName));
controllers.addAll(advancedAppInfoControllers);
controllers.add(new PreferenceCategoryController(
context, KEY_ADVANCED_APP_INFO_CATEGORY, advancedAppInfoControllers));
return controllers;
}
@@ -415,6 +418,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
}
public PackageInfo getPackageInfo() {
if (mAppEntry == null) {
retrieveAppEntry();
}
return mPackageInfo;
}
@@ -603,7 +609,8 @@ public class AppInfoDashboardFragment extends DashboardFragment
return false;
}
protected boolean refreshUi() {
@VisibleForTesting
boolean refreshUi() {
retrieveAppEntry();
if (mAppEntry == null) {
return false; // onCreate must have failed, make sure to exit
@@ -782,10 +789,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
}
}
private void startAppInfoFragment(Class<?> fragment, int title) {
startAppInfoFragment(fragment, title, this, mAppEntry);
}
public static void startAppInfoFragment(Class<?> fragment, int title,
SettingsPreferenceFragment caller, AppEntry appEntry) {
// start new fragment to display extended information
@@ -871,100 +874,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
if (UserManager.get(getContext()).isManagedProfile()) {
return;
}
final PreferenceScreen screen = getPreferenceScreen();
final Context context = getContext();
// Get the package info with the activities
PackageInfo packageInfoWithActivities = null;
try {
packageInfoWithActivities = mPm.getPackageInfoAsUser(mPackageName,
PackageManager.GET_ACTIVITIES, UserHandle.myUserId());
} catch (NameNotFoundException e) {
Log.e(TAG, "Exception while retrieving the package info of " + mPackageName, e);
}
boolean hasDrawOverOtherApps = hasPermission(permission.SYSTEM_ALERT_WINDOW);
boolean hasWriteSettings = hasPermission(permission.WRITE_SETTINGS);
boolean hasPictureInPictureActivities = (packageInfoWithActivities != null) &&
PictureInPictureSettings.checkPackageHasPictureInPictureActivities(
packageInfoWithActivities.packageName,
packageInfoWithActivities.activities);
boolean isPotentialAppSource = isPotentialAppSource();
if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities ||
isPotentialAppSource) {
PreferenceCategory category = new PreferenceCategory(getPrefContext());
category.setTitle(R.string.advanced_apps);
screen.addPreference(category);
if (hasDrawOverOtherApps) {
Preference pref = new Preference(getPrefContext());
pref.setTitle(R.string.draw_overlay);
pref.setKey("system_alert_window");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startAppInfoFragment(DrawOverlayDetails.class, R.string.draw_overlay);
return true;
}
});
category.addPreference(pref);
}
if (hasWriteSettings) {
Preference pref = new Preference(getPrefContext());
pref.setTitle(R.string.write_settings);
pref.setKey("write_settings_apps");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startAppInfoFragment(WriteSettingsDetails.class, R.string.write_settings);
return true;
}
});
category.addPreference(pref);
}
if (hasPictureInPictureActivities) {
Preference pref = new Preference(getPrefContext());
pref.setTitle(R.string.picture_in_picture_app_detail_title);
pref.setKey("picture_in_picture");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
AppInfoBase.startAppInfoFragment(PictureInPictureDetails.class,
R.string.picture_in_picture_app_detail_title, mPackageName,
mPackageInfo.applicationInfo.uid, AppInfoDashboardFragment.this,
-1, getMetricsCategory());
return true;
}
});
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,
R.string.install_other_apps);
return true;
}
});
category.addPreference(pref);
}
}
addAppInstallerInfoPref(screen);
addAppInstallerInfoPref(getPreferenceScreen());
maybeAddInstantAppButtons();
}
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 =
AppStoreUtil.getInstallerPackageName(getContext(), mPackageName);
@@ -1008,39 +921,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
}
}
private boolean hasPermission(String permission) {
if (mPackageInfo == null || mPackageInfo.requestedPermissions == null) {
return false;
}
for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
if (mPackageInfo.requestedPermissions[i].equals(permission)) {
return true;
}
}
return false;
}
private void updateDynamicPrefs() {
final Context context = getContext();
Preference pref = findPreference("system_alert_window");
if (pref != null) {
pref.setSummary(DrawOverlayDetails.getSummary(getContext(), mAppEntry));
}
pref = findPreference("picture_in_picture");
if (pref != null) {
pref.setSummary(PictureInPictureDetails.getPreferenceSummary(getContext(),
mPackageInfo.applicationInfo.uid, mPackageName));
}
pref = findPreference("write_settings_apps");
if (pref != null) {
pref.setSummary(WriteSettingsDetails.getSummary(getContext(), mAppEntry));
}
pref = findPreference("install_other_apps");
if (pref != null) {
pref.setSummary(ExternalSourcesDetails.getPreferenceSummary(getContext(), mAppEntry));
}
}
private void onPackageRemoved() {
getActivity().finishActivity(SUB_INFO_FRAGMENT);
getActivity().finishAndRemoveTask();
@@ -1112,7 +992,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
return mPackageName;
}
final Bundle args = getArguments();
String mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
if (mPackageName == null) {
Intent intent = (args == null) ?
getActivity().getIntent() : (Intent) args.getParcelable("intent");
@@ -1229,7 +1109,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.DIALOG_APP_INFO_ACTION;
return MetricsEvent.DIALOG_APP_INFO_ACTION;
}
@Override

View File

@@ -90,7 +90,7 @@ public class AppStateInstallAppsBridge extends AppStateBaseBridge {
return mAppOpsManager.checkOpNoThrow(appOpCode, uid, packageName);
}
InstallAppsState createInstallAppsStateFor(String packageName, int uid) {
public InstallAppsState createInstallAppsStateFor(String packageName, int uid) {
final InstallAppsState appState = new InstallAppsState();
appState.permissionRequested = hasRequestedAppOpPermission(
Manifest.permission.REQUEST_INSTALL_PACKAGES, packageName);

View File

@@ -75,6 +75,11 @@ import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.applications.appinfo.DrawOverlayDetails;
import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.PictureInPictureDetails;
import com.android.settings.applications.appinfo.PictureInPictureSettings;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
import com.android.settings.applications.defaultapps.DefaultEmergencyPreferenceController;
import com.android.settings.applications.defaultapps.DefaultHomePreferenceController;

View File

@@ -0,0 +1,70 @@
/*
* 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.appinfo;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppInfoDashboardFragment;
public class DrawOverlayDetailPreferenceController extends AppInfoPreferenceControllerBase {
private static final String KEY = "system_alert_window";
public DrawOverlayDetailPreferenceController(Context context, AppInfoDashboardFragment parent) {
super(context, parent, KEY);
}
@Override
public int getAvailabilityStatus() {
if (UserManager.get(mContext).isManagedProfile()) {
return DISABLED_FOR_USER;
}
final PackageInfo packageInfo = mParent.getPackageInfo();
if (packageInfo == null || packageInfo.requestedPermissions == null) {
return DISABLED_FOR_USER;
}
for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
if (packageInfo.requestedPermissions[i].equals(SYSTEM_ALERT_WINDOW)) {
return AVAILABLE;
}
}
return DISABLED_FOR_USER;
}
@Override
public void updateState(Preference preference) {
preference.setSummary(getSummary());
}
@Override
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
return DrawOverlayDetails.class;
}
@VisibleForTesting
CharSequence getSummary() {
return DrawOverlayDetails.getSummary(mContext, mParent.getAppEntry());
}
}

View File

@@ -13,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
@@ -29,12 +31,13 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
import com.android.settings.applications.AppStateOverlayBridge;
import com.android.settings.applications.AppStateOverlayBridge.OverlayState;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -44,7 +47,6 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc
private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
private static final String KEY_APP_OPS_SETTINGS_PREFS = "app_ops_settings_preference";
private static final String KEY_APP_OPS_SETTINGS_DESC = "app_ops_settings_description";
private static final String LOG_TAG = "DrawOverlayDetails";
private static final int [] APP_OPS_OP_CODE = {
@@ -57,7 +59,6 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc
private AppOpsManager mAppOpsManager;
private SwitchPreference mSwitchPref;
private Preference mOverlayPrefs;
private Preference mOverlayDesc;
private Intent mSettingsIntent;
private OverlayState mOverlayState;
@@ -70,16 +71,9 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
// find preferences
addPreferencesFromResource(R.xml.app_ops_permissions_details);
addPreferencesFromResource(R.xml.draw_overlay_permissions_details);
mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
mOverlayPrefs = findPreference(KEY_APP_OPS_SETTINGS_PREFS);
mOverlayDesc = findPreference(KEY_APP_OPS_SETTINGS_DESC);
// set title/summary for all of them
getPreferenceScreen().setTitle(R.string.draw_overlay);
mSwitchPref.setTitle(R.string.permit_draw_overlay);
mOverlayPrefs.setTitle(R.string.app_overlay_permission_preference);
mOverlayDesc.setSummary(R.string.allow_overlay_description);
// install event listeners
mSwitchPref.setOnPreferenceChangeListener(this);
@@ -116,7 +110,8 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc
try {
getActivity().startActivityAsUser(mSettingsIntent, new UserHandle(mUserId));
} catch (ActivityNotFoundException e) {
Log.w(LOG_TAG, "Unable to launch app draw overlay settings " + mSettingsIntent, e);
Log.w(LOG_TAG, "Unable to launch app draw overlay settings " + mSettingsIntent,
e);
}
}
return true;
@@ -161,7 +156,14 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc
// you cannot ask a user to grant you a permission you did not have!
mSwitchPref.setEnabled(mOverlayState.permissionDeclared && mOverlayState.controlEnabled);
mOverlayPrefs.setEnabled(isAllowed);
ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent,
PackageManager.GET_META_DATA, mUserId);
if (resolveInfo == null) {
if (findPreference(KEY_APP_OPS_SETTINGS_PREFS) != null) {
getPreferenceScreen().removePreference(mOverlayPrefs);
}
}
return true;
}

View File

@@ -0,0 +1,71 @@
/*
* 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.appinfo;
import android.content.Context;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.applications.AppStateInstallAppsBridge;
public class ExternalSourceDetailPreferenceController extends AppInfoPreferenceControllerBase {
private static final String KEY = "install_other_apps";
private final String mPackageName;
public ExternalSourceDetailPreferenceController(Context context,
AppInfoDashboardFragment parent, String packageName) {
super(context, parent, KEY);
mPackageName = packageName;
}
@Override
public int getAvailabilityStatus() {
if (UserManager.get(mContext).isManagedProfile()) {
return DISABLED_FOR_USER;
}
return isPotentialAppSource() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public void updateState(Preference preference) {
preference.setSummary(getPreferenceSummary());
}
@Override
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
return ExternalSourcesDetails.class;
}
@VisibleForTesting
CharSequence getPreferenceSummary() {
return ExternalSourcesDetails.getPreferenceSummary(mContext, mParent.getAppEntry());
}
@VisibleForTesting
boolean isPotentialAppSource() {
AppStateInstallAppsBridge.InstallAppsState appState =
new AppStateInstallAppsBridge(mContext, null, null).createInstallAppsStateFor(
mPackageName, mParent.getPackageInfo().applicationInfo.uid);
return appState.isPotentialAppSource();
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
@@ -30,6 +30,8 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.applications.AppStateInstallAppsBridge;
import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.applications.ApplicationsState.AppEntry;

View File

@@ -0,0 +1,86 @@
/*
* 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.appinfo;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.util.Log;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppInfoDashboardFragment;
public class PictureInPictureDetailPreferenceController extends AppInfoPreferenceControllerBase {
private static final String KEY = "picture_in_picture";
private static final String TAG = "PicInPicDetailControl";
private final PackageManager mPackageManager;
private final String mPackageName;
public PictureInPictureDetailPreferenceController(Context context,
AppInfoDashboardFragment parent, String packageName) {
super(context, parent, KEY);
mPackageManager = context.getPackageManager();
mPackageName = packageName;
}
@Override
public int getAvailabilityStatus() {
if (UserManager.get(mContext).isManagedProfile()) {
return DISABLED_FOR_USER;
}
return hasPictureInPictureActivites() ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public void updateState(Preference preference) {
preference.setSummary(getPreferenceSummary());
}
@Override
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
return PictureInPictureDetails.class;
}
@VisibleForTesting
boolean hasPictureInPictureActivites() {
// Get the package info with the activities
PackageInfo packageInfoWithActivities = null;
try {
packageInfoWithActivities = mPackageManager.getPackageInfoAsUser(mPackageName,
PackageManager.GET_ACTIVITIES, UserHandle.myUserId());
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Exception while retrieving the package info of " + mPackageName, e);
}
return packageInfoWithActivities != null
&& PictureInPictureSettings.checkPackageHasPictureInPictureActivities(
packageInfoWithActivities.packageName,
packageInfoWithActivities.activities);
}
@VisibleForTesting
int getPreferenceSummary() {
return PictureInPictureDetails.getPreferenceSummary(mContext,
mParent.getPackageInfo().applicationInfo.uid, mPackageName);
}
}

View File

@@ -13,14 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
@@ -28,6 +26,7 @@ import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.overlay.FeatureFactory;
import static android.app.AppOpsManager.MODE_ALLOWED;
@@ -38,42 +37,31 @@ public class PictureInPictureDetails extends AppInfoWithHeader
implements OnPreferenceChangeListener {
private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
private static final String KEY_APP_OPS_SETTINGS_PREFS = "app_ops_settings_preference";
private static final String KEY_APP_OPS_SETTINGS_DESC = "app_ops_settings_description";
private static final String LOG_TAG = "PictureInPictureDetails";
private SwitchPreference mSwitchPref;
private Preference mOverlayDesc;
private Intent mSettingsIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// find preferences
addPreferencesFromResource(R.xml.app_ops_permissions_details);
addPreferencesFromResource(R.xml.picture_in_picture_permissions_details);
mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
mOverlayDesc = findPreference(KEY_APP_OPS_SETTINGS_DESC);
getPreferenceScreen().removePreference(findPreference(KEY_APP_OPS_SETTINGS_PREFS));
// set title/summary for all of them
getPreferenceScreen().setTitle(R.string.picture_in_picture_app_detail_title);
mSwitchPref.setTitle(R.string.picture_in_picture_app_detail_switch);
mOverlayDesc.setSummary(R.string.picture_in_picture_app_detail_summary);
// install event listeners
mSwitchPref.setOnPreferenceChangeListener(this);
mSettingsIntent = new Intent(Intent.ACTION_MAIN)
.setAction(Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mSwitchPref) {
logSpecialPermissionChange((Boolean) newValue, mPackageName);
setEnterPipStateForPackage(getActivity(), mPackageInfo.applicationInfo.uid, mPackageName,
(Boolean) newValue);
setEnterPipStateForPackage(getActivity(), mPackageInfo.applicationInfo.uid,
mPackageName, (Boolean) newValue);
return true;
}
return false;
@@ -121,7 +109,7 @@ public class PictureInPictureDetails extends AppInfoWithHeader
* @return the summary for the current state of whether the app associated with the given
* {@param packageName} is allowed to enter picture-in-picture.
*/
static int getPreferenceSummary(Context context, int uid, String packageName) {
public static int getPreferenceSummary(Context context, int uid, String packageName) {
final boolean enabled = PictureInPictureDetails.getEnterPipStateForPackage(context, uid,
packageName);
return enabled ? R.string.app_permission_summary_allowed

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
@@ -37,6 +37,7 @@ import android.view.View;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.notification.EmptyTextSettings;
import com.android.settings.widget.AppPreference;
import com.android.settings.wrapper.ActivityInfoWrapper;
@@ -95,7 +96,7 @@ public class PictureInPictureSettings extends EmptyTextSettings {
* @return true if the package has any activities that declare that they support
* picture-in-picture.
*/
static boolean checkPackageHasPictureInPictureActivities(String packageName,
public static boolean checkPackageHasPictureInPictureActivities(String packageName,
ActivityInfo[] activities) {
ActivityInfoWrapper[] wrappedActivities = null;
if (activities != null) {

View File

@@ -13,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
@@ -31,7 +33,9 @@ import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
import com.android.settings.applications.AppStateWriteSettingsBridge;
import com.android.settings.applications.AppStateWriteSettingsBridge.WriteSettingsState;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -42,7 +46,6 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere
private static final String KEY_APP_OPS_PREFERENCE_SCREEN = "app_ops_preference_screen";
private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
private static final String KEY_APP_OPS_SETTINGS_PREFS = "app_ops_settings_preference";
private static final String KEY_APP_OPS_SETTINGS_DESC = "app_ops_settings_description";
private static final String LOG_TAG = "WriteSettingsDetails";
private static final int [] APP_OPS_OP_CODE = {
@@ -55,7 +58,6 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere
private AppOpsManager mAppOpsManager;
private SwitchPreference mSwitchPref;
private Preference mWriteSettingsPrefs;
private Preference mWriteSettingsDesc;
private Intent mSettingsIntent;
private WriteSettingsState mWriteSettingsState;
@@ -67,15 +69,9 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere
mAppBridge = new AppStateWriteSettingsBridge(context, mState, null);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
addPreferencesFromResource(R.xml.app_ops_permissions_details);
addPreferencesFromResource(R.xml.write_system_settings_permissions_details);
mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
mWriteSettingsPrefs = findPreference(KEY_APP_OPS_SETTINGS_PREFS);
mWriteSettingsDesc = findPreference(KEY_APP_OPS_SETTINGS_DESC);
getPreferenceScreen().setTitle(R.string.write_settings);
mSwitchPref.setTitle(R.string.permit_write_settings);
mWriteSettingsPrefs.setTitle(R.string.write_settings_preference);
mWriteSettingsDesc.setSummary(R.string.write_settings_description);
mSwitchPref.setOnPreferenceChangeListener(this);
mWriteSettingsPrefs.setOnPreferenceClickListener(this);
@@ -147,9 +143,14 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere
// you can't ask a user for a permission you didn't even declare!
mSwitchPref.setEnabled(mWriteSettingsState.permissionDeclared);
mWriteSettingsPrefs.setEnabled(canWrite);
ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent,
PackageManager.GET_META_DATA, mUserId);
if (resolveInfo == null) {
if (getPreferenceScreen().findPreference(KEY_APP_OPS_SETTINGS_PREFS) != null) {
getPreferenceScreen().removePreference(mWriteSettingsPrefs);
}
}
return true;
}

View File

@@ -0,0 +1,71 @@
/*
* 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.appinfo;
import static android.Manifest.permission.WRITE_SETTINGS;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppInfoDashboardFragment;
public class WriteSystemSettingsPreferenceController extends AppInfoPreferenceControllerBase {
private static final String KEY = "write_settings_apps";
public WriteSystemSettingsPreferenceController(Context context,
AppInfoDashboardFragment parent) {
super(context, parent, KEY);
}
@Override
public int getAvailabilityStatus() {
if (UserManager.get(mContext).isManagedProfile()) {
return DISABLED_FOR_USER;
}
final PackageInfo packageInfo = mParent.getPackageInfo();
if (packageInfo == null || packageInfo.requestedPermissions == null) {
return DISABLED_FOR_USER;
}
for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
if (packageInfo.requestedPermissions[i].equals(WRITE_SETTINGS)) {
return AVAILABLE;
}
}
return DISABLED_FOR_USER;
}
@Override
public void updateState(Preference preference) {
preference.setSummary(getSummary());
}
@Override
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
return WriteSettingsDetails.class;
}
@VisibleForTesting
CharSequence getSummary() {
return WriteSettingsDetails.getSummary(mContext, mParent.getAppEntry());
}
}

View File

@@ -89,14 +89,14 @@ import com.android.settings.applications.AppStateUsageBridge.UsageState;
import com.android.settings.applications.AppStateWriteSettingsBridge;
import com.android.settings.applications.AppStorageSettings;
import com.android.settings.applications.DefaultAppSettings;
import com.android.settings.applications.DrawOverlayDetails;
import com.android.settings.applications.ExternalSourcesDetails;
import com.android.settings.applications.InstalledAppCounter;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.NotificationApps;
import com.android.settings.applications.UsageAccessDetails;
import com.android.settings.applications.WriteSettingsDetails;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.applications.appinfo.DrawOverlayDetails;
import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.dashboard.SummaryLoader;

View File

@@ -40,19 +40,19 @@ import com.android.settings.accounts.ManagedProfileSettings;
import com.android.settings.accounts.UserAndAccountDashboardFragment;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.DefaultAppSettings;
import com.android.settings.applications.DrawOverlayDetails;
import com.android.settings.applications.ExternalSourcesDetails;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.ManageDomainUrls;
import com.android.settings.applications.NotificationApps;
import com.android.settings.applications.PictureInPictureDetails;
import com.android.settings.applications.PictureInPictureSettings;
import com.android.settings.applications.ProcessStatsSummary;
import com.android.settings.applications.ProcessStatsUi;
import com.android.settings.applications.UsageAccessDetails;
import com.android.settings.applications.VrListenerSettings;
import com.android.settings.applications.WriteSettingsDetails;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.applications.appinfo.DrawOverlayDetails;
import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.PictureInPictureDetails;
import com.android.settings.applications.appinfo.PictureInPictureSettings;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.applications.assist.ManageAssist;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;

View File

@@ -20,7 +20,7 @@ com.android.settings.datausage.AppDataUsage
com.android.settings.datausage.DataPlanUsageSummary
com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard
com.android.settings.applications.ManageDomainUrls
com.android.settings.applications.WriteSettingsDetails
com.android.settings.applications.appinfo.WriteSettingsDetails
com.android.settings.applications.ProcessStatsSummary
com.android.settings.users.RestrictedProfileSettings
com.android.settings.accounts.ChooseAccountActivity
@@ -36,7 +36,7 @@ com.android.settings.accessibility.ToggleSelectToSpeakPreferenceFragmentForSetup
com.android.settings.accounts.AccountSyncSettings
com.android.settings.notification.RedactionInterstitial$RedactionInterstitialFragment
com.android.settings.inputmethod.InputMethodAndSubtypeEnabler
com.android.settings.applications.DrawOverlayDetails
com.android.settings.applications.appinfo.DrawOverlayDetails
com.android.settings.backup.ToggleBackupSettingFragment
com.android.settings.users.UserDetailsSettings
com.android.settings.datausage.UnrestrictedDataAccess
@@ -59,9 +59,9 @@ com.android.settings.applications.AppStorageSettings
com.android.settings.notification.NotificationAccessSettings
com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment
com.android.settings.localepicker.LocaleListEditor
com.android.settings.applications.ExternalSourcesDetails
com.android.settings.applications.PictureInPictureSettings
com.android.settings.applications.PictureInPictureDetails
com.android.settings.applications.appinfo.ExternalSourcesDetails
com.android.settings.applications.appinfo.PictureInPictureSettings
com.android.settings.applications.appinfo.PictureInPictureDetails
com.android.settings.ApnSettings
com.android.settings.PrivacySettings
com.android.settings.WifiCallingSettings

View File

@@ -0,0 +1,120 @@
/*
* 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.appinfo;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.Manifest.permission.WRITE_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DrawOverlayDetailPreferenceControllerTest {
@Mock
private UserManager mUserManager;
@Mock
private AppInfoDashboardFragment mFragment;
@Mock
private Preference mPreference;
private Context mContext;
private DrawOverlayDetailPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mController = spy(new DrawOverlayDetailPreferenceController(mContext, mFragment));
final String key = mController.getPreferenceKey();
when(mPreference.getKey()).thenReturn(key);
}
@Test
public void getAvailabilityStatus_managedProfile_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_noPermissionRequested_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(false);
when(mFragment.getPackageInfo()).thenReturn(new PackageInfo());
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_noSystemAlertWindowPermission_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(false);
final PackageInfo info = new PackageInfo();
info.requestedPermissions = new String[] {WRITE_SETTINGS};
when(mFragment.getPackageInfo()).thenReturn(info);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_hasSystemAlertWindowPermission_shouldReturnAvailable() {
when(mUserManager.isManagedProfile()).thenReturn(false);
final PackageInfo info = new PackageInfo();
info.requestedPermissions = new String[] {SYSTEM_ALERT_WINDOW};
when(mFragment.getPackageInfo()).thenReturn(info);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE);
}
@Test
public void getDetailFragmentClass_shouldReturnDrawOverlayDetails() {
assertThat(mController.getDetailFragmentClass()).isEqualTo(DrawOverlayDetails.class);
}
@Test
public void updateState_shouldSetSummary() {
final String summary = "test summary";
doReturn(summary).when(mController).getSummary();
mController.updateState(mPreference);
verify(mPreference).setSummary(summary);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;

View File

@@ -0,0 +1,105 @@
/*
* 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.appinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ExternalSourceDetailPreferenceControllerTest {
@Mock
private UserManager mUserManager;
@Mock
private AppInfoDashboardFragment mFragment;
@Mock
private Preference mPreference;
private Context mContext;
private ExternalSourceDetailPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mController = spy(
new ExternalSourceDetailPreferenceController(mContext, mFragment, "Package1"));
final String key = mController.getPreferenceKey();
when(mPreference.getKey()).thenReturn(key);
}
@Test
public void getAvailabilityStatus_managedProfile_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_notPotentialAppSource_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(false);
doReturn(false).when(mController).isPotentialAppSource();
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_isPotentialAppSource_shouldReturnAvailable() {
when(mUserManager.isManagedProfile()).thenReturn(false);
doReturn(true).when(mController).isPotentialAppSource();
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE);
}
@Test
public void getDetailFragmentClass_shouldReturnExternalSourcesDetails() {
assertThat(mController.getDetailFragmentClass()).isEqualTo(ExternalSourcesDetails.class);
}
@Test
public void updateState_shouldSetSummary() {
final String summary = "test summary";
doReturn(summary).when(mController).getPreferenceSummary();
mController.updateState(mPreference);
verify(mPreference).setSummary(summary);
}
}

View File

@@ -0,0 +1,107 @@
/*
* 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.appinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class PictureInPictureDetailPreferenceControllerTest {
@Mock
private UserManager mUserManager;
@Mock
private AppInfoDashboardFragment mFragment;
@Mock
private Preference mPreference;
private Context mContext;
private PictureInPictureDetailPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mController = spy(
new PictureInPictureDetailPreferenceController(mContext, mFragment, "Package1"));
final String key = mController.getPreferenceKey();
when(mPreference.getKey()).thenReturn(key);
}
@Test
public void getAvailabilityStatus_managedProfile_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_noPictureInPictureActivities_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(false);
doReturn(false).when(mController).hasPictureInPictureActivites();
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_hasPictureInPictureActivities_shouldReturnAvailable() {
when(mUserManager.isManagedProfile()).thenReturn(false);
doReturn(true).when(mController).hasPictureInPictureActivites();
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE);
}
@Test
public void getDetailFragmentClass_shouldReturnPictureInPictureDetails() {
assertThat(mController.getDetailFragmentClass()).isEqualTo(PictureInPictureDetails.class);
}
@Test
public void updateState_shouldSetSummary() {
final int summary = R.string.app_permission_summary_allowed;
doReturn(summary).when(mController).getPreferenceSummary();
mController.updateState(mPreference);
verify(mPreference).setSummary(summary);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.nullable;

View File

@@ -14,7 +14,7 @@
* limitations under the License
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;

View File

@@ -14,7 +14,7 @@
* limitations under the License
*/
package com.android.settings.applications;
package com.android.settings.applications.appinfo;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.eq;

View File

@@ -0,0 +1,120 @@
/*
* 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.appinfo;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.Manifest.permission.WRITE_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WriteSystemSettingsPreferenceControllerTest {
@Mock
private UserManager mUserManager;
@Mock
private AppInfoDashboardFragment mFragment;
@Mock
private Preference mPreference;
private Context mContext;
private WriteSystemSettingsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
mController = spy(new WriteSystemSettingsPreferenceController(mContext, mFragment));
final String key = mController.getPreferenceKey();
when(mPreference.getKey()).thenReturn(key);
}
@Test
public void getAvailabilityStatus_managedProfile_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_noPermissionRequested_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(false);
when(mFragment.getPackageInfo()).thenReturn(new PackageInfo());
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_noWriteSettingsPermission_shouldReturnDisabled() {
when(mUserManager.isManagedProfile()).thenReturn(false);
final PackageInfo info = new PackageInfo();
info.requestedPermissions = new String[] {SYSTEM_ALERT_WINDOW};
when(mFragment.getPackageInfo()).thenReturn(info);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_hasWriteSettingsPermission_shouldReturnAvailable() {
when(mUserManager.isManagedProfile()).thenReturn(false);
final PackageInfo info = new PackageInfo();
info.requestedPermissions = new String[] {WRITE_SETTINGS};
when(mFragment.getPackageInfo()).thenReturn(info);
assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE);
}
@Test
public void getDetailFragmentClass_shouldReturnWriteSettingsDetails() {
assertThat(mController.getDetailFragmentClass()).isEqualTo(WriteSettingsDetails.class);
}
@Test
public void updateState_shouldSetSummary() {
final String summary = "test summary";
doReturn(summary).when(mController).getSummary();
mController.updateState(mPreference);
verify(mPreference).setSummary(summary);
}
}