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

Commit 63eddc12 authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Refactor FeatureFactory

Not use reflection, sets the FeatureFactoryImpl in SettingsApplication
instead.

Bug: 286764889
Test: m Settings
Test: m SettingsSpaUnitTests
Test: m RunSettingsRoboTests
Change-Id: I881bf1009a94222fc89578d14a6792a6e1507be2
parent a09fd452
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -106,7 +106,6 @@ android_library {
    plugins: ["androidx.room_room-compiler-plugin"],

    libs: [
        "keepanno-annotations",
        "telephony-common",
        "ims-common",
    ],
+0 −3
Original line number Diff line number Diff line
@@ -38,9 +38,6 @@
    <!-- Whether to show Camera laser sensor switch in Developer Options -->
    <bool name="config_show_camera_laser_sensor">false</bool>

    <!-- Fully-qualified class name for the implementation of the FeatureFactory to be instantiated. -->
    <string name="config_featureFactory" translatable="false">com.android.settings.overlay.FeatureFactoryImpl</string>

    <!-- Package name and fully-qualified class name for the wallpaper picker activity. -->
    <string name="config_wallpaper_picker_package" translatable="false">com.android.settings</string>
    <string name="config_wallpaper_picker_class" translatable="false">com.android.settings.Settings$WallpaperSettingsActivity</string>
+16 −0
Original line number Diff line number Diff line
@@ -17,15 +17,20 @@
package com.android.settings;

import android.app.Application;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings;
import android.util.FeatureFlagUtils;

import androidx.annotation.NonNull;

import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
import com.android.settings.core.instrumentation.ElapsedTimeUtils;
import com.android.settings.homepage.SettingsHomepageActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.overlay.FeatureFactoryImpl;
import com.android.settings.spa.SettingsSpaEnvironment;
import com.android.settingslib.applications.AppIconCacheManager;
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory;
@@ -39,6 +44,12 @@ public class SettingsApplication extends Application {

    private WeakReference<SettingsHomepageActivity> mHomeActivity = new WeakReference<>(null);

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        FeatureFactory.setFactory(this, getFeatureFactory());
    }

    @Override
    public void onCreate() {
        super.onCreate();
@@ -62,6 +73,11 @@ public class SettingsApplication extends Application {
        }
    }

    @NonNull
    protected FeatureFactory getFeatureFactory() {
        return new FeatureFactoryImpl();
    }

    /**
     * Set the spa environment instance.
     * Override this function to set different spa environment for different Settings app.
+0 −225
Original line number Diff line number Diff line
/*
 * 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.overlay;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;

import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider;
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider;
import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.biometrics.face.FaceFeatureProvider;
import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.gestures.AssistGestureFeatureProvider;
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
import com.android.settings.inputmethod.KeyboardSettingsFeatureProvider;
import com.android.settings.localepicker.LocaleFeatureProvider;
import com.android.settings.panel.PanelFeatureProvider;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.security.SecurityFeatureProvider;
import com.android.settings.security.SecuritySettingsFeatureProvider;
import com.android.settings.slices.SlicesFeatureProvider;
import com.android.settings.users.UserFeatureProvider;
import com.android.settings.vpn2.AdvancedVpnFeatureProvider;
import com.android.settings.wifi.WifiTrackerLibProvider;
import com.android.settings.wifi.factory.WifiFeatureProvider;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.tools.r8.keepanno.annotations.KeepItemKind;
import com.android.tools.r8.keepanno.annotations.KeepTarget;
import com.android.tools.r8.keepanno.annotations.UsesReflection;

/**
 * Abstract class for creating feature controllers. Allows OEM implementations to define their own
 * factories with their own controllers containing whatever code is needed to implement
 * the features. To provide a factory implementation, implementors should override
 * {@link R.string#config_featureFactory} in their override.
 */
public abstract class FeatureFactory {
    private static final String LOG_TAG = "FeatureFactory";
    private static final boolean DEBUG = false;

    protected static FeatureFactory sFactory;
    protected static Context sAppContext;

    /**
     * Returns a factory for creating feature controllers. Creates the factory if it does not
     * already exist. Uses the value of {@link R.string#config_featureFactory} to instantiate
     * a factory implementation.
     */
    @UsesReflection(
            description = "This method instantiates subclasses of FeatureFactory via reflection.",
            value = {
                @KeepTarget(
                    kind = KeepItemKind.CLASS_AND_MEMBERS,
                    extendsClassConstant = FeatureFactory.class,
                    methodName = "<init>")
            })
    public static FeatureFactory getFactory(Context context) {
        if (sFactory != null) {
            return sFactory;
        }
        if (sAppContext == null) {
            sAppContext = context.getApplicationContext();
        }

        if (DEBUG) Log.d(LOG_TAG, "getFactory");
        final String clsName = context.getString(R.string.config_featureFactory);
        if (TextUtils.isEmpty(clsName)) {
            throw new UnsupportedOperationException("No feature factory configured");
        }
        try {
            sFactory = (FeatureFactory) context.getClassLoader().loadClass(clsName).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            throw new FactoryNotFoundException(e);
        }

        if (DEBUG) Log.d(LOG_TAG, "started " + sFactory.getClass().getSimpleName());
        return sFactory;
    }

    /**
     * Returns an application {@link Context} used to create this {@link FeatureFactory}. If the
     * factory has not been properly created yet (aka {@link #getFactory} has not been called), this
     * will return null.
     */
    @Nullable
    public static Context getAppContext() {
        return sAppContext;
    }

    public abstract AssistGestureFeatureProvider getAssistGestureFeatureProvider();

    /**
     * Gets implementation for the Suggestion Feature provider.
     */
    public abstract SuggestionFeatureProvider getSuggestionFeatureProvider();

    /**
     * Retrieves implementation for Hardware Info feature.
     */
    public abstract HardwareInfoFeatureProvider getHardwareInfoFeatureProvider();

    public abstract SupportFeatureProvider getSupportFeatureProvider(Context context);

    public abstract MetricsFeatureProvider getMetricsFeatureProvider();

    public abstract PowerUsageFeatureProvider getPowerUsageFeatureProvider(Context context);

    /**
     * Retrieves implementation for Battery Status feature.
     */
    public abstract BatteryStatusFeatureProvider getBatteryStatusFeatureProvider(
            Context context);

    /**
     * Gets implementation for Battery Settings provider.
     */
    public abstract BatterySettingsFeatureProvider getBatterySettingsFeatureProvider();

    public abstract DashboardFeatureProvider getDashboardFeatureProvider(Context context);

    public abstract DockUpdaterFeatureProvider getDockUpdaterFeatureProvider();

    public abstract ApplicationFeatureProvider getApplicationFeatureProvider(Context context);

    public abstract LocaleFeatureProvider getLocaleFeatureProvider();

    public abstract EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(
            Context context);

    public abstract SearchFeatureProvider getSearchFeatureProvider();

    public abstract SurveyFeatureProvider getSurveyFeatureProvider(Context context);

    public abstract SecurityFeatureProvider getSecurityFeatureProvider();

    public abstract UserFeatureProvider getUserFeatureProvider(Context context);

    public abstract SlicesFeatureProvider getSlicesFeatureProvider();

    public abstract AccountFeatureProvider getAccountFeatureProvider();

    public abstract PanelFeatureProvider getPanelFeatureProvider();

    public abstract ContextualCardFeatureProvider getContextualCardFeatureProvider(Context context);

    /**
     * Retrieves implementation for Bluetooth feature.
     */
    public abstract BluetoothFeatureProvider getBluetoothFeatureProvider();

    public abstract FaceFeatureProvider getFaceFeatureProvider();

    /**
     * Gets implementation for Biometrics repository provider.
     */
    public abstract BiometricsRepositoryProvider getBiometricsRepositoryProvider();

    /**
     * Gets implementation for the WifiTrackerLib.
     */
    public abstract WifiTrackerLibProvider getWifiTrackerLibProvider();

    /**
     * Retrieves implementation for SecuritySettings feature.
     */
    public abstract SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider();

    /**
     * Retrieves implementation for Accessibility search index feature.
     */
    public abstract AccessibilitySearchFeatureProvider getAccessibilitySearchFeatureProvider();

    /**
     * Retrieves implementation for Accessibility metrics category feature.
     */
    public abstract AccessibilityMetricsFeatureProvider getAccessibilityMetricsFeatureProvider();

    /**
     * Retrieves implementation for advanced vpn feature.
     */
    public abstract AdvancedVpnFeatureProvider getAdvancedVpnFeatureProvider();

    /**
     * Retrieves implementation for Wi-Fi feature.
     */
    public abstract WifiFeatureProvider getWifiFeatureProvider();

    /**
     * Retrieves implementation for keyboard settings feature.
     */
    public abstract KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider();

    public static final class FactoryNotFoundException extends RuntimeException {
        public FactoryNotFoundException(Throwable throwable) {
            super("Unable to create factory. Did you misconfigure Proguard?", throwable);
        }
    }
}
+183 −0
Original line number Diff line number Diff line
/*
 * 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.overlay

import android.content.Context
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider
import com.android.settings.accounts.AccountFeatureProvider
import com.android.settings.applications.ApplicationFeatureProvider
import com.android.settings.biometrics.face.FaceFeatureProvider
import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider
import com.android.settings.bluetooth.BluetoothFeatureProvider
import com.android.settings.dashboard.DashboardFeatureProvider
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider
import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider
import com.android.settings.fuelgauge.PowerUsageFeatureProvider
import com.android.settings.gestures.AssistGestureFeatureProvider
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider
import com.android.settings.inputmethod.KeyboardSettingsFeatureProvider
import com.android.settings.localepicker.LocaleFeatureProvider
import com.android.settings.overlay.FeatureFactory.Companion.setFactory
import com.android.settings.panel.PanelFeatureProvider
import com.android.settings.search.SearchFeatureProvider
import com.android.settings.security.SecurityFeatureProvider
import com.android.settings.security.SecuritySettingsFeatureProvider
import com.android.settings.slices.SlicesFeatureProvider
import com.android.settings.users.UserFeatureProvider
import com.android.settings.vpn2.AdvancedVpnFeatureProvider
import com.android.settings.wifi.WifiTrackerLibProvider
import com.android.settings.wifi.factory.WifiFeatureProvider
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider

/**
 * Abstract class for creating feature controllers.
 *
 * Allows OEM implementations to define their own factories with their own controllers containing
 * whatever code is needed to implement the features.
 * To provide a factory implementation, implementors should call [setFactory] in their Application.
 */
abstract class FeatureFactory {
    abstract val assistGestureFeatureProvider: AssistGestureFeatureProvider

    /**
     * Gets implementation for the Suggestion Feature provider.
     */
    abstract val suggestionFeatureProvider: SuggestionFeatureProvider

    /**
     * Retrieves implementation for Hardware Info feature.
     */
    abstract val hardwareInfoFeatureProvider: HardwareInfoFeatureProvider

    abstract fun getSupportFeatureProvider(context: Context): SupportFeatureProvider?
    abstract val metricsFeatureProvider: MetricsFeatureProvider
    abstract fun getPowerUsageFeatureProvider(context: Context): PowerUsageFeatureProvider

    /**
     * Retrieves implementation for Battery Status feature.
     */
    abstract fun getBatteryStatusFeatureProvider(
        context: Context
    ): BatteryStatusFeatureProvider

    /**
     * Gets implementation for Battery Settings provider.
     */
    abstract val batterySettingsFeatureProvider: BatterySettingsFeatureProvider

    abstract fun getDashboardFeatureProvider(context: Context): DashboardFeatureProvider
    abstract val dockUpdaterFeatureProvider: DockUpdaterFeatureProvider
    abstract fun getApplicationFeatureProvider(context: Context): ApplicationFeatureProvider
    abstract val localeFeatureProvider: LocaleFeatureProvider

    abstract fun getEnterprisePrivacyFeatureProvider(
        context: Context,
    ): EnterprisePrivacyFeatureProvider

    abstract val searchFeatureProvider: SearchFeatureProvider
    abstract fun getSurveyFeatureProvider(context: Context): SurveyFeatureProvider?
    abstract val securityFeatureProvider: SecurityFeatureProvider
    abstract fun getUserFeatureProvider(context: Context): UserFeatureProvider
    abstract val slicesFeatureProvider: SlicesFeatureProvider
    abstract val accountFeatureProvider: AccountFeatureProvider
    abstract val panelFeatureProvider: PanelFeatureProvider
    abstract fun getContextualCardFeatureProvider(context: Context): ContextualCardFeatureProvider

    /**
     * Retrieves implementation for Bluetooth feature.
     */
    abstract val bluetoothFeatureProvider: BluetoothFeatureProvider

    abstract val faceFeatureProvider: FaceFeatureProvider

    /**
     * Gets implementation for Biometrics repository provider.
     */
    abstract val biometricsRepositoryProvider: BiometricsRepositoryProvider

    /**
     * Gets implementation for the WifiTrackerLib.
     */
    abstract val wifiTrackerLibProvider: WifiTrackerLibProvider

    /**
     * Retrieves implementation for SecuritySettings feature.
     */
    abstract val securitySettingsFeatureProvider: SecuritySettingsFeatureProvider

    /**
     * Retrieves implementation for Accessibility search index feature.
     */
    abstract val accessibilitySearchFeatureProvider: AccessibilitySearchFeatureProvider

    /**
     * Retrieves implementation for Accessibility metrics category feature.
     */
    abstract val accessibilityMetricsFeatureProvider: AccessibilityMetricsFeatureProvider

    /**
     * Retrieves implementation for advanced vpn feature.
     */
    abstract val advancedVpnFeatureProvider: AdvancedVpnFeatureProvider

    /**
     * Retrieves implementation for Wi-Fi feature.
     */
    abstract val wifiFeatureProvider: WifiFeatureProvider

    /**
     * Retrieves implementation for keyboard settings feature.
     */
    abstract val keyboardSettingsFeatureProvider: KeyboardSettingsFeatureProvider

    companion object {
        private var _factory: FeatureFactory? = null

        /** Returns a factory for creating feature controllers. */
        @JvmStatic
        val factory: FeatureFactory
            get() = _factory ?: throw UnsupportedOperationException("No feature factory configured")

        private var _appContext: Context? = null

        /** Returns an application [Context] used to create this [FeatureFactory]. */
        @JvmStatic
        val appContext: Context
            get() = _appContext
                ?: throw UnsupportedOperationException("No feature factory configured")

        @JvmStatic
        fun setFactory(appContext: Context, factory: FeatureFactory) {
            _appContext = appContext
            _factory = factory
        }

        /** Returns a factory for creating feature controllers. */
        @Deprecated(
            "Replace with factory without Context",
            ReplaceWith(
                "factory",
                "com.android.settings.overlay.FeatureFactory.Companion.factory",
            )
        )
        @JvmStatic
        fun getFactory(context: Context?): FeatureFactory = factory
    }
}
Loading