Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6169de0b authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Add concert mode extension type

Flag and append the new concert mode extension type
along with some initial base service scaffolding.

Bug: 297083874
Bug: 300313307
Test: Successful build

Change-Id: I2298aaddbf241cab28fc5d9eff3b7aae01a8d3e1
parent c1ac283d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18976,6 +18976,7 @@ package android.hardware.camera2 {
    field public static final int EXTENSION_AUTOMATIC = 0; // 0x0
    field @Deprecated public static final int EXTENSION_BEAUTY = 1; // 0x1
    field public static final int EXTENSION_BOKEH = 2; // 0x2
    field @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static final int EXTENSION_EYES_FREE_VIDEOGRAPHY = 5; // 0x5
    field public static final int EXTENSION_FACE_RETOUCH = 1; // 0x1
    field public static final int EXTENSION_HDR = 3; // 0x3
    field public static final int EXTENSION_NIGHT = 4; // 0x4
+88 −0
Original line number Diff line number Diff line
@@ -4480,6 +4480,94 @@ package android.hardware.camera2 {
}
package android.hardware.camera2.extension {
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract class AdvancedExtender {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") protected AdvancedExtender(@NonNull android.hardware.camera2.CameraManager);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.List<android.hardware.camera2.CaptureRequest.Key> getAvailableCaptureRequestKeys(@NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.List<android.hardware.camera2.CaptureResult.Key> getAvailableCaptureResultKeys(@NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public long getMetadataVendorId(@NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract android.hardware.camera2.extension.SessionProcessor getSessionProcessor();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.Map<java.lang.Integer,java.util.List<android.util.Size>> getSupportedCaptureOutputResolutions(@NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.Map<java.lang.Integer,java.util.List<android.util.Size>> getSupportedPreviewOutputResolutions(@NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void init(@NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract boolean isExtensionAvailable(@NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract class CameraExtensionService extends android.app.Service {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") protected CameraExtensionService();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract android.hardware.camera2.extension.AdvancedExtender onInitializeAdvancedExtension(int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract boolean onRegisterClient(@NonNull android.os.IBinder);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void onUnregisterClient(@NonNull android.os.IBinder);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public final class CameraOutputSurface {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public CameraOutputSurface(@NonNull android.view.Surface, @Nullable android.util.Size);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int getImageFormat();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @Nullable public android.util.Size getSize();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @Nullable public android.view.Surface getSurface();
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public class CharacteristicsMap {
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @Nullable public android.hardware.camera2.CameraCharacteristics get(@NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public java.util.Set<java.lang.String> getCameraIds();
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public class ExtensionConfiguration {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public ExtensionConfiguration(int, int, @NonNull java.util.List<android.hardware.camera2.extension.ExtensionOutputConfiguration>, @Nullable android.hardware.camera2.CaptureRequest);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public class ExtensionOutputConfiguration {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public ExtensionOutputConfiguration(@NonNull java.util.List<android.hardware.camera2.extension.CameraOutputSurface>, int, @Nullable String, int);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public final class RequestProcessor {
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void abortCaptures();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int setRepeating(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void stopRepeating();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int submit(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int submitBurst(@NonNull java.util.List<android.hardware.camera2.extension.RequestProcessor.Request>, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static final class RequestProcessor.Request {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public RequestProcessor.Request(@NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<android.util.Pair<android.hardware.camera2.CaptureRequest.Key,java.lang.Object>>, int);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static interface RequestProcessor.RequestCallback {
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureBufferLost(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, long, int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureCompleted(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @Nullable android.hardware.camera2.TotalCaptureResult);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @NonNull android.hardware.camera2.CaptureFailure);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureProgressed(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @NonNull android.hardware.camera2.CaptureResult);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceAborted(int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceCompleted(int, long);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureStarted(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, long, long);
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract class SessionProcessor {
    ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") protected SessionProcessor();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void deInitSession(@NonNull android.os.IBinder);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract android.hardware.camera2.extension.ExtensionConfiguration initSession(@NonNull android.os.IBinder, @NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap, @NonNull android.hardware.camera2.extension.CameraOutputSurface, @NonNull android.hardware.camera2.extension.CameraOutputSurface);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void onCaptureSessionEnd();
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void onCaptureSessionStart(@NonNull android.hardware.camera2.extension.RequestProcessor, @NonNull String);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void setParameters(@NonNull android.hardware.camera2.CaptureRequest);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startCapture(@Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startRepeating(@Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startTrigger(@NonNull android.hardware.camera2.CaptureRequest, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void stopRepeating();
  }
  @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static interface SessionProcessor.CaptureCallback {
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureCompleted(long, int, @NonNull android.hardware.camera2.CaptureResult);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureProcessStarted(int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceAborted(int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceCompleted(int);
    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureStarted(int, long);
  }
}
package android.hardware.camera2.params {
  public final class OutputConfiguration implements android.os.Parcelable {
+19 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package android.hardware.camera2;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -39,11 +40,15 @@ import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.FeatureFlagUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
import android.util.Size;

import com.android.internal.camera.flags.Flags;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -128,6 +133,12 @@ public final class CameraExtensionCharacteristics {
     */
    public static final int EXTENSION_NIGHT = 4;

    /**
     * An extension that aims to lock and stabilize a given region or object of interest.
     */
    @FlaggedApi(Flags.FLAG_CONCERT_MODE)
    public static final int EXTENSION_EYES_FREE_VIDEOGRAPHY = 5;

    /**
     * @hide
     */
@@ -136,7 +147,8 @@ public final class CameraExtensionCharacteristics {
                EXTENSION_FACE_RETOUCH,
                EXTENSION_BOKEH,
                EXTENSION_HDR,
                EXTENSION_NIGHT})
                EXTENSION_NIGHT,
                EXTENSION_EYES_FREE_VIDEOGRAPHY})
    public @interface Extension {
    }

@@ -594,8 +606,13 @@ public final class CameraExtensionCharacteristics {
            return Collections.unmodifiableList(ret);
        }

        IntArray extensionList = new IntArray(EXTENSION_LIST.length);
        extensionList.addAll(EXTENSION_LIST);
        if (Flags.concertMode()) {
            extensionList.add(EXTENSION_EYES_FREE_VIDEOGRAPHY);
        }
        try {
            for (int extensionType : EXTENSION_LIST) {
            for (int extensionType : extensionList.toArray()) {
                if (isExtensionSupported(mCameraId, extensionType, mCharacteristicsMapNative)) {
                    ret.add(extensionType);
                }
+353 −0

File added.

Preview size limit exceeded, changes collapsed.

+170 −0
Original line number Diff line number Diff line
/*
 * 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.Service;
import android.content.Intent;
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;

/**
 * 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 static Object mLock = new Object();

    @GuardedBy("mLock")
    private static IInitializeSessionCallback mInitializeCb = null;

    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            synchronized (mLock) {
                mInitializeCb = null;
            }
        }
    };

    @FlaggedApi(Flags.FLAG_CONCERT_MODE)
    protected CameraExtensionService() {}

    @FlaggedApi(Flags.FLAG_CONCERT_MODE)
    @Override
    @NonNull
    public IBinder onBind(@Nullable Intent intent) {
        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(int extensionType)
                throws RemoteException {
            // Basic Extension API is not supported
            return null;
        }

        @Override
        public IImageCaptureExtenderImpl initializeImageExtension(int extensionType)
                throws RemoteException {
            // Basic Extension API is not supported
            return null;
        }

        @Override
        public IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType)
                throws RemoteException {
            return CameraExtensionService.this.onInitializeAdvancedExtension(
                    extensionType).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(int extensionType);
}
Loading