Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4e09de3 authored by Becca Hughes's avatar Becca Hughes Committed by Android (Google) Code Review
Browse files

Merge "Swap cog and left hand side of row" into main

parents 4b2a0526 e70dad42
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -4285,6 +4285,15 @@
                       android:value="true" />
        </activity>

        <!-- Access to the Credential Manager list. -->
        <activity android:name=".applications.credentials.CredentialsPickerActivity"
                android:excludeFromRecents="true"
                android:launchMode="singleInstance"
                android:exported="false">
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                       android:value="com.android.settings.applications.credentials.DefaultCombinedPicker" />
        </activity>

        <activity
            android:name=".Settings$SystemDashboardActivity"
            android:label="@string/header_category_system"
+31 −0
Original line number Diff line number Diff line
@@ -82,6 +82,37 @@ public final class CombinedProviderInfo {
        return mAutofillServiceInfo.getServiceInfo().applicationInfo;
    }

    /** Returns the package name. */
    public @Nullable String getPackageName() {
        ApplicationInfo ai = getApplicationInfo();
        if (ai != null) {
            return ai.packageName;
        }

        return null;
    }

    /** Returns the settings activity. */
    public @Nullable String getSettingsActivity() {
        // This logic is not used by the top entry but rather what activity should
        // be launched from the settings screen.
        for (CredentialProviderInfo cpi : mCredentialProviderInfos) {
            final CharSequence settingsActivity = cpi.getSettingsActivity();
            if (!TextUtils.isEmpty(settingsActivity)) {
                return String.valueOf(settingsActivity);
            }
        }

        if (mAutofillServiceInfo != null) {
            final String settingsActivity = mAutofillServiceInfo.getSettingsActivity();
            if (!TextUtils.isEmpty(settingsActivity)) {
                return settingsActivity;
            }
        }

        return null;
    }

    /** Returns the app icon. */
    @Nullable
    public Drawable getAppIcon(@NonNull Context context, int userId) {
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.credentials;


import com.android.settings.SettingsActivity;

/** Standalone activity used to launch a {@link DefaultCombinedPicker} fragment. */
public class CredentialsPickerActivity extends SettingsActivity {

    @Override
    protected boolean isValidFragment(String fragmentName) {
        return super.isValidFragment(fragmentName)
                || DefaultCombinedPicker.class.getName().equals(fragmentName);
    }
}
+50 −58
Original line number Diff line number Diff line
@@ -16,11 +16,10 @@

package com.android.settings.applications.credentials;

import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager;
import android.credentials.CredentialProviderInfo;
@@ -29,16 +28,19 @@ import android.provider.Settings;
import android.service.autofill.AutofillService;
import android.service.autofill.AutofillServiceInfo;
import android.text.TextUtils;
import android.util.Log;
import android.view.autofill.AutofillManager;

import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
import com.android.settingslib.applications.DefaultAppInfo;

import java.util.ArrayList;
import java.util.List;

public class DefaultCombinedPreferenceController extends DefaultAppPreferenceController {
public class DefaultCombinedPreferenceController extends DefaultAppPreferenceController
        implements Preference.OnPreferenceClickListener {

    private static final Intent AUTOFILL_PROBE = new Intent(AutofillService.SERVICE_INTERFACE);
    private static final String TAG = "DefaultCombinedPreferenceController";
@@ -73,18 +75,55 @@ public class DefaultCombinedPreferenceController extends DefaultAppPreferenceCon

    @Override
    protected Intent getSettingIntent(DefaultAppInfo info) {
        if (info == null) {
            return null;
        // Despite this method being called getSettingIntent this intent actually
        // opens the primary picker. This is so that we can swap the cog and the left
        // hand side presses to align the UX.
        return new Intent(mContext, CredentialsPickerActivity.class);
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);

        final String prefKey = getPreferenceKey();
        final Preference preference = screen.findPreference(prefKey);
        if (preference != null) {
            preference.setOnPreferenceClickListener((Preference.OnPreferenceClickListener) this);
        }
        final AutofillSettingIntentProvider intentProvider =
                new AutofillSettingIntentProvider(mContext, getUser(), info.getKey());
        return intentProvider.getIntent();
    }

    @Override
    protected DefaultAppInfo getDefaultAppInfo() {
    public boolean onPreferenceClick(Preference preference) {
        // Get the selected provider.
        final CombinedProviderInfo topProvider = getTopProvider();
        if (topProvider == null) {
            return false;
        }

        // If the top provider has a defined Credential Manager settings
        // provider then we should open that up.
        final String settingsActivity = topProvider.getSettingsActivity();
        if (!TextUtils.isEmpty(settingsActivity)) {
            final Intent intent =
                    new Intent(Intent.ACTION_MAIN)
                            .setComponent(
                                    new ComponentName(
                                            topProvider.getPackageName(), settingsActivity));
            startActivity(intent);
            return true;
        }

        return false;
    }

    private @Nullable CombinedProviderInfo getTopProvider() {
        List<CombinedProviderInfo> providers = getAllProviders(getUser());
        CombinedProviderInfo topProvider = CombinedProviderInfo.getTopProvider(providers);
        return CombinedProviderInfo.getTopProvider(providers);
    }

    @Override
    protected DefaultAppInfo getDefaultAppInfo() {
        CombinedProviderInfo topProvider = getTopProvider();
        if (topProvider != null) {
            ServiceInfo brandingService = topProvider.getBrandingService();
            if (brandingService == null) {
@@ -138,53 +177,6 @@ public class DefaultCombinedPreferenceController extends DefaultAppPreferenceCon
        return true;
    }

    /** Provides Intent to setting activity for the specified autofill service. */
    static final class AutofillSettingIntentProvider {

        private final String mKey;
        private final Context mContext;
        private final int mUserId;

        public AutofillSettingIntentProvider(Context context, int userId, String key) {
            mKey = key;
            mContext = context;
            mUserId = userId;
        }

        public Intent getIntent() {
            final List<ResolveInfo> resolveInfos =
                    mContext.getPackageManager()
                            .queryIntentServicesAsUser(
                                    AUTOFILL_PROBE, PackageManager.GET_META_DATA, mUserId);

            for (ResolveInfo resolveInfo : resolveInfos) {
                final ServiceInfo serviceInfo = resolveInfo.serviceInfo;

                // If there are multiple autofill services then pick the first one.
                if (mKey != null && mKey.startsWith(serviceInfo.packageName)) {
                    final String settingsActivity;
                    try {
                        settingsActivity =
                                new AutofillServiceInfo(mContext, serviceInfo)
                                        .getSettingsActivity();
                    } catch (SecurityException e) {
                        // Service does not declare the proper permission, ignore it.
                        Log.e(TAG, "Error getting info for " + serviceInfo + ": " + e);
                        return null;
                    }
                    if (TextUtils.isEmpty(settingsActivity)) {
                        return null;
                    }
                    return new Intent(Intent.ACTION_MAIN)
                            .setComponent(
                                    new ComponentName(serviceInfo.packageName, settingsActivity));
                }
            }

            return null;
        }
    }

    protected int getUser() {
        return UserHandle.myUserId();
    }
+0 −9
Original line number Diff line number Diff line
@@ -36,15 +36,6 @@ class DefaultPrivateCombinedPreferenceController(context: Context?) : DefaultCom
        return "default_credman_autofill_private"
    }

    override fun getSettingIntent(info: DefaultAppInfo ?): Intent ? {
        if (info == null) {
            return null
        }
        return userHandle?.let { handle ->
            AutofillSettingIntentProvider(mContext, handle.identifier, info.key).intent
        } ?: null
    }

    override fun startActivity(intent: Intent) {
        userHandle?.let { handle ->
            mContext.startActivityAsUser(intent, handle)
Loading