script-astra/Android/Sdk/sources/android-35/android/hardware/camera2/extension/CameraExtensionService.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

211 lines
7.0 KiB
Java

/*
* Copyright (C) 2023 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.
*/
package android.hardware.camera2.extension;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.AppOpsManager;
import android.app.Service;
import android.content.Intent;
import android.hardware.camera2.CameraExtensionCharacteristics.Extension;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.camera.flags.Flags;
interface CameraUsageTracker {
void startCameraOperation();
void finishCameraOperation();
}
/**
* Base service class that extension service implementations must extend.
*
* @hide
*/
@SystemApi
@FlaggedApi(Flags.FLAG_CONCERT_MODE)
public abstract class CameraExtensionService extends Service {
private static final String TAG = "CameraExtensionService";
private CameraUsageTracker mCameraUsageTracker;
private static Object mLock = new Object();
private final class CameraTracker implements CameraUsageTracker {
private final AppOpsManager mAppOpsService = getApplicationContext().getSystemService(
AppOpsManager.class);
private final String mPackageName = getPackageName();
private final String mAttributionTag = getAttributionTag();
private int mUid = getApplicationInfo().uid;
@Override
public void startCameraOperation() {
if (mAppOpsService != null) {
mAppOpsService.startOp(AppOpsManager.OPSTR_CAMERA, mUid, mPackageName,
mAttributionTag, "Camera extensions");
}
}
@Override
public void finishCameraOperation() {
if (mAppOpsService != null) {
mAppOpsService.finishOp(AppOpsManager.OPSTR_CAMERA, mUid, mPackageName,
mAttributionTag);
}
}
}
@GuardedBy("mLock")
private static IInitializeSessionCallback mInitializeCb = null;
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
synchronized (mLock) {
mInitializeCb = null;
}
if (mCameraUsageTracker != null) {
mCameraUsageTracker.finishCameraOperation();
}
}
};
@FlaggedApi(Flags.FLAG_CONCERT_MODE)
protected CameraExtensionService() { }
@FlaggedApi(Flags.FLAG_CONCERT_MODE)
@Override
@NonNull
public final IBinder onBind(@Nullable Intent intent) {
if (mCameraUsageTracker == null) {
mCameraUsageTracker = new CameraTracker();
}
return new CameraExtensionServiceImpl();
}
private class CameraExtensionServiceImpl extends ICameraExtensionsProxyService.Stub {
@Override
public boolean registerClient(IBinder token) throws RemoteException {
return CameraExtensionService.this.onRegisterClient(token);
}
@Override
public void unregisterClient(IBinder token) throws RemoteException {
CameraExtensionService.this.onUnregisterClient(token);
}
@Override
public boolean advancedExtensionsSupported() throws RemoteException {
return true;
}
@Override
public void initializeSession(IInitializeSessionCallback cb) {
boolean ret = false;
synchronized (mLock) {
if (mInitializeCb == null) {
mInitializeCb = cb;
try {
mInitializeCb.asBinder().linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
Log.e(TAG, "Failure to register binder death notifier!");
}
ret = true;
}
}
try {
if (ret) {
cb.onSuccess();
} else {
cb.onFailure();
}
} catch (RemoteException e) {
Log.e(TAG, "Client doesn't respond!");
}
}
@Override
public void releaseSession() {
synchronized (mLock) {
if (mInitializeCb != null) {
mInitializeCb.asBinder().unlinkToDeath(mDeathRecipient, 0);
mInitializeCb = null;
}
}
}
@Override
public IPreviewExtenderImpl initializePreviewExtension(@Extension int extensionType)
throws RemoteException {
// Basic Extension API is not supported
return null;
}
@Override
public IImageCaptureExtenderImpl initializeImageExtension(@Extension int extensionType)
throws RemoteException {
// Basic Extension API is not supported
return null;
}
@Override
public IAdvancedExtenderImpl initializeAdvancedExtension(@Extension int extensionType)
throws RemoteException {
AdvancedExtender extender = CameraExtensionService.this.onInitializeAdvancedExtension(
extensionType);
extender.setCameraUsageTracker(mCameraUsageTracker);
return extender.getAdvancedExtenderBinder();
}
}
/**
* Register an extension client. The client must call this method
* after successfully binding to the service.
*
* @param token Binder token that can be used for adding
* death notifier in case the client exits
* unexpectedly.
* @return true if the registration is successful, false otherwise
*/
@FlaggedApi(Flags.FLAG_CONCERT_MODE)
public abstract boolean onRegisterClient(@NonNull IBinder token);
/**
* Unregister an extension client.
*
* @param token Binder token
*/
@FlaggedApi(Flags.FLAG_CONCERT_MODE)
public abstract void onUnregisterClient(@NonNull IBinder token);
/**
* Initialize and return an advanced extension.
*
* @param extensionType {@link android.hardware.camera2.CameraExtensionCharacteristics}
* extension type
* @return Valid advanced extender of the requested type
*/
@FlaggedApi(Flags.FLAG_CONCERT_MODE)
@NonNull
public abstract AdvancedExtender onInitializeAdvancedExtension(@Extension int extensionType);
}