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

Commit 07fd6822 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11945538 from b44a5d6c to 24Q3-release

Change-Id: Ib4e4d90adda83055c6e35df25cc4eae2b3c70bb8
parents 33ecea83 b44a5d6c
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -7188,9 +7188,10 @@ public abstract class Context {
     * as the package remains in the foreground, or has any active manifest components (e.g. when
     * another app is accessing a content provider in the package).
     * <p>
     * If you want to revoke the permissions right away, you could call {@code System.exit()}, but
     * this could affect other apps that are accessing your app at the moment. For example, apps
     * accessing a content provider in your app will all crash.
     * If you want to revoke the permissions right away, you could call {@code System.exit()} in
     * {@code Handler.postDelayed} with a delay to allow completion of async IPC, But
     * {@code System.exit()} could affect other apps that are accessing your app at the moment.
     * For example, apps accessing a content provider in your app will all crash.
     * <p>
     * Note that the settings UI shows a permission group as granted as long as at least one
     * permission in the group is granted. If you want the user to observe the revocation in the
+16 −10
Original line number Diff line number Diff line
@@ -1472,9 +1472,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
            new Key<Integer>("android.flash.info.strengthDefaultLevel", int.class);

    /**
     * <p>Maximum flash brightness level for manual flash control in SINGLE mode.</p>
     * <p>Maximum flash brightness level for manual flash control in <code>SINGLE</code> mode.</p>
     * <p>Maximum flash brightness level in camera capture mode and
     * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to SINGLE.
     * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to <code>SINGLE</code>.
     * Value will be &gt; 1 if the manual flash strength control feature is supported,
     * otherwise the value will be equal to 1.
     * Note that this level is just a number of supported levels (the granularity of control).
@@ -1490,7 +1490,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
            new Key<Integer>("android.flash.singleStrengthMaxLevel", int.class);

    /**
     * <p>Default flash brightness level for manual flash control in SINGLE mode.</p>
     * <p>Default flash brightness level for manual flash control in <code>SINGLE</code> mode.</p>
     * <p>If flash unit is available this will be greater than or equal to 1 and less
     * or equal to {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel}.
     * Note for devices that do not support the manual flash strength control
@@ -1506,9 +1506,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
            new Key<Integer>("android.flash.singleStrengthDefaultLevel", int.class);

    /**
     * <p>Maximum flash brightness level for manual flash control in TORCH mode</p>
     * <p>Maximum flash brightness level for manual flash control in <code>TORCH</code> mode</p>
     * <p>Maximum flash brightness level in camera capture mode and
     * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to TORCH.
     * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to <code>TORCH</code>.
     * Value will be &gt; 1 if the manual flash strength control feature is supported,
     * otherwise the value will be equal to 1.</p>
     * <p>Note that this level is just a number of supported levels(the granularity of control).
@@ -1530,7 +1530,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
            new Key<Integer>("android.flash.torchStrengthMaxLevel", int.class);

    /**
     * <p>Default flash brightness level for manual flash control in TORCH mode</p>
     * <p>Default flash brightness level for manual flash control in <code>TORCH</code> mode</p>
     * <p>If flash unit is available this will be greater than or equal to 1 and less
     * or equal to {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}.
     * Note for the devices that do not support the manual flash strength control feature,
@@ -4152,10 +4152,16 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
    /**
     * <p>Whether the RAW images output from this camera device are subject to
     * lens shading correction.</p>
     * <p>If TRUE, all images produced by the camera device in the RAW image formats will
     * have lens shading correction already applied to it. If FALSE, the images will
     * not be adjusted for lens shading correction.
     * See {@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_RAW android.request.maxNumOutputRaw} for a list of RAW image formats.</p>
     * <p>If <code>true</code>, all images produced by the camera device in the <code>RAW</code> image formats will have
     * at least some lens shading correction already applied to it. If <code>false</code>, the images will
     * not be adjusted for lens shading correction.  See {@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_RAW android.request.maxNumOutputRaw} for a
     * list of RAW image formats.</p>
     * <p>When <code>true</code>, the <code>lensShadingCorrectionMap</code> key may still have values greater than 1.0,
     * and those will need to be applied to any captured RAW frames for them to match the shading
     * correction of processed buffers such as <code>YUV</code> or <code>JPEG</code> images. This may occur, for
     * example, when some basic fixed lens shading correction is applied by hardware to RAW data,
     * and additional correction is done dynamically in the camera processing pipeline after
     * demosaicing.</p>
     * <p>This key will be <code>null</code> for all devices do not report this information.
     * Devices with RAW capability will always report this information in this key.</p>
     * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+6 −6
Original line number Diff line number Diff line
@@ -2683,27 +2683,27 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
    /**
     * <p>Flash strength level to be used when manual flash control is active.</p>
     * <p>Flash strength level to use in capture mode i.e. when the applications control
     * flash with either SINGLE or TORCH mode.</p>
     * flash with either <code>SINGLE</code> or <code>TORCH</code> mode.</p>
     * <p>Use {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} to check whether the device supports
     * flash strength control or not.
     * If the values of android.flash.info.singleStrengthMaxLevel and
     * If the values of {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} are greater than 1,
     * then the device supports manual flash strength control.</p>
     * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> TORCH the value must be &gt;= 1
     * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>TORCH</code> the value must be &gt;= 1
     * and &lt;= {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}.
     * If the application doesn't set the key and
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} &gt; 1,
     * then the flash will be fired at the default level set by HAL in
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_DEFAULT_LEVEL android.flash.torchStrengthDefaultLevel}.
     * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> SINGLE, then the value must be &gt;= 1
     * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>SINGLE</code>, then the value must be &gt;= 1
     * and &lt;= {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel}.
     * If the application does not set this key and
     * {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} &gt; 1,
     * then the flash will be fired at the default level set by HAL
     * in {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL android.flash.singleStrengthDefaultLevel}.
     * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of ON_AUTO_FLASH, ON_ALWAYS_FLASH,
     * ON_AUTO_FLASH_REDEYE, ON_EXTERNAL_FLASH values, then the strengthLevel will be ignored.</p>
     * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of <code>ON_AUTO_FLASH</code>, <code>ON_ALWAYS_FLASH</code>,
     * <code>ON_AUTO_FLASH_REDEYE</code>, <code>ON_EXTERNAL_FLASH</code> values, then the strengthLevel will be ignored.</p>
     * <p><b>Range of valid values:</b><br>
     * <code>[1-{@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}]</code> when the {@link CaptureRequest#FLASH_MODE android.flash.mode} is
     * set to TORCH;
+9 −6
Original line number Diff line number Diff line
@@ -2976,27 +2976,27 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
    /**
     * <p>Flash strength level to be used when manual flash control is active.</p>
     * <p>Flash strength level to use in capture mode i.e. when the applications control
     * flash with either SINGLE or TORCH mode.</p>
     * flash with either <code>SINGLE</code> or <code>TORCH</code> mode.</p>
     * <p>Use {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} to check whether the device supports
     * flash strength control or not.
     * If the values of android.flash.info.singleStrengthMaxLevel and
     * If the values of {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} are greater than 1,
     * then the device supports manual flash strength control.</p>
     * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> TORCH the value must be &gt;= 1
     * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>TORCH</code> the value must be &gt;= 1
     * and &lt;= {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}.
     * If the application doesn't set the key and
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} &gt; 1,
     * then the flash will be fired at the default level set by HAL in
     * {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_DEFAULT_LEVEL android.flash.torchStrengthDefaultLevel}.
     * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> SINGLE, then the value must be &gt;= 1
     * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>SINGLE</code>, then the value must be &gt;= 1
     * and &lt;= {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel}.
     * If the application does not set this key and
     * {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} &gt; 1,
     * then the flash will be fired at the default level set by HAL
     * in {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL android.flash.singleStrengthDefaultLevel}.
     * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of ON_AUTO_FLASH, ON_ALWAYS_FLASH,
     * ON_AUTO_FLASH_REDEYE, ON_EXTERNAL_FLASH values, then the strengthLevel will be ignored.</p>
     * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of <code>ON_AUTO_FLASH</code>, <code>ON_ALWAYS_FLASH</code>,
     * <code>ON_AUTO_FLASH_REDEYE</code>, <code>ON_EXTERNAL_FLASH</code> values, then the strengthLevel will be ignored.</p>
     * <p><b>Range of valid values:</b><br>
     * <code>[1-{@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}]</code> when the {@link CaptureRequest#FLASH_MODE android.flash.mode} is
     * set to TORCH;
@@ -4846,6 +4846,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
     * correction map that needs to be applied to get shading
     * corrected images that match the camera device's output for
     * non-RAW formats.</p>
     * <p>Therefore, whatever the value of lensShadingApplied is, the lens
     * shading map should always be applied to RAW images if the goal is to
     * match the shading appearance of processed (non-RAW) images.</p>
     * <p>For a complete shading correction map, the least shaded
     * section of the image will have a gain factor of 1; all
     * other sections will have gains above 1.</p>
+261 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.telephony;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.DropBoxManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Optional;

/**
 * A persistent logger backend that stores logs in Android DropBoxManager
 *
 * @hide
 */
public class DropBoxManagerLoggerBackend implements PersistentLoggerBackend {

    private static final String TAG = "DropBoxManagerLoggerBackend";
    // Separate tag reference to be explicitly used for dropboxmanager instead of logcat logging
    private static final String DROPBOX_TAG = "DropBoxManagerLoggerBackend";
    private static final DateTimeFormatter LOG_TIMESTAMP_FORMATTER =
            DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS");
    private static final ZoneId LOCAL_ZONE_ID = ZoneId.systemDefault();
    private static final int BUFFER_SIZE_BYTES = 500 * 1024; // 500 KB
    private static final int MIN_BUFFER_BYTES_FOR_FLUSH = 5 * 1024; // 5 KB

    private static DropBoxManagerLoggerBackend sInstance;

    private final DropBoxManager mDropBoxManager;
    private final Object mBufferLock = new Object();
    @GuardedBy("mBufferLock")
    private final StringBuilder mLogBuffer = new StringBuilder();
    private long mBufferStartTime = -1L;
    private final HandlerThread mHandlerThread = new HandlerThread(DROPBOX_TAG);
    private final Handler mHandler;
    // Flag for determining if logging is enabled as a general feature
    private final boolean mDropBoxManagerLoggingEnabled;
    // Flag for controlling if logging is enabled at runtime
    private boolean mIsLoggingEnabled = false;

    /**
     * Returns a singleton instance of {@code DropBoxManagerLoggerBackend} that will log to
     * DropBoxManager if the config_dropboxmanager_persistent_logging_enabled resource config is
     * enabled.
     * @param context Android context
     */
    @Nullable
    public static synchronized DropBoxManagerLoggerBackend getInstance(@NonNull Context context) {
        if (sInstance == null) {
            sInstance = new DropBoxManagerLoggerBackend(context);
        }
        return sInstance;
    }

    private DropBoxManagerLoggerBackend(@NonNull Context context) {
        mDropBoxManager = context.getSystemService(DropBoxManager.class);
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        mDropBoxManagerLoggingEnabled = persistentLoggingEnabled(context);
    }

    private boolean persistentLoggingEnabled(@NonNull Context context) {
        try {
            return context.getResources().getBoolean(
                    R.bool.config_dropboxmanager_persistent_logging_enabled);
        } catch (RuntimeException e) {
            Log.w(TAG, "Persistent logging config not found");
            return false;
        }
    }

    /**
     * Enable or disable logging to DropBoxManager
     * @param isLoggingEnabled Whether logging should be enabled
     */
    public void setLoggingEnabled(boolean isLoggingEnabled) {
        Log.i(DROPBOX_TAG, "toggle logging: " + isLoggingEnabled);
        mIsLoggingEnabled = isLoggingEnabled;
    }

    /**
     * Persist a DEBUG log message.
     * @param tag Used to identify the source of a log message.
     * @param msg The message you would like logged.
     */
    public void debug(@NonNull String tag, @NonNull String msg) {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }
        bufferLog("D", tag, msg, Optional.empty());
    }

    /**
     * Persist a INFO log message.
     * @param tag Used to identify the source of a log message.
     * @param msg The message you would like logged.
     */
    public void info(@NonNull String tag, @NonNull String msg) {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }
        bufferLog("I", tag, msg, Optional.empty());
    }

    /**
     * Persist a WARN log message.
     * @param tag Used to identify the source of a log message.
     * @param msg The message you would like logged.
     */
    public void warn(@NonNull String tag, @NonNull String msg) {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }
        bufferLog("W", tag, msg, Optional.empty());
    }

    /**
     * Persist a WARN log message.
     * @param tag Used to identify the source of a log message.
     * @param msg The message you would like logged.
     * @param t An exception to log.
     */
    public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }
        bufferLog("W", tag, msg, Optional.of(t));
    }

    /**
     * Persist a ERROR log message.
     * @param tag Used to identify the source of a log message.
     * @param msg The message you would like logged.
     */
    public void error(@NonNull String tag, @NonNull String msg) {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }
        bufferLog("E", tag, msg, Optional.empty());
    }

    /**
     * Persist a ERROR log message.
     * @param tag Used to identify the source of a log message.
     * @param msg The message you would like logged.
     * @param t An exception to log.
     */
    public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }
        bufferLog("E", tag, msg, Optional.of(t));
    }

    private synchronized void bufferLog(
            @NonNull String level,
            @NonNull String tag,
            @NonNull String msg,
            Optional<Throwable> t) {
        if (!mIsLoggingEnabled) {
            return;
        }

        if (mBufferStartTime == -1L) {
            mBufferStartTime = System.currentTimeMillis();
        }

        synchronized (mBufferLock) {
            mLogBuffer
                    .append(formatLog(level, tag, msg, t))
                    .append("\n");

            if (mLogBuffer.length() >= BUFFER_SIZE_BYTES) {
                flushAsync();
            }
        }
    }

    private String formatLog(
            @NonNull String level,
            @NonNull String tag,
            @NonNull String msg,
            Optional<Throwable> t) {
        // Expected format = "$Timestamp $Level $Tag: $Message"
        return formatTimestamp(System.currentTimeMillis()) + " " + level + " " + tag + ": "
                + t.map(throwable -> msg + ": " + Log.getStackTraceString(throwable)).orElse(msg);
    }

    private String formatTimestamp(long currentTimeMillis) {
        return Instant.ofEpochMilli(currentTimeMillis)
                .atZone(LOCAL_ZONE_ID)
                .format(LOG_TIMESTAMP_FORMATTER);
    }

    /**
     * Flushes all buffered logs into DropBoxManager as a single log record with a tag of
     * {@link #DROPBOX_TAG} asynchronously. Should be invoked sparingly as DropBoxManager has
     * device-level limitations on the number files that can be stored.
     */
    public void flushAsync() {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }

        mHandler.post(this::flush);
    };

    /**
     * Flushes all buffered logs into DropBoxManager as a single log record with a tag of
     * {@link #DROPBOX_TAG}. Should be invoked sparingly as DropBoxManager has device-level
     * limitations on the number files that can be stored.
     */
    public void flush() {
        if (!mDropBoxManagerLoggingEnabled) {
            return;
        }

        synchronized (mBufferLock) {
            if (mLogBuffer.length() < MIN_BUFFER_BYTES_FOR_FLUSH) {
                return;
            }

            Log.d(DROPBOX_TAG, "Flushing logs from "
                    + formatTimestamp(mBufferStartTime) + " to "
                    + formatTimestamp(System.currentTimeMillis()));

            try {
                mDropBoxManager.addText(DROPBOX_TAG, mLogBuffer.toString());
            } catch (Exception e) {
                Log.w(DROPBOX_TAG, "Failed to flush logs of length "
                        + mLogBuffer.length() + " to DropBoxManager", e);
            }
            mLogBuffer.setLength(0);
        }
        mBufferStartTime = -1L;
    }
}
Loading