| | |
| | | package com.safeluck.floatwindow; |
| | | |
| | | import android.app.Service; |
| | | import android.content.ComponentName; |
| | | import android.content.Context; |
| | | import android.content.ServiceConnection; |
| | | import android.content.Intent; |
| | | import android.os.IBinder; |
| | | import android.os.RemoteCallbackList; |
| | |
| | | |
| | | // 当前使用的管理器类型 |
| | | private ManagerType currentManagerType = ManagerType.NONE; |
| | | |
| | | // P2 跨进程服务(用于 usbCameraId == 2) |
| | | private IMediaAidlInterface p2Service; |
| | | private boolean p2Bound = false; |
| | | private MediaArgu pendingP2StartMedia; |
| | | |
| | | private final IMyCallback p2Callback = new IMyCallback.Stub() { |
| | | @Override |
| | | public void onResult(ResponseVO re) throws RemoteException { |
| | | // 将 P2 进程回调转发给客户端 |
| | | notifyCallback(re); |
| | | } |
| | | }; |
| | | |
| | | private final ServiceConnection p2Connection = new ServiceConnection() { |
| | | @Override |
| | | public void onServiceConnected(ComponentName name, IBinder service) { |
| | | p2Service = IMediaAidlInterface.Stub.asInterface(service); |
| | | p2Bound = true; |
| | | Timber.d("P2UsbCameraVideoService connected"); |
| | | try { |
| | | p2Service.registerCallback(p2Callback); |
| | | } catch (RemoteException e) { |
| | | Timber.e(e, "Failed to register p2Callback"); |
| | | } |
| | | |
| | | // 如果有 pending startMedia,连接后立刻执行 |
| | | if (pendingP2StartMedia != null) { |
| | | try { |
| | | p2Service.startMedia(pendingP2StartMedia); |
| | | pendingP2StartMedia = null; |
| | | } catch (RemoteException e) { |
| | | Timber.e(e, "Failed to startMedia on P2 service"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void onServiceDisconnected(ComponentName name) { |
| | | Timber.w("P2UsbCameraVideoService disconnected"); |
| | | p2Bound = false; |
| | | p2Service = null; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 管理器类型枚举 |
| | |
| | | NONE, |
| | | USB_PUSH, |
| | | USB_RECORD, |
| | | ANDROID_RECORD |
| | | ANDROID_RECORD, |
| | | P2_USB_PUSH, |
| | | P2_USB_RECORD |
| | | } |
| | | |
| | | // AIDL Binder |
| | |
| | | |
| | | Timber.d("FloatingService onCreate"); |
| | | } |
| | | |
| | | private void ensureP2Bound() { |
| | | if (p2Bound) return; |
| | | Intent intent = new Intent(this, P2UsbCameraVideoService.class); |
| | | try { |
| | | bindService(intent, p2Connection, Context.BIND_AUTO_CREATE); |
| | | } catch (Exception e) { |
| | | Timber.e(e, "bindService P2UsbCameraVideoService failed"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public int onStartCommand(Intent intent, int flags, int startId) { |
| | |
| | | if (media == null) { |
| | | Timber.w("startMedia: media is null"); |
| | | notifyCallback(1, -1, "MediaArgu is null"); |
| | | return; |
| | | } |
| | | |
| | | // usbCameraId == 2:走 P2 跨进程服务,支持两路 USB 同时工作 |
| | | if (media.isUsedOutCamera() && media.getUsbCameraId() == 2) { |
| | | stopCurrentManager(); |
| | | ensureP2Bound(); |
| | | if (p2Service != null) { |
| | | try { |
| | | p2Service.startMedia(media); |
| | | currentManagerType = media.isPush() ? ManagerType.P2_USB_PUSH : ManagerType.P2_USB_RECORD; |
| | | } catch (RemoteException e) { |
| | | Timber.e(e, "startMedia forward to P2 failed"); |
| | | notifyCallback(1, -3, "启动P2服务失败: " + e.getMessage()); |
| | | } |
| | | } else { |
| | | // 等待连接完成后执行 |
| | | pendingP2StartMedia = media; |
| | | currentManagerType = media.isPush() ? ManagerType.P2_USB_PUSH : ManagerType.P2_USB_RECORD; |
| | | } |
| | | return; |
| | | } |
| | | |
| | |
| | | androidCameraRecordManager.stopRecord(); |
| | | } |
| | | break; |
| | | case P2_USB_PUSH: |
| | | case P2_USB_RECORD: |
| | | if (p2Service != null) { |
| | | try { |
| | | p2Service.stopMedia(); |
| | | } catch (RemoteException e) { |
| | | Timber.e(e, "stopMedia forward to P2 failed"); |
| | | } |
| | | } else { |
| | | pendingP2StartMedia = null; |
| | | } |
| | | break; |
| | | case NONE: |
| | | break; |
| | | } |
| | |
| | | super.onDestroy(); |
| | | stopMedia(); |
| | | mCallbacks.kill(); |
| | | if (p2Bound) { |
| | | try { |
| | | if (p2Service != null) { |
| | | p2Service.unregisterCallback(p2Callback); |
| | | } |
| | | } catch (RemoteException e) { |
| | | Timber.e(e, "Failed to unregister p2Callback"); |
| | | } |
| | | try { |
| | | unbindService(p2Connection); |
| | | } catch (Exception e) { |
| | | Timber.w(e, "unbindService P2 failed"); |
| | | } |
| | | p2Bound = false; |
| | | p2Service = null; |
| | | } |
| | | Timber.d("FloatingService onDestroy"); |
| | | } |
| | | |