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

Commit 25df673b authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 1b51c9cb: Merge "Make SystemService constructor take a Context." into klp-modular-dev

* commit '1b51c9cb':
  Make SystemService constructor take a Context.
parents 2d6b55aa 1b51c9cb
Loading
Loading
Loading
Loading
+38 −21
Original line number Diff line number Diff line
@@ -23,24 +23,24 @@ import android.os.ServiceManager;
/**
 * The base class for services running in the system process. Override and implement
 * the lifecycle event callback methods as needed.
 *
 * <p>
 * The lifecycle of a SystemService:
 *
 * {@link #onCreate(android.content.Context)} is called to initialize the
 * service.
 *
 * {@link #onStart()} is called to get the service running. It is common
 * for services to publish their Binder interface at this point. All required
 * dependencies are also assumed to be ready to use.
 *
 * Then {@link #onBootPhase(int)} is called as many times as there are boot phases
 * </p><ul>
 * <li>The constructor is called and provided with the system {@link Context}
 * to initialize the system service.
 * <li>{@link #onStart()} is called to get the service running.  The service should
 * publish its binder interface at this point using
 * {@link #publishBinderService(String, IBinder)}.  It may also publish additional
 * local interfaces that other services within the system server may use to access
 * privileged internal functions.
 * <li>Then {@link #onBootPhase(int)} is called as many times as there are boot phases
 * until {@link #PHASE_BOOT_COMPLETE} is sent, which is the last boot phase. Each phase
 * is an opportunity to do special work, like acquiring optional service dependencies,
 * waiting to see if SafeMode is enabled, or registering with a service that gets
 * started after this one.
 *
 * NOTE: All lifecycle methods are called from the same thread that created the
 * SystemService.
 * </ul><p>
 * NOTE: All lifecycle methods are called from the system server's main looper thread.
 * </p>
 *
 * {@hide}
 */
@@ -54,17 +54,34 @@ public abstract class SystemService {
    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
    public static final int PHASE_BOOT_COMPLETE = 1000;

    private SystemServiceManager mManager;
    private Context mContext;
    private final Context mContext;

    final void init(Context context, SystemServiceManager manager) {
    /**
     * Initializes the system service.
     * <p>
     * Subclasses must define a single argument constructor that accepts the context
     * and passes it to super.
     * </p>
     *
     * @param context The system server context.
     */
    public SystemService(Context context) {
        mContext = context;
        mManager = manager;
        onCreate(context);
    }

    /**
     * Gets the system context.
     */
    public final Context getContext() {
        return mContext;
    }

    /**
     * Returns true if the system is running in safe mode.
     * TODO: we should define in which phase this becomes valid
     */
    public final boolean isSafeMode() {
        return mManager.isSafeMode();
        return getManager().isSafeMode();
    }

    /**
@@ -126,8 +143,8 @@ public abstract class SystemService {
        return LocalServices.getService(type);
    }

    public final Context getContext() {
        return mContext;
    private SystemServiceManager getManager() {
        return LocalServices.getService(SystemServiceManager.class);
    }

//    /**
+39 −47
Original line number Diff line number Diff line
@@ -17,14 +17,15 @@
package com.android.server;

import android.content.Context;
import android.util.Log;
import android.util.Slog;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

/**
 * Manages creating, starting, and other lifecycle events of
 * {@link com.android.server.SystemService}s.
 * {@link com.android.server.SystemService system services}.
 *
 * {@hide}
 */
@@ -68,24 +69,43 @@ public class SystemServiceManager {
     */
    @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        final T serviceInstance = (T)createInstance(serviceClass);
        try {
            Slog.i(TAG, "Creating " + serviceClass.getSimpleName());
            serviceInstance.init(mContext, this);
        } catch (Throwable e) {
            throw new RuntimeException("Failed to create service " + serviceClass.getName(), e);
        }

        mServices.add(serviceInstance);
        final String name = serviceClass.getName();
        Slog.i(TAG, "Starting " + name);

        // Create the service.
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service could not be instantiated", ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service constructor threw an exception", ex);
        }

        // Register it.
        mServices.add(service);

        // Start it.
        try {
            Slog.i(TAG, "Starting " + serviceClass.getSimpleName());
            serviceInstance.onStart();
        } catch (Throwable e) {
            throw new RuntimeException("Failed to start service " + serviceClass.getName(), e);
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + name
                    + ": onStart threw an exception", ex);
        }

        return serviceInstance;
        return service;
    }

    /**
@@ -107,9 +127,11 @@ public class SystemServiceManager {
            final SystemService service = mServices.get(i);
            try {
                service.onBootPhase(mCurrentPhase);
            } catch (Throwable e) {
                reportWtf("Service " + service.getClass().getName() +
                        " threw an Exception processing boot phase " + mCurrentPhase, e);
            } catch (Exception ex) {
                throw new RuntimeException("Failed to boot service "
                        + service.getClass().getName()
                        + ": onBootPhase threw an exception during phase "
                        + mCurrentPhase, ex);
            }
        }
    }
@@ -144,34 +166,4 @@ public class SystemServiceManager {

        Slog.e(TAG, builder.toString());
    }

    private SystemService createInstance(Class<?> clazz) {
        // Make sure it's a type we expect
        if (!SystemService.class.isAssignableFrom(clazz)) {
            reportWtf("Class " + clazz.getName() + " does not extend " +
                    SystemService.class.getName());
        }

        try {
            return (SystemService) clazz.newInstance();
        } catch (InstantiationException e) {
            reportWtf("Class " + clazz.getName() + " is abstract", e);
        } catch (IllegalAccessException e) {
            reportWtf("Class " + clazz.getName() +
                    " must have a public no-arg constructor", e);
        }
        return null;
    }

    private static void reportWtf(String message) {
        reportWtf(message, null);
    }

    private static void reportWtf(String message, Throwable e) {
        Slog.i(TAG, "******************************");
        Log.wtf(TAG, message, e);

        // Make sure we die
        throw new RuntimeException(message, e);
    }
}
+5 −5
Original line number Diff line number Diff line
@@ -53,13 +53,13 @@ public class AppWidgetService extends SystemService {

    static final String TAG = "AppWidgetService";

    Context mContext;
    Handler mSaveStateHandler;
    final Context mContext;
    final Handler mSaveStateHandler;

    SparseArray<AppWidgetServiceImpl> mAppWidgetServices;
    final SparseArray<AppWidgetServiceImpl> mAppWidgetServices;

    @Override
    public void onCreate(Context context) {
    public AppWidgetService(Context context) {
        super(context);
        mContext = context;

        mSaveStateHandler = BackgroundThread.getHandler();
+14 −0
Original line number Diff line number Diff line
@@ -274,6 +274,20 @@ public class BackupManagerService extends IBackupManager.Stub {
    // Watch the device provisioning operation during setup
    ContentObserver mProvisionedObserver;

    public static final class Lifecycle extends SystemService {
        private final BackupManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new BackupManagerService(context);
        }

        @Override
        public void onStart() {
            publishBinderService(Context.BACKUP_SERVICE, mService);
        }
    }

    class ProvisionedObserver extends ContentObserver {
        public ProvisionedObserver(Handler handler) {
            super(handler);
+0 −36
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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.server.backup;

import android.content.Context;

import com.android.server.SystemService;

public class BackupManagerSystemService extends SystemService {
    private BackupManagerService mBackupManagerImpl;

    @Override
    public void onCreate(Context context) {
        mBackupManagerImpl = new BackupManagerService(context);
    }

    @Override
    public void onStart() {
        publishBinderService(Context.BACKUP_SERVICE, mBackupManagerImpl);
    }
}
Loading