Commit 0c24a571 authored by Amit Kumar's avatar Amit Kumar 💻
Browse files

Build SystemUIShared in the project itself

parent 1822e6b3
Pipeline #124132 failed with stage
in 4 minutes and 56 seconds
*.iml
.project
.classpath
.project.properties
gen/
bin/
.idea/
.gradle/
local.properties
gradle/
build/
gradlew*
.DS_Store
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.systemui.shared">
</manifest>
import foundation.e.blisslauncher.buildsrc.Versions
apply plugin: 'com.android.library'
android {
compileSdkVersion Versions.compile_sdk
buildToolsVersion "30.0.3"
defaultConfig {
minSdkVersion Versions.min_sdk
targetSdkVersion Versions.target_sdk
versionCode 1
versionName "1.0"
}
sourceSets {
main {
java.srcDirs = ['src']
aidl.srcDirs = ['src']
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
}
}
lintOptions {
abortOnError false
}
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
addFrameworkJar('framework.jar')
}
dependencies {
compileOnly files('libs/framework.jar')
}
/*
* 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.systemui.plugins;
import com.android.systemui.plugins.annotations.Requires;
import android.content.Context;
/**
* Plugins are separate APKs that
* are expected to implement interfaces provided by SystemUI. Their
* code is dynamically loaded into the SysUI process which can allow
* for multiple prototypes to be created and run on a single android
* build.
*
* PluginLifecycle:
* <pre class="prettyprint">
*
* plugin.onCreate(Context sysuiContext, Context pluginContext);
* --- This is always called before any other calls
*
* pluginListener.onPluginConnected(Plugin p);
* --- This lets the plugin hook know that a plugin is now connected.
*
* ** Any other calls back and forth between sysui/plugin **
*
* pluginListener.onPluginDisconnected(Plugin p);
* --- Lets the plugin hook know that it should stop interacting with
* this plugin and drop all references to it.
*
* plugin.onDestroy();
* --- Finally the plugin can perform any cleanup to ensure that its not
* leaking into the SysUI process.
*
* Any time a plugin APK is updated the plugin is destroyed and recreated
* to load the new code/resources.
*
* </pre>
*
* Creating plugin hooks:
*
* To create a plugin hook, first create an interface in
* frameworks/base/packages/SystemUI/plugin that extends Plugin.
* Include in it any hooks you want to be able to call into from
* sysui and create callback interfaces for anything you need to
* pass through into the plugin.
*
* Then to attach to any plugins simply add a plugin listener and
* onPluginConnected will get called whenever new plugins are installed,
* updated, or enabled. Like this example from SystemUIApplication:
*
* <pre class="prettyprint">
* {@literal
* PluginManager.getInstance(this).addPluginListener(OverlayPlugin.COMPONENT,
* new PluginListener<OverlayPlugin>() {
* @Override
* public void onPluginConnected(OverlayPlugin plugin) {
* StatusBar phoneStatusBar = getComponent(StatusBar.class);
* if (phoneStatusBar != null) {
* plugin.setup(phoneStatusBar.getStatusBarWindow(),
* phoneStatusBar.getNavigationBarView());
* }
* }
* }, OverlayPlugin.VERSION, true /* Allow multiple plugins *\/);
* }
* </pre>
* Note the VERSION included here. Any time incompatible changes in the
* interface are made, this version should be changed to ensure old plugins
* aren't accidentally loaded. Since the plugin library is provided by
* SystemUI, default implementations can be added for new methods to avoid
* version changes when possible.
*
* Implementing a Plugin:
*
* See the ExamplePlugin for an example Android.mk on how to compile
* a plugin. Note that SystemUILib is not static for plugins, its classes
* are provided by SystemUI.
*
* Plugin security is based around a signature permission, so plugins must
* hold the following permission in their manifest.
*
* <pre class="prettyprint">
* {@literal
* <uses-permission android:name="com.android.systemui.permission.PLUGIN" />
* }
* </pre>
*
* A plugin is found through a querying for services, so to let SysUI know
* about it, create a service with a name that points at your implementation
* of the plugin interface with the action accompanying it:
*
* <pre class="prettyprint">
* {@literal
* <service android:name=".TestOverlayPlugin">
* <intent-filter>
* <action android:name="com.android.systemui.action.PLUGIN_COMPONENT" />
* </intent-filter>
* </service>
* }
* </pre>
*/
public interface Plugin {
/**
* @deprecated
* @see Requires
*/
default int getVersion() {
// Default of -1 indicates the plugin supports the new Requires model.
return -1;
}
default void onCreate(Context sysuiContext, Context pluginContext) {
}
default void onDestroy() {
}
}
/*
* 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.systemui.plugins;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
public abstract class PluginFragment extends Fragment implements Plugin {
private Context mPluginContext;
@Override
public void onCreate(Context sysuiContext, Context pluginContext) {
mPluginContext = pluginContext;
}
@Override
public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
return super.onGetLayoutInflater(savedInstanceState).cloneInContext(getContext());
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public Context getContext() {
return mPluginContext;
}
}
/*
* 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.systemui.plugins;
import android.content.Context;
/**
* Interface for listening to plugins being connected.
*/
public interface PluginListener<T extends Plugin> {
/**
* Called when the plugin has been loaded and is ready to be used.
* This may be called multiple times if multiple plugins are allowed.
* It may also be called in the future if the plugin package changes
* and needs to be reloaded.
*/
void onPluginConnected(T plugin, Context pluginContext);
/**
* Called when a plugin has been uninstalled/updated and should be removed
* from use.
*/
default void onPluginDisconnected(T plugin) {
// Optional.
}
}
/*
* 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.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Used for repeated @DependsOn internally, not for plugin
* use.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Dependencies {
DependsOn[] value();
}
/*
* 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.annotations;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Used to indicate that an interface in the plugin library needs another
* interface to function properly. When this is added, it will be enforced
* that all plugins that @Requires the annotated interface also @Requires
* the specified class as well.
*/
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(value = Dependencies.class)
public @interface DependsOn {
Class<?> target();
}
/*
* 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.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Should be added to all interfaces in plugin lib to specify their
* current version and optionally their action to implement the plugin.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface ProvidesInterface {
int version();
String action() default "";
}
/*
* 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.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Used for repeated @Requires internally, not for plugin
* use.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Requirements {
Requires[] value();
}
/*
* 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.annotations;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Used to annotate which interfaces a given plugin depends on.
*
* At minimum all plugins should have at least one @Requires annotation
* for the plugin interface that they are implementing. They will also
* need an @Requires for each class that the plugin interface @DependsOn.
*/
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(value = Requirements.class)
public @interface Requires {
Class<?> target();
int version();
}
/*
* Copyright (C) 2018 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.shared.plugins;
import android.annotation.IntDef;
import android.content.ComponentName;
/**
* Enables and disables plugins.
*/
public interface PluginEnabler {
int ENABLED = 0;
int DISABLED_MANUALLY = 1;
int DISABLED_INVALID_VERSION = 1;
int DISABLED_FROM_EXPLICIT_CRASH = 2;
int DISABLED_FROM_SYSTEM_CRASH = 3;
@IntDef({ENABLED, DISABLED_MANUALLY, DISABLED_INVALID_VERSION, DISABLED_FROM_EXPLICIT_CRASH,
DISABLED_FROM_SYSTEM_CRASH})
@interface DisableReason {
}
/** Enables plugin via the PackageManager. */
void setEnabled(ComponentName component);
/** Disables a plugin via the PackageManager and records the reason for disabling. */
void setDisabled(ComponentName component, @DisableReason int reason);
/** Returns true if the plugin is enabled in the PackageManager. */
boolean isEnabled(ComponentName component);
/**
* Returns the reason that a plugin is disabled, (if it is).
*
* It should return {@link #ENABLED} if the plugin is turned on.
* It should return {@link #DISABLED_MANUALLY} if the plugin is off but the reason is unknown.
*/
@DisableReason
int getDisableReason(ComponentName componentName);
}
/*
* Copyright (C) 2018 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.shared.plugins;
import android.content.Context;
import android.os.Looper;
/**
* Provides necessary components for initializing {@link PluginManagerImpl}.
*/
public interface PluginInitializer {
Looper getBgLooper();
/**
* Called from the bg looper during initialization of {@link PluginManagerImpl}.
*/
void onPluginManagerInit();
String[] getWhitelistedPlugins(Context context);
PluginEnabler getPluginEnabler(Context context);
/**
* Called from {@link PluginManagerImpl#handleWtfs()}.
*/
void handleWtfs();
}
/*
* 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.shared.plugins;
import android.text.TextUtils;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.annotations.ProvidesInterface;
public interface PluginManager {
String PLUGIN_CHANGED = "com.android.systemui.action.PLUGIN_CHANGED";
// must be one of the channels created in NotificationChannels.java
String NOTIFICATION_CHANNEL_ID = "ALR";
String[] getWhitelistedPlugins();
<T extends Plugin> T getOneShotPlugin(Class<T> cls);
<T extends Plugin> T getOneShotPlugin(String action, Class<?> cls);
<T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls);
<T extends Plugin> void addPluginListener(PluginListener<T> listener, Class<?> cls,
boolean allowMultiple);
<T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
Class<?> cls);
<T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
Class cls, boolean allowMultiple);
void removePluginListener(PluginListener<?> listener);