diff options
9 files changed, 166 insertions, 7 deletions
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java new file mode 100644 index 000000000000..925214e3ab3a --- /dev/null +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginActivity.java @@ -0,0 +1,92 @@ +/* + * 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(); + } +} diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java index 25ce3ddf8169..db2e3765d2d0 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 1b694b372124..bb4412375ff8 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 4a459974fcb6..fe6eb4b5acfe 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -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); + } } diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java new file mode 100644 index 000000000000..9becc38d760e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginActivityManager.java @@ -0,0 +1,43 @@ +/* + * 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); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java index 493d244f5e99..a96839943cad 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java @@ -42,7 +42,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.Dependency; import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper; -import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.annotations.ProvidesInterface; import dalvik.system.PathClassLoader; @@ -120,14 +119,21 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null, false, mLooper, cls, this); + PluginListener<Plugin> listener = new PluginListener<Plugin>() { + @Override + public void onPluginConnected(Plugin plugin, Context pluginContext) { } + }; + mPluginMap.put(listener, p); mPluginPrefs.addAction(action); - PluginInfo<T> info = p.getPlugin(); + PluginInstanceManager.PluginInfo<T> info = p.getPlugin(); if (info != null) { mOneShotPackages.add(info.mPackage); mHasOneShot = true; startListening(); + mPluginMap.remove(listener); return info.mPlugin; } + mPluginMap.remove(listener); return null; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 9ba32b354d8f..de2ace4c30d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -43,11 +43,14 @@ import android.widget.Toast; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.Dependency; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; +import com.android.systemui.plugins.PluginActivity; +import com.android.systemui.plugins.PluginActivityManager; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.activity.ConfigurationChangedEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent; @@ -234,6 +237,8 @@ public class Recents extends SystemUI registerWithSystemUser(); } putComponent(Recents.class, this); + Dependency.get(PluginActivityManager.class).addActivityPlugin(RecentsImpl.RECENTS_ACTIVITY, + PluginActivity.ACTION_RECENTS); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java index b8e9fcd29096..bba982c3b060 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java @@ -26,8 +26,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; -import android.support.test.annotation.UiThreadTest; -import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -36,11 +34,10 @@ import android.testing.TestableLooper.RunWithLooper; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; +import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java index 0a83a896dfaf..d1b1c5b9a066 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java @@ -14,7 +14,6 @@ package com.android.systemui.utils.leaks; -import android.content.Context; import android.testing.LeakCheck; import com.android.systemui.plugins.Plugin; |