android 10.0 双屏异显(2)

前篇说了默认启动为异显状态,并且SystemUI 与键盘实现异显以及异显与同显的互相切换,

这篇说一下异显时第三方apk异声问题。

首先异声需要rockchip的补丁,合了补丁后在播放music之前,调用setAudioSessionId就可以决定输出的声卡。

所以看这篇文章需要先合rk补丁,由于补丁并不能区分第三分apk声音输入源,下面是我在framework做的区分源修改。

1.在activity启动时保存activity的包名及显示位置。

frameworks/base/core/java/android/app/ActivityThread.java 的 performResumeActivity函数中增加:
/*------add by hdb start----------------*/
		//Slog.v(TAG, "hdb---performResumeActivity---");
		final int displayId;
        try {
            displayId = ActivityTaskManager.getService().getActivityDisplayId(r.token);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
		if(r.packageInfo != null){
			String pName = r.packageInfo.getPackageName();
			if(pName != null){
				if(mActionManager == null){
					if(getApplication() != null){
						mActionManager = (ActionManager)getApplication().getSystemService(Context.ACTION_SERVICE);
					}
				}
				
				if(mActionManager != null){
					mActionManager.addPackageIdAndName(pName,displayId);
				//	Slog.i(TAG,"hdb---performResumeActivity---displayId:"+displayId +"  pName:"+pName);
				}
				
			}
		}
		
		/*-------add by hdb end--------------*/

//备注一下,ActionManager 为自己添加的系统服务

2.在自己增加的系统服务中添加方法:

frameworks/base/core/java/android/app/ActionManager.java 文件中添加:
public void addPackageIdAndName(String name, int id){
			try {
				if(mService != null){
					mService.addPackageIdAndName(name,id);
				}
			   
			} catch (RemoteException ex) {
			}
        }

    	public int getIdFormPackageName(String name){
			try {
				if(mService != null){
					return mService.getIdFormPackageName(name);
				}
			    
			} catch (RemoteException ex) {
			}
			return 0;
		}

		public void setActiveToPackageName(String name, boolean active){
			try {
				if(mService != null){
					mService.setActiveToPackageName(name,active);
				}
			    
			} catch (RemoteException ex) {
			}
			
		}

		public boolean getActiveFormPackageName(String name){
			try {
				if(mService != null){
					return mService.getActiveFormPackageName(name);
				}
			    
			} catch (RemoteException ex) {
			}

			return false;
			
		}


frameworks/base/core/java/android/app/IActionManager.aidl 文件中添加:
        void setActiveToPackageName(in String name, boolean active);
       int getIdFormPackageName(in String name);^M
       void addPackageIdAndName(in String name, int id);
       boolean getActiveFormPackageName(in String name);

frameworks/base/services/java/com/android/server/ActionService.java 文件中添加

/*------------------------add by hdb start------------------------**/
	private ArrayList<PackageIdAndName> mPackageIdAndNames = new ArrayList<PackageIdAndName>();
    private Object mPackageIdLock = new Object();
    public void addPackageIdAndName(String name, int id){
		Slog.i(TAG,"hdb---addPackageIdAndName-0--name:"+name+"   id:"+id);
                synchronized (mPackageIdLock) {
                        if (mPackageIdAndNames.size() > 0) {
                                for (int i = 0; i < mPackageIdAndNames.size(); i++) {
                                        PackageIdAndName packageIdAndName = mPackageIdAndNames.get(i);
                                        if (packageIdAndName.getName().equalsIgnoreCase(name)) {
                                                packageIdAndName.setId(id);
												Slog.i(TAG,"hdb---addPackageIdAndName--11-id:"+id);
                                                return;
                                        }
                                }
                        }
						Slog.i(TAG,"hdb---addPackageIdAndName--22-name:"+name+"   id:"+id);
                        mPackageIdAndNames.add(new PackageIdAndName(name,id));
                }

        }

	public void setActiveToPackageName(String name, boolean active){
		Slog.i(TAG,"hdb---setActiveFormToPackageName-0--name:"+name+"   active:"+active);
                synchronized (mPackageIdLock) {
                        if (mPackageIdAndNames.size() > 0) {
                                for (int i = 0; i < mPackageIdAndNames.size(); i++) {
                                        PackageIdAndName packageIdAndName = mPackageIdAndNames.get(i);
                                        if (packageIdAndName.getName().equalsIgnoreCase(name)) {
                                                packageIdAndName.setActive(active);
												Slog.i(TAG,"hdb---setActiveFormToPackageName--11-active:"+active);
                                                return;
                                        }
                                }
                        }
                }

        }

    public int getIdFormPackageName(String name){
		if(mHandler.hasMessages(MSG_READ_MAX9191_0C)){
			mHandler.removeMessages(MSG_READ_MAX9191_0C);
		}
		mHandler.sendEmptyMessageDelayed(MSG_READ_MAX9191_0C, MSG_READ_MAX9191_0C_DELAY);
		Slog.i(TAG,"hdb---getIdFormPackageName-0--name:"+name+"  size:"+mPackageIdAndNames.size());
            synchronized (mPackageIdLock) {
                    if (mPackageIdAndNames.size() > 0) {
                            for (int i = 0; i < mPackageIdAndNames.size(); i++) {
                                    PackageIdAndName packageIdAndName = mPackageIdAndNames.get(i);
						//			Slog.i(TAG,"hdb---getIdFormPackageName---getname:"+packageIdAndName.getName()+"  name:"+name);
                                    if (packageIdAndName.getName().equalsIgnoreCase(name)) {
										Slog.i(TAG,"hdb---getIdFormPackageName-11--id:"+packageIdAndName.getId());
                                            return packageIdAndName.getId();
                                    }
                            }
                    }
					Slog.i(TAG,"hdb---getIdFormPackageName--222--error----");
                    return 0;
            }

    }

	public boolean getActiveFormPackageName(String name){
		Slog.i(TAG,"hdb---getActiveFormPackageName-0--name:"+name+"  size:"+mPackageIdAndNames.size());
            synchronized (mPackageIdLock) {
                    if (mPackageIdAndNames.size() > 0) {
                            for (int i = 0; i < mPackageIdAndNames.size(); i++) {
                                    PackageIdAndName packageIdAndName = mPackageIdAndNames.get(i);
									//Slog.i(TAG,"hdb---getActiveFormPackageName---getname:"+packageIdAndName.getName()+"  name:"+name);
                                    if (packageIdAndName.getName().equalsIgnoreCase(name)) {
										Slog.i(TAG,"hdb---getActiveFormPackageName-11--active:"+packageIdAndName.isActive());
                                            return packageIdAndName.isActive();
                                    }
                            }
                    }
					Slog.i(TAG,"hdb---getActiveFormPackageName--222--error----");
                    return false;
            }

    }


    private class PackageIdAndName{
            private String name;
            private int id;
			private boolean active;

            public PackageIdAndName(String name, int id) {
                    super();
                    this.name = name;
                    this.id = id;
            }
            public String getName() {
                    return name;
            }
            public void setName(String name) {
                    this.name = name;
            }
            public int getId() {
                    return id;
            }
            public void setId(int id) {
                    this.id = id;
            }
			public boolean isActive() {
                    return active;
            }
            public void setActive(boolean active) {
                    this.active = active;
            }
    }
	/**-------------------------add by hdb end------------------------------------*/

3.audio播放最后都会跑frameworks/av/media/libaudioclient/AudioTrack.cpp

但是我保存的数据在自定义的服务中,所以这里需要跨进程通讯

1.新建文件
frameworks/native/libs/binder/IActionManager.cpp
--- /dev/null
+++ b/frameworks/native/libs/binder/IActionManager.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2005 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 "IActionManager"
+
+#include <binder/IActionManager.h>
+
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/binder/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpActionManager : public BpInterface<IActionManager>
+{
+public:
+    explicit BpActionManager(const sp<IBinder>& impl)
+        : BpInterface<IActionManager>(impl)
+    {
+    }
+       
+       virtual void setActiveToPackageName(const String16& packageName, bool active)
+       {       
+               Parcel data, reply;
+        data.writeInterfaceToken(IActionManager::getInterfaceDescriptor());
+        data.writeBool(active);
+        data.writeString16(packageName);
+        remote()->transact(SET_ACTIVE_TO_PACKAGENAME, data, &reply);
+               
+               //int code = reply.readExceptionCode();
+               //ALOGD("hdb-----BpActionManager");
+       }
+       
+       virtual int getIdFormPackageName(const String16& packageName)
+       {
+               Parcel data, reply;
+        data.writeInterfaceToken(IActionManager::getInterfaceDescriptor());
+        data.writeString16(packageName);
+        remote()->transact(GET_ID_FORM_PACKAGENAME, data, &reply);
+               // fail on exception
+        if (reply.readExceptionCode() != 0) return false;
+        return reply.readInt32();
+       }
+};
+
+IMPLEMENT_META_INTERFACE(ActionManager, "android.app.IActionManager");
+
+}; // namespace android


2.创建文件
frameworks/native/libs/binder/include/binder/IActionManager.h

--- /dev/null
+++ b/frameworks/native/libs/binder/include/binder/IActionManager.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+#ifndef ANDROID_IACTION_MANAGER_H
+#define ANDROID_IACTION_MANAGER_H
+
+#ifndef __ANDROID_VNDK__
+
+#include <binder/IInterface.h>
+#include <stdlib.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IActionManager : public IInterface
+{
+public:
+       
+    DECLARE_META_INTERFACE(ActionManager)
+
+       virtual void setActiveToPackageName(const String16& packageName, bool active) = 0;
+       virtual int getIdFormPackageName(const String16& packageName) = 0;
+
+    enum {
+               SET_ACTIVE_TO_PACKAGENAME = IBinder::FIRST_CALL_TRANSACTION,
+        GET_ID_FORM_PACKAGENAME = IBinder::FIRST_CALL_TRANSACTION + 1,
+    };
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+ 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
+#endif // ANDROID_IPERMISSION_CONTROLLER_H
+

3.android.bp中加入编译
index aedf6b0d18..af1ac33522 100644
--- a/frameworks/native/libs/binder/Android.bp
+++ b/frameworks/native/libs/binder/Android.bp
@@ -54,6 +54,7 @@ cc_library_shared {
         "IMemory.cpp",
         "IPCThreadState.cpp",
         "IPermissionController.cpp",
+       "IActionManager.cpp",
         "IProcessInfoService.cpp",
         "IResultReceiver.cpp",
         "IServiceManager.cpp",
@@ -88,6 +89,7 @@ cc_library_shared {
                 "IBatteryStats.cpp",
                 "IMediaResourceMonitor.cpp",
                 "IPermissionController.cpp",
+               "IActionManager.cpp",
                 "IProcessInfoService.cpp",
                 "IUidObserver.cpp",
                 "PermissionCache.cpp",


4.frameworks/av/media/libaudioclient/AudioTrack.cpp 文件跨进程调用
index 9a9f46d20f..bc881fc48b 100644
--- a/frameworks/av/media/libaudioclient/AudioTrack.cpp
+++ b/frameworks/av/media/libaudioclient/AudioTrack.cpp
@@ -37,6 +37,12 @@
 #include <media/AudioSystem.h>
 #include <media/MediaAnalyticsItem.h>
 #include <media/TypeConverter.h>
+#include <binder/IServiceManager.h>// add by hdb
+#include <binder/PermissionController.h>
+#include <binder/IActionManager.h>
+
+
+
 
 #define WAIT_PERIOD_MS                  10
 #define WAIT_STREAM_END_TIMEOUT_SEC     120
@@ -355,7 +361,6 @@ status_t AudioTrack::set(
     uint32_t channelCount;
     pid_t callingPid;
     pid_t myPid;
-
     // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
     ALOGV("%s(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
           "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
@@ -1468,6 +1473,39 @@ status_t AudioTrack::createTrack_l()
     }
     uint32_t this_flags = (uint32_t)mFlags;
     this_flags &= ~AUDIO_OUTPUT_DUAL_MASK;
+       
+       /*------hdb-------------------------------------------------------------------------*/
+       uid_t callingUID = IPCThreadState::self()->getCallingUid();
+       ALOGD("hdb----createTrack_l---callingUID=%d",callingUID);
+       if(callingUID >= 10000){ //not system app
+               sp<IServiceManager> sm = defaultServiceManager();
+           sp<IBinder> binder = sm->getService(String16("permission"));
+           if (binder != 0) {
+               sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
+               Vector<String16> packages;
+               permCtrl->getPackagesForUid(callingUID, packages);
+               if (!packages.isEmpty()) {
+               //    String8 opPkg = (String8)packages[0].string();
+               //    ALOGD("hdb----createTrack_l---opPkg:%s", opPkg.string());
+
+                               sp<IBinder> binder1 = sm->getService(String16("action"));
+                               if (binder1 != 0) {
+                                       ALOGD("hdb---binder1-createTrack_l--in-");
+                               sp<IActionManager> actionM = interface_cast<IActionManager>(binder1);
+                                       int dislayId = actionM->getIdFormPackageName((String16)packages[0].string());
+                                       if(dislayId == 0){
+                                               mSessionId = (audio_session_t)121;
+                                       }else{
+                                               mSessionId = (audio_session_t)57;
+                                       }
+                               }
+               }
+
+                       
+           }
+       }
+       
+       /*-------hdb------------------------------------------------------------------------------*/
     if(mSessionId == (audio_session_t)57){
         ALOGD("set secondary sound flags");
         this_flags |= AUDIO_OUTPUT_SECONDARY; // secondary sound

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值