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

Commit dc4633ec authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Revert "OMS: add tests for the OMS transactional API"" am: 78a3fdfb...

Merge "Revert "OMS: add tests for the OMS transactional API"" am: 78a3fdfb am: 55e40879 am: 77c94b84

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1548439

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I6aa33aa183bb845497b33922b13a4be25d7592b3
parents ee771f2d 77c94b84
Loading
Loading
Loading
Loading
+31 −47
Original line number Diff line number Diff line
@@ -18,76 +18,60 @@ package com.android.overlaytest;

import static java.util.concurrent.TimeUnit.SECONDS;

import android.annotation.NonNull;
import android.content.Context;
import android.content.om.OverlayManager;
import android.content.om.OverlayManagerTransaction;
import android.os.UserHandle;
import android.app.UiAutomation;
import android.content.res.Resources;
import android.os.ParcelFileDescriptor;

import androidx.test.InstrumentationRegistry;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;

class LocalOverlayManager {
    private static final long TIMEOUT = 30;

    public static void toggleOverlaysAndWait(@NonNull final String[] overlaysToEnable,
            @NonNull final String[] overlaysToDisable) throws Exception {
        final int userId = UserHandle.myUserId();
        OverlayManagerTransaction.Builder builder = new OverlayManagerTransaction.Builder();
        for (String pkg : overlaysToEnable) {
            builder.setEnabled(pkg, true, userId);
    public static void setEnabledAndWait(Executor executor, final String packageName,
            boolean enable) throws Exception {
        final String pattern = (enable ? "[x]" : "[ ]") + " " + packageName;
        if (executeShellCommand("cmd overlay list").contains(pattern)) {
            // nothing to do, overlay already in the requested state
            return;
        }
        for (String pkg : overlaysToDisable) {
            builder.setEnabled(pkg, false, userId);
        }
        OverlayManagerTransaction transaction = builder.build();

        final Context ctx = InstrumentationRegistry.getTargetContext();
        final Resources res = InstrumentationRegistry.getContext().getResources();
        final String[] oldApkPaths = res.getAssets().getApkPaths();
        FutureTask<Boolean> task = new FutureTask<>(() -> {
            while (true) {
                final String[] paths = ctx.getResources().getAssets().getApkPaths();
                if (arrayTailContains(paths, overlaysToEnable)
                        && arrayDoesNotContain(paths, overlaysToDisable)) {
                if (!Arrays.equals(oldApkPaths, res.getAssets().getApkPaths())) {
                    return true;
                }
                Thread.sleep(10);
            }
        });

        OverlayManager om = ctx.getSystemService(OverlayManager.class);
        om.commit(transaction);

        Executor executor = (cmd) -> new Thread(cmd).start();
        executor.execute(task);
        executeShellCommand("cmd overlay " + (enable ? "enable " : "disable ") + packageName);
        task.get(TIMEOUT, SECONDS);
    }

    private static boolean arrayTailContains(@NonNull final String[] array,
            @NonNull final String[] substrings) {
        if (array.length < substrings.length) {
            return false;
    private static String executeShellCommand(final String command)
            throws Exception {
        final UiAutomation uiAutomation =
                InstrumentationRegistry.getInstrumentation().getUiAutomation();
        final ParcelFileDescriptor pfd = uiAutomation.executeShellCommand(command);
        try (InputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
            final BufferedReader reader = new BufferedReader(
                    new InputStreamReader(in, StandardCharsets.UTF_8));
            StringBuilder str = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                str.append(line);
            }
        for (int i = 0; i < substrings.length; i++) {
            String a = array[array.length - substrings.length + i];
            String s = substrings[i];
            if (!a.contains(s)) {
                return false;
            }
        }
        return true;
            return str.toString();
        }

    private static boolean arrayDoesNotContain(@NonNull final String[] array,
            @NonNull final String[] substrings) {
        for (String s : substrings) {
            for (String a : array) {
                if (a.contains(s)) {
                    return false;
                }
            }
        }
        return true;
    }
}
+0 −133
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 com.android.overlaytest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.testng.Assert.assertThrows;

import android.content.Context;
import android.content.om.OverlayInfo;
import android.content.om.OverlayManager;
import android.content.om.OverlayManagerTransaction;
import android.content.res.Resources;
import android.os.UserHandle;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.List;

@RunWith(JUnit4.class)
@MediumTest
public class TransactionTest {
    static final String APP_OVERLAY_ONE_PKG = "com.android.overlaytest.app_overlay_one";
    static final String APP_OVERLAY_TWO_PKG = "com.android.overlaytest.app_overlay_two";

    private Context mContext;
    private Resources mResources;
    private OverlayManager mOverlayManager;
    private int mUserId;
    private UserHandle mUserHandle;

    @Before
    public void setUp() throws Exception {
        mContext = InstrumentationRegistry.getContext();
        mResources = mContext.getResources();
        mOverlayManager = mContext.getSystemService(OverlayManager.class);
        mUserId = UserHandle.myUserId();
        mUserHandle = UserHandle.of(mUserId);

        LocalOverlayManager.toggleOverlaysAndWait(
                new String[]{},
                new String[]{APP_OVERLAY_ONE_PKG, APP_OVERLAY_TWO_PKG});
    }

    @Test
    public void testValidTransaction() throws Exception {
        assertOverlayIsEnabled(APP_OVERLAY_ONE_PKG, false, mUserId);
        assertOverlayIsEnabled(APP_OVERLAY_TWO_PKG, false, mUserId);

        OverlayManagerTransaction t = new OverlayManagerTransaction.Builder()
                .setEnabled(APP_OVERLAY_ONE_PKG, true)
                .setEnabled(APP_OVERLAY_TWO_PKG, true)
                .build();
        mOverlayManager.commit(t);

        assertOverlayIsEnabled(APP_OVERLAY_ONE_PKG, true, mUserId);
        assertOverlayIsEnabled(APP_OVERLAY_TWO_PKG, true, mUserId);
        List<OverlayInfo> ois =
                mOverlayManager.getOverlayInfosForTarget("com.android.overlaytest", mUserHandle);
        assertEquals(ois.size(), 2);
        assertEquals(ois.get(0).packageName, APP_OVERLAY_ONE_PKG);
        assertEquals(ois.get(1).packageName, APP_OVERLAY_TWO_PKG);

        OverlayManagerTransaction t2 = new OverlayManagerTransaction.Builder()
                .setEnabled(APP_OVERLAY_TWO_PKG, true)
                .setEnabled(APP_OVERLAY_ONE_PKG, true)
                .build();
        mOverlayManager.commit(t2);

        assertOverlayIsEnabled(APP_OVERLAY_ONE_PKG, true, mUserId);
        assertOverlayIsEnabled(APP_OVERLAY_TWO_PKG, true, mUserId);
        List<OverlayInfo> ois2 =
                mOverlayManager.getOverlayInfosForTarget("com.android.overlaytest", mUserHandle);
        assertEquals(ois2.size(), 2);
        assertEquals(ois2.get(0).packageName, APP_OVERLAY_TWO_PKG);
        assertEquals(ois2.get(1).packageName, APP_OVERLAY_ONE_PKG);

        OverlayManagerTransaction t3 = new OverlayManagerTransaction.Builder()
                .setEnabled(APP_OVERLAY_TWO_PKG, false)
                .build();
        mOverlayManager.commit(t3);

        assertOverlayIsEnabled(APP_OVERLAY_ONE_PKG, true, mUserId);
        assertOverlayIsEnabled(APP_OVERLAY_TWO_PKG, false, mUserId);
        List<OverlayInfo> ois3 =
                mOverlayManager.getOverlayInfosForTarget("com.android.overlaytest", mUserHandle);
        assertEquals(ois3.size(), 2);
        assertEquals(ois3.get(0).packageName, APP_OVERLAY_TWO_PKG);
        assertEquals(ois3.get(1).packageName, APP_OVERLAY_ONE_PKG);
    }

    @Test
    public void testInvalidRequestHasNoEffect() {
        assertOverlayIsEnabled(APP_OVERLAY_ONE_PKG, false, mUserId);
        assertOverlayIsEnabled(APP_OVERLAY_TWO_PKG, false, mUserId);

        OverlayManagerTransaction t = new OverlayManagerTransaction.Builder()
                .setEnabled(APP_OVERLAY_ONE_PKG, true)
                .setEnabled("does-not-exist", true)
                .setEnabled(APP_OVERLAY_TWO_PKG, true)
                .build();
        assertThrows(SecurityException.class, () -> mOverlayManager.commit(t));

        assertOverlayIsEnabled(APP_OVERLAY_ONE_PKG, false, mUserId);
        assertOverlayIsEnabled(APP_OVERLAY_TWO_PKG, false, mUserId);
    }

    private void assertOverlayIsEnabled(final String packageName, boolean enabled, int userId) {
        final OverlayInfo oi = mOverlayManager.getOverlayInfo(packageName, UserHandle.of(userId));
        assertNotNull(oi);
        assertEquals(oi.isEnabled(), enabled);
    }
}
+6 −3
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.concurrent.Executor;

@RunWith(JUnit4.class)
@MediumTest
public class WithMultipleOverlaysTest extends OverlayBaseTest {
@@ -31,8 +33,9 @@ public class WithMultipleOverlaysTest extends OverlayBaseTest {

    @BeforeClass
    public static void enableOverlay() throws Exception {
        LocalOverlayManager.toggleOverlaysAndWait(
                new String[]{FRAMEWORK_OVERLAY_PKG, APP_OVERLAY_ONE_PKG, APP_OVERLAY_TWO_PKG},
                new String[]{});
        Executor executor = (cmd) -> new Thread(cmd).start();
        LocalOverlayManager.setEnabledAndWait(executor, APP_OVERLAY_ONE_PKG, true);
        LocalOverlayManager.setEnabledAndWait(executor, APP_OVERLAY_TWO_PKG, true);
        LocalOverlayManager.setEnabledAndWait(executor, FRAMEWORK_OVERLAY_PKG, true);
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.concurrent.Executor;

@RunWith(JUnit4.class)
@MediumTest
public class WithOverlayTest extends OverlayBaseTest {
@@ -30,9 +32,10 @@ public class WithOverlayTest extends OverlayBaseTest {
    }

    @BeforeClass
    public static void enableOverlays() throws Exception {
        LocalOverlayManager.toggleOverlaysAndWait(
                new String[]{FRAMEWORK_OVERLAY_PKG, APP_OVERLAY_ONE_PKG},
                new String[]{APP_OVERLAY_TWO_PKG});
    public static void enableOverlay() throws Exception {
        Executor executor = (cmd) -> new Thread(cmd).start();
        LocalOverlayManager.setEnabledAndWait(executor, APP_OVERLAY_ONE_PKG, true);
        LocalOverlayManager.setEnabledAndWait(executor, APP_OVERLAY_TWO_PKG, false);
        LocalOverlayManager.setEnabledAndWait(executor, FRAMEWORK_OVERLAY_PKG, true);
    }
}
+6 −3
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.concurrent.Executor;

@RunWith(JUnit4.class)
@MediumTest
public class WithoutOverlayTest extends OverlayBaseTest {
@@ -31,8 +33,9 @@ public class WithoutOverlayTest extends OverlayBaseTest {

    @BeforeClass
    public static void disableOverlays() throws Exception {
        LocalOverlayManager.toggleOverlaysAndWait(
                new String[]{},
                new String[]{FRAMEWORK_OVERLAY_PKG, APP_OVERLAY_ONE_PKG, APP_OVERLAY_TWO_PKG});
        Executor executor = (cmd) -> new Thread(cmd).start();
        LocalOverlayManager.setEnabledAndWait(executor, APP_OVERLAY_ONE_PKG, false);
        LocalOverlayManager.setEnabledAndWait(executor, APP_OVERLAY_TWO_PKG, false);
        LocalOverlayManager.setEnabledAndWait(executor, FRAMEWORK_OVERLAY_PKG, false);
    }
}