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

Commit 6e0f86b4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "Extend extension support"""

parents 676c206c 0b80c4e5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ public class Dependency extends SystemUI {
                new FragmentService(mContext));

        mProviders.put(ExtensionController.class, () ->
                new ExtensionControllerImpl());
                new ExtensionControllerImpl(mContext));

        mProviders.put(PluginDependencyProvider.class, () ->
                new PluginDependencyProvider(get(PluginManager.class)));
+64 −0
Original line number Diff line number Diff line
@@ -15,60 +15,50 @@
package com.android.systemui.fragments;

import android.app.Fragment;
import android.content.Context;
import android.util.Log;
import android.view.View;

import com.android.systemui.Dependency;
import com.android.systemui.plugins.FragmentBase;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.statusbar.policy.ExtensionController.Extension;

public class PluginFragmentListener implements PluginListener<Plugin> {
import java.util.function.Consumer;

    private static final String TAG = "PluginFragmentListener";
/**
 * Wires up an Extension to a Fragment tag/id so that it always contains the class
 * selected by the extension.
 */
public class ExtensionFragmentListener<T extends FragmentBase> implements Consumer<T> {

    private static final String TAG = "ExtensionFragmentListener";

    private final FragmentHostManager mFragmentHostManager;
    private final PluginManager mPluginManager;
    private final Class<? extends Fragment> mDefaultClass;
    private final Class<? extends FragmentBase> mExpectedInterface;
    private final String mTag;
    private final Extension<T> mExtension;
    private String mOldClass;

    public PluginFragmentListener(View view, String tag, Class<? extends Fragment> defaultFragment,
            Class<? extends FragmentBase> expectedInterface) {
    private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) {
        mTag = tag;
        mFragmentHostManager = FragmentHostManager.get(view);
        mPluginManager = Dependency.get(PluginManager.class);
        mExpectedInterface = expectedInterface;
        mDefaultClass = defaultFragment;
    }

    public void startListening() {
        mPluginManager.addPluginListener(this, mExpectedInterface,
                false /* Only allow one */);
    }

    public void stopListening() {
        mPluginManager.removePluginListener(this);
        mExtension = extension;
        mFragmentHostManager.getFragmentManager().beginTransaction()
                .replace(id, (Fragment) mExtension.get(), mTag)
                .commit();
    }

    @Override
    public void onPluginConnected(Plugin plugin, Context pluginContext) {
    public void accept(T extension) {
        try {
            mExpectedInterface.cast(plugin);
            Fragment.class.cast(plugin);
            mFragmentHostManager.getPluginManager().setCurrentPlugin(mTag,
                    plugin.getClass().getName(), pluginContext);
            Fragment.class.cast(extension);
            mFragmentHostManager.getExtensionManager().setCurrentExtension(mTag,
                    mOldClass, extension.getClass().getName(), mExtension.getContext());
            mOldClass = extension.getClass().getName();
        } catch (ClassCastException e) {
            Log.e(TAG, plugin.getClass().getName() + " must be a Fragment and implement "
                    + mExpectedInterface.getName(), e);
            Log.e(TAG, extension.getClass().getName() + " must be a Fragment", e);
        }
    }

    @Override
    public void onPluginDisconnected(Plugin plugin) {
        mFragmentHostManager.getPluginManager().removePlugin(mTag,
                plugin.getClass().getName(), mDefaultClass.getName());
    public static <T> void attachExtensonToFragment(View view, String tag, int id,
            Extension<T> extension) {
        extension.addCallback(new ExtensionFragmentListener(view, tag, id, extension));
    }
}
+15 −20
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
@@ -51,7 +52,7 @@ public class FragmentHostManager {
    private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
            ActivityInfo.CONFIG_FONT_SCALE);
    private final FragmentService mManager;
    private final PluginFragmentManager mPlugins = new PluginFragmentManager();
    private final ExtensionFragmentManager mPlugins = new ExtensionFragmentManager();

    private FragmentController mFragments;
    private FragmentLifecycleCallbacks mLifecycleCallbacks;
@@ -174,7 +175,7 @@ public class FragmentHostManager {
        return mFragments.getFragmentManager();
    }

    PluginFragmentManager getPluginManager() {
    ExtensionFragmentManager getExtensionManager() {
        return mPlugins;
    }

@@ -261,22 +262,16 @@ public class FragmentHostManager {
        }
    }

    class PluginFragmentManager {
        private final ArrayMap<String, Context> mPluginLookup = new ArrayMap<>();
    class ExtensionFragmentManager {
        private final ArrayMap<String, Context> mExtensionLookup = new ArrayMap<>();

        public void removePlugin(String tag, String currentClass, String defaultClass) {
        public void setCurrentExtension(@NonNull  String tag, @Nullable String oldClass,
                @NonNull String currentClass, @Nullable Context context) {
            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
            mPluginLookup.remove(currentClass);
            getFragmentManager().beginTransaction()
                    .replace(((View) fragment.getView().getParent()).getId(),
                            instantiate(mContext, defaultClass, null), tag)
                    .commit();
            reloadFragments();
            if (oldClass != null) {
                mExtensionLookup.remove(oldClass);
            }

        public void setCurrentPlugin(String tag, String currentClass, Context context) {
            Fragment fragment = getFragmentManager().findFragmentByTag(tag);
            mPluginLookup.put(currentClass, context);
            mExtensionLookup.put(currentClass, context);
            getFragmentManager().beginTransaction()
                    .replace(((View) fragment.getView().getParent()).getId(),
                            instantiate(context, currentClass, null), tag)
@@ -292,11 +287,11 @@ public class FragmentHostManager {
        }

        Fragment instantiate(Context context, String className, Bundle arguments) {
            Context pluginContext = mPluginLookup.get(className);
            if (pluginContext != null) {
                Fragment f = Fragment.instantiate(pluginContext, className, arguments);
            Context extensionContext = mExtensionLookup.get(className);
            if (extensionContext != null) {
                Fragment f = Fragment.instantiate(extensionContext, className, arguments);
                if (f instanceof Plugin) {
                    ((Plugin) f).onCreate(mContext, pluginContext);
                    ((Plugin) f).onCreate(mContext, extensionContext);
                }
                return f;
            }
+51 −50
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ package com.android.systemui.statusbar.phone;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;

import static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
@@ -36,11 +37,17 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager.StackId;
import android.app.ActivityOptions;
import android.app.INotificationManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.app.StatusBarManager;
import android.app.TaskStackBuilder;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
@@ -49,8 +56,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -75,7 +85,9 @@ import android.media.session.PlaybackState;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
@@ -88,63 +100,86 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.DateTimeView;
import android.widget.ImageView;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.ActivityStarterDelegate;
import com.android.systemui.DejankUtils;
import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
import com.android.systemui.EventLogTags;
import com.android.systemui.Interpolators;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.ExtensionFragmentListener;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.PluginFragmentListener;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
@@ -183,6 +218,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
@@ -190,11 +226,15 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout
        .OnChildLocationsChangedListener;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.util.NotificationChannels;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.volume.VolumeComponent;

@@ -205,50 +245,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ActivityManager.StackId;
import android.app.INotificationManager;
import android.app.KeyguardManager;
import android.app.NotificationChannel;
import android.app.RemoteInput;
import android.app.TaskStackBuilder;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.os.Build;
import android.os.Handler;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.NotificationListenerService;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.IWindowManager;
import android.view.ViewAnimationUtils;
import android.view.accessibility.AccessibilityManager;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.DejankUtils;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
import com.android.systemui.SystemUI;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.recents.Recents;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.util.NotificationChannels;

import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

@@ -1133,11 +1133,12 @@ public class StatusBar extends SystemUI implements DemoMode,
        View container = mStatusBarWindow.findViewById(R.id.qs_frame);
        if (container != null) {
            FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
            fragmentHostManager.getFragmentManager().beginTransaction()
                    .replace(R.id.qs_frame, new QSFragment(), QS.TAG)
                    .commit();
            new PluginFragmentListener(container, QS.TAG, QSFragment.class, QS.class)
                    .startListening();
            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
                    Dependency.get(ExtensionController.class).newExtension(QS.class)
                            .withPlugin(QS.class)
                            .withUiMode(UI_MODE_TYPE_CAR, () -> new QSFragment())
                            .withDefault(() -> new QSFragment())
                            .build());
            final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
                    mIconController);
            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
+4 −2
Original line number Diff line number Diff line
@@ -14,8 +14,7 @@

package com.android.systemui.statusbar.policy;

import com.android.systemui.Dependency;
import com.android.systemui.plugins.Plugin;
import android.content.Context;

import java.util.Map;
import java.util.function.Consumer;
@@ -31,7 +30,9 @@ public interface ExtensionController {

    interface Extension<T> {
        T get();
        Context getContext();
        void destroy();
        void addCallback(Consumer<T> callback);
    }

    interface ExtensionBuilder<T> {
@@ -42,6 +43,7 @@ public interface ExtensionController {
                PluginConverter<T, P> converter);
        ExtensionBuilder<T> withDefault(Supplier<T> def);
        ExtensionBuilder<T> withCallback(Consumer<T> callback);
        ExtensionBuilder<T> withUiMode(int mode, Supplier<T> def);
        Extension build();
    }

Loading