Camera: Enhance camera atoms for system health
Introduce camera system health atoms, including: - Camera open, close, and session creation time - Camera session and stream combination information, - Stream statistics: - stream width, height, format, dataspace, usage flag, - max buffer count - buffer loss - first frame latency. Test: ./out/host/linux-x86/bin/statsd_testdrive 227 Test: CTS PerformanceTest Bug: 154159000 Change-Id: I858d64f3324bb9652a59e5857f2730c92c616a8e
This commit is contained in:
@@ -527,6 +527,7 @@ java_library {
|
||||
"android.hardware.vibrator-V1.3-java",
|
||||
"android.system.keystore2-java",
|
||||
"android.system.suspend.control.internal-java",
|
||||
"cameraprotosnano",
|
||||
"devicepolicyprotosnano",
|
||||
|
||||
"com.android.sysprop.apex",
|
||||
|
||||
@@ -42,6 +42,7 @@ import "frameworks/base/core/proto/android/server/job/enums.proto";
|
||||
import "frameworks/base/core/proto/android/server/location/enums.proto";
|
||||
import "frameworks/base/core/proto/android/service/procstats_enum.proto";
|
||||
import "frameworks/base/core/proto/android/service/usb.proto";
|
||||
import "frameworks/base/core/proto/android/stats/camera/camera.proto";
|
||||
import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
|
||||
import "frameworks/base/core/proto/android/stats/connectivity/tethering.proto";
|
||||
import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto";
|
||||
@@ -9946,10 +9947,12 @@ message DisplayJankReported {
|
||||
* frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java
|
||||
*/
|
||||
message CameraActionEvent {
|
||||
// Camera session duration
|
||||
// Camera session duration in milliseconds if action is SESSION.
|
||||
// 0 if action is OPEN or CLOSE.
|
||||
optional int64 duration_millis = 1;
|
||||
|
||||
// Camera API level used
|
||||
// Camera API level used.
|
||||
// 1 for camera1 API, and 2 for camera2 API.
|
||||
optional int32 api_level = 2;
|
||||
|
||||
// Name of client package
|
||||
@@ -9963,6 +9966,56 @@ message CameraActionEvent {
|
||||
EXTERNAL = 3;
|
||||
}
|
||||
optional Facing facing = 4;
|
||||
|
||||
// Camera ID
|
||||
optional string camera_id = 5;
|
||||
|
||||
// Camera action type
|
||||
enum Action {
|
||||
UNKNOWN_ACTION = 0;
|
||||
OPEN = 1;
|
||||
CLOSE = 2;
|
||||
SESSION = 3;
|
||||
}
|
||||
optional Action action = 6;
|
||||
|
||||
// Whether the client is accessing camera using ndk
|
||||
optional bool is_ndk = 7;
|
||||
|
||||
// Action OPEN: Open latency
|
||||
// Action CLOSE: Close latency
|
||||
// Action SESSION: Camera session creation duration.
|
||||
// If this entry is reusing an existing session, the value is -1.
|
||||
optional int32 latency_millis = 8;
|
||||
|
||||
// session type: 0 for normal mode, 1 for constrained high speed mode
|
||||
optional int32 operating_mode = 9;
|
||||
|
||||
// If actioh is SESSION: number of internal reconfigurations
|
||||
// Else: 0
|
||||
optional int32 internal_reconfig = 10;
|
||||
|
||||
// Number of requests for this capture session. Only applicable to SESSION
|
||||
// action.
|
||||
optional int64 request_count = 11;
|
||||
// Number of result errors. Only applicable to SESSION action.
|
||||
optional int64 result_error_count = 12;
|
||||
// Whether the device runs into error state.
|
||||
optional bool device_error = 13;
|
||||
|
||||
// If action is SESSION: Stream states
|
||||
// Else: stream_count = 0
|
||||
optional int32 stream_count = 14;
|
||||
optional android.stats.camera.CameraStreamProto stream_1 = 15
|
||||
[(android.os.statsd.log_mode) = MODE_BYTES];
|
||||
optional android.stats.camera.CameraStreamProto stream_2 = 16
|
||||
[(android.os.statsd.log_mode) = MODE_BYTES];
|
||||
optional android.stats.camera.CameraStreamProto stream_3 = 17
|
||||
[(android.os.statsd.log_mode) = MODE_BYTES];
|
||||
optional android.stats.camera.CameraStreamProto stream_4 = 18
|
||||
[(android.os.statsd.log_mode) = MODE_BYTES];
|
||||
optional android.stats.camera.CameraStreamProto stream_5 = 19
|
||||
[(android.os.statsd.log_mode) = MODE_BYTES];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6750,6 +6750,7 @@ android.sysprop.-$$Lambda$TelephonyProperties$illdaSIVv8AlxP9uc8NqC3Ta1tA
|
||||
android.sysprop.-$$Lambda$TelephonyProperties$klELuV5zVSqFveC5l6c3FSJmLAU
|
||||
android.sysprop.-$$Lambda$TelephonyProperties$pFU8zg4eHAdooeRLJg1WBG52cKk
|
||||
android.sysprop.-$$Lambda$TelephonyProperties$sXc3eBCFirzHWb9pvClH7EsiM_Q
|
||||
android.stats.camera.nano.CameraStreamProto
|
||||
android.sysprop.AdbProperties
|
||||
android.sysprop.ApexProperties
|
||||
android.sysprop.ContactsProperties
|
||||
|
||||
202
core/java/android/hardware/CameraSessionStats.java
Normal file
202
core/java/android/hardware/CameraSessionStats.java
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* The camera action state used for passing camera usage information from
|
||||
* camera service to camera service proxy .
|
||||
*
|
||||
* Include camera id, facing, state, client apk name, apiLevel, isNdk,
|
||||
* and session/stream statistics.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class CameraSessionStats implements Parcelable {
|
||||
public static final int CAMERA_STATE_OPEN = 0;
|
||||
public static final int CAMERA_STATE_ACTIVE = 1;
|
||||
public static final int CAMERA_STATE_IDLE = 2;
|
||||
public static final int CAMERA_STATE_CLOSED = 3;
|
||||
|
||||
/**
|
||||
* Values for notifyCameraState facing
|
||||
*/
|
||||
public static final int CAMERA_FACING_BACK = 0;
|
||||
public static final int CAMERA_FACING_FRONT = 1;
|
||||
public static final int CAMERA_FACING_EXTERNAL = 2;
|
||||
|
||||
/**
|
||||
* Values for notifyCameraState api level
|
||||
*/
|
||||
public static final int CAMERA_API_LEVEL_1 = 1;
|
||||
public static final int CAMERA_API_LEVEL_2 = 2;
|
||||
|
||||
private String mCameraId;
|
||||
private int mFacing;
|
||||
private int mNewCameraState;
|
||||
private String mClientName;
|
||||
private int mApiLevel;
|
||||
private boolean mIsNdk;
|
||||
private int mLatencyMs;
|
||||
private int mSessionType;
|
||||
private int mInternalReconfigure;
|
||||
private long mRequestCount;
|
||||
private long mResultErrorCount;
|
||||
private boolean mDeviceError;
|
||||
private ArrayList<CameraStreamStats> mStreamStats;
|
||||
|
||||
public CameraSessionStats() {
|
||||
mFacing = -1;
|
||||
mNewCameraState = -1;
|
||||
mApiLevel = -1;
|
||||
mIsNdk = false;
|
||||
mLatencyMs = -1;
|
||||
mSessionType = -1;
|
||||
mInternalReconfigure = -1;
|
||||
mRequestCount = 0;
|
||||
mResultErrorCount = 0;
|
||||
mDeviceError = false;
|
||||
mStreamStats = new ArrayList<CameraStreamStats>();
|
||||
}
|
||||
|
||||
public CameraSessionStats(String cameraId, int facing, int newCameraState,
|
||||
String clientName, int apiLevel, boolean isNdk, int creationDuration,
|
||||
int sessionType, int internalReconfigure) {
|
||||
mCameraId = cameraId;
|
||||
mFacing = facing;
|
||||
mNewCameraState = newCameraState;
|
||||
mClientName = clientName;
|
||||
mApiLevel = apiLevel;
|
||||
mIsNdk = isNdk;
|
||||
mLatencyMs = creationDuration;
|
||||
mSessionType = sessionType;
|
||||
mInternalReconfigure = internalReconfigure;
|
||||
mStreamStats = new ArrayList<CameraStreamStats>();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<CameraSessionStats> CREATOR =
|
||||
new Parcelable.Creator<CameraSessionStats>() {
|
||||
@Override
|
||||
public CameraSessionStats createFromParcel(Parcel in) {
|
||||
return new CameraSessionStats(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CameraSessionStats[] newArray(int size) {
|
||||
return new CameraSessionStats[size];
|
||||
}
|
||||
};
|
||||
|
||||
private CameraSessionStats(Parcel in) {
|
||||
readFromParcel(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(mCameraId);
|
||||
dest.writeInt(mFacing);
|
||||
dest.writeInt(mNewCameraState);
|
||||
dest.writeString(mClientName);
|
||||
dest.writeInt(mApiLevel);
|
||||
dest.writeBoolean(mIsNdk);
|
||||
dest.writeInt(mLatencyMs);
|
||||
dest.writeInt(mSessionType);
|
||||
dest.writeInt(mInternalReconfigure);
|
||||
dest.writeLong(mRequestCount);
|
||||
dest.writeLong(mResultErrorCount);
|
||||
dest.writeBoolean(mDeviceError);
|
||||
dest.writeTypedList(mStreamStats);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel in) {
|
||||
mCameraId = in.readString();
|
||||
mFacing = in.readInt();
|
||||
mNewCameraState = in.readInt();
|
||||
mClientName = in.readString();
|
||||
mApiLevel = in.readInt();
|
||||
mIsNdk = in.readBoolean();
|
||||
mLatencyMs = in.readInt();
|
||||
mSessionType = in.readInt();
|
||||
mInternalReconfigure = in.readInt();
|
||||
mRequestCount = in.readLong();
|
||||
mResultErrorCount = in.readLong();
|
||||
mDeviceError = in.readBoolean();
|
||||
|
||||
ArrayList<CameraStreamStats> streamStats = new ArrayList<CameraStreamStats>();
|
||||
in.readTypedList(streamStats, CameraStreamStats.CREATOR);
|
||||
mStreamStats = streamStats;
|
||||
}
|
||||
|
||||
public String getCameraId() {
|
||||
return mCameraId;
|
||||
}
|
||||
|
||||
public int getFacing() {
|
||||
return mFacing;
|
||||
}
|
||||
|
||||
public int getNewCameraState() {
|
||||
return mNewCameraState;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return mClientName;
|
||||
}
|
||||
|
||||
public int getApiLevel() {
|
||||
return mApiLevel;
|
||||
}
|
||||
|
||||
public boolean isNdk() {
|
||||
return mIsNdk;
|
||||
}
|
||||
|
||||
public int getLatencyMs() {
|
||||
return mLatencyMs;
|
||||
}
|
||||
|
||||
public int getSessionType() {
|
||||
return mSessionType;
|
||||
}
|
||||
|
||||
public int getInternalReconfigureCount() {
|
||||
return mInternalReconfigure;
|
||||
}
|
||||
|
||||
public long getRequestCount() {
|
||||
return mRequestCount;
|
||||
}
|
||||
|
||||
public long getResultErrorCount() {
|
||||
return mResultErrorCount;
|
||||
}
|
||||
|
||||
public boolean getDeviceErrorFlag() {
|
||||
return mDeviceError;
|
||||
}
|
||||
|
||||
public List<CameraStreamStats> getStreamStats() {
|
||||
return mStreamStats;
|
||||
}
|
||||
}
|
||||
169
core/java/android/hardware/CameraStreamStats.java
Normal file
169
core/java/android/hardware/CameraStreamStats.java
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
/**
|
||||
* The camera stream statistics used for passing camera stream information from
|
||||
* camera service to camera service proxy.
|
||||
*
|
||||
* Include camera stream configuration, request/error counts, startup latency,
|
||||
* and latency/jitter histograms.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class CameraStreamStats implements Parcelable {
|
||||
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private int mFormat;
|
||||
private int mDataSpace;
|
||||
private long mUsage;
|
||||
private long mRequestCount;
|
||||
private long mErrorCount;
|
||||
private int mStartLatencyMs;
|
||||
private int mMaxHalBuffers;
|
||||
private int mMaxAppBuffers;
|
||||
|
||||
private static final String TAG = "CameraStreamStats";
|
||||
|
||||
public CameraStreamStats() {
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mFormat = 0;
|
||||
mDataSpace = 0;
|
||||
mUsage = 0;
|
||||
mRequestCount = 0;
|
||||
mErrorCount = 0;
|
||||
mStartLatencyMs = 0;
|
||||
mMaxHalBuffers = 0;
|
||||
mMaxAppBuffers = 0;
|
||||
}
|
||||
|
||||
public CameraStreamStats(int width, int height, int format,
|
||||
int dataSpace, long usage, long requestCount, long errorCount,
|
||||
int startLatencyMs, int maxHalBuffers, int maxAppBuffers) {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFormat = format;
|
||||
mDataSpace = dataSpace;
|
||||
mUsage = usage;
|
||||
mRequestCount = requestCount;
|
||||
mErrorCount = errorCount;
|
||||
mStartLatencyMs = startLatencyMs;
|
||||
mMaxHalBuffers = maxHalBuffers;
|
||||
mMaxAppBuffers = maxAppBuffers;
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<CameraStreamStats> CREATOR =
|
||||
new Parcelable.Creator<CameraStreamStats>() {
|
||||
@Override
|
||||
public CameraStreamStats createFromParcel(Parcel in) {
|
||||
try {
|
||||
CameraStreamStats streamStats = new CameraStreamStats(in);
|
||||
return streamStats;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception creating CameraStreamStats from parcel", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CameraStreamStats[] newArray(int size) {
|
||||
return new CameraStreamStats[size];
|
||||
}
|
||||
};
|
||||
|
||||
private CameraStreamStats(Parcel in) {
|
||||
readFromParcel(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mWidth);
|
||||
dest.writeInt(mHeight);
|
||||
dest.writeInt(mFormat);
|
||||
dest.writeInt(mDataSpace);
|
||||
dest.writeLong(mUsage);
|
||||
dest.writeLong(mRequestCount);
|
||||
dest.writeLong(mErrorCount);
|
||||
dest.writeInt(mStartLatencyMs);
|
||||
dest.writeInt(mMaxHalBuffers);
|
||||
dest.writeInt(mMaxAppBuffers);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel in) {
|
||||
mWidth = in.readInt();
|
||||
mHeight = in.readInt();
|
||||
mFormat = in.readInt();
|
||||
mDataSpace = in.readInt();
|
||||
mUsage = in.readLong();
|
||||
mRequestCount = in.readLong();
|
||||
mErrorCount = in.readLong();
|
||||
mStartLatencyMs = in.readInt();
|
||||
mMaxHalBuffers = in.readInt();
|
||||
mMaxAppBuffers = in.readInt();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
public int getFormat() {
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
public int getDataSpace() {
|
||||
return mDataSpace;
|
||||
}
|
||||
|
||||
public long getUsage() {
|
||||
return mUsage;
|
||||
}
|
||||
|
||||
public long getRequestCount() {
|
||||
return mRequestCount;
|
||||
}
|
||||
|
||||
public long getErrorCount() {
|
||||
return mErrorCount;
|
||||
}
|
||||
|
||||
public int getStartLatencyMs() {
|
||||
return mStartLatencyMs;
|
||||
}
|
||||
|
||||
public int getMaxHalBuffers() {
|
||||
return mMaxHalBuffers;
|
||||
}
|
||||
|
||||
public int getMaxAppBuffers() {
|
||||
return mMaxAppBuffers;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import android.hardware.camera2.utils.TaskDrainer;
|
||||
import android.hardware.camera2.utils.TaskSingleDrainer;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
@@ -1002,7 +1003,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
|
||||
// begin transition to unconfigured
|
||||
mDeviceImpl.configureStreamsChecked(/*inputConfig*/null, /*outputs*/null,
|
||||
/*operatingMode*/ ICameraDeviceUser.NORMAL_MODE,
|
||||
/*sessionParams*/ null);
|
||||
/*sessionParams*/ null, SystemClock.uptimeMillis());
|
||||
} catch (CameraAccessException e) {
|
||||
// OK: do not throw checked exceptions.
|
||||
Log.e(TAG, mIdString + "Exception while unconfiguring outputs: ", e);
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.util.Range;
|
||||
import android.util.Size;
|
||||
@@ -374,7 +375,8 @@ public class CameraDeviceImpl extends CameraDevice
|
||||
outputConfigs.add(new OutputConfiguration(s));
|
||||
}
|
||||
configureStreamsChecked(/*inputConfig*/null, outputConfigs,
|
||||
/*operatingMode*/ICameraDeviceUser.NORMAL_MODE, /*sessionParams*/ null);
|
||||
/*operatingMode*/ICameraDeviceUser.NORMAL_MODE, /*sessionParams*/ null,
|
||||
SystemClock.uptimeMillis());
|
||||
|
||||
}
|
||||
|
||||
@@ -395,12 +397,15 @@ public class CameraDeviceImpl extends CameraDevice
|
||||
* @param operatingMode If the stream configuration is for a normal session,
|
||||
* a constrained high speed session, or something else.
|
||||
* @param sessionParams Session parameters.
|
||||
* @param createSessionStartTimeMs The timestamp when session creation starts, measured by
|
||||
* uptimeMillis().
|
||||
* @return whether or not the configuration was successful
|
||||
*
|
||||
* @throws CameraAccessException if there were any unexpected problems during configuration
|
||||
*/
|
||||
public boolean configureStreamsChecked(InputConfiguration inputConfig,
|
||||
List<OutputConfiguration> outputs, int operatingMode, CaptureRequest sessionParams)
|
||||
List<OutputConfiguration> outputs, int operatingMode, CaptureRequest sessionParams,
|
||||
long createSessionStartTime)
|
||||
throws CameraAccessException {
|
||||
// Treat a null input the same an empty list
|
||||
if (outputs == null) {
|
||||
@@ -479,9 +484,10 @@ public class CameraDeviceImpl extends CameraDevice
|
||||
int offlineStreamIds[];
|
||||
if (sessionParams != null) {
|
||||
offlineStreamIds = mRemoteDevice.endConfigure(operatingMode,
|
||||
sessionParams.getNativeCopy());
|
||||
sessionParams.getNativeCopy(), createSessionStartTime);
|
||||
} else {
|
||||
offlineStreamIds = mRemoteDevice.endConfigure(operatingMode, null);
|
||||
offlineStreamIds = mRemoteDevice.endConfigure(operatingMode, null,
|
||||
createSessionStartTime);
|
||||
}
|
||||
|
||||
mOfflineSupport.clear();
|
||||
@@ -650,6 +656,7 @@ public class CameraDeviceImpl extends CameraDevice
|
||||
List<OutputConfiguration> outputConfigurations,
|
||||
CameraCaptureSession.StateCallback callback, Executor executor,
|
||||
int operatingMode, CaptureRequest sessionParams) throws CameraAccessException {
|
||||
long createSessionStartTime = SystemClock.uptimeMillis();
|
||||
synchronized(mInterfaceLock) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "createCaptureSessionInternal");
|
||||
@@ -677,7 +684,7 @@ public class CameraDeviceImpl extends CameraDevice
|
||||
try {
|
||||
// configure streams and then block until IDLE
|
||||
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
|
||||
operatingMode, sessionParams);
|
||||
operatingMode, sessionParams, createSessionStartTime);
|
||||
if (configureSuccess == true && inputConfig != null) {
|
||||
input = mRemoteDevice.getInputSurface();
|
||||
}
|
||||
|
||||
@@ -110,11 +110,11 @@ public class ICameraDeviceUserWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
public int[] endConfigure(int operatingMode, CameraMetadataNative sessionParams)
|
||||
throws CameraAccessException {
|
||||
public int[] endConfigure(int operatingMode, CameraMetadataNative sessionParams,
|
||||
long startTimeMs) throws CameraAccessException {
|
||||
try {
|
||||
return mRemoteDevice.endConfigure(operatingMode, (sessionParams == null) ?
|
||||
new CameraMetadataNative() : sessionParams);
|
||||
new CameraMetadataNative() : sessionParams, startTimeMs);
|
||||
} catch (Throwable t) {
|
||||
CameraManager.throwAsPublicException(t);
|
||||
throw new UnsupportedOperationException("Unexpected exception", t);
|
||||
|
||||
33
core/proto/android/stats/camera/Android.bp
Normal file
33
core/proto/android/stats/camera/Android.bp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2020 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.
|
||||
|
||||
java_library {
|
||||
name: "cameraprotosnano",
|
||||
proto: {
|
||||
type: "nano",
|
||||
},
|
||||
srcs: [
|
||||
"*.proto",
|
||||
],
|
||||
java_version: "1.8",
|
||||
target: {
|
||||
android: {
|
||||
jarjar_rules: "jarjar-rules.txt",
|
||||
},
|
||||
host: {
|
||||
static_libs: ["libprotobuf-java-nano"],
|
||||
}
|
||||
},
|
||||
sdk_version: "core_platform",
|
||||
}
|
||||
44
core/proto/android/stats/camera/camera.proto
Normal file
44
core/proto/android/stats/camera/camera.proto
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
package android.stats.camera;
|
||||
option java_multiple_files = true;
|
||||
|
||||
message CameraStreamProto {
|
||||
// The stream width (in pixels)
|
||||
optional int32 width = 1;
|
||||
// The stream height (in pixels)
|
||||
optional int32 height = 2;
|
||||
// The format of the stream
|
||||
optional int32 format = 3;
|
||||
// The dataspace of the stream
|
||||
optional int32 data_space = 4;
|
||||
// The usage flag of the stream
|
||||
optional int64 usage = 5;
|
||||
|
||||
// The number of requests for this stream
|
||||
optional int64 request_count = 6;
|
||||
// The number of buffer error for this stream
|
||||
optional int64 error_count = 7;
|
||||
// The capture latency of first request for this stream
|
||||
optional int32 first_capture_latency_millis = 8;
|
||||
|
||||
// The maximum number of hal buffers
|
||||
optional int32 max_hal_buffers = 9;
|
||||
// The maximum number of app buffers
|
||||
optional int32 max_app_buffers = 10;
|
||||
}
|
||||
1
core/proto/android/stats/camera/jarjar-rules.txt
Normal file
1
core/proto/android/stats/camera/jarjar-rules.txt
Normal file
@@ -0,0 +1 @@
|
||||
rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
|
||||
@@ -22,6 +22,8 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.hardware.CameraSessionStats;
|
||||
import android.hardware.CameraStreamStats;
|
||||
import android.hardware.ICameraService;
|
||||
import android.hardware.ICameraServiceProxy;
|
||||
import android.media.AudioManager;
|
||||
@@ -36,11 +38,13 @@ import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserManager;
|
||||
import android.stats.camera.nano.CameraStreamProto;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.framework.protobuf.nano.MessageNano;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
@@ -97,7 +101,10 @@ public class CameraServiceProxy extends SystemService
|
||||
@interface DeviceStateFlags {}
|
||||
|
||||
// Maximum entries to keep in usage history before dumping out
|
||||
private static final int MAX_USAGE_HISTORY = 100;
|
||||
private static final int MAX_USAGE_HISTORY = 20;
|
||||
// Number of stream statistics being dumped for each camera session
|
||||
// Must be equal to number of CameraStreamProto in CameraActionEvent
|
||||
private static final int MAX_STREAM_STATISTICS = 5;
|
||||
|
||||
private final Context mContext;
|
||||
private final ServiceThread mHandlerThread;
|
||||
@@ -123,7 +130,6 @@ public class CameraServiceProxy extends SystemService
|
||||
private final ArrayMap<String, CameraUsageEvent> mActiveCameraUsage = new ArrayMap<>();
|
||||
private final List<CameraUsageEvent> mCameraUsageHistory = new ArrayList<>();
|
||||
|
||||
private final MetricsLogger mLogger = new MetricsLogger();
|
||||
private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
|
||||
private static final String NFC_SERVICE_BINDER_NAME = "nfc";
|
||||
private static final IBinder nfcInterfaceToken = new Binder();
|
||||
@@ -137,27 +143,50 @@ public class CameraServiceProxy extends SystemService
|
||||
* Structure to track camera usage
|
||||
*/
|
||||
private static class CameraUsageEvent {
|
||||
public final String mCameraId;
|
||||
public final int mCameraFacing;
|
||||
public final String mClientName;
|
||||
public final int mAPILevel;
|
||||
public final boolean mIsNdk;
|
||||
public final int mAction;
|
||||
public final int mLatencyMs;
|
||||
public final int mOperatingMode;
|
||||
|
||||
private boolean mCompleted;
|
||||
public int mInternalReconfigure;
|
||||
public long mRequestCount;
|
||||
public long mResultErrorCount;
|
||||
public boolean mDeviceError;
|
||||
public List<CameraStreamStats> mStreamStats;
|
||||
private long mDurationOrStartTimeMs; // Either start time, or duration once completed
|
||||
|
||||
public CameraUsageEvent(int facing, String clientName, int apiLevel) {
|
||||
CameraUsageEvent(String cameraId, int facing, String clientName, int apiLevel,
|
||||
boolean isNdk, int action, int latencyMs, int operatingMode) {
|
||||
mCameraId = cameraId;
|
||||
mCameraFacing = facing;
|
||||
mClientName = clientName;
|
||||
mAPILevel = apiLevel;
|
||||
mDurationOrStartTimeMs = SystemClock.elapsedRealtime();
|
||||
mCompleted = false;
|
||||
mIsNdk = isNdk;
|
||||
mAction = action;
|
||||
mLatencyMs = latencyMs;
|
||||
mOperatingMode = operatingMode;
|
||||
}
|
||||
|
||||
public void markCompleted() {
|
||||
public void markCompleted(int internalReconfigure, long requestCount,
|
||||
long resultErrorCount, boolean deviceError,
|
||||
List<CameraStreamStats> streamStats) {
|
||||
if (mCompleted) {
|
||||
return;
|
||||
}
|
||||
mCompleted = true;
|
||||
mDurationOrStartTimeMs = SystemClock.elapsedRealtime() - mDurationOrStartTimeMs;
|
||||
mInternalReconfigure = internalReconfigure;
|
||||
mRequestCount = requestCount;
|
||||
mResultErrorCount = resultErrorCount;
|
||||
mDeviceError = deviceError;
|
||||
mStreamStats = streamStats;
|
||||
if (CameraServiceProxy.DEBUG) {
|
||||
Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) +
|
||||
" was in use by " + mClientName + " for " +
|
||||
@@ -211,19 +240,22 @@ public class CameraServiceProxy extends SystemService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyCameraState(String cameraId, int newCameraState, int facing,
|
||||
String clientName, int apiLevel) {
|
||||
public void notifyCameraState(CameraSessionStats cameraState) {
|
||||
if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
|
||||
Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
|
||||
" camera service UID!");
|
||||
return;
|
||||
}
|
||||
String state = cameraStateToString(newCameraState);
|
||||
String facingStr = cameraFacingToString(facing);
|
||||
if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " facing " + facingStr + " state now " +
|
||||
state + " for client " + clientName + " API Level " + apiLevel);
|
||||
String state = cameraStateToString(cameraState.getNewCameraState());
|
||||
String facingStr = cameraFacingToString(cameraState.getFacing());
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Camera " + cameraState.getCameraId()
|
||||
+ " facing " + facingStr + " state now " + state
|
||||
+ " for client " + cameraState.getClientName()
|
||||
+ " API Level " + cameraState.getApiLevel());
|
||||
}
|
||||
|
||||
updateActivityCount(cameraId, newCameraState, facing, clientName, apiLevel);
|
||||
updateActivityCount(cameraState);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -385,20 +417,80 @@ public class CameraServiceProxy extends SystemService
|
||||
private void logCameraUsageEvent(CameraUsageEvent e) {
|
||||
int facing = FrameworkStatsLog.CAMERA_ACTION_EVENT__FACING__UNKNOWN;
|
||||
switch(e.mCameraFacing) {
|
||||
case ICameraServiceProxy.CAMERA_FACING_BACK:
|
||||
case CameraSessionStats.CAMERA_FACING_BACK:
|
||||
facing = FrameworkStatsLog.CAMERA_ACTION_EVENT__FACING__BACK;
|
||||
break;
|
||||
case ICameraServiceProxy.CAMERA_FACING_FRONT:
|
||||
case CameraSessionStats.CAMERA_FACING_FRONT:
|
||||
facing = FrameworkStatsLog.CAMERA_ACTION_EVENT__FACING__FRONT;
|
||||
break;
|
||||
case ICameraServiceProxy.CAMERA_FACING_EXTERNAL:
|
||||
case CameraSessionStats.CAMERA_FACING_EXTERNAL:
|
||||
facing = FrameworkStatsLog.CAMERA_ACTION_EVENT__FACING__EXTERNAL;
|
||||
break;
|
||||
default:
|
||||
Slog.w(TAG, "Unknown camera facing: " + e.mCameraFacing);
|
||||
}
|
||||
|
||||
int streamCount = 0;
|
||||
if (e.mStreamStats != null) {
|
||||
streamCount = e.mStreamStats.size();
|
||||
}
|
||||
if (CameraServiceProxy.DEBUG) {
|
||||
Slog.v(TAG, "CAMERA_ACTION_EVENT: action " + e.mAction
|
||||
+ " clientName " + e.mClientName
|
||||
+ ", duration " + e.getDuration()
|
||||
+ ", APILevel " + e.mAPILevel
|
||||
+ ", cameraId " + e.mCameraId
|
||||
+ ", facing " + facing
|
||||
+ ", isNdk " + e.mIsNdk
|
||||
+ ", latencyMs " + e.mLatencyMs
|
||||
+ ", operatingMode " + e.mOperatingMode
|
||||
+ ", internalReconfigure " + e.mInternalReconfigure
|
||||
+ ", requestCount " + e.mRequestCount
|
||||
+ ", resultErrorCount " + e.mResultErrorCount
|
||||
+ ", deviceError " + e.mDeviceError
|
||||
+ ", streamCount is " + streamCount);
|
||||
}
|
||||
// Convert from CameraStreamStats to CameraStreamProto
|
||||
CameraStreamProto[] streamProtos = new CameraStreamProto[MAX_STREAM_STATISTICS];
|
||||
for (int i = 0; i < MAX_STREAM_STATISTICS; i++) {
|
||||
streamProtos[i] = new CameraStreamProto();
|
||||
if (i < streamCount) {
|
||||
CameraStreamStats streamStats = e.mStreamStats.get(i);
|
||||
streamProtos[i].width = streamStats.getWidth();
|
||||
streamProtos[i].height = streamStats.getHeight();
|
||||
streamProtos[i].format = streamStats.getFormat();
|
||||
streamProtos[i].dataSpace = streamStats.getDataSpace();
|
||||
streamProtos[i].usage = streamStats.getUsage();
|
||||
streamProtos[i].requestCount = streamStats.getRequestCount();
|
||||
streamProtos[i].errorCount = streamStats.getErrorCount();
|
||||
streamProtos[i].firstCaptureLatencyMillis = streamStats.getStartLatencyMs();
|
||||
streamProtos[i].maxHalBuffers = streamStats.getMaxHalBuffers();
|
||||
streamProtos[i].maxAppBuffers = streamStats.getMaxAppBuffers();
|
||||
|
||||
if (CameraServiceProxy.DEBUG) {
|
||||
Slog.v(TAG, "Stream " + i + ": width " + streamProtos[i].width
|
||||
+ ", height " + streamProtos[i].height
|
||||
+ ", format " + streamProtos[i].format
|
||||
+ ", dataSpace " + streamProtos[i].dataSpace
|
||||
+ ", usage " + streamProtos[i].usage
|
||||
+ ", requestCount " + streamProtos[i].requestCount
|
||||
+ ", errorCount " + streamProtos[i].errorCount
|
||||
+ ", firstCaptureLatencyMillis "
|
||||
+ streamProtos[i].firstCaptureLatencyMillis
|
||||
+ ", maxHalBuffers " + streamProtos[i].maxHalBuffers
|
||||
+ ", maxAppBuffers " + streamProtos[i].maxAppBuffers);
|
||||
}
|
||||
}
|
||||
}
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.CAMERA_ACTION_EVENT, e.getDuration(),
|
||||
e.mAPILevel, e.mClientName, facing);
|
||||
e.mAPILevel, e.mClientName, facing, e.mCameraId, e.mAction, e.mIsNdk,
|
||||
e.mLatencyMs, e.mOperatingMode, e.mInternalReconfigure,
|
||||
e.mRequestCount, e.mResultErrorCount, e.mDeviceError,
|
||||
streamCount, MessageNano.toByteArray(streamProtos[0]),
|
||||
MessageNano.toByteArray(streamProtos[1]),
|
||||
MessageNano.toByteArray(streamProtos[2]),
|
||||
MessageNano.toByteArray(streamProtos[3]),
|
||||
MessageNano.toByteArray(streamProtos[4]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,35 +502,6 @@ public class CameraServiceProxy extends SystemService
|
||||
synchronized(mLock) {
|
||||
// Randomize order of events so that it's not meaningful
|
||||
Collections.shuffle(mCameraUsageHistory);
|
||||
for (CameraUsageEvent e : mCameraUsageHistory) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Camera: " + e.mClientName + " used a camera facing " +
|
||||
cameraFacingToString(e.mCameraFacing) + " for " +
|
||||
e.getDuration() + " ms");
|
||||
}
|
||||
int subtype = 0;
|
||||
switch(e.mCameraFacing) {
|
||||
case ICameraServiceProxy.CAMERA_FACING_BACK:
|
||||
subtype = MetricsEvent.CAMERA_BACK_USED;
|
||||
break;
|
||||
case ICameraServiceProxy.CAMERA_FACING_FRONT:
|
||||
subtype = MetricsEvent.CAMERA_FRONT_USED;
|
||||
break;
|
||||
case ICameraServiceProxy.CAMERA_FACING_EXTERNAL:
|
||||
subtype = MetricsEvent.CAMERA_EXTERNAL_USED;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
LogMaker l = new LogMaker(MetricsEvent.ACTION_CAMERA_EVENT)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.setSubtype(subtype)
|
||||
.setLatency(e.getDuration())
|
||||
.addTaggedData(MetricsEvent.FIELD_CAMERA_API_LEVEL, e.mAPILevel)
|
||||
.setPackageName(e.mClientName);
|
||||
mLogger.write(l);
|
||||
}
|
||||
|
||||
mLogWriterService.execute(new EventWriterTask(
|
||||
new ArrayList<CameraUsageEvent>(mCameraUsageHistory)));
|
||||
|
||||
@@ -569,13 +632,25 @@ public class CameraServiceProxy extends SystemService
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateActivityCount(String cameraId, int newCameraState, int facing,
|
||||
String clientName, int apiLevel) {
|
||||
private void updateActivityCount(CameraSessionStats cameraState) {
|
||||
String cameraId = cameraState.getCameraId();
|
||||
int newCameraState = cameraState.getNewCameraState();
|
||||
int facing = cameraState.getFacing();
|
||||
String clientName = cameraState.getClientName();
|
||||
int apiLevel = cameraState.getApiLevel();
|
||||
boolean isNdk = cameraState.isNdk();
|
||||
int sessionType = cameraState.getSessionType();
|
||||
int internalReconfigureCount = cameraState.getInternalReconfigureCount();
|
||||
int latencyMs = cameraState.getLatencyMs();
|
||||
long requestCount = cameraState.getRequestCount();
|
||||
long resultErrorCount = cameraState.getResultErrorCount();
|
||||
boolean deviceError = cameraState.getDeviceErrorFlag();
|
||||
List<CameraStreamStats> streamStats = cameraState.getStreamStats();
|
||||
synchronized(mLock) {
|
||||
// Update active camera list and notify NFC if necessary
|
||||
boolean wasEmpty = mActiveCameraUsage.isEmpty();
|
||||
switch (newCameraState) {
|
||||
case ICameraServiceProxy.CAMERA_STATE_OPEN:
|
||||
case CameraSessionStats.CAMERA_STATE_OPEN:
|
||||
// Notify the audio subsystem about the facing of the most-recently opened
|
||||
// camera This can be used to select the best audio tuning in case video
|
||||
// recording with that camera will happen. Since only open events are used, if
|
||||
@@ -584,13 +659,18 @@ public class CameraServiceProxy extends SystemService
|
||||
AudioManager audioManager = getContext().getSystemService(AudioManager.class);
|
||||
if (audioManager != null) {
|
||||
// Map external to front for audio tuning purposes
|
||||
String facingStr = (facing == ICameraServiceProxy.CAMERA_FACING_BACK) ?
|
||||
String facingStr = (facing == CameraSessionStats.CAMERA_FACING_BACK) ?
|
||||
"back" : "front";
|
||||
String facingParameter = "cameraFacing=" + facingStr;
|
||||
audioManager.setParameters(facingParameter);
|
||||
}
|
||||
CameraUsageEvent openEvent = new CameraUsageEvent(
|
||||
cameraId, facing, clientName, apiLevel, isNdk,
|
||||
FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__OPEN,
|
||||
latencyMs, sessionType);
|
||||
mCameraUsageHistory.add(openEvent);
|
||||
break;
|
||||
case ICameraServiceProxy.CAMERA_STATE_ACTIVE:
|
||||
case CameraSessionStats.CAMERA_STATE_ACTIVE:
|
||||
// Check current active camera IDs to see if this package is already talking to
|
||||
// some camera
|
||||
boolean alreadyActivePackage = false;
|
||||
@@ -609,40 +689,55 @@ public class CameraServiceProxy extends SystemService
|
||||
}
|
||||
|
||||
// Update activity events
|
||||
CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName, apiLevel);
|
||||
CameraUsageEvent newEvent = new CameraUsageEvent(
|
||||
cameraId, facing, clientName, apiLevel, isNdk,
|
||||
FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__SESSION,
|
||||
latencyMs, sessionType);
|
||||
CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
|
||||
if (oldEvent != null) {
|
||||
Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
|
||||
oldEvent.markCompleted();
|
||||
oldEvent.markCompleted(/*internalReconfigure*/0, /*requestCount*/0,
|
||||
/*resultErrorCount*/0, /*deviceError*/false, streamStats);
|
||||
mCameraUsageHistory.add(oldEvent);
|
||||
}
|
||||
break;
|
||||
case ICameraServiceProxy.CAMERA_STATE_IDLE:
|
||||
case ICameraServiceProxy.CAMERA_STATE_CLOSED:
|
||||
case CameraSessionStats.CAMERA_STATE_IDLE:
|
||||
case CameraSessionStats.CAMERA_STATE_CLOSED:
|
||||
CameraUsageEvent doneEvent = mActiveCameraUsage.remove(cameraId);
|
||||
if (doneEvent == null) break;
|
||||
if (doneEvent != null) {
|
||||
|
||||
doneEvent.markCompleted();
|
||||
mCameraUsageHistory.add(doneEvent);
|
||||
if (mCameraUsageHistory.size() > MAX_USAGE_HISTORY) {
|
||||
dumpUsageEvents();
|
||||
}
|
||||
doneEvent.markCompleted(internalReconfigureCount, requestCount,
|
||||
resultErrorCount, deviceError, streamStats);
|
||||
mCameraUsageHistory.add(doneEvent);
|
||||
|
||||
// Check current active camera IDs to see if this package is still talking to
|
||||
// some camera
|
||||
boolean stillActivePackage = false;
|
||||
for (int i = 0; i < mActiveCameraUsage.size(); i++) {
|
||||
if (mActiveCameraUsage.valueAt(i).mClientName.equals(clientName)) {
|
||||
stillActivePackage = true;
|
||||
break;
|
||||
// Check current active camera IDs to see if this package is still
|
||||
// talking to some camera
|
||||
boolean stillActivePackage = false;
|
||||
for (int i = 0; i < mActiveCameraUsage.size(); i++) {
|
||||
if (mActiveCameraUsage.valueAt(i).mClientName.equals(clientName)) {
|
||||
stillActivePackage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If not longer active, notify window manager about this package being done
|
||||
// with camera
|
||||
if (!stillActivePackage) {
|
||||
WindowManagerInternal wmi =
|
||||
LocalServices.getService(WindowManagerInternal.class);
|
||||
wmi.removeNonHighRefreshRatePackage(clientName);
|
||||
}
|
||||
}
|
||||
// If not longer active, notify window manager about this package being done
|
||||
// with camera
|
||||
if (!stillActivePackage) {
|
||||
WindowManagerInternal wmi =
|
||||
LocalServices.getService(WindowManagerInternal.class);
|
||||
wmi.removeNonHighRefreshRatePackage(clientName);
|
||||
|
||||
if (newCameraState == CameraSessionStats.CAMERA_STATE_CLOSED) {
|
||||
CameraUsageEvent closeEvent = new CameraUsageEvent(
|
||||
cameraId, facing, clientName, apiLevel, isNdk,
|
||||
FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__CLOSE,
|
||||
latencyMs, sessionType);
|
||||
mCameraUsageHistory.add(closeEvent);
|
||||
}
|
||||
|
||||
if (mCameraUsageHistory.size() > MAX_USAGE_HISTORY) {
|
||||
dumpUsageEvents();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -683,10 +778,10 @@ public class CameraServiceProxy extends SystemService
|
||||
|
||||
private static String cameraStateToString(int newCameraState) {
|
||||
switch (newCameraState) {
|
||||
case ICameraServiceProxy.CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
|
||||
case ICameraServiceProxy.CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
|
||||
case ICameraServiceProxy.CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
|
||||
case ICameraServiceProxy.CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
|
||||
case CameraSessionStats.CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
|
||||
case CameraSessionStats.CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
|
||||
case CameraSessionStats.CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
|
||||
case CameraSessionStats.CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
|
||||
default: break;
|
||||
}
|
||||
return "CAMERA_STATE_UNKNOWN";
|
||||
@@ -694,9 +789,9 @@ public class CameraServiceProxy extends SystemService
|
||||
|
||||
private static String cameraFacingToString(int cameraFacing) {
|
||||
switch (cameraFacing) {
|
||||
case ICameraServiceProxy.CAMERA_FACING_BACK: return "CAMERA_FACING_BACK";
|
||||
case ICameraServiceProxy.CAMERA_FACING_FRONT: return "CAMERA_FACING_FRONT";
|
||||
case ICameraServiceProxy.CAMERA_FACING_EXTERNAL: return "CAMERA_FACING_EXTERNAL";
|
||||
case CameraSessionStats.CAMERA_FACING_BACK: return "CAMERA_FACING_BACK";
|
||||
case CameraSessionStats.CAMERA_FACING_FRONT: return "CAMERA_FACING_FRONT";
|
||||
case CameraSessionStats.CAMERA_FACING_EXTERNAL: return "CAMERA_FACING_EXTERNAL";
|
||||
default: break;
|
||||
}
|
||||
return "CAMERA_FACING_UNKNOWN";
|
||||
|
||||
Reference in New Issue
Block a user