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

Commit 5809208a authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 7659088 from 45319d55 to sc-qpr1-release

Change-Id: I94dc6607fc616e83d32d9cff8860996631d13654
parents 0d1410dc 45319d55
Loading
Loading
Loading
Loading
+125 −21
Original line number Diff line number Diff line
@@ -107,9 +107,13 @@ static const char PROGRESS_PROP_NAME[] = "service.bootanim.progress";
static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
static constexpr size_t TEXT_POS_LEN_MAX = 16;
static const int DYNAMIC_COLOR_COUNT = 4;
static const char U_TEXTURE[] = "uTexture";
static const char U_FADE[] = "uFade";
static const char U_CROP_AREA[] = "uCropArea";
static const char U_START_COLOR_PREFIX[] = "uStartColor";
static const char U_END_COLOR_PREFIX[] = "uEndColor";
static const char U_COLOR_PROGRESS[] = "uColorProgress";
static const char A_UV[] = "aUv";
static const char A_POSITION[] = "aPosition";
static const char VERTEX_SHADER_SOURCE[] = R"(
@@ -121,6 +125,28 @@ static const char VERTEX_SHADER_SOURCE[] = R"(
        gl_Position = aPosition;
        vUv = aUv;
    })";
static const char IMAGE_FRAG_DYNAMIC_COLORING_SHADER_SOURCE[] = R"(
    precision mediump float;
    uniform sampler2D uTexture;
    uniform float uFade;
    uniform float uColorProgress;
    uniform vec4 uStartColor0;
    uniform vec4 uStartColor1;
    uniform vec4 uStartColor2;
    uniform vec4 uStartColor3;
    uniform vec4 uEndColor0;
    uniform vec4 uEndColor1;
    uniform vec4 uEndColor2;
    uniform vec4 uEndColor3;
    varying highp vec2 vUv;
    void main() {
        vec4 mask = texture2D(uTexture, vUv);
        vec4 color = mask.r * mix(uStartColor0, uEndColor0, uColorProgress)
            + mask.g * mix(uStartColor1, uEndColor1, uColorProgress)
            + mask.b * mix(uStartColor2, uEndColor2, uColorProgress)
            + mask.a * mix(uStartColor3, uEndColor3, uColorProgress);
        gl_FragColor = vec4(color.x, color.y, color.z, (1.0 - uFade)) * color.a;
    })";
static const char IMAGE_FRAG_SHADER_SOURCE[] = R"(
    precision mediump float;
    uniform sampler2D uTexture;
@@ -128,7 +154,7 @@ static const char IMAGE_FRAG_SHADER_SOURCE[] = R"(
    varying highp vec2 vUv;
    void main() {
        vec4 color = texture2D(uTexture, vUv);
        gl_FragColor = vec4(color.x, color.y, color.z, 1.0 - uFade);
        gl_FragColor = vec4(color.x, color.y, color.z, (1.0 - uFade)) * color.a;
    })";
static const char TEXT_FRAG_SHADER_SOURCE[] = R"(
    precision mediump float;
@@ -212,7 +238,8 @@ void BootAnimation::binderDied(const wp<IBinder>&) {
    requestExit();
}

static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitmapInfo* outInfo) {
static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitmapInfo* outInfo,
    bool premultiplyAlpha) {
    AImageDecoder* decoder = nullptr;
    AImageDecoder_createFromBuffer(encodedData, dataLength, &decoder);
    if (!decoder) {
@@ -226,6 +253,10 @@ static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitm
    outInfo->stride = AImageDecoder_getMinimumStride(decoder);
    outInfo->flags = 0;

    if (!premultiplyAlpha) {
        AImageDecoder_setUnpremultipliedRequired(decoder, true);
    }

    const size_t size = outInfo->stride * outInfo->height;
    void* pixels = malloc(size);
    int result = AImageDecoder_decodeImage(decoder, pixels, outInfo->stride, size);
@@ -239,13 +270,14 @@ static void* decodeImage(const void* encodedData, size_t dataLength, AndroidBitm
}

status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
        const char* name) {
        const char* name, bool premultiplyAlpha) {
    Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
    if (asset == nullptr)
        return NO_INIT;

    AndroidBitmapInfo bitmapInfo;
    void* pixels = decodeImage(asset->getBuffer(false), asset->getLength(), &bitmapInfo);
    void* pixels = decodeImage(asset->getBuffer(false), asset->getLength(), &bitmapInfo,
        premultiplyAlpha);
    auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };

    asset->close();
@@ -293,9 +325,11 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
    return NO_ERROR;
}

status_t BootAnimation::initTexture(FileMap* map, int* width, int* height) {
status_t BootAnimation::initTexture(FileMap* map, int* width, int* height,
    bool premultiplyAlpha) {
    AndroidBitmapInfo bitmapInfo;
    void* pixels = decodeImage(map->getDataPtr(), map->getDataLength(), &bitmapInfo);
    void* pixels = decodeImage(map->getDataPtr(), map->getDataLength(), &bitmapInfo,
        premultiplyAlpha);
    auto pixelDeleter = std::unique_ptr<void, decltype(free)*>{ pixels, free };

    // FileMap memory is never released until application exit.
@@ -675,9 +709,12 @@ GLuint linkShader(GLuint vertexShader, GLuint fragmentShader) {
}

void BootAnimation::initShaders() {
    bool dynamicColoringEnabled = mAnimation != nullptr && mAnimation->dynamicColoringEnabled;
    GLuint vertexShader = compileShader(GL_VERTEX_SHADER, (const GLchar *)VERTEX_SHADER_SOURCE);
    GLuint imageFragmentShader =
        compileShader(GL_FRAGMENT_SHADER, (const GLchar *)IMAGE_FRAG_SHADER_SOURCE);
        compileShader(GL_FRAGMENT_SHADER, dynamicColoringEnabled
            ? (const GLchar *)IMAGE_FRAG_DYNAMIC_COLORING_SHADER_SOURCE
            : (const GLchar *)IMAGE_FRAG_SHADER_SOURCE);
    GLuint textFragmentShader =
        compileShader(GL_FRAGMENT_SHADER, (const GLchar *)TEXT_FRAG_SHADER_SOURCE);

@@ -869,6 +906,20 @@ static bool parseColor(const char str[7], float color[3]) {
    return true;
}

// Parse a color represented as a signed decimal int string.
// E.g. "-2757722" (whose hex 2's complement is 0xFFD5EBA6).
// If the input color string is empty, set color with values in defaultColor.
static void parseColorDecimalString(const std::string& colorString,
    float color[3], float defaultColor[3]) {
    if (colorString == "") {
        memcpy(color, defaultColor, sizeof(float) * 3);
        return;
    }
    int colorInt = atoi(colorString.c_str());
    color[0] = ((float)((colorInt >> 16) & 0xFF)) / 0xFF; // r
    color[1] = ((float)((colorInt >> 8) & 0xFF)) / 0xFF; // g
    color[2] = ((float)(colorInt & 0xFF)) / 0xFF; // b
}

static bool readFile(ZipFileRO* zip, const char* name, String8& outString) {
    ZipEntryRO entry = zip->findEntryByName(name);
@@ -1010,6 +1061,8 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
        return false;
    }
    char const* s = desString.string();
    std::string dynamicColoringPartName = "";
    bool postDynamicColoring = false;

    // Parse the description file
    for (;;) {
@@ -1028,7 +1081,13 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
        char color[7] = "000000"; // default to black if unspecified
        char clockPos1[TEXT_POS_LEN_MAX + 1] = "";
        char clockPos2[TEXT_POS_LEN_MAX + 1] = "";
        char dynamicColoringPartNameBuffer[ANIM_ENTRY_NAME_MAX];
        char pathType;
        // start colors default to black if unspecified
        char start_color_0[7] = "000000";
        char start_color_1[7] = "000000";
        char start_color_2[7] = "000000";
        char start_color_3[7] = "000000";

        int nextReadPos;

@@ -1043,6 +1102,15 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
            } else {
              animation.progressEnabled = false;
            }
        } else if (sscanf(l, "dynamic_colors %" STRTO(ANIM_PATH_MAX) "s #%6s #%6s #%6s #%6s",
            dynamicColoringPartNameBuffer,
            start_color_0, start_color_1, start_color_2, start_color_3)) {
            animation.dynamicColoringEnabled = true;
            parseColor(start_color_0, animation.startColors[0]);
            parseColor(start_color_1, animation.startColors[1]);
            parseColor(start_color_2, animation.startColors[2]);
            parseColor(start_color_3, animation.startColors[3]);
            dynamicColoringPartName = std::string(dynamicColoringPartNameBuffer);
        } else if (sscanf(l, "%c %d %d %" STRTO(ANIM_PATH_MAX) "s%n",
                          &pathType, &count, &pause, path, &nextReadPos) >= 4) {
            if (pathType == 'f') {
@@ -1055,6 +1123,16 @@ bool BootAnimation::parseAnimationDesc(Animation& animation) {
            //       "clockPos1=%s, clockPos2=%s",
            //       pathType, count, pause, path, framesToFadeCount, color, clockPos1, clockPos2);
            Animation::Part part;
            if (path == dynamicColoringPartName) {
                // Part is specified to use dynamic coloring.
                part.useDynamicColoring = true;
                part.postDynamicColoring = false;
                postDynamicColoring = true;
            } else {
                // Part does not use dynamic coloring.
                part.useDynamicColoring = false;
                part.postDynamicColoring =  postDynamicColoring;
            }
            part.playUntilComplete = pathType == 'c';
            part.framesToFadeCount = framesToFadeCount;
            part.count = count;
@@ -1262,6 +1340,10 @@ bool BootAnimation::movie() {
        mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
    }

    if (mAnimation != nullptr && mAnimation->dynamicColoringEnabled) {
        initDynamicColors();
    }

    playAnimation(*mAnimation);

    if (mTimeCheckThread != nullptr) {
@@ -1315,6 +1397,27 @@ void BootAnimation::drawTexturedQuad(float xStart, float yStart, float width, fl
        sizeof(quadPositions) / sizeof(quadPositions[0]) / 2);
}

void BootAnimation::initDynamicColors() {
    for (int i = 0; i < DYNAMIC_COLOR_COUNT; i++) {
        parseColorDecimalString(
            android::base::GetProperty("persist.bootanim.color" + std::to_string(i + 1), ""),
            mAnimation->endColors[i], mAnimation->startColors[i]);
    }
    glUseProgram(mImageShader);
    SLOGI("[BootAnimation] Dynamically coloring boot animation.");
    for (int i = 0; i < DYNAMIC_COLOR_COUNT; i++) {
        float *startColor = mAnimation->startColors[i];
        float *endColor = mAnimation->endColors[i];
        glUniform4f(glGetUniformLocation(mImageShader,
            (U_START_COLOR_PREFIX + std::to_string(i)).c_str()),
            startColor[0], startColor[1], startColor[2], 1 /* alpha */);
        glUniform4f(glGetUniformLocation(mImageShader,
            (U_END_COLOR_PREFIX + std::to_string(i)).c_str()),
            endColor[0], endColor[1], endColor[2], 1 /* alpha */);
    }
    mImageColorProgressLocation = glGetUniformLocation(mImageShader, U_COLOR_PROGRESS);
}

bool BootAnimation::playAnimation(const Animation& animation) {
    const size_t pcount = animation.parts.size();
    nsecs_t frameDuration = s2ns(1) / animation.fps;
@@ -1357,6 +1460,14 @@ bool BootAnimation::playAnimation(const Animation& animation) {
            for (size_t j=0 ; j<fcount ; j++) {
                if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;

                // Color progress is
                // - the normalized animation progress between [0, 1] for the dynamic coloring part,
                // - 0 for parts that come before,
                // - 1 for parts that come after.
                float colorProgress = part.useDynamicColoring
                    ? (float)j / fcount
                    : (part.postDynamicColoring ? 1 : 0);

                processDisplayEvents();

                const int animationX = (mWidth - animation.width) / 2;
@@ -1371,24 +1482,14 @@ bool BootAnimation::playAnimation(const Animation& animation) {
                    glGenTextures(1, &frame.tid);
                    glBindTexture(GL_TEXTURE_2D, frame.tid);
                    int w, h;
                    initTexture(frame.map, &w, &h);
                    // Set decoding option to alpha unpremultiplied so that the R, G, B channels
                    // of transparent pixels are preserved.
                    initTexture(frame.map, &w, &h, false /* don't premultiply alpha */);
                }

                const int xc = animationX + frame.trimX;
                const int yc = animationY + frame.trimY;
                Region clearReg(Rect(mWidth, mHeight));
                clearReg.subtractSelf(Rect(xc, yc, xc+frame.trimWidth, yc+frame.trimHeight));
                if (!clearReg.isEmpty()) {
                    Region::const_iterator head(clearReg.begin());
                    Region::const_iterator tail(clearReg.end());
                    glEnable(GL_SCISSOR_TEST);
                    while (head != tail) {
                        const Rect& r2(*head++);
                        glScissor(r2.left, mHeight - r2.bottom, r2.width(), r2.height());
                glClear(GL_COLOR_BUFFER_BIT);
                    }
                    glDisable(GL_SCISSOR_TEST);
                }
                // specify the y center as ceiling((mHeight - frame.trimHeight) / 2)
                // which is equivalent to mHeight - (yc + frame.trimHeight)
                const int frameDrawY = mHeight - (yc + frame.trimHeight);
@@ -1404,6 +1505,9 @@ bool BootAnimation::playAnimation(const Animation& animation) {
                glUseProgram(mImageShader);
                glUniform1i(mImageTextureLocation, 0);
                glUniform1f(mImageFadeLocation, fade);
                if (animation.dynamicColoringEnabled) {
                    glUniform1f(mImageColorProgressLocation, colorProgress);
                }
                glEnable(GL_BLEND);
                drawTexturedQuad(xc, frameDrawY, frame.trimWidth, frame.trimHeight);
                glDisable(GL_BLEND);
+16 −4
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ public:
    };

    struct Font {
        FileMap* map;
        FileMap* map = nullptr;
        Texture texture;
        int char_width;
        int char_height;
@@ -62,7 +62,7 @@ public:
    struct Animation {
        struct Frame {
            String8 name;
            FileMap* map;
            FileMap* map = nullptr;
            int trimX;
            int trimY;
            int trimWidth;
@@ -90,6 +90,10 @@ public:
            uint8_t* audioData;
            int audioLength;
            Animation* animation;
            // Controls if dynamic coloring is enabled for this part.
            bool useDynamicColoring = false;
            // Defines if this part is played after the dynamic coloring part.
            bool postDynamicColoring = false;

            bool hasFadingPhase() const {
                return !playUntilComplete && framesToFadeCount > 0;
@@ -105,6 +109,10 @@ public:
        ZipFileRO* zip;
        Font clockFont;
        Font progressFont;
         // Controls if dynamic coloring is enabled for the whole animation.
        bool dynamicColoringEnabled = false;
        float startColors[4][3]; // Start colors of dynamic color transition.
        float endColors[4][3];   // End colors of dynamic color transition.
    };

    // All callbacks will be called from this class's internal thread.
@@ -163,8 +171,10 @@ private:
    int displayEventCallback(int fd, int events, void* data);
    void processDisplayEvents();

    status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
    status_t initTexture(FileMap* map, int* width, int* height);
    status_t initTexture(Texture* texture, AssetManager& asset, const char* name,
        bool premultiplyAlpha = true);
    status_t initTexture(FileMap* map, int* width, int* height,
        bool premultiplyAlpha = true);
    status_t initFont(Font* font, const char* fallback);
    void initShaders();
    bool android();
@@ -194,6 +204,7 @@ private:
    void checkExit();

    void handleViewport(nsecs_t timestep);
    void initDynamicColors();

    sp<SurfaceComposerClient>       mSession;
    AssetManager mAssets;
@@ -226,6 +237,7 @@ private:
    GLuint mImageTextureLocation;
    GLuint mTextCropAreaLocation;
    GLuint mTextTextureLocation;
    GLuint mImageColorProgressLocation;
};

// ---------------------------------------------------------------------------
+3 −0
Original line number Diff line number Diff line
dupin@google.com
shanh@google.com
jreck@google.com
+26 −0
Original line number Diff line number Diff line
@@ -280,6 +280,32 @@ public class BackupManager {
        }
    }

    /**
     * Convenience method for callers who need to indicate that some other package or
     * some other user needs a backup pass. This can be useful in the case of groups of
     * packages that share a uid and/or have user-specific data.
     * <p>
     * This method requires that the application hold the "android.permission.BACKUP"
     * permission if the package named in the package argument does not run under the
     * same uid as the caller. This method also requires that the application hold the
     * "android.permission.INTERACT_ACROSS_USERS_FULL" if the user argument is not the
     * same as the user the caller is running under.
     * @param userId The user to back up
     * @param packageName The package name identifying the application to back up.
     *
     * @hide
     */
    public static void dataChangedForUser(int userId, String packageName) {
        checkServiceBinder();
        if (sService != null) {
            try {
                sService.dataChangedForUser(userId, packageName);
            } catch (RemoteException e) {
                Log.e(TAG, "dataChanged(userId,pkg) couldn't connect");
            }
        }
    }

    /**
     * @deprecated Applications shouldn't request a restore operation using this method. In Android
     * P and later, this method is a no-op.
+44 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.util.ArrayMap;
import android.util.Log;
import android.view.View;
import android.view.autofill.AutofillId;
import android.widget.TextView;

import com.android.internal.annotations.GuardedBy;

@@ -42,11 +43,50 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

// TODO(b/178044703): Describe what UI Translation is.
/**
 * The {@link UiTranslationManager} class provides ways for apps to use the ui translation
 * <p>The {@link UiTranslationManager} class provides ways for apps to use the ui translation
 * function in framework.
 *
 * <p> The UI translation provides ways for apps to support inline translation for the views. For
 * example the system supports text translation for {@link TextView}. To support UI translation for
 * your views, you should override the following methods to provide the content to be translated
 * and deal with the translated result. Here is an example for {@link TextView}-like views:
 *
 * <pre><code>
 * public class MyTextView extends View {
 *     public MyTextView(...) {
 *         // implements how to show the translated result in your View in
 *         // ViewTranslationCallback and set it by setViewTranslationCallback()
 *         setViewTranslationCallback(new MyViewTranslationCallback());
 *     }
 *
 *     public void onCreateViewTranslationRequest(int[] supportedFormats,
 *             Consumer<ViewTranslationRequest> requestsCollector) {
 *        // collect the information that needs to be translated
 *        ViewTranslationRequest.Builder requestBuilder =
 *                     new ViewTranslationRequest.Builder(getAutofillId());
 *        requestBuilder.setValue(ViewTranslationRequest.ID_TEXT,
 *                         TranslationRequestValue.forText(etText()));
 *        requestsCollector.accept(requestBuilder.build());
 *     }
 *
 *     public void onProvideContentCaptureStructure(
 *             ViewStructure structure, int flags) {
 *         // set ViewTranslationResponse
 *         super.onViewTranslationResponse(response);
 *     }
 * }
 * </code></pre>
 *
 * <p>If your view provides its own virtual hierarchy (for example, if it's a browser that draws the
 * HTML using {@link android.graphics.Canvas} or native libraries in a different render process),
 * you must override {@link View#onCreateVirtualViewTranslationRequests(long[], int[], Consumer)} to
 * provide the content to be translated and implement
 * {@link View#onVirtualViewTranslationResponses(android.util.LongSparseArray)} for the translated
 * result. You also need to implement {@link android.view.translation.ViewTranslationCallback} to
 * handle the translated information show or hide in your {@link View}.
 */
public final class UiTranslationManager {

@@ -248,14 +288,14 @@ public final class UiTranslationManager {
        }
    }

    // TODO(b/178044703): Fix the View API link when it becomes public.
    /**
     * Register for notifications of UI Translation state changes on the foreground activity. This
     * is available to the owning application itself and also the current input method.
     * <p>
     * The application whose UI is being translated can use this to customize the UI Translation
     * behavior in ways that aren't made easy by methods like
     * View#onCreateTranslationRequest().
     * {@link View#onCreateViewTranslationRequest(int[], Consumer)}.
     *
     * <p>
     * Input methods can use this to offer complementary features to UI Translation; for example,
     * enabling outgoing message translation when the system is translating incoming messages in a
Loading