service_manager.c revision 5fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bf
194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Copyright 2008 The Android Open Source Project
294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */
394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdio.h>
594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdlib.h>
694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <errno.h>
794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <fcntl.h>
894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <private/android_filesystem_config.h>
1094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "binder.h"
1294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#if 0
1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define ALOGI(x...) fprintf(stderr, "svcmgr: " x)
1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define ALOGE(x...) fprintf(stderr, "svcmgr: " x)
1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#else
1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define LOG_TAG "ServiceManager"
1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <cutils/log.h>
1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#endif
2094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* TODO:
2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * These should come from a config file or perhaps be
2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * based on some namespace rules of some sort (media
2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * uid can register media.*, etc)
2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */
2694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic struct {
279b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    uid_t uid;
2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const char *name;
2994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} allowed[] = {
3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_MEDIA, "media.audio_flinger" },
3164c8be07878a6a110e5386c5f789fa9db51c5746Glenn Kasten    { AID_MEDIA, "media.log" },
3294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_MEDIA, "media.player" },
3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_MEDIA, "media.camera" },
3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_MEDIA, "media.audio_policy" },
3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_DRM,   "drm.drmManager" },
3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_NFC,   "nfc" },
3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_BLUETOOTH, "bluetooth" },
3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "radio.phone" },
3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "radio.sms" },
4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "radio.phonesubinfo" },
4194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "radio.simphonebook" },
4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* TODO: remove after phone services are updated: */
4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "phone" },
4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "sip" },
4594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "isms" },
4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "iphonesubinfo" },
4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_RADIO, "simphonebook" },
4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_MEDIA, "common_time.clock" },
4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    { AID_MEDIA, "common_time.config" },
50244408786cf1f374eeacbf6d16dd5a6f7b5e3c59Kenny Root    { AID_KEYSTORE, "android.security.keystore" },
5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood};
5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
535fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescuuint32_t svcmgr_handle;
5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
559b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuconst char *str8(const uint16_t *x)
5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    static char buf[128];
5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    unsigned max = 127;
5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    char *p = buf;
6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (x) {
6294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        while (*x && max--) {
6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            *p++ = *x++;
6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
6694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    *p++ = 0;
6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return buf;
6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
709b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuint str16eq(const uint16_t *a, const char *b)
7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    while (*a && *b)
7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (*a++ != *b++) return 0;
7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (*a || *b)
7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return 0;
7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return 1;
7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
799b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuint svc_can_register(uid_t uid, const uint16_t *name)
8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
819b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    size_t n;
829b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu
8394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if ((uid == 0) || (uid == AID_SYSTEM))
8494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return 1;
8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            return 1;
8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return 0;
9194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
939b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo
9494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct svcinfo *next;
965fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    uint32_t handle;
9794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct binder_death death;
9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    int allow_isolated;
999b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    size_t len;
10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    uint16_t name[0];
10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood};
10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1039b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *svclist = NULL;
10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1059b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescustruct svcinfo *find_svc(const uint16_t *s16, size_t len)
10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct svcinfo *si;
10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    for (si = svclist; si; si = si->next) {
11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if ((len == si->len) &&
11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            !memcmp(s16, si->name, len * sizeof(uint16_t))) {
11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            return si;
11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
1159b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    return NULL;
11694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid svcinfo_death(struct binder_state *bs, void *ptr)
11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
1209b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    struct svcinfo *si = (struct svcinfo* ) ptr;
1219b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu
12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ALOGI("service '%s' died\n", str8(si->name));
1235fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    if (si->handle) {
1245fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        binder_release(bs, si->handle);
1255fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        si->handle = 0;
1269b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    }
12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1299b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescuuint16_t svcmgr_id[] = {
13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    'a','n','d','r','o','i','d','.','o','s','.',
1319b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r'
13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood};
13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1349b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu
1355fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescuuint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid)
13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct svcinfo *si;
13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    si = find_svc(s, len);
13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1405fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    //ALOGI("check_service('%s') handle = %x\n", str8(s), si ? si->handle : 0);
1415fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    if (si && si->handle) {
14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (!si->allow_isolated) {
14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            // If this service doesn't allow access from isolated processes,
14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            // then check the uid to see if it is isolated.
1459b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu            uid_t appid = uid % AID_USER;
14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                return 0;
14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
1505fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        return si->handle;
15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    } else {
15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return 0;
15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint do_add_service(struct binder_state *bs,
1579b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu                   const uint16_t *s, size_t len,
1585fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu                   uint32_t handle, uid_t uid, int allow_isolated)
15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct svcinfo *si;
1615fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s), handle,
16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    //        allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1645fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    if (!handle || (len == 0) || (len > 127))
16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (!svc_can_register(uid, s)) {
1685fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
1695fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu             str8(s), handle, uid);
17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    si = find_svc(s, len);
17494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (si) {
1755fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        if (si->handle) {
1765fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu            ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
1775fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu                 str8(s), handle, uid);
17894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            svcinfo_death(bs, si);
17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
1805fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        si->handle = handle;
18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    } else {
18294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
18394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (!si) {
1845fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu            ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",
1855fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu                 str8(s), handle, uid);
18694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            return -1;
18794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
1885fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        si->handle = handle;
18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si->len = len;
19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si->name[len] = '\0';
1929b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu        si->death.func = (void*) svcinfo_death;
19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si->death.ptr = si;
19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si->allow_isolated = allow_isolated;
19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si->next = svclist;
19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        svclist = si;
19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1995fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    binder_acquire(bs, handle);
2005fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    binder_link_to_death(bs, handle, &si->death);
20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return 0;
20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint svcmgr_handler(struct binder_state *bs,
205bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu                   struct binder_transaction_data *txn,
20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                   struct binder_io *msg,
20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                   struct binder_io *reply)
20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct svcinfo *si;
21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    uint16_t *s;
2119b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    size_t len;
2125fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu    uint32_t handle;
21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    uint32_t strict_policy;
21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    int allow_isolated;
21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//    ALOGI("target=%p code=%d pid=%d uid=%d\n",
21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//         txn->target, txn->code, txn->sender_pid, txn->sender_euid);
21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
219bcf38880c65297da58194eb0c0ce8d6e2bab7d94Serban Constantinescu    if (txn->target.handle != svcmgr_handle)
22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Equivalent to Parcel::enforceInterface(), reading the RPC
22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // header with the strict mode policy mask and the interface name.
22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Note that we ignore the strict_policy and don't propagate it
22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // further (since we do no outbound RPCs anyway).
22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    strict_policy = bio_get_uint32(msg);
22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    s = bio_get_string16(msg, &len);
22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if ((len != (sizeof(svcmgr_id) / 2)) ||
22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        fprintf(stderr,"invalid id %s\n", str8(s));
23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    switch(txn->code) {
23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    case SVC_MGR_GET_SERVICE:
23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    case SVC_MGR_CHECK_SERVICE:
23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        s = bio_get_string16(msg, &len);
2385fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        handle = do_find_service(bs, s, len, txn->sender_euid);
2395fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        if (!handle)
24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
2415fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        bio_put_ref(reply, handle);
24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return 0;
24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    case SVC_MGR_ADD_SERVICE:
24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        s = bio_get_string16(msg, &len);
2465fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        handle = bio_get_ref(msg);
24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
2485fb1b8836aa5cf0f38b49bc7bfb8343b84fdf9bfSerban Constantinescu        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated))
24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            return -1;
25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        break;
25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    case SVC_MGR_LIST_SERVICES: {
25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        unsigned n = bio_get_uint32(msg);
25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        si = svclist;
25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        while ((n-- > 0) && si)
25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            si = si->next;
25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (si) {
25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            bio_put_string16(reply, si->name);
26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            return 0;
26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    default:
26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        ALOGE("unknown code %d\n", txn->code);
26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bio_put_uint32(reply, 0);
27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return 0;
27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint main(int argc, char **argv)
27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    struct binder_state *bs;
27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bs = binder_open(128*1024);
278a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu    if (!bs) {
279a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu        ALOGE("failed to open binder driver\n");
280a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu        return -1;
281a44542ca74b7da5b44ba30c205c3244805bb0600Serban Constantinescu    }
28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (binder_become_context_manager(bs)) {
28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        ALOGE("cannot become context manager (%s)\n", strerror(errno));
28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return -1;
28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
2889b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu    svcmgr_handle = BINDER_SERVICE_MANAGER;
28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    binder_loop(bs, svcmgr_handler);
2909b738bb4110926b85da65d36b2e6f1a50199ec4cSerban Constantinescu
29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return 0;
29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
293