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

Commit e41386fa authored by Anna Bauza's avatar Anna Bauza Committed by Android (Google) Code Review
Browse files

Merge "Generate Property Invalidated Cache from annotation." into main

parents d86c1436 a0760e36
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -368,6 +368,7 @@ java_defaults {
    jarjar_rules: ":framework-jarjar-rules",
    javac_shard_size: 150,
    plugins: [
        "cached-property-annotation-processor",
        "view-inspector-annotation-processor",
        "staledataclass-annotation-processor",
        "error_prone_android_framework",
+57 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_base_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_base_license"],
    default_team: "trendy_team_framework_android_multiuser",
}

java_library_host {
    name: "libcached-property-annotation-processor",
    srcs: [
        ":framework-annotations",
        "src/**/*.java",
    ],
    static_libs: [
        "codegen-version-info",
        "android.multiuser.flags-aconfig-java-host",
        "guava",
    ],
    use_tools_jar: true,
}

java_plugin {
    name: "cached-property-annotation-processor",
    processor_class: "android.processor.property_cache.CachedPropertyProcessor",
    static_libs: ["libcached-property-annotation-processor"],
}

java_aconfig_library {
    name: "android.multiuser.flags-aconfig-java-host",
    aconfig_declarations: "android.multiuser.flags-aconfig",
    host_supported: true,
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

java_test_host {
    name: "cached-property-annotation-processor-test",
    srcs: ["test/java/**/*.java"],
    java_resources: [":CachedPropertyAnnotationJavaTestSource"],
    static_libs: [
        "compile-testing-prebuilt",
        "truth",
        "junit",
        "guava",
        "libcached-property-annotation-processor",
    ],
    test_suites: ["general-tests"],
}

filegroup {
    name: "CachedPropertyAnnotationJavaTestSource",
    srcs: ["test/resources/*.java"],
    path: "test/resources/",
    visibility: ["//visibility:private"],
}
+7 −0
Original line number Diff line number Diff line
{
  "postsubmit": [
    {
      "name": "cached-property-annotation-processor-test"
    }
  ]
}
+138 −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.processor.property_cache;

import com.android.internal.annotations.CachedProperty;
import com.android.internal.annotations.CachedPropertyDefaults;

import com.google.common.base.CaseFormat;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;

public class CacheConfig {
    private final CacheModifiers mModifiers;
    private final int mMaxSize;
    private final String mModuleName;
    private final String mApiName;
    private final String mClassName;
    private final String mQualifiedName;
    private String mPropertyName;
    private String mMethodName;
    private int mNumberOfParams = 0;
    private String mInputType = Constants.JAVA_LANG_VOID;
    private String mResultType;

    public CacheConfig(TypeElement classElement, ExecutableElement method) {
        CachedPropertyDefaults classAnnotation = classElement.getAnnotation(
                CachedPropertyDefaults.class);
        CachedProperty methodAnnotation = method.getAnnotation(CachedProperty.class);

        mModuleName = methodAnnotation.module().isEmpty() ? classAnnotation.module()
                : methodAnnotation.module();
        mClassName = classElement.getSimpleName().toString();
        mQualifiedName = classElement.getQualifiedName().toString();
        mModifiers = new CacheModifiers(methodAnnotation.modsFlagOnOrNone());
        mMethodName = method.getSimpleName().toString();
        mPropertyName = getPropertyName(mMethodName);
        mApiName = methodAnnotation.api().isEmpty() ? getUniqueApiName(mClassName, mPropertyName)
                : methodAnnotation.api();
        mMaxSize = methodAnnotation.max() == -1 ? classAnnotation.max() : methodAnnotation.max();
        mNumberOfParams = method.getParameters().size();
        if (mNumberOfParams > 0) {
            mInputType = primitiveTypeToObjectEquivalent(
                method.getParameters().get(0).asType().toString());
        }
        mResultType = primitiveTypeToObjectEquivalent(method.getReturnType().toString());
    }

    public CacheModifiers getModifiers() {
        return mModifiers;
    }

    public int getMaxSize() {
        return mMaxSize;
    }

    public String getApiName() {
        return mApiName;
    }

    public String getClassName() {
        return mClassName;
    }

    public String getQualifiedName() {
        return mQualifiedName;
    }

    public String getModuleName() {
        return mModuleName;
    }

    public String getMethodName() {
        return mMethodName;
    }

    public String getPropertyName() {
        return mPropertyName;
    }

    public String getPropertyVariable() {
        return (mModifiers.isStatic() ? "s" : "m") + mPropertyName;
    }

    private String getPropertyName(String methodName) {
        if (methodName.startsWith("get")) {
            return methodName.substring(3);
        } else if (methodName.startsWith("is")) {
            return methodName.substring(2);
        } else {
            return CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, methodName);
        }
    }

    public int getNumberOfParams() {
        return mNumberOfParams;
    }

    public String getInputType() {
        return mInputType;
    }

    public String getResultType() {
        return mResultType;
    }

    /**
     * This method returns the unique api name for a given class and property name.
     * Property name is retrieved from the method name.
     * Both names are combined and converted to lower snake case.
     *
     * @param className    The name of the class that contains the property.
     * @param propertyName The name of the property.
     * @return The registration name for the property.
     */
    private String getUniqueApiName(String className, String propertyName) {
        return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, className + propertyName);
    }

    private String primitiveTypeToObjectEquivalent(String simpleType) {
        // checking against primitive types
        return Constants.PRIMITIVE_TYPE_MAP.getOrDefault(simpleType, simpleType);
    }
}
+40 −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.processor.property_cache;

import com.android.internal.annotations.CacheModifier;

import java.util.Arrays;
import java.util.List;

public class CacheModifiers {
    private final boolean mIsStatic;
    private static final String STATIC_MODIFIER_STRING = "static ";

    CacheModifiers(CacheModifier[] modifierArray) {
        final List<CacheModifier> modifiers = Arrays.asList(modifierArray);
        mIsStatic = modifiers.contains(CacheModifier.STATIC);
    }

    public boolean isStatic() {
        return mIsStatic;
    }

    public String getStaticModifier() {
        return mIsStatic ? STATIC_MODIFIER_STRING : Constants.EMPTY_STRING;
    }
}
Loading