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

Commit 88fff901 authored by Quarx2k's avatar Quarx2k Committed by Steve Kondik
Browse files

Allow loading of vendor specific services from compiled jar files.

This is needed e.g. for the Motorola AGPS code.
parent 0620b6bb
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -415,6 +415,11 @@
    <string-array name="config_twoDigitNumberPattern">
    </string-array>

    <!-- Contains a list of vendor specific services to start via ServiceManager.
         Format for each item is: <path_to_service_jar_file>:<service_class_name> -->
    <string-array name="config_vendorServices">
    </string-array>

    <!-- ************************************************
         *                                              *
         *    GLOBAL DEFAULT VALUES FOR CM SETTINGS     *
+38 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.internal.app.ShutdownThread;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;

import dalvik.system.DexClassLoader;
import dalvik.system.VMRuntime;
import dalvik.system.Zygote;

@@ -31,6 +32,7 @@ import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentService;
import android.content.ContextWrapper;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -38,6 +40,7 @@ import android.content.pm.IPackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.media.AudioService;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -58,6 +61,7 @@ import android.accounts.AccountManagerService;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import java.lang.reflect.Constructor;

class ServerThread extends Thread {
    private static final String TAG = "SystemServer";
@@ -478,6 +482,40 @@ class ServerThread extends Thread {
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting AssetRedirectionManager Service", e);
            }

            String[] vendorServices = context.getResources().getStringArray(
                    com.android.internal.R.array.config_vendorServices);

            if (vendorServices != null && vendorServices.length > 0) {
                String cachePath = new ContextWrapper(context).getCacheDir().getAbsolutePath();
                ClassLoader parentLoader = ClassLoader.getSystemClassLoader();

                for (String service : vendorServices) {
                    String[] parts = service.split(":");
                    if (parts.length != 2) {
                        Slog.e(TAG, "Found invalid vendor service " + service);
                        continue;
                    }

                    String jarPath = parts[0];
                    String className = parts[1];

                    try {
                        /* Intentionally skipping all null checks in this block, as we also want an
                           error message if class loading or ctor resolution failed. The catch block
                           conveniently provides that for us also for NullPointerException */
                        DexClassLoader loader = new DexClassLoader(jarPath, cachePath, null, parentLoader);
                        Class<?> klass = loader.loadClass(className);
                        Constructor<?> ctor = klass.getDeclaredConstructors()[0];
                        Object instance = ctor.newInstance(context);

                        ServiceManager.addService(klass.getSimpleName(), (IBinder) instance);
                        Slog.i(TAG, "Vendor service " + className + " started.");
                    } catch (Exception e) {
                        Slog.e(TAG, "Starting vendor service " + className + " failed.", e);
                    }
                }
            }
        }

        // make sure the ADB_ENABLED setting value matches the secure property value