Add basic chimera classes for DroidGuard compatibility

This commit is contained in:
Marvin W 2021-11-08 13:54:45 +01:00
parent 6202aa9b34
commit d8325870cb
No known key found for this signature in database
GPG Key ID: 072E9235DB996F2A
9 changed files with 476 additions and 0 deletions

View File

@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2020, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'maven-publish'
apply plugin: 'signing'
dependencies {
api project(':play-services-basement')
api "androidx.lifecycle:lifecycle-service:$lifecycleVersion"
implementation "androidx.annotation:annotation:$annotationVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
}
android {
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
apply from: '../gradle/publish-android.gradle'
description = 'microG chimera implementation'

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2021, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.microg.gms.chimera.core">
<application />
</manifest>

View File

@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.chimera;
public interface InstanceProvider {
Object getChimeraImpl();
}

View File

@ -0,0 +1,118 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.chimera;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
public abstract class IntentService extends Service {
private Looper serviceLooper;
private ServiceHandler serviceHandler;
private String name;
private boolean redelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
this.name = name;
}
/**
* Sets intent redelivery preferences. Usually called from the constructor
* with your preferred semantics.
*
* <p>If enabled is true,
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_REDELIVER_INTENT}, so if this process dies before
* {@link #onHandleIntent(Intent)} returns, the process will be restarted
* and the intent redelivered. If multiple Intents have been sent, only
* the most recent one is guaranteed to be redelivered.
*
* <p>If enabled is false (the default),
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_NOT_STICKY}, and if the process dies, the Intent
* dies along with it.
*/
public void setIntentRedelivery(boolean redelivery) {
this.redelivery = redelivery;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + name + "]");
thread.start();
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
Message msg = this.serviceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
this.serviceHandler.sendMessage(msg);
}
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see Service#onStartCommand
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return redelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
serviceLooper.quit();
}
/**
* Unless you provide binding for your service, you don't need to implement this
* method, because the default implementation returns null.
* @see Service#onBind
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* This method is invoked on the worker thread with a request to process.
* Only one Intent is processed at a time, but the processing happens on a
* worker thread that runs independently from other application logic.
* So, if this code takes a long time, it will hold up other requests to
* the same IntentService, but it will not hold up anything else.
* When all requests have been handled, the IntentService stops itself,
* so you should not call {@link #stopSelf}.
*
* @param intent The value passed to {@link
* android.content.Context#startService(Intent)}.
* This may be null if the service is being restarted after
* its process has gone away; see
* {@link Service#onStartCommand}
* for details.
*/
public abstract void onHandleIntent(Intent intent);
}

View File

@ -0,0 +1,131 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.chimera;
import android.app.Application;
import android.app.Notification;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.IBinder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
public abstract class Service extends ContextWrapper implements InstanceProvider {
public static final int START_CONTINUATION_MASK = 0xf;
public static final int START_FLAG_REDELIVERY = 1;
public static final int START_FLAG_RETRY = 2;
public static final int START_NOT_STICKY = 2;
public static final int START_REDELIVER_INTENT = 3;
public static final int START_STICKY = 1;
public static final int START_STICKY_COMPATIBILITY = 0;
private android.app.Service containerService;
private ProxyCallbacks callbacks;
public interface ProxyCallbacks {
void superOnCreate();
void superOnDestroy();
int superOnStartCommand(Intent intent, int flags, int startId);
void superStopSelf();
void superStopSelf(int startId);
boolean superStopSelfResult(int startId);
}
public Service() {
super(null);
}
protected void dump(FileDescriptor fs, PrintWriter writer, String[] args) {
}
public final Application getApplication() {
return containerService.getApplication();
}
@Override
public Object getChimeraImpl() {
return this;
}
public android.app.Service getContainerService() {
return containerService;
}
public abstract IBinder onBind(Intent intent);
public void onConfigurationChanged(Configuration configuration) {
}
public void onCreate() {
this.callbacks.superOnCreate();
}
public void onDestroy() {
this.callbacks.superOnDestroy();
}
public void onLowMemory() {
}
public void onRebind(Intent intent) {
}
public void onStart(Intent intent, int startId) {
}
public int onStartCommand(Intent intent, int flags, int startId) {
return this.callbacks.superOnStartCommand(intent, flags, startId);
}
public void onTaskRemoved(Intent rootIntent) {
}
public void onTrimMemory(int level) {
}
public boolean onUnbind(Intent intent) {
return false;
}
public void publicDump(FileDescriptor fd, PrintWriter writer, String[] args) {
dump(fd, writer, args);
}
public void setProxy(android.app.Service service, Context context) {
this.containerService = service;
this.callbacks = (ProxyCallbacks) service;
attachBaseContext(context);
}
public final void startForeground(int id, Notification notification) {
this.containerService.startForeground(id, notification);
}
public final void stopForeground(boolean removeNotification) {
this.containerService.stopForeground(removeNotification);
}
public final void stopSelf() {
this.callbacks.superStopSelf();
}
public final boolean stopSelfResult(int startId) {
return this.callbacks.superStopSelfResult(startId);
}
public final void stopSelf(int startId) {
this.callbacks.superStopSelf(startId);
}
}

View File

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.chimera
import android.content.Context
import com.google.android.chimera.Service
interface ServiceLoader {
fun loadService(context: Context): Service
companion object {
inline fun <reified T : Service> static() = StaticServiceLoader(T::class.java)
}
}

View File

@ -0,0 +1,134 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.chimera
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import com.google.android.chimera.Service.ProxyCallbacks
import android.os.IBinder
import com.google.android.chimera.Service
import java.io.FileDescriptor
import java.io.PrintWriter
abstract class ServiceProxy(private val loader: ServiceLoader) : android.app.Service(), ProxyCallbacks {
private var actualService: Service? = null
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
if (actualService == null) {
val service = loader.loadService(base)
actualService = service
service.setProxy(this, this)
}
}
override fun dump(fs: FileDescriptor, writer: PrintWriter, args: Array<String>) {
if (actualService != null) {
actualService!!.publicDump(fs, writer, args)
}
}
override fun onBind(intent: Intent): IBinder? {
return if (actualService != null) {
actualService!!.onBind(intent)
} else null
}
override fun onConfigurationChanged(newConfig: Configuration) {
if (actualService != null) {
actualService!!.onConfigurationChanged(newConfig)
}
}
override fun onCreate() {
if (actualService != null) {
actualService!!.onCreate()
}
}
override fun onDestroy() {
if (actualService != null) {
actualService!!.onDestroy()
}
}
override fun onLowMemory() {
if (actualService != null) {
actualService!!.onLowMemory()
}
}
override fun onRebind(intent: Intent) {
if (actualService != null) {
if (intent != null) intent.setExtrasClassLoader(actualService!!.classLoader)
actualService!!.onRebind(intent)
}
}
override fun onStart(intent: Intent, startId: Int) {
if (actualService != null) {
if (intent != null) intent.setExtrasClassLoader(actualService!!.classLoader)
actualService!!.onStart(intent, startId)
} else {
stopSelf(startId)
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return if (actualService != null) {
if (intent != null) intent.setExtrasClassLoader(actualService!!.classLoader)
actualService!!.onStartCommand(intent, flags, startId)
} else {
super.onStartCommand(intent, flags, startId)
}
}
override fun onTaskRemoved(rootIntent: Intent) {
if (actualService != null) {
if (rootIntent != null) rootIntent.setExtrasClassLoader(actualService!!.classLoader)
actualService!!.onTaskRemoved(rootIntent)
}
}
override fun onTrimMemory(level: Int) {
if (actualService != null) {
actualService!!.onTrimMemory(level)
}
}
override fun onUnbind(intent: Intent): Boolean {
return if (actualService != null) {
if (intent != null) intent.setExtrasClassLoader(actualService!!.classLoader)
actualService!!.onUnbind(intent)
} else {
false
}
}
override fun superOnCreate() {
super.onCreate()
}
override fun superOnDestroy() {
super.onDestroy()
}
override fun superOnStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun superStopSelf() {
super.stopSelf()
}
override fun superStopSelf(startId: Int) {
super.stopSelf(startId)
}
override fun superStopSelfResult(startId: Int): Boolean {
return super.stopSelfResult(startId)
}
}

View File

@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.chimera
import android.content.Context
import com.google.android.chimera.Service
class StaticServiceLoader<T : Service>(private val serviceClass: Class<T>) : ServiceLoader {
override fun loadService(context: Context): Service {
return serviceClass.getDeclaredConstructor().newInstance()
}
}

View File

@ -43,6 +43,7 @@ include ':play-services-basement-ktx'
include ':play-services-tasks-ktx'
include ':play-services-base-core'
include ':play-services-chimera-core'
include ':play-services-conscrypt-provider-core'
include ':play-services-cronet-core'
include ':play-services-location-core'