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

Commit c4b4cb8a authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Added DeviceConfig properties to fine tune ContentCapture:"

parents d2d04c6e d32d8f6f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2748,7 +2748,15 @@ package android.view.contentcapture {
  public final class ContentCaptureManager {
    method public boolean isContentCaptureFeatureEnabled();
    method public void setContentCaptureFeatureEnabled(boolean);
    field public static final String DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY = "idle_flush_frequency";
    field public static final String DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL = "logging_level";
    field public static final String DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE = "log_history_size";
    field public static final String DEVICE_CONFIG_PROPERTY_MAX_BUFFER_SIZE = "max_buffer_size";
    field public static final String DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED = "service_explicitly_enabled";
    field public static final String DEVICE_CONFIG_PROPERTY_TEXT_CHANGE_FLUSH_FREQUENCY = "text_change_flush_frequency";
    field public static final int LOGGING_LEVEL_DEBUG = 1; // 0x1
    field public static final int LOGGING_LEVEL_OFF = 0; // 0x0
    field public static final int LOGGING_LEVEL_VERBOSE = 2; // 0x2
  }

  public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
+73 −5
Original line number Diff line number Diff line
@@ -15,16 +15,29 @@
 */
package android.view.contentcapture;

import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL;
import static android.view.contentcapture.ContentCaptureManager.LOGGING_LEVEL_DEBUG;
import static android.view.contentcapture.ContentCaptureManager.LOGGING_LEVEL_OFF;
import static android.view.contentcapture.ContentCaptureManager.LOGGING_LEVEL_VERBOSE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Build;
import android.provider.DeviceConfig;
import android.util.Log;
import android.view.contentcapture.ContentCaptureManager.LoggingLevel;

/**
 * Helpe class for this package.
 * Helper class for this package and server's.
 *
 * @hide
 */
final class ContentCaptureHelper {
public final class ContentCaptureHelper {

    private static final String TAG = ContentCaptureHelper.class.getSimpleName();

    // TODO(b/121044306): define a way to dynamically set them(for example, using settings?)
    static final boolean VERBOSE = false;
    static final boolean DEBUG = true; // STOPSHIP if not set to false
    public static boolean sVerbose = false;
    public static boolean sDebug = true;

    /**
     * Used to log text that could contain PII.
@@ -34,6 +47,61 @@ final class ContentCaptureHelper {
        return text == null ? null : text.length() + "_chars";
    }

    /**
     * Gets the value of a device config property from the Content Capture namespace.
     */
    public static int getIntDeviceConfigProperty(@NonNull String key, int defaultValue) {
        final String value = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE, key);
        if (value == null) return defaultValue;

        try {
            return Integer.parseInt(value);
        } catch (Exception e) {
            Log.w(TAG, "error parsing value (" + value + ") of property " + key + ": " + e);
            return defaultValue;
        }
    }

    /**
     * Sets the value of the static logging level constants based on device config.
     */
    public static void setLoggingLevel() {
        final int defaultLevel = Build.IS_DEBUGGABLE ? LOGGING_LEVEL_DEBUG : LOGGING_LEVEL_OFF;
        final int level = getIntDeviceConfigProperty(DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL,
                defaultLevel);
        Log.i(TAG, "Setting logging level to " + getLoggingLevelAsString(level));
        sVerbose = sDebug = false;
        switch (level) {
            case LOGGING_LEVEL_VERBOSE:
                sVerbose = true;
                // fall through
            case LOGGING_LEVEL_DEBUG:
                sDebug = true;
                return;
            case LOGGING_LEVEL_OFF:
                // You log nothing, Jon Snow!
                return;
            default:
                Log.w(TAG, "setLoggingLevel(): invalud level: " + level);
        }
    }

    /**
     * Gets a user-friendly value for a content capture logging level.
     */
    public static String getLoggingLevelAsString(@LoggingLevel int level) {
        switch (level) {
            case LOGGING_LEVEL_OFF:
                return "OFF";
            case LOGGING_LEVEL_DEBUG:
                return "DEBUG";
            case LOGGING_LEVEL_VERBOSE:
                return "VERBOSE";
            default:
                return "UNKNOWN-" + level;
        }
    }

    private ContentCaptureHelper() {
        throw new UnsupportedOperationException("contains only static methods");
    }
+90 −10
Original line number Diff line number Diff line
@@ -15,9 +15,10 @@
 */
package android.view.contentcapture;

import static android.view.contentcapture.ContentCaptureHelper.DEBUG;
import static android.view.contentcapture.ContentCaptureHelper.VERBOSE;
import static android.view.contentcapture.ContentCaptureHelper.sDebug;
import static android.view.contentcapture.ContentCaptureHelper.sVerbose;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -38,6 +39,8 @@ import com.android.internal.util.Preconditions;
import com.android.internal.util.SyncResultReceiver;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * TODO(b/123577059): add javadocs / mention it can be null
@@ -78,6 +81,75 @@ public final class ContentCaptureManager {
    public static final String DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED =
            "service_explicitly_enabled";

    /**
     * Maximum number of events that are buffered before sent to the app.
     *
     * @hide
     */
    @TestApi
    public static final String DEVICE_CONFIG_PROPERTY_MAX_BUFFER_SIZE = "max_buffer_size";

    /**
     * Frequency (in ms) of buffer flushes when no events are received.
     *
     * @hide
     */
    @TestApi
    public static final String DEVICE_CONFIG_PROPERTY_IDLE_FLUSH_FREQUENCY = "idle_flush_frequency";

    /**
     * Frequency (in ms) of buffer flushes when no events are received and the last one was a
     * text change event.
     *
     * @hide
     */
    @TestApi
    public static final String DEVICE_CONFIG_PROPERTY_TEXT_CHANGE_FLUSH_FREQUENCY =
            "text_change_flush_frequency";

    /**
     * Size of events that are logging on {@code dump}.
     *
     * <p>Set it to {@code 0} or less to disable history.
     *
     * @hide
     */
    @TestApi
    public static final String DEVICE_CONFIG_PROPERTY_LOG_HISTORY_SIZE = "log_history_size";

    /**
     * Sets the logging level for {@code logcat} statements.
     *
     * <p>Valid values are: {@link #LOGGING_LEVEL_OFF}, {@value #LOGGING_LEVEL_DEBUG}, and
     * {@link #LOGGING_LEVEL_VERBOSE}.
     *
     * @hide
     */
    @TestApi
    public static final String DEVICE_CONFIG_PROPERTY_LOGGING_LEVEL = "logging_level";


    /** @hide */
    @TestApi
    public static final int LOGGING_LEVEL_OFF = 0;

    /** @hide */
    @TestApi
    public static final int LOGGING_LEVEL_DEBUG = 1;

    /** @hide */
    @TestApi
    public static final int LOGGING_LEVEL_VERBOSE = 2;

    /** @hide */
    @IntDef(flag = false, value = {
            LOGGING_LEVEL_OFF,
            LOGGING_LEVEL_DEBUG,
            LOGGING_LEVEL_VERBOSE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface LoggingLevel {}

    private final Object mLock = new Object();

    @NonNull
@@ -101,10 +173,16 @@ public final class ContentCaptureManager {
    /** @hide */
    public ContentCaptureManager(@NonNull Context context,
            @NonNull IContentCaptureManager service) {
        if (VERBOSE) Log.v(TAG, "Constructor for " + context.getPackageName());
        mContext = Preconditions.checkNotNull(context, "context cannot be null");
        mService = Preconditions.checkNotNull(service, "service cannot be null");

        // TODO(b/123096662): right now we're reading the device config values here, but ideally
        // it should be read on ContentCaptureManagerService and passed back when the activity
        // started.
        ContentCaptureHelper.setLoggingLevel();

        if (sVerbose) Log.v(TAG, "Constructor for " + context.getPackageName());

        // TODO(b/119220549): we might not even need a handler, as the IPCs are oneway. But if we
        // do, then we should optimize it to run the tests after the Choreographer finishes the most
        // important steps of the frame.
@@ -126,7 +204,7 @@ public final class ContentCaptureManager {
        synchronized (mLock) {
            if (mMainSession == null) {
                mMainSession = new MainContentCaptureSession(mContext, this, mHandler, mService);
                if (VERBOSE) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession);
                if (sVerbose) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession);
            }
            return mMainSession;
        }
@@ -210,7 +288,7 @@ public final class ContentCaptureManager {
     * it on {@link android.app.Activity#onCreate(android.os.Bundle, android.os.PersistableBundle)}.
     */
    public void setContentCaptureEnabled(boolean enabled) {
        if (DEBUG) {
        if (sDebug) {
            Log.d(TAG, "setContentCaptureEnabled(): setting to " + enabled + " for " + mContext);
        }

@@ -264,7 +342,7 @@ public final class ContentCaptureManager {
    @SystemApi
    @TestApi
    public void setContentCaptureFeatureEnabled(boolean enabled) {
        if (DEBUG) Log.d(TAG, "setContentCaptureFeatureEnabled(): setting to " + enabled);
        if (sDebug) Log.d(TAG, "setContentCaptureFeatureEnabled(): setting to " + enabled);

        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
        final int resultCode;
@@ -308,10 +386,12 @@ public final class ContentCaptureManager {
        synchronized (mLock) {
            pw.print(prefix2); pw.print("isContentCaptureEnabled(): ");
            pw.println(isContentCaptureEnabled());
            pw.print(prefix2); pw.print("Context: "); pw.println(mContext);
            pw.print(prefix2); pw.print("User: "); pw.println(mContext.getUserId());
            pw.print(prefix2); pw.print("Service: "); pw.println(mService);
            pw.print(prefix2); pw.print("Flags: "); pw.println(mFlags);
            pw.print(prefix); pw.print("Debug: "); pw.print(sDebug);
            pw.print(" Verbose: "); pw.println(sVerbose);
            pw.print(prefix); pw.print("Context: "); pw.println(mContext);
            pw.print(prefix); pw.print("User: "); pw.println(mContext.getUserId());
            pw.print(prefix); pw.print("Service: "); pw.println(mService);
            pw.print(prefix); pw.print("Flags: "); pw.println(mFlags);
            if (mMainSession != null) {
                final String prefix3 = prefix2 + "  ";
                pw.print(prefix2); pw.println("Main session:");
+6 −6
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
 */
package android.view.contentcapture;

import static android.view.contentcapture.ContentCaptureHelper.DEBUG;
import static android.view.contentcapture.ContentCaptureHelper.VERBOSE;
import static android.view.contentcapture.ContentCaptureHelper.sDebug;
import static android.view.contentcapture.ContentCaptureHelper.sVerbose;

import android.annotation.CallSuper;
import android.annotation.IntDef;
@@ -233,7 +233,7 @@ public abstract class ContentCaptureSession implements AutoCloseable {
    public final ContentCaptureSession createContentCaptureSession(
            @NonNull ContentCaptureContext context) {
        final ContentCaptureSession child = newChild(context);
        if (DEBUG) {
        if (sDebug) {
            Log.d(TAG, "createContentCaptureSession(" + context + ": parent=" + mId + ", child="
                    + child.mId);
        }
@@ -285,20 +285,20 @@ public abstract class ContentCaptureSession implements AutoCloseable {
    public final void destroy() {
        synchronized (mLock) {
            if (mDestroyed) {
                if (DEBUG) Log.d(TAG, "destroy(" + mId + "): already destroyed");
                if (sDebug) Log.d(TAG, "destroy(" + mId + "): already destroyed");
                return;
            }
            mDestroyed = true;

            // TODO(b/111276913): check state (for example, how to handle if it's waiting for remote
            // id) and send it to the cache of batched commands
            if (VERBOSE) {
            if (sVerbose) {
                Log.v(TAG, "destroy(): state=" + getStateAsString(mState) + ", mId=" + mId);
            }
            // Finish children first
            if (mChildren != null) {
                final int numberChildren = mChildren.size();
                if (VERBOSE) Log.v(TAG, "Destroying " + numberChildren + " children first");
                if (sVerbose) Log.v(TAG, "Destroying " + numberChildren + " children first");
                for (int i = 0; i < numberChildren; i++) {
                    final ContentCaptureSession child = mChildren.get(i);
                    try {
+76 −49

File changed.

Preview size limit exceeded, changes collapsed.

Loading