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

Commit 0ea67d82 authored by Jason Monk's avatar Jason Monk
Browse files

Add plugin to swap out recents

Adds new mechanism for activities in sysui to be replaced by plugins
and allows that to happen for recents.

Test: runtest systemui
Change-Id: I8b570ce7c57484c58a52afe5e247d24ebfa0c57f
parent a178205e
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
/*
 * 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.systemui.plugins;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;

import com.android.systemui.plugins.annotations.ProvidesInterface;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A PluginActivity is an activity that replaces another full activity (e.g. RecentsActivity)
 * at runtime within the sysui process.
 */
@ProvidesInterface(version = PluginActivity.VERSION)
public abstract class PluginActivity extends Activity implements Plugin {

    public static final int VERSION = 1;

    public static final String ACTION_RECENTS = "com.android.systemui.action.PLUGIN_RECENTS";

    private Context mSysuiContext;
    private boolean mSettingActionBar;

    @Override
    public final void onCreate(Context sysuiContext, Context pluginContext) {
        mSysuiContext = sysuiContext;
        super.attachBaseContext(pluginContext);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Theme theme = getClass().getDeclaredAnnotation(Theme.class);
        if (theme != null && theme.value() != 0) {
            setTheme(theme.value());
        }
        mSettingActionBar = true;
        getActionBar();
        mSettingActionBar = false;
    }

    @Override
    public Resources getResources() {
        return mSettingActionBar ? mSysuiContext.getResources() : super.getResources();
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        mSysuiContext = newBase;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public Context getSysuiContext() {
        return mSysuiContext;
    }

    public Context getPluginContext() {
        return getBaseContext();
    }

    /**
     * Since PluginActivities are declared as services instead of activities (since they
     * are plugins), they can't have a theme attached to them. Instead a PluginActivity
     * can annotate itself with @Theme to specify the resource of the style it wants
     * to be themed with.
     */
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Theme {
        int value();
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@ public class PluginDependency {
    public static final int VERSION = 1;
    static DependencyProvider sProvider;

    /**
     * Allows a plugin to get a hold of static dependencies if they have declared dependence
     * on their interface. For one-shot plugins this will only work during onCreate and will
     * not work afterwards.
     */
    public static <T> T get(Plugin p, Class<T> cls) {
        return sProvider.get(p, cls);
    }
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.assist.AssistManager;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.PluginActivityManager;
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.PluginManagerImpl;
@@ -276,6 +277,9 @@ public class Dependency extends SystemUI {

        mProviders.put(UiOffloadThread.class, UiOffloadThread::new);

        mProviders.put(PluginActivityManager.class,
                () -> new PluginActivityManager(mContext, getDependency(PluginManager.class)));

        // Put all dependencies above here so the factory can override them if it wants.
        SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
    }
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui;

import android.app.Activity;
import android.app.ActivityThread;
import android.app.Application;
import android.content.BroadcastReceiver;
@@ -39,6 +40,7 @@ import com.android.systemui.pip.PipUI;
import com.android.systemui.plugins.GlobalActions;
import com.android.systemui.plugins.OverlayPlugin;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginActivityManager;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.power.PowerUI;
@@ -266,4 +268,10 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
    public SystemUI[] getServices() {
        return mServices;
    }

    @Override
    public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
        if (!mServicesStarted) return null;
        return Dependency.get(PluginActivityManager.class).instantiate(cl, className, intent);
    }
}
+43 −0
Original line number Diff line number Diff line
/*
 * 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.systemui.plugins;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.ArrayMap;

public class PluginActivityManager {

    private final Context mContext;
    private final PluginManager mPluginManager;
    private final ArrayMap<String, String> mActionLookup = new ArrayMap<>();

    public PluginActivityManager(Context context, PluginManager pluginManager) {
        mContext = context;
        mPluginManager = pluginManager;
    }

    public void addActivityPlugin(String className, String action) {
        mActionLookup.put(className, action);
    }

    public Activity instantiate(ClassLoader cl, String className, Intent intent) {
        String action = mActionLookup.get(className);
        if (TextUtils.isEmpty(action)) return null;
        return mPluginManager.getOneShotPlugin(action, PluginActivity.class);
    }
}
Loading