Android系统服务实现流程

 

通过adb可以查看系统服务

adb shell

shell@CHT80A:/ $ service list
Found 105 services:
0       media.widi.uibc: [intel.widi.IUibcServer]
1       oemtelephony: [com.intel.internal.telephony.OemTelephony.IOemTelephony]
2       phone: [com.android.internal.telephony.ITelephony]
3       isms: [com.android.internal.telephony.ISms]
4       iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo]
5       simphonebook: [com.android.internal.telephony.IIccPhoneBook]
6       isub: [com.android.internal.telephony.ISub]
7       telecom: [com.android.internal.telecom.ITelecomService]
8       imms: [com.android.internal.telephony.IMms]
9       media_projection: [android.media.projection.IMediaProjectionManager]
10      launcherapps: [android.content.pm.ILauncherApps]

......

 

看vibrator: [android.os.IVibratorService]这个服务。

/frameworks/base/core/java/android/content/Context.java

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.os.Vibrator} for interacting with the vibration hardware.
     *
     * @see #getSystemService
     * @see android.os.Vibrator
     */
    public static final String VIBRATOR_SERVICE = "vibrator";

 

/frameworks/base/core/java/android/app/ContextImpl.java

//在静态块中注册这个服务

registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                return new SystemVibrator(ctx);
            }});

 

 

frameworks/base/services/java/com/android/server/SystemServer.java

将vibrate Service 加入到SystemServer 启动进程。

在  startOtherServices() 函数 的try模块中增加以下代码

            vibrator = new VibratorService(context);
            ServiceManager.addService("vibrator", vibrator);

 

/frameworks/base/core/java/android/os/IVibratorService.aidl  通过aidl通信

interface IVibratorService
{
    boolean hasVibrator();
    void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token);
    void vibratePattern(int uid, String opPkg, in long[] pattern, int repeat, int usageHint, IBinder token);
    void cancelVibrate(IBinder token);
}

编译要加入到make file 中:/frameworks/base/Android.mk:207:    core/java/android/os/IVibratorService.aidl

/frameworks/base/services/core/java/com/android/server/VibratorService.java 服务本身,实现IVibratorService中定义的接口

public class VibratorService extends IVibratorService.Stub
        implements InputManager.InputDeviceListener {

 

native static boolean vibratorExists();

    @Override // Binder call
    public boolean hasVibrator() {
        return doVibratorExists();
    }

    private boolean doVibratorExists() {
        // For now, we choose to ignore the presence of input devices that have vibrators
        // when reporting whether the device has a vibrator.  Applications often use this
        // information to decide whether to enable certain features so they expect the
        // result of hasVibrator() to be constant.  For now, just report whether
        // the device has a built-in vibrator.
        //synchronized (mInputDeviceVibrators) {
        //    return !mInputDeviceVibrators.isEmpty() || vibratorExists();
        //}
        return vibratorExists();
    }

}

 

通过JNI与C++交互:

/frameworks/base/services/core/jni/com_android_server_VibratorService.cpp

static jboolean vibratorExists(JNIEnv, jobject)
{
    if (gVibraModule && gVibraDevice) {
        return JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}

编译的时候:

./frameworks/base/services/core/jni/Android.mk:26:    $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp

 

Manager如下:

/frameworks/base/core/java/android/os/Vibrator.java

public abstract class Vibrator {

    private final String mPackageName;

    /**
     * @hide to prevent subclassing from outside of the framework
     */
    public Vibrator() {
        mPackageName = ActivityThread.currentPackageName();
    }

    /**
     * @hide to prevent subclassing from outside of the framework
     */
    protected Vibrator(Context context) {
        mPackageName = context.getOpPackageName();
    }

    /**
     * Check whether the hardware has a vibrator.
     *
     * @return True if the hardware has a vibrator, else false.
     */
    public abstract boolean hasVibrator();

    /**
     * Vibrate constantly for the specified period of time.
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#VIBRATE}.
     *
     * @param milliseconds The number of milliseconds to vibrate.
     */
    public void vibrate(long milliseconds) {
        vibrate(milliseconds, null);
    }

    /**
     * Vibrate constantly for the specified period of time.
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#VIBRATE}.
     *
     * @param milliseconds The number of milliseconds to vibrate.
     * @param attributes {@link AudioAttributes} corresponding to the vibration. For example,
     *        specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or
     *        {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for
     *        vibrations associated with incoming calls.
     */
    public void vibrate(long milliseconds, AudioAttributes attributes) {
        vibrate(Process.myUid(), mPackageName, milliseconds, attributes);
    }

    /**
     * Vibrate with a given pattern.
     *
     * <p>
     * Pass in an array of ints that are the durations for which to turn on or off
     * the vibrator in milliseconds.  The first value indicates the number of milliseconds
     * to wait before turning the vibrator on.  The next value indicates the number of milliseconds
     * for which to keep the vibrator on before turning it off.  Subsequent values alternate
     * between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
     * </p><p>
     * To cause the pattern to repeat, pass the index into the pattern array at which
     * to start the repeat, or -1 to disable repeating.
     * </p>
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#VIBRATE}.
     *
     * @param pattern an array of longs of times for which to turn the vibrator on or off.
     * @param repeat the index into pattern at which to repeat, or -1 if
     *        you don't want to repeat.
     */
    public void vibrate(long[] pattern, int repeat) {
        vibrate(pattern, repeat, null);
    }

    /**
     * Vibrate with a given pattern.
     *
     * <p>
     * Pass in an array of ints that are the durations for which to turn on or off
     * the vibrator in milliseconds.  The first value indicates the number of milliseconds
     * to wait before turning the vibrator on.  The next value indicates the number of milliseconds
     * for which to keep the vibrator on before turning it off.  Subsequent values alternate
     * between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
     * </p><p>
     * To cause the pattern to repeat, pass the index into the pattern array at which
     * to start the repeat, or -1 to disable repeating.
     * </p>
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#VIBRATE}.
     *
     * @param pattern an array of longs of times for which to turn the vibrator on or off.
     * @param repeat the index into pattern at which to repeat, or -1 if
     *        you don't want to repeat.
     * @param attributes {@link AudioAttributes} corresponding to the vibration. For example,
     *        specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or
     *        {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for
     *        vibrations associated with incoming calls.
     */
    public void vibrate(long[] pattern, int repeat, AudioAttributes attributes) {
        vibrate(Process.myUid(), mPackageName, pattern, repeat, attributes);
    }

    /**
     * @hide
     * Like {@link #vibrate(long, AudioAttributes)}, but allowing the caller to specify that
     * the vibration is owned by someone else.
     */
    public abstract void vibrate(int uid, String opPkg, long milliseconds,
            AudioAttributes attributes);

    /**
     * @hide
     * Like {@link #vibrate(long[], int, AudioAttributes)}, but allowing the caller to specify that
     * the vibration is owned by someone else.
     */
    public abstract void vibrate(int uid, String opPkg, long[] pattern, int repeat,
            AudioAttributes attributes);

    /**
     * Turn the vibrator off.
     * <p>This method requires the caller to hold the permission
     * {@link android.Manifest.permission#VIBRATE}.
     */
    public abstract void cancel();
}
 

/frameworks/base/core/java/android/os/SystemVibrator.java 

public class SystemVibrator extends Vibrator {
    private static final String TAG = "Vibrator";

    private final IVibratorService mService;
    private final Binder mToken = new Binder();

    public SystemVibrator() {
        mService = IVibratorService.Stub.asInterface(
                ServiceManager.getService("vibrator"));
    }

    public SystemVibrator(Context context) {
        super(context);
        mService = IVibratorService.Stub.asInterface(
                ServiceManager.getService("vibrator"));
    }

    @Override
    public boolean hasVibrator() {
        if (mService == null) {
            Log.w(TAG, "Failed to vibrate; no vibrator service.");
            return false;
        }
        try {
            return mService.hasVibrator();
        } catch (RemoteException e) {
        }
        return false;
    }

    /**
     * @hide
     */
    @Override
    public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) {
        if (mService == null) {
            Log.w(TAG, "Failed to vibrate; no vibrator service.");
            return;
        }
        try {
            mService.vibrate(uid, opPkg, milliseconds, usageForAttributes(attributes), mToken);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to vibrate.", e);
        }
    }

    /**
     * @hide
     */
    @Override
    public void vibrate(int uid, String opPkg, long[] pattern, int repeat,
            AudioAttributes attributes) {
        if (mService == null) {
            Log.w(TAG, "Failed to vibrate; no vibrator service.");
            return;
        }
        // catch this here because the server will do nothing.  pattern may
        // not be null, let that be checked, because the server will drop it
        // anyway
        if (repeat < pattern.length) {
            try {
                mService.vibratePattern(uid, opPkg, pattern, repeat, usageForAttributes(attributes),
                        mToken);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed to vibrate.", e);
            }
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    private static int usageForAttributes(AudioAttributes attributes) {
        return attributes != null ? attributes.getUsage() : AudioAttributes.USAGE_UNKNOWN;
    }

    @Override
    public void cancel() {
        if (mService == null) {
            return;
        }
        try {
            mService.cancelVibrate(mToken);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to cancel vibration.", e);
        }
    }
}

 

应用层去调用

Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
            vibrator.vibrate(sVibratePattern, 0, VIBRATION_ATTRIBUTES);

还需要天机SE权限

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值