Add scaffolds for performance tests of DocumentsUI

Bug: 27370274
Change-Id: I14dea1b85cd84c8bb3c0eee27b2954108bfa4f8b
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 46cbbdf..699700b 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -39,6 +39,7 @@
 import android.support.annotation.CallSuper;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.Menu;
@@ -67,6 +68,7 @@
     SearchViewManager mSearchManager;
     DrawerController mDrawer;
     NavigationView mNavigator;
+    List<EventListener> mEventListeners = new ArrayList<>();
 
     private final String mTag;
 
@@ -329,6 +331,8 @@
     void openContainerDocument(DocumentInfo doc) {
         assert(doc.isContainer());
 
+        notifyDirectoryNavigated(doc.derivedUri);
+
         mState.pushDocument(doc);
         // Show an opening animation only if pressing "back" would get us back to the
         // previous directory. Especially after opening a root document, pressing
@@ -594,6 +598,28 @@
         return super.onKeyDown(keyCode, event);
     }
 
+    @VisibleForTesting
+    public void addEventListener(EventListener listener) {
+        mEventListeners.add(listener);
+    }
+
+    @VisibleForTesting
+    public void removeEventListener(EventListener listener) {
+        mEventListeners.remove(listener);
+    }
+
+    public void notifyDirectoryLoaded(Uri uri) {
+        for (EventListener listener : mEventListeners) {
+            listener.onDirectoryLoaded(uri);
+        }
+    }
+
+    void notifyDirectoryNavigated(Uri uri) {
+        for (EventListener listener : mEventListeners) {
+            listener.onDirectoryNavigated(uri);
+        }
+    }
+
     /**
      * Toggles focus between the navigation drawer and the directory listing. If the drawer isn't
      * locked, open/close it as appropriate.
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 13b7b14..d2e918c 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -59,7 +59,6 @@
     private CancellationSignal mSignal;
     private DirectoryResult mResult;
 
-
     public DirectoryLoader(Context context, int type, RootInfo root, DocumentInfo doc, Uri uri,
             int userSortOrder, boolean inSearchMode) {
         super(context, ProviderExecutor.forAuthority(root.authority));
@@ -84,6 +83,7 @@
         final String authority = mUri.getAuthority();
 
         final DirectoryResult result = new DirectoryResult();
+        result.doc = mDoc;
 
         // Use default document when searching
         if (mSearchMode) {
diff --git a/src/com/android/documentsui/DirectoryResult.java b/src/com/android/documentsui/DirectoryResult.java
index 22e438a..6268643 100644
--- a/src/com/android/documentsui/DirectoryResult.java
+++ b/src/com/android/documentsui/DirectoryResult.java
@@ -22,12 +22,15 @@
 import android.content.ContentProviderClient;
 import android.database.Cursor;
 
+import com.android.documentsui.model.DocumentInfo;
+
 import libcore.io.IoUtils;
 
 public class DirectoryResult implements AutoCloseable {
     ContentProviderClient client;
     public Cursor cursor;
     public Exception exception;
+    public DocumentInfo doc;
 
     public int sortOrder = SORT_ORDER_UNKNOWN;
 
diff --git a/src/com/android/documentsui/EventListener.java b/src/com/android/documentsui/EventListener.java
new file mode 100644
index 0000000..c15e9a6
--- /dev/null
+++ b/src/com/android/documentsui/EventListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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;
+
+import android.net.Uri;
+import android.support.annotation.Nullable;
+
+public interface EventListener {
+    /**
+     * @param uri Uri navigated to. If recents, then null.
+     */
+    void onDirectoryNavigated(@Nullable Uri uri);
+
+    /**
+     * @param uri Uri of the loaded directory. If recents, then null.
+     */
+    void onDirectoryLoaded(@Nullable Uri uri);
+}
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index dfceff8..1348a58 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1290,6 +1290,11 @@
                 showDirectory();
                 mAdapter.notifyDataSetChanged();
             }
+
+            if (!model.isLoading()) {
+                ((BaseActivity) getActivity()).notifyDirectoryLoaded(
+                    model.doc != null ? model.doc.derivedUri : null);
+            }
         }
 
         @Override
diff --git a/src/com/android/documentsui/dirlist/Model.java b/src/com/android/documentsui/dirlist/Model.java
index 5e55e1a..8170e2a 100644
--- a/src/com/android/documentsui/dirlist/Model.java
+++ b/src/com/android/documentsui/dirlist/Model.java
@@ -64,6 +64,7 @@
 
     @Nullable String info;
     @Nullable String error;
+    @Nullable DocumentInfo doc;
 
     /**
      * Generates a Model ID for a cursor entry that refers to a document. The Model ID is a unique
@@ -111,6 +112,7 @@
             mPositions.clear();
             info = null;
             error = null;
+            doc = null;
             mIsLoading = false;
             notifyUpdateListeners();
             return;
@@ -125,6 +127,7 @@
         mCursor = result.cursor;
         mCursorCount = mCursor.getCount();
         mSortOrder = result.sortOrder;
+        doc = result.doc;
 
         updateModelData();