Run audio services in audioserver instead of mediaserver

audioflinger, audiopolicy, (fm) radio, soundtrigger moved to audioserver.
medialog is removed from mediaserver.
audioserver has same permissions and rights as mediaserver.

mediaserver is allowed to specify client uid to audioserver.

Subsequent CL will add medialog to audioserver.

TBD: Pare down permissions.

Bug: 24511453
Change-Id: Iccaa08b874a502710d142e72f8abbb3d97c44cfa
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
new file mode 100644
index 0000000..324ebbb
--- /dev/null
+++ b/media/audioserver/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	main_audioserver.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libaudioflinger \
+	libaudiopolicyservice \
+	libbinder \
+	liblog \
+	libmedia \
+	libradioservice \
+	libsoundtriggerservice \
+	libutils \
+
+LOCAL_C_INCLUDES := \
+	frameworks/av/services/audioflinger \
+	frameworks/av/services/audiopolicy \
+	frameworks/av/services/audiopolicy/common/managerdefinitions/include \
+	frameworks/av/services/audiopolicy/common/include \
+	frameworks/av/services/audiopolicy/engine/interface \
+	frameworks/av/services/audiopolicy/service \
+	frameworks/av/services/radio \
+	frameworks/av/services/soundtrigger \
+	$(call include-path-for, audio-utils) \
+	external/sonic \
+
+LOCAL_MODULE := audioserver
+LOCAL_32_BIT_ONLY := true
+
+LOCAL_INIT_RC := audioserver.rc
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
new file mode 100644
index 0000000..1b39c8d
--- /dev/null
+++ b/media/audioserver/audioserver.rc
@@ -0,0 +1,6 @@
+service audioserver /system/bin/audioserver
+    class main
+    user audioserver
+    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
+    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
+    ioprio rt 4
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
new file mode 100644
index 0000000..a7123aa
--- /dev/null
+++ b/media/audioserver/main_audioserver.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define LOG_TAG "audioserver"
+//#define LOG_NDEBUG 0
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+// from LOCAL_C_INCLUDES
+#include "AudioFlinger.h"
+#include "AudioPolicyService.h"
+#include "RadioService.h"
+#include "SoundTriggerHwService.h"
+
+using namespace android;
+
+int main(int argc __unused, char **argv __unused)
+{
+    signal(SIGPIPE, SIG_IGN);
+
+    // TODO: add logging b/24511453#3
+
+    sp<ProcessState> proc(ProcessState::self());
+    sp<IServiceManager> sm(defaultServiceManager());
+    ALOGI("ServiceManager: %p", sm.get());
+    AudioFlinger::instantiate();
+    AudioPolicyService::instantiate();
+    RadioService::instantiate();
+    SoundTriggerHwService::instantiate();
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+}
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 580d8c1..ee99a26 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -14,22 +14,15 @@
 	main_mediaserver.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libaudioflinger \
-	libaudiopolicyservice \
 	libcamera_metadata\
 	libcameraservice \
-	libicuuc \
 	libmedialogservice \
 	libresourcemanagerservice \
 	libcutils \
-	libnbaio \
 	libmedia \
 	libmediaplayerservice \
 	libutils \
-	liblog \
 	libbinder \
-	libsoundtriggerservice \
-	libradioservice
 
 LOCAL_STATIC_LIBRARIES := \
         libicuandroid_utils \
@@ -37,18 +30,8 @@
 
 LOCAL_C_INCLUDES := \
     frameworks/av/media/libmediaplayerservice \
-    frameworks/av/services/medialog \
-    frameworks/av/services/audioflinger \
-    frameworks/av/services/audiopolicy \
-    frameworks/av/services/audiopolicy/common/managerdefinitions/include \
-    frameworks/av/services/audiopolicy/common/include \
-    frameworks/av/services/audiopolicy/engine/interface \
     frameworks/av/services/camera/libcameraservice \
     frameworks/av/services/mediaresourcemanager \
-    $(call include-path-for, audio-utils) \
-    frameworks/av/services/soundtrigger \
-    frameworks/av/services/radio \
-    external/sonic
 
 LOCAL_MODULE:= mediaserver
 LOCAL_32_BIT_ONLY := true
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 4a485ed..7e3041b 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -18,126 +18,30 @@
 #define LOG_TAG "mediaserver"
 //#define LOG_NDEBUG 0
 
-#include <fcntl.h>
-#include <sys/prctl.h>
-#include <sys/wait.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
-#include <cutils/properties.h>
 #include <utils/Log.h>
 #include "RegisterExtensions.h"
 
 // from LOCAL_C_INCLUDES
-#include "AudioFlinger.h"
 #include "CameraService.h"
-#include "IcuUtils.h"
-#include "MediaLogService.h"
 #include "MediaPlayerService.h"
 #include "ResourceManagerService.h"
-#include "service/AudioPolicyService.h"
-#include "SoundTriggerHwService.h"
-#include "RadioService.h"
 
 using namespace android;
 
-int main(int argc __unused, char** argv)
+int main(int argc __unused, char **argv __unused)
 {
     signal(SIGPIPE, SIG_IGN);
-    char value[PROPERTY_VALUE_MAX];
-    bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
-    pid_t childPid;
-    // FIXME The advantage of making the process containing media.log service the parent process of
-    // the process that contains all the other real services, is that it allows us to collect more
-    // detailed information such as signal numbers, stop and continue, resource usage, etc.
-    // But it is also more complex.  Consider replacing this by independent processes, and using
-    // binder on death notification instead.
-    if (doLog && (childPid = fork()) != 0) {
-        // media.log service
-        //prctl(PR_SET_NAME, (unsigned long) "media.log", 0, 0, 0);
-        // unfortunately ps ignores PR_SET_NAME for the main thread, so use this ugly hack
-        strcpy(argv[0], "media.log");
-        sp<ProcessState> proc(ProcessState::self());
-        MediaLogService::instantiate();
-        ProcessState::self()->startThreadPool();
-        for (;;) {
-            siginfo_t info;
-            int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED);
-            if (ret == EINTR) {
-                continue;
-            }
-            if (ret < 0) {
-                break;
-            }
-            char buffer[32];
-            const char *code;
-            switch (info.si_code) {
-            case CLD_EXITED:
-                code = "CLD_EXITED";
-                break;
-            case CLD_KILLED:
-                code = "CLD_KILLED";
-                break;
-            case CLD_DUMPED:
-                code = "CLD_DUMPED";
-                break;
-            case CLD_STOPPED:
-                code = "CLD_STOPPED";
-                break;
-            case CLD_TRAPPED:
-                code = "CLD_TRAPPED";
-                break;
-            case CLD_CONTINUED:
-                code = "CLD_CONTINUED";
-                break;
-            default:
-                snprintf(buffer, sizeof(buffer), "unknown (%d)", info.si_code);
-                code = buffer;
-                break;
-            }
-            struct rusage usage;
-            getrusage(RUSAGE_CHILDREN, &usage);
-            ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds",
-                    info.si_pid, info.si_status, code,
-                    usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000,
-                    usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000);
-            sp<IServiceManager> sm = defaultServiceManager();
-            sp<IBinder> binder = sm->getService(String16("media.log"));
-            if (binder != 0) {
-                Vector<String16> args;
-                binder->dump(-1, args);
-            }
-            switch (info.si_code) {
-            case CLD_EXITED:
-            case CLD_KILLED:
-            case CLD_DUMPED: {
-                ALOG(LOG_INFO, "media.log", "exiting");
-                _exit(0);
-                // not reached
-                }
-            default:
-                break;
-            }
-        }
-    } else {
-        // all other services
-        if (doLog) {
-            prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
-            setpgid(0, 0);                      // but if I die first, don't kill my parent
-        }
-        InitializeIcuOrDie();
-        sp<ProcessState> proc(ProcessState::self());
-        sp<IServiceManager> sm = defaultServiceManager();
-        ALOGI("ServiceManager: %p", sm.get());
-        AudioFlinger::instantiate();
-        MediaPlayerService::instantiate();
-        ResourceManagerService::instantiate();
-        CameraService::instantiate();
-        AudioPolicyService::instantiate();
-        SoundTriggerHwService::instantiate();
-        RadioService::instantiate();
-        registerExtensions();
-        ProcessState::self()->startThreadPool();
-        IPCThreadState::self()->joinThreadPool();
-    }
+
+    sp<ProcessState> proc(ProcessState::self());
+    sp<IServiceManager> sm(defaultServiceManager());
+    ALOGI("ServiceManager: %p", sm.get());
+    MediaPlayerService::instantiate();
+    ResourceManagerService::instantiate();
+    CameraService::instantiate();
+    registerExtensions();
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
 }
diff --git a/media/utils/BatteryNotifier.cpp b/media/utils/BatteryNotifier.cpp
index 7f9cd7a..341d391 100644
--- a/media/utils/BatteryNotifier.cpp
+++ b/media/utils/BatteryNotifier.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "BatteryNotifier"
+//#define LOG_NDEBUG 0
+
 #include "include/mediautils/BatteryNotifier.h"
 
 #include <binder/IServiceManager.h>
@@ -64,7 +67,7 @@
     sp<IBatteryStats> batteryService = getBatteryService_l();
     mVideoRefCount = 0;
     if (batteryService != nullptr) {
-        batteryService->noteResetAudio();
+        batteryService->noteResetVideo();
     }
 }
 
@@ -72,7 +75,7 @@
     Mutex::Autolock _l(mLock);
     sp<IBatteryStats> batteryService = getBatteryService_l();
     if (mAudioRefCount == 0 && batteryService != nullptr) {
-        batteryService->noteStartAudio(AID_MEDIA);
+        batteryService->noteStartAudio(AID_AUDIOSERVER);
     }
     mAudioRefCount++;
 }
@@ -88,7 +91,7 @@
 
     mAudioRefCount--;
     if (mAudioRefCount == 0 && batteryService != nullptr) {
-        batteryService->noteStopAudio(AID_MEDIA);
+        batteryService->noteStopAudio(AID_AUDIOSERVER);
     }
 }
 
@@ -190,20 +193,25 @@
         const String16 name("batterystats");
         mBatteryStatService = interface_cast<IBatteryStats>(sm->checkService(name));
         if (mBatteryStatService == nullptr) {
-            ALOGE("batterystats service unavailable!");
+            // this may occur normally during the init sequence as mediaserver
+            // and audioserver start before the batterystats service is available.
+            ALOGW("batterystats service unavailable!");
             return nullptr;
         }
 
         mDeathNotifier = new DeathNotifier();
         IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier);
 
-        // Notify start now if media already started
+        // Notify start now if mediaserver or audioserver is already started.
+        // 1) mediaserver and audioserver is started before batterystats service
+        // 2) batterystats server may have crashed.
         if (mVideoRefCount > 0) {
             mBatteryStatService->noteStartVideo(AID_MEDIA);
         }
         if (mAudioRefCount > 0) {
-            mBatteryStatService->noteStartAudio(AID_MEDIA);
+            mBatteryStatService->noteStartAudio(AID_AUDIOSERVER);
         }
+        // TODO: Notify for camera and flashlight state as well?
     }
     return mBatteryStatService;
 }
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 385e0b9..462a676 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1457,8 +1457,15 @@
     cblk.clear();
     buffers.clear();
 
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (!isTrustedCallingUid(callingUid)) {
+        ALOGW_IF(clientUid != callingUid,
+                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
+        clientUid = callingUid;
+    }
+
     // check calling permissions
-    if (!recordingAllowed(opPackageName)) {
+    if (!recordingAllowed(opPackageName, tid, clientUid)) {
         ALOGE("openRecord() permission denied: recording not allowed");
         lStatus = PERMISSION_DENIED;
         goto Exit;
@@ -1508,7 +1515,6 @@
         }
         ALOGV("openRecord() lSessionId: %d input %d", lSessionId, input);
 
-        // TODO: the uid should be passed in as a parameter to openRecord
         recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
                                                   frameCount, lSessionId, notificationFrames,
                                                   clientUid, flags, tid, &lStatus);
@@ -2591,7 +2597,7 @@
 
         // check recording permission for visualizer
         if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
-            !recordingAllowed(opPackageName)) {
+            !recordingAllowed(opPackageName, pid, IPCThreadState::self()->getCallingUid())) {
             lStatus = PERMISSION_DENIED;
             goto Exit;
         }
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index 2e68dad..afc2440 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -32,29 +32,37 @@
 
 // Not valid until initialized by AudioFlinger constructor.  It would have to be
 // re-initialized if the process containing AudioFlinger service forks (which it doesn't).
+// This is often used to validate binder interface calls within audioserver
+// (e.g. AudioPolicyManager to AudioFlinger).
 pid_t getpid_cached;
 
-bool recordingAllowed(const String16& opPackageName) {
-    // Note: We are getting the UID from the calling IPC thread state because all
-    // clients that perform recording create AudioRecord in their own processes
-    // and the system does not create AudioRecord objects on behalf of apps. This
-    // differs from playback where in some situations the system recreates AudioTrack
-    // instances associated with a client's MediaPlayer on behalf of this client.
-    // In the latter case we have to store the client UID and pass in along for
-    // security checks.
+// A trusted calling UID may specify the client UID as part of a binder interface call.
+// otherwise the calling UID must be equal to the client UID.
+bool isTrustedCallingUid(uid_t uid) {
+    switch (uid) {
+    case AID_MEDIA:
+    case AID_AUDIOSERVER:
+        return true;
+    default:
+        return false;
+    }
+}
 
+bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
+    // we're always OK.
     if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
+
     static const String16 sRecordAudio("android.permission.RECORD_AUDIO");
 
+    // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
+    // may open a record track on behalf of a client.  Note that pid may be a tid.
     // IMPORTANT: Don't use PermissionCache - a runtime permission and may change.
-    const bool ok = checkCallingPermission(sRecordAudio);
+    const bool ok = checkPermission(sRecordAudio, pid, uid);
     if (!ok) {
         ALOGE("Request requires android.permission.RECORD_AUDIO");
         return false;
     }
 
-    const uid_t uid = IPCThreadState::self()->getCallingUid();
-
     // To permit command-line native tests
     if (uid == AID_ROOT) return true;
 
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index fba6dce..1e79553 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -19,8 +19,8 @@
 namespace android {
 
 extern pid_t getpid_cached;
-
-bool recordingAllowed(const String16& opPackageName);
+bool isTrustedCallingUid(uid_t uid);
+bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
 bool captureAudioOutputAllowed();
 bool captureHotwordAllowed();
 bool settingsAllowed();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 553970b..4d3747a 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -914,14 +914,14 @@
             status = mPowerManager->acquireWakeLockWithUid(POWERMANAGER_PARTIAL_WAKE_LOCK,
                     binder,
                     getWakeLockTag(),
-                    String16("media"),
+                    String16("audioserver"),
                     uid,
                     true /* FIXME force oneway contrary to .aidl */);
         } else {
             status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
                     binder,
                     getWakeLockTag(),
-                    String16("media"),
+                    String16("audioserver"),
                     true /* FIXME force oneway contrary to .aidl */);
         }
         if (status == NO_ERROR) {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 0e24b52..b1638ea 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -100,13 +100,11 @@
         mType(type),
         mThreadIoHandle(thread->id())
 {
-    // if the caller is us, trust the specified uid
-    if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) {
-        int newclientUid = IPCThreadState::self()->getCallingUid();
-        if (clientUid != -1 && clientUid != newclientUid) {
-            ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid);
-        }
-        clientUid = newclientUid;
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (!isTrustedCallingUid(callingUid) || clientUid == -1) {
+        ALOGW_IF(clientUid != -1 && clientUid != (int)callingUid,
+                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
+        clientUid = (int)callingUid;
     }
     // clientUid contains the uid of the app that is responsible for this track, so we can blame
     // battery usage on it.
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 41a3fcb..8c976aa 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -164,13 +164,11 @@
     ALOGV("getOutput()");
     Mutex::Autolock _l(mLock);
 
-    // if the caller is us, trust the specified uid
-    if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
-        uid_t newclientUid = IPCThreadState::self()->getCallingUid();
-        if (uid != (uid_t)-1 && uid != newclientUid) {
-            ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
-        }
-        uid = newclientUid;
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
+        ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
+        uid = callingUid;
     }
     return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
                                     format, channelMask, flags, selectedDeviceId, offloadInfo);
@@ -284,13 +282,11 @@
     sp<AudioPolicyEffects>audioPolicyEffects;
     status_t status;
     AudioPolicyInterface::input_type_t inputType;
-    // if the caller is us, trust the specified uid
-    if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
-        uid_t newclientUid = IPCThreadState::self()->getCallingUid();
-        if (uid != (uid_t)-1 && uid != newclientUid) {
-            ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
-        }
-        uid = newclientUid;
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
+        ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
+        uid = callingUid;
     }
 
     {