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

Commit c9dc6d4d authored by Jun Ono's avatar Jun Ono Committed by android-build-merger
Browse files

Add test for file copy operation between Internal and External storage

am: 6b69cbb2

Change-Id: Ia60cd1da52dc7846507c1b32a2f40354510f974b
parents 92a58181 6b69cbb2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2,6 +2,11 @@ Welcome to our tests!

unit tests are under the 'unit/' dir, function under 'functional/'.

Some of the test cases in functional/ check the file operation among the different storage media.
Therefore, insert SD Card media to the test device when running this instrumentation test if the
device has SD Card slot. If SD Card is not inserted or supported, the test creates virtual SD Card
and uses it instead.

To run just small tests"
adb shell am instrument -w -e debug false -e log false -e timeout_msec 300000 -e size small com.android.documentsui.tests/android.support.test.runner.AndroidJUnitRunner

+20 −0
Original line number Diff line number Diff line
@@ -336,4 +336,24 @@ public class DocumentsProviderHelper {
    public void configure(String args, Bundle configuration) throws RemoteException {
        mClient.call("configure", args, configuration);
    }

    public List<RootInfo> getRootList() throws RemoteException {
        List<RootInfo> list = new ArrayList<>();
        final Uri rootsUri = DocumentsContract.buildRootsUri(mAuthority);
        Cursor cursor = null;
        try {
            cursor = mClient.query(rootsUri, null, null, null, null);
            while (cursor.moveToNext()) {
                RootInfo rootInfo = RootInfo.fromRootsCursor(mAuthority, cursor);
                if (rootInfo != null) {
                    list.add(rootInfo);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("Can't load rootInfo list", e);
        } finally {
            IoUtils.closeQuietly(cursor);
        }
        return list;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ public final class Bots {
    public final MenuBot menu;
    public final UiBot main;
    public final InspectorBot inspector;
    public final NotificationsBot notifications;

    public Bots(UiDevice device, UiAutomation automation, Context context, int timeout) {
        main = new UiBot(device, context, TIMEOUT);
@@ -57,6 +58,7 @@ public final class Bots {
        gesture = new GestureBot(device, automation, context, TIMEOUT);
        menu = new MenuBot(device, context, TIMEOUT);
        inspector = new InspectorBot(device, context, TIMEOUT);
        notifications = new NotificationsBot(device, context, TIMEOUT);
    }

    /**
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.documentsui.bots;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.text.TextUtils;
import android.view.KeyEvent;

/**
 * A test helper class for controlling notification items.
 */
public class NotificationsBot extends Bots.BaseBot {
    private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
    private static final String allow_res_name = "allow";
    private static final String turn_off_res_name = "notification_listener_disable_warning_confirm";

    public NotificationsBot(UiDevice device, Context context, int timeout) {
        super(device, context, timeout);
    }

    public void setNotificationAccess(Activity activity, String appName, boolean enabled)
            throws UiObjectNotFoundException, NameNotFoundException {
        Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
        activity.startActivity(intent);
        mDevice.waitForIdle();

        clickLabel(appName);

        Context settings_context = mContext.createPackageContext(SETTINGS_PACKAGE_NAME,
                Context.CONTEXT_RESTRICTED);
        String label_res_name = enabled ? allow_res_name : turn_off_res_name;
        int res_id = settings_context.getResources().getIdentifier(label_res_name,
                "string", SETTINGS_PACKAGE_NAME);

        clickLabel(settings_context.getResources().getString(res_id));
        mDevice.pressKeyCode(KeyEvent.KEYCODE_BACK);
        mDevice.waitForIdle();
    }

    public boolean isNotificationAccessEnabled(ContentResolver resolver, String pkgName) {
        String listeners = Settings.Secure.getString(resolver, "enabled_notification_listeners");
        if (!TextUtils.isEmpty(listeners)) {
            String[] list = listeners.split(":");
            for(String item : list) {
                if(item.startsWith(pkgName)) {
                    return true;
                }
            }
        }
        return false;
    }

    private void clickLabel(String label) throws UiObjectNotFoundException {
        UiSelector selector = new UiSelector().textMatches("(?i)" + label);
        mDevice.findObject(selector).click();
        mDevice.waitForIdle();
    }
}
+59 −21
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.content.pm.PackageManager.NameNotFoundException;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.view.View;
@@ -28,7 +29,7 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.RemoteViews;

import android.util.Log;

/**
* This class receives a callback when Notification is posted or removed
@@ -36,6 +37,8 @@ import android.widget.RemoteViews;
* And, this sends the operation's result by Broadcast.
*/
public class TestNotificationService extends NotificationListenerService {
    private static final String TAG = "TestNotificationService";

    public static final String ACTION_CHANGE_CANCEL_MODE =
            "com.android.documentsui.services.TestNotificationService.ACTION_CHANGE_CANCEL_MODE";

@@ -45,27 +48,45 @@ public class TestNotificationService extends NotificationListenerService {
    public static final String ACTION_OPERATION_RESULT =
            "com.android.documentsui.services.TestNotificationService.ACTION_OPERATION_RESULT";

    public static final String ACTION_DISPLAY_SD_CARD_NOTIFICATION =
            "com.android.documentsui.services.TestNotificationService.ACTION_DISPLAY_SD_CARD_NOTIFICATION";

    public static final String ACTION_SD_CARD_SETTING_COMPLETED =
            "com.android.documentsui.services.TestNotificationService.ACTION_SD_CARD_SETTING_COMPLETED";

    public static final String ANDROID_PACKAGENAME = "android";

    public static final String CANCEL_RES_NAME = "cancel";

    public static final String EXTRA_RESULT =
            "com.android.documentsui.services.TestNotificationService.EXTRA_RESULT";

    public static final String EXTRA_ERROR_REASON =
            "com.android.documentsui.services.TestNotificationService.EXTRA_ERROR_REASON";

    public static final String UNSUPPORTED_NOTIFICATION_TEXT = "Issue with Virtual SD card";

    public static final String CORRUPTED_NOTIFICATION_TEXT = "Corrupted Virtual SD card";

    public static final String VIRTUAL_SD_CARD_TEXT = "Virtual SD card";

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

    private final static String SD_CARD_NOTIFICATION_PACKAGE = "com.android.systemui";

    public enum MODE {
        CANCEL_MODE,
        EXECUTION_MODE;
    }

    private String DOCUMENTSUI= "com.android.documentsui";
    private MODE mCurrentMode = MODE.CANCEL_MODE;

    private boolean mCancelled = false;

    private FrameLayout mFrameLayout = null;

    private ProgressBar mProgressBar = null;

    private MODE mCurrentMode = MODE.CANCEL_MODE;

    private boolean mCancelled = false;

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -103,19 +124,23 @@ public class TestNotificationService extends NotificationListenerService {
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        String pkgName = sbn.getPackageName();
        if (!pkgName.equals(DOCUMENTSUI)) {
            return;
        }

        if (SD_CARD_NOTIFICATION_PACKAGE.equals(pkgName)) {
            sendBroadcastForVirtualSdCard(sbn.getNotification());
        } else if (DOCUMENTSUI_PACKAGE.equals(pkgName)) {
            if (MODE.CANCEL_MODE.equals(mCurrentMode)) {
                try {
                    mCancelled = doCancel(sbn.getNotification());
                } catch (Exception e) {
                    Log.d(TAG, "Error occurs when cancel notification.", e);
                }
            }
        }
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        String pkgName = sbn.getPackageName();
        if (!pkgName.equals(DOCUMENTSUI)) {
        if (!DOCUMENTSUI_PACKAGE.equals(pkgName)) {
            return;
        }

@@ -135,7 +160,18 @@ public class TestNotificationService extends NotificationListenerService {
        sendBroadcast(intent);
    }

    private boolean doCancel(Notification noti) {
    private void sendBroadcastForVirtualSdCard(Notification notification) {
        String title = notification.extras.getString(Notification.EXTRA_TITLE);
        if (UNSUPPORTED_NOTIFICATION_TEXT.equals(title) ||
                CORRUPTED_NOTIFICATION_TEXT.equals(title)) {
            sendBroadcast(new Intent(ACTION_DISPLAY_SD_CARD_NOTIFICATION));
        } else if (VIRTUAL_SD_CARD_TEXT.equals(title)) {
            sendBroadcast(new Intent(ACTION_SD_CARD_SETTING_COMPLETED));
        }
    }

    private boolean doCancel(Notification noti)
            throws NameNotFoundException, PendingIntent.CanceledException {
        if (!isStartProgress(noti)) {
            return false;
        }
@@ -147,12 +183,15 @@ public class TestNotificationService extends NotificationListenerService {

        boolean result = false;
        for (Notification.Action item : aList) {
            if (item.title.equals("Cancel")) {
                try {
            Context android_context = getBaseContext().createPackageContext(ANDROID_PACKAGENAME,
                    Context.CONTEXT_RESTRICTED);
            int res_id = android_context.getResources().getIdentifier(CANCEL_RES_NAME,
                    "string", ANDROID_PACKAGENAME);
            final String cancel_label = android_context.getResources().getString(res_id);

            if (cancel_label.equals(item.title)) {
                item.actionIntent.send();
                result = true;
                } catch (PendingIntent.CanceledException e) {
                }
            }
        }
        return result;
@@ -208,4 +247,3 @@ public class TestNotificationService extends NotificationListenerService {
        return result;
    }
}
Loading