Merge "Add controllers for iinstant app related preferences."

This commit is contained in:
TreeHugger Robot
2017-12-13 00:56:56 +00:00
committed by Android (Google) Code Review
12 changed files with 672 additions and 207 deletions

View File

@@ -45,9 +45,6 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
@@ -64,6 +61,8 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.applications.appinfo.AppBatteryPreferenceController;
import com.android.settings.applications.appinfo.AppDataUsagePreferenceController;
import com.android.settings.applications.appinfo.AppInstallerInfoPreferenceController;
import com.android.settings.applications.appinfo.AppInstallerPreferenceCategoryController;
import com.android.settings.applications.appinfo.AppMemoryPreferenceController;
import com.android.settings.applications.appinfo.AppNotificationPreferenceController;
import com.android.settings.applications.appinfo.AppOpenByDefaultPreferenceController;
@@ -77,9 +76,10 @@ import com.android.settings.applications.appinfo.DefaultPhoneShortcutPreferenceC
import com.android.settings.applications.appinfo.DefaultSmsShortcutPreferenceController;
import com.android.settings.applications.appinfo.DrawOverlayDetailPreferenceController;
import com.android.settings.applications.appinfo.ExternalSourceDetailPreferenceController;
import com.android.settings.applications.appinfo.InstantAppButtonsPreferenceController;
import com.android.settings.applications.appinfo.InstantAppDomainsPreferenceController;
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;
import com.android.settings.dashboard.DashboardFragment;
@@ -97,9 +97,9 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Dashboard fragment to display application information from Settings. This activity presents
@@ -136,10 +136,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
private static final int DLG_DISABLE = DLG_BASE + 2;
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
private static final String KEY_HEADER = "header_view";
private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
private static final String KEY_ACTION_BUTTONS = "action_buttons";
private static final String KEY_INSTANT_APP_SUPPORTED_LINKS =
"instant_app_launch_supported_domain_urls";
public static final String ARG_PACKAGE_NAME = "package";
public static final String ARG_PACKAGE_UID = "uid";
@@ -172,7 +169,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
private boolean mShowUninstalled;
private LayoutPreference mHeader;
private boolean mUpdatedSysApp = false;
private AppDomainsPreference mInstantAppDomainsPreference;
private boolean mDisableAfterUninstall;
private List<Callback> mCallbacks = new ArrayList<>();
@@ -180,7 +176,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
@VisibleForTesting
ActionButtonPreference mActionButtons;
private InstantAppButtonsController mInstantAppButtonsController;
private InstantAppButtonsPreferenceController mInstantAppButtonPreferenceController;
/**
* Callback to invoke when app info has been changed.
@@ -335,8 +331,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
}
setHasOptionsMenu(true);
addDynamicPrefs();
}
@Override
@@ -381,6 +375,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
controllers.add(new AppOpenByDefaultPreferenceController(context, this));
controllers.add(new AppPermissionPreferenceController(context, this, packageName));
controllers.add(new AppVersionPreferenceController(context, this));
controllers.add(new InstantAppDomainsPreferenceController(context, this));
final AppInstallerInfoPreferenceController appInstallerInfoPreferenceController =
new AppInstallerInfoPreferenceController(context, this, packageName);
controllers.add(appInstallerInfoPreferenceController);
for (AbstractPreferenceController controller : controllers) {
mCallbacks.add((Callback) controller);
@@ -388,6 +386,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
// The following are controllers for preferences that don't need to refresh the preference
// state when app state changes.
mInstantAppButtonPreferenceController =
new InstantAppButtonsPreferenceController(context, this, packageName);
controllers.add(mInstantAppButtonPreferenceController);
controllers.add(new AppBatteryPreferenceController(context, this, packageName, lifecycle));
controllers.add(new AppMemoryPreferenceController(context, this, lifecycle));
controllers.add(new DefaultHomeShortcutPreferenceController(context, packageName));
@@ -407,6 +408,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
controllers.add(new PreferenceCategoryController(
context, KEY_ADVANCED_APP_INFO_CATEGORY, advancedAppInfoControllers));
controllers.add(new AppInstallerPreferenceCategoryController(
context, Arrays.asList(appInstallerInfoPreferenceController)));
return controllers;
}
@@ -444,8 +448,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
.styleActionBar(activity)
.bindHeaderButtons();
mInstantAppDomainsPreference =
(AppDomainsPreference) findPreference(KEY_INSTANT_APP_SUPPORTED_LINKS);
}
@Override
@@ -536,24 +538,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
}
}
/**
* Utility method to hide and show specific preferences based on whether the app being displayed
* is an Instant App or an installed app.
*/
@VisibleForTesting
void prepareInstantAppPrefs() {
final boolean isInstant = AppUtils.isInstant(mPackageInfo.applicationInfo);
if (isInstant) {
Set<String> handledDomainSet = Utils.getHandledDomains(mPm, mPackageInfo.packageName);
String[] handledDomains = handledDomainSet.toArray(new String[handledDomainSet.size()]);
mInstantAppDomainsPreference.setTitles(handledDomains);
// Dummy values, unused in the implementation
mInstantAppDomainsPreference.setValues(new int[handledDomains.length]);
} else {
getPreferenceScreen().removePreference(mInstantAppDomainsPreference);
}
}
// Utility method to set application label and icon.
private void setAppLabelAndIcon(PackageInfo pkgInfo) {
final View appSnippet = mHeader.findViewById(R.id.entity_header);
@@ -642,7 +626,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
checkForceStop();
setAppLabelAndIcon(mPackageInfo);
initUninstallButtons();
prepareInstantAppPrefs();
// Update the preference summaries.
Activity context = getActivity();
@@ -676,7 +659,8 @@ public class AppInfoDashboardFragment extends DashboardFragment
return true;
}
protected AlertDialog createDialog(int id, int errorCode) {
@VisibleForTesting
AlertDialog createDialog(int id, int errorCode) {
switch (id) {
case DLG_DISABLE:
return new AlertDialog.Builder(getActivity())
@@ -722,10 +706,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
.setNegativeButton(R.string.dlg_cancel, null)
.create();
}
if (mInstantAppButtonsController != null) {
return mInstantAppButtonsController.createDialog(id);
}
return null;
return mInstantAppButtonPreferenceController.createDialog(id);
}
private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
@@ -870,57 +851,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|| (mUserManager.isSplitSystemUser() && userCount == 2);
}
private void addDynamicPrefs() {
if (UserManager.get(getContext()).isManagedProfile()) {
return;
}
addAppInstallerInfoPref(getPreferenceScreen());
maybeAddInstantAppButtons();
}
private void addAppInstallerInfoPref(PreferenceScreen screen) {
String installerPackageName =
AppStoreUtil.getInstallerPackageName(getContext(), mPackageName);
final CharSequence installerLabel = Utils.getApplicationLabel(getContext(),
installerPackageName);
if (installerLabel == null) {
return;
}
final int detailsStringId = AppUtils.isInstant(mPackageInfo.applicationInfo)
? R.string.instant_app_details_summary
: R.string.app_install_details_summary;
PreferenceCategory category = new PreferenceCategory(getPrefContext());
category.setTitle(R.string.app_install_details_group_title);
screen.addPreference(category);
Preference pref = new Preference(getPrefContext());
pref.setTitle(R.string.app_install_details_title);
pref.setKey("app_info_store");
pref.setSummary(getString(detailsStringId, installerLabel));
Intent intent =
AppStoreUtil.getAppStoreLink(getContext(), installerPackageName, mPackageName);
if (intent != null) {
pref.setIntent(intent);
} else {
pref.setEnabled(false);
}
category.addPreference(pref);
}
@VisibleForTesting
void maybeAddInstantAppButtons() {
if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
LayoutPreference buttons = (LayoutPreference) findPreference(KEY_INSTANT_APP_BUTTONS);
mInstantAppButtonsController = mApplicationFeatureProvider
.newInstantAppButtonsController(this,
buttons.findViewById(R.id.instant_app_button_container),
id -> showDialogInner(id, 0))
.setPackageName(mPackageName)
.show();
}
}
private void onPackageRemoved() {
getActivity().finishActivity(SUB_INFO_FRAGMENT);
getActivity().finishAndRemoveTask();
@@ -1041,9 +971,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
mFinishing = true;
}
private void showDialogInner(int id, int moveErrorCode) {
public void showDialogInner(int id, int moveErrorCode) {
DialogFragment newFragment =
AppInfoBase.MyAlertDialogFragment.newInstance(id, moveErrorCode);
MyAlertDialogFragment.newInstance(id, moveErrorCode);
newFragment.setTargetFragment(this, 0);
newFragment.show(getFragmentManager(), "dialog " + id);
}
@@ -1094,8 +1024,8 @@ public class AppInfoDashboardFragment extends DashboardFragment
public static void startAppInfoFragment(Class<?> fragment, int titleRes,
String pkg, int uid, Activity source, int request, int sourceMetricsCategory) {
Bundle args = new Bundle();
args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkg);
args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid);
args.putString(ARG_PACKAGE_NAME, pkg);
args.putInt(ARG_PACKAGE_UID, uid);
Intent intent = Utils.onBuildStartFragmentIntent(source, fragment.getName(),
args, null, titleRes, null, false, sourceMetricsCategory);
@@ -1116,16 +1046,16 @@ public class AppInfoDashboardFragment extends DashboardFragment
public Dialog onCreateDialog(Bundle savedInstanceState) {
int id = getArguments().getInt(ARG_ID);
int errorCode = getArguments().getInt("moveError");
Dialog dialog = ((AppInfoBase) getTargetFragment()).createDialog(id, errorCode);
Dialog dialog = ((AppInfoDashboardFragment) getTargetFragment())
.createDialog(id, errorCode);
if (dialog == null) {
throw new IllegalArgumentException("unknown id " + id);
}
return dialog;
}
public static AppInfoBase.MyAlertDialogFragment newInstance(int id, int errorCode) {
AppInfoBase.MyAlertDialogFragment
dialogFragment = new AppInfoBase.MyAlertDialogFragment();
public static MyAlertDialogFragment newInstance(int id, int errorCode) {
MyAlertDialogFragment dialogFragment = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_ID, id);
args.putInt("moveError", errorCode);

View File

@@ -16,11 +16,9 @@
package com.android.settings.applications;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.util.Log;
// This class provides methods that help dealing with app stores.
@@ -43,9 +41,6 @@ public class AppStoreUtil {
} catch (IllegalArgumentException e) {
Log.e(LOG_TAG, "Exception while retrieving the package installer of " + packageName, e);
}
if (installerPackageName == null) {
return null;
}
return installerPackageName;
}

View File

@@ -0,0 +1,69 @@
/*
* 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.Intent;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.applications.AppStoreUtil;
import com.android.settingslib.applications.AppUtils;
public class AppInstallerInfoPreferenceController extends AppInfoPreferenceControllerBase {
private static final String KEY_APP_INSTALLER_INFO = "app_info_store";
private final String mPackageName;
private final String mInstallerPackage;
private final CharSequence mInstallerLabel;
public AppInstallerInfoPreferenceController(Context context, AppInfoDashboardFragment parent,
String packageName) {
super(context, parent, KEY_APP_INSTALLER_INFO);
mPackageName = packageName;
mInstallerPackage = AppStoreUtil.getInstallerPackageName(mContext, mPackageName);
mInstallerLabel = Utils.getApplicationLabel(mContext, mInstallerPackage);
}
@Override
public int getAvailabilityStatus() {
if (UserManager.get(mContext).isManagedProfile()) {
return DISABLED_FOR_USER;
}
return mInstallerLabel!= null ? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public void updateState(Preference preference) {
final int detailsStringId = AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
? R.string.instant_app_details_summary
: R.string.app_install_details_summary;
preference.setSummary(mContext.getString(detailsStringId, mInstallerLabel));
Intent intent = AppStoreUtil.getAppStoreLink(mContext, mInstallerPackage, mPackageName);
if (intent != null) {
preference.setIntent(intent);
} else {
preference.setEnabled(false);
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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 com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.List;
public class AppInstallerPreferenceCategoryController extends PreferenceCategoryController {
private static final String KEY_APP_INSTALLER_INFO_CATEGORY = "app_installer";
public AppInstallerPreferenceCategoryController(Context context,
List<AbstractPreferenceController> childrenControllers) {
super(context, KEY_APP_INSTALLER_INFO_CATEGORY, childrenControllers);
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.app.AlertDialog;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.instantapps.InstantAppButtonsController;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.AppUtils;
public class InstantAppButtonsPreferenceController extends BasePreferenceController {
private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
private final AppInfoDashboardFragment mParent;
private final String mPackageName;
private InstantAppButtonsController mInstantAppButtonsController;
public InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent,
String packageName) {
super(context, KEY_INSTANT_APP_BUTTONS);
mParent = parent;
mPackageName = packageName;
}
@Override
public int getAvailabilityStatus() {
return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
LayoutPreference buttons =
(LayoutPreference) screen.findPreference(KEY_INSTANT_APP_BUTTONS);
mInstantAppButtonsController = getApplicationFeatureProvider()
.newInstantAppButtonsController(mParent,
buttons.findViewById(R.id.instant_app_button_container),
id -> mParent.showDialogInner(id, 0))
.setPackageName(mPackageName)
.show();
}
public AlertDialog createDialog(int id) {
return mInstantAppButtonsController.createDialog(id);
}
@VisibleForTesting
ApplicationFeatureProvider getApplicationFeatureProvider() {
return FeatureFactory.getFactory(mContext).getApplicationFeatureProvider(mContext);
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.PackageManager;
import android.support.v7.preference.Preference;
import com.android.settings.Utils;
import com.android.settings.applications.AppDomainsPreference;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settingslib.applications.AppUtils;
import java.util.Set;
public class InstantAppDomainsPreferenceController extends AppInfoPreferenceControllerBase {
private static final String KEY_INSTANT_APP_SUPPORTED_LINKS =
"instant_app_launch_supported_domain_urls";
private PackageManager mPackageManager;
public InstantAppDomainsPreferenceController(Context context, AppInfoDashboardFragment parent) {
super(context, parent, KEY_INSTANT_APP_SUPPORTED_LINKS);
mPackageManager = mContext.getPackageManager();
}
@Override
public int getAvailabilityStatus() {
return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
? AVAILABLE : DISABLED_FOR_USER;
}
@Override
public void updateState(Preference preference) {
final AppDomainsPreference instantAppDomainsPreference = (AppDomainsPreference) preference;
final Set<String> handledDomainSet =
Utils.getHandledDomains(mPackageManager, mParent.getPackageInfo().packageName);
final String[] handledDomains =
handledDomainSet.toArray(new String[handledDomainSet.size()]);
instantAppDomainsPreference.setTitles(handledDomains);
// Dummy values, unused in the implementation
instantAppDomainsPreference.setValues(new int[handledDomains.length]);
}
}

View File

@@ -21,7 +21,6 @@ import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.view.View;
import android.widget.Button;