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

Commit c8087cb7 authored by Xin Li's avatar Xin Li
Browse files

Merge Android 14

Bug: 298295554
Merged-In: I0cc56908541e39295cf3ba7d9143c7e207562889
Change-Id: I33d5380115a593f03a426117f676f80b5bb28ac2
parents 0bbbdf31 cec36187
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -53,11 +53,11 @@ java_defaults {
    certificate: "platform",

    optimize: {
        shrink_resources: true,
        proguard_flags_files: ["proguard.flags"],
    },

    sdk_version: "system_current",
    target_sdk_version: "30",
    min_sdk_version: "29",

    lint: { strict_updatability_linting: true }
@@ -111,7 +111,7 @@ android_library {
    ],

    sdk_version: "system_current",
    target_sdk_version: "30",
    target_sdk_version: "33",
    min_sdk_version: "29",
    lint: { strict_updatability_linting: true }
}
@@ -141,7 +141,7 @@ android_library {
    ],

    sdk_version: "system_current",
    target_sdk_version: "30",
    target_sdk_version: "33",
    min_sdk_version: "29",
    lint: { strict_updatability_linting: true }
}
@@ -168,8 +168,8 @@ android_app {

    required: ["privapp_whitelist_com.android.documentsui"],

    target_sdk_version: "30",
    min_sdk_version: "29",
    updatable: true,
    lint: { strict_updatability_linting: true }
}
+3 −1
Original line number Diff line number Diff line
@@ -19,11 +19,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.documentsui">

    <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="30"/>
    <uses-sdk android:minSdkVersion="29"/>

    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <uses-permission android:name="android.permission.REMOVE_TASKS" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CACHE_CONTENT" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -201,6 +202,7 @@
        <service
            android:name=".services.FileOperationService"
            android:exported="false"
            android:foregroundServiceType="dataSync"
            android:process=":com.android.documentsui.services">
        </service>

+0 −6
Original line number Diff line number Diff line
@@ -7,11 +7,5 @@
    {
      "name": "DocumentsUIUnitTests"
    }
  ],
  "postsubmit": [
    {
      "name": "DocumentsUIGoogleTests",
      "keywords": ["primary-device"]
    }
  ]
}
+2 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.documentsui.appperftests">

    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
    <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />

    <application>
+81 −57
Original line number Diff line number Diff line
@@ -16,31 +16,35 @@

package com.android.documentsui;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import static org.junit.Assume.assumeNotNull;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.DocumentsContract;
import android.support.test.uiautomator.UiDevice;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import android.util.Log;

import org.junit.BeforeClass;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;

@RunWith(AndroidJUnit4.class)
public class FilesAppPerfTest {
    private static final String TAG = "FilesAppPerfTest";

    // Keys used to report metrics to APCT.
    private static final String KEY_FILES_COLD_START_PERFORMANCE_MEDIAN =
@@ -48,16 +52,31 @@ public class FilesAppPerfTest {
    private static final String KEY_FILES_WARM_START_PERFORMANCE_MEDIAN =
            "files-warm-start-performance-median";

    private static final String TARGET_PACKAGE = "com.android.documentsui";

    private static final int NUM_MEASUREMENTS = 10;
    private static final long REMOVAL_TIMEOUT_MS = 3000;
    private static final long TIMEOUT_INTERVAL_MS = 200;

    private Instrumentation mInstrumentation;
    private Context mContext;
    private LauncherActivity mLauncherActivity;
    private ActivityInfo mDocumentsUiActivityInfo;

    @Before
    public void setUp() {
        mInstrumentation = getInstrumentation();
        mContext = mInstrumentation.getContext();
        final ResolveInfo info = mContext.getPackageManager().resolveActivity(
                LauncherActivity.OPEN_DOCUMENT_INTENT, PackageManager.ResolveInfoFlags.of(0));
        assumeNotNull(info);
        mDocumentsUiActivityInfo = info.activityInfo;
        mLauncherActivity = (LauncherActivity) mInstrumentation.startActivitySync(
                new Intent(mContext, LauncherActivity.class).addFlags(
                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION));
    }

    private LauncherActivity mActivity;
    private static UiDevice mDevice;

    @BeforeClass
    public static void setUp() {
        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    @After
    public void tearDown() {
        mLauncherActivity.finishAndRemoveTask();
    }

    @Test
@@ -71,22 +90,31 @@ public class FilesAppPerfTest {
    }

    public void runFilesStartPerformanceTest(boolean cold) throws Exception {
        final String documentsUiPackageName = mDocumentsUiActivityInfo.packageName;
        String[] providerPackageNames = null;
        if (cold) {
            providerPackageNames = getDocumentsProviderPackageNames();
        }
        final ActivityManager am = mContext.getSystemService(ActivityManager.class);
        long[] measurements = new long[NUM_MEASUREMENTS];
        for (int i = 0; i < NUM_MEASUREMENTS; i++) {
            if (cold) {
                // Kill all providers, as well as DocumentsUI to measure a cold start.
                killProviders();
                mDevice.executeShellCommand("am force-stop " + TARGET_PACKAGE);
                for (String pkgName : providerPackageNames) {
                    // Use kill-bg to avoid affecting other important services.
                    Log.i(TAG, "killBackgroundProcesses " + pkgName);
                    am.killBackgroundProcesses(pkgName);
                }
                Log.i(TAG, "forceStopPackage " + documentsUiPackageName);
                am.forceStopPackage(documentsUiPackageName);
                // Wait for any closing animations to finish.
                mInstrumentation.getUiAutomation().syncInputTransactions();
            }
            mDevice.waitForIdle();

            LauncherActivity.testCaseLatch = new CountDownLatch(1);
            mActivity = launchActivity(
                    InstrumentationRegistry.getInstrumentation().getTargetContext()
                            .getPackageName(),
                    LauncherActivity.class, null);
            LauncherActivity.testCaseLatch.await();
            measurements[i] = LauncherActivity.measurement;
            measurements[i] = mLauncherActivity.startAndWaitDocumentsUi();
            // The DocumentUi will finish automatically according to the request code for testing,
            // so wait until it is completely removed to avoid affecting next iteration.
            waitUntilDocumentsUiActivityRemoved();
        }

        reportMetrics(cold ? KEY_FILES_COLD_START_PERFORMANCE_MEDIAN
@@ -99,41 +127,37 @@ public class FilesAppPerfTest {
        final long median = measurements[NUM_MEASUREMENTS / 2 - 1];
        status.putDouble(key + "(ms)", median);

        InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status);
        mInstrumentation.sendStatus(Activity.RESULT_OK, status);
    }

    private void killProviders() throws Exception {
        final Context context = InstrumentationRegistry.getInstrumentation().getContext();
        final PackageManager pm = context.getPackageManager();
        final ActivityManager am = (ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE);
    private String[] getDocumentsProviderPackageNames() {
        final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE);
        final List<ResolveInfo> providers = pm.queryIntentContentProviders(intent, 0);
        for (ResolveInfo info : providers) {
            final String packageName = info.providerInfo.packageName;
            am.killBackgroundProcesses(packageName);
        final List<ResolveInfo> providers = mContext.getPackageManager()
                .queryIntentContentProviders(intent, PackageManager.ResolveInfoFlags.of(0));
        final String[] pkgNames = new String[providers.size()];
        for (int i = 0; i < providers.size(); i++) {
            pkgNames[i] = providers.get(i).providerInfo.packageName;
        }
        return pkgNames;
    }

    private final <T extends Activity> T launchActivity(
            String pkg,
            Class<T> activityCls,
            Bundle extras) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        if (extras != null) {
            intent.putExtras(extras);
    private void waitUntilDocumentsUiActivityRemoved() {
        final UiDevice uiDevice = UiDevice.getInstance(mInstrumentation);
        final String classPattern = new ComponentName(mDocumentsUiActivityInfo.packageName,
                mDocumentsUiActivityInfo.name).flattenToShortString();
        final long startTime = SystemClock.uptimeMillis();
        while (SystemClock.uptimeMillis() - startTime <= REMOVAL_TIMEOUT_MS) {
            SystemClock.sleep(TIMEOUT_INTERVAL_MS);
            final String windowTokenDump;
            try {
                windowTokenDump = uiDevice.executeShellCommand("dumpsys window tokens");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        return launchActivityWithIntent(pkg, activityCls, intent);
            if (!windowTokenDump.contains(classPattern)) {
                return;
            }

    private final <T extends Activity> T launchActivityWithIntent(
            String pkg,
            Class<T> activityCls,
            Intent intent) {
        intent.setClassName(pkg, activityCls.getName());
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        T activity = (T) InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        return activity;
        }
        Log.i(TAG, "Removal timeout of " + classPattern);
    }
}
Loading