--- /dev/null
- protected int getMetricsCategory() {
+ /*
+ * Copyright (C) 2016 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 android.app.Application;
+ import android.content.Context;
+ import android.content.DialogInterface;
+ import android.content.pm.PackageManager;
+ import android.os.Build;
+ import android.os.Bundle;
+ import android.os.UserHandle;
+ import android.provider.Settings;
+ import android.support.v14.preference.SwitchPreference;
+ import android.support.v7.preference.Preference;
+ import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+ import android.support.v7.preference.PreferenceCategory;
+ import android.support.v7.preference.PreferenceGroup;
+ import android.support.v7.preference.PreferenceViewHolder;
+ import android.util.ArraySet;
+ import android.view.Menu;
+ import android.view.MenuInflater;
+ import android.view.MenuItem;
+ import android.view.View;
+
+ import com.android.internal.logging.MetricsProto.MetricsEvent;
+ import com.android.settings.AppHeader;
+ 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.AppInfoBase;
+ import com.android.settings.applications.AppStateBaseBridge;
+ import com.android.settings.applications.InstalledAppDetails;
+ import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
+ import com.android.settingslib.applications.ApplicationsState;
+ import com.android.settingslib.applications.ApplicationsState.AppEntry;
+ import com.android.settingslib.applications.ApplicationsState.AppFilter;
+
+ import java.util.ArrayList;
+
+ /**
+ * Activity to manage how Android handles URL resolution. Includes both per-app
+ * handling as well as system handling for Web Actions.
+ */
+ public class ManageDomainUrls extends SettingsPreferenceFragment
+ implements ApplicationsState.Callbacks, OnPreferenceChangeListener {
+
+ // STOPSHIP; b/30256615
+ private static final boolean DISABLE_WEB_ACTIONS = !Build.IS_DEBUGGABLE;
+
+ private ApplicationsState mApplicationsState;
+ private ApplicationsState.Session mSession;
+ private PreferenceGroup mDomainAppList;
+ private SwitchPreference mWebAction;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setAnimationAllowed(true);
+ setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
+ mApplicationsState = ApplicationsState.getInstance(
+ (Application) getContext().getApplicationContext());
+ mSession = mApplicationsState.newSession(this);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ setLoading(true, false);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mSession.resume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mSession.pause();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mSession.release();
+ }
+
+ @Override
+ public void onRunningStateChanged(boolean running) {
+ }
+
+ @Override
+ public void onPackageListChanged() {
+ }
+
+ @Override
+ public void onRebuildComplete(ArrayList<AppEntry> apps) {
+ if (getContext() == null) {
+ return;
+ }
+
+ if (DISABLE_WEB_ACTIONS) {
+ mDomainAppList = getPreferenceScreen();
+ } else {
+ final PreferenceGroup preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen.getPreferenceCount() == 0) {
+ // add preferences
+ final PreferenceCategory webActionCategory =
+ new PreferenceCategory(getPrefContext());
+ webActionCategory.setTitle(R.string.web_action_section_title);
+ preferenceScreen.addPreference(webActionCategory);
+
+ // toggle to enable / disable Web Actions [aka Instant Apps]
+ mWebAction = new SwitchPreference(getPrefContext());
+ mWebAction.setTitle(R.string.web_action_enable_title);
+ mWebAction.setSummary(R.string.web_action_enable_summary);
+ mWebAction.setChecked(Settings.Secure.getInt(getContentResolver(),
+ Settings.Secure.WEB_ACTION_ENABLED, 1) != 0);
+ mWebAction.setOnPreferenceChangeListener(this);
+ webActionCategory.addPreference(mWebAction);
+
+ // list to manage link handling per app
+ mDomainAppList = new PreferenceCategory(getPrefContext());
+ mDomainAppList.setTitle(R.string.domain_url_section_title);
+ preferenceScreen.addPreference(mDomainAppList);
+ }
+ }
+ rebuildAppList(mDomainAppList, apps);
+ setLoading(false, true);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mWebAction) {
+ final int enabled = (boolean) newValue ? 1 : 0;
+ Settings.Secure.putInt(
+ getContentResolver(), Settings.Secure.WEB_ACTION_ENABLED, enabled);
+ return true;
+ }
+ return false;
+ }
+
+ private void rebuild() {
+ final ArrayList<AppEntry> apps = mSession.rebuild(
+ ApplicationsState.FILTER_WITH_DOMAIN_URLS, ApplicationsState.ALPHA_COMPARATOR);
+ if (apps != null) {
+ onRebuildComplete(apps);
+ }
+ }
+
+ private void rebuildAppList(PreferenceGroup group, ArrayList<AppEntry> apps) {
+ cacheRemoveAllPrefs(group);
+ final int N = apps.size();
+ for (int i = 0; i < N; i++) {
+ AppEntry entry = apps.get(i);
+ String key = entry.info.packageName + "|" + entry.info.uid;
+ DomainAppPreference preference = (DomainAppPreference) getCachedPreference(key);
+ if (preference == null) {
+ preference = new DomainAppPreference(getPrefContext(), entry);
+ preference.setKey(key);
+ group.addPreference(preference);
+ } else {
+ preference.reuse();
+ }
+ preference.setOrder(i);
+ }
+ removeCachedPrefs(group);
+ }
+
+ @Override
+ public void onPackageIconChanged() {
+ }
+
+ @Override
+ public void onPackageSizeChanged(String packageName) {
+ }
+
+ @Override
+ public void onAllSizesComputed() {
+ }
+
+ @Override
+ public void onLauncherInfoChanged() {
+ }
+
+ @Override
+ public void onLoadEntriesCompleted() {
+ rebuild();
+ }
+
+ @Override
++ public int getMetricsCategory() {
+ return MetricsEvent.MANAGE_DOMAIN_URLS;
+ }
+
+ private class DomainAppPreference extends Preference {
+ private final AppEntry mEntry;
+ private final PackageManager mPm;
+
+ public DomainAppPreference(final Context context, AppEntry entry) {
+ super(context);
+ mPm = context.getPackageManager();
+ mEntry = entry;
+ mEntry.ensureLabel(getContext());
+ setState();
+ if (mEntry.icon != null) {
+ setIcon(mEntry.icon);
+ }
+ }
+
+ private void setState() {
+ setTitle(mEntry.label);
+ setSummary(getDomainsSummary(mEntry.info.packageName));
+ }
+
+ public void reuse() {
+ setState();
+ notifyChanged();
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ if (mEntry.icon == null) {
+ holder.itemView.post(new Runnable() {
+ @Override
+ public void run() {
+ // Ensure we have an icon before binding.
+ mApplicationsState.ensureIcon(mEntry);
+ // This might trigger us to bind again, but it gives an easy way to only
+ // load the icon once its needed, so its probably worth it.
+ setIcon(mEntry.icon);
+ }
+ });
+ }
+ super.onBindViewHolder(holder);
+ }
+
+ private CharSequence getDomainsSummary(String packageName) {
+ // If the user has explicitly said "no" for this package, that's the
+ // string we should show.
+ int domainStatus =
+ mPm.getIntentVerificationStatusAsUser(packageName, UserHandle.myUserId());
+ if (domainStatus == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
+ return getContext().getString(R.string.domain_urls_summary_none);
+ }
+ // Otherwise, ask package manager for the domains for this package,
+ // and show the first one (or none if there aren't any).
+ ArraySet<String> result = Utils.getHandledDomains(mPm, packageName);
+ if (result.size() == 0) {
+ return getContext().getString(R.string.domain_urls_summary_none);
+ } else if (result.size() == 1) {
+ return getContext().getString(R.string.domain_urls_summary_one, result.valueAt(0));
+ } else {
+ return getContext().getString(R.string.domain_urls_summary_some, result.valueAt(0));
+ }
+ }
+ }
+ }