aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorherriojr <jherriott@cyngn.com>2015-08-14 15:51:40 -0700
committerSteve Kondik <steve@cyngn.com>2016-11-02 21:45:25 -0700
commit018c616026bea96595031c0e61fd773a46f7a9b6 (patch)
treefb07f381c20a708dbf8d1f0a7a164e2b3fb830df
parent2d2e49c3e4a434c115d7cb1dd99d9f522ae2bece (diff)
downloadandroid_packages_apps_CMFileManager-018c616026bea96595031c0e61fd773a46f7a9b6.tar.gz
android_packages_apps_CMFileManager-018c616026bea96595031c0e61fd773a46f7a9b6.tar.bz2
android_packages_apps_CMFileManager-018c616026bea96595031c0e61fd773a46f7a9b6.zip
Added in the MFU Screen and data layer.
This implementation includes the MFU for keeping track of the top 5 most frequently accessed files. It is implemented in such a way that we can easily change algorithms if need be. Change-Id: Ib9b068deb5ac66f4cff99128396318133d4729c0 Ticket: CLOUD-48
-rw-r--r--AndroidManifest.xml4
-rw-r--r--res/drawable/circle_large.xml25
-rw-r--r--res/drawable/ic_frequent_placeholder.xml26
-rw-r--r--res/layout/home_fragment.xml24
-rw-r--r--res/layout/mstaru_list.xml78
-rw-r--r--res/layout/mstaru_row.xml50
-rw-r--r--res/layout/navigation.xml3
-rw-r--r--res/values/colors.xml12
-rw-r--r--res/values/ids.xml2
-rw-r--r--res/values/strings.xml8
-rw-r--r--src/com/cyanogenmod/filemanager/FileManagerApplication.java8
-rwxr-xr-xsrc/com/cyanogenmod/filemanager/activities/MainActivity.java67
-rw-r--r--src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java8
-rw-r--r--src/com/cyanogenmod/filemanager/controllers/MStarUController.java129
-rw-r--r--src/com/cyanogenmod/filemanager/mstaru/IMostStarUsedFilesManager.java82
-rw-r--r--src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedContract.java42
-rw-r--r--src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedManager.java287
-rw-r--r--src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedProvider.java320
-rw-r--r--src/com/cyanogenmod/filemanager/service/MoveFileService.java3
-rw-r--r--src/com/cyanogenmod/filemanager/ui/IconHolder.java134
-rw-r--r--src/com/cyanogenmod/filemanager/ui/IconRenderer.java115
-rw-r--r--src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java4
-rwxr-xr-xsrc/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java7
-rw-r--r--src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java14
24 files changed, 1358 insertions, 94 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 57a81b06..e0b04339 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -76,6 +76,10 @@
android:authorities="com.cyanogenmod.filemanager.providers.index"
android:name=".providers.MimeTypeIndexProvider"/>
+ <provider android:name=".mstaru.MostFrequentlyUsedProvider"
+ android:authorities="com.cyanogenmod.filemanager.mfu"
+ android:exported="false"/>
+
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.cyanogenmod.filemanager.providers.file"
diff --git a/res/drawable/circle_large.xml b/res/drawable/circle_large.xml
new file mode 100644
index 00000000..14b6e087
--- /dev/null
+++ b/res/drawable/circle_large.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 The CyanogenMod 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+
+ <solid android:color="@color/white"/>
+
+ <size android:width="120dp"
+ android:height="120dp"/>
+</shape> \ No newline at end of file
diff --git a/res/drawable/ic_frequent_placeholder.xml b/res/drawable/ic_frequent_placeholder.xml
new file mode 100644
index 00000000..521e624a
--- /dev/null
+++ b/res/drawable/ic_frequent_placeholder.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 The CyanogenMod 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z" />
+</vector> \ No newline at end of file
diff --git a/res/layout/home_fragment.xml b/res/layout/home_fragment.xml
index 2dc24c03..c7d687fd 100644
--- a/res/layout/home_fragment.xml
+++ b/res/layout/home_fragment.xml
@@ -71,19 +71,23 @@
android:gravity="center" />
<!-- A CardView that contains a TextView -->
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="15dp"
+ android:background="@color/black_11"/>
+
+ <include layout="@layout/mstaru_list" />
+
<android.support.v7.widget.CardView
android:id="@+id/card_view3"
android:layout_gravity="center"
- android:layout_width="200dp"
- android:layout_height="200dp"
- card_view:cardCornerRadius="4dp">
-
- <TextView
- android:id="@+id/info_text2"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- </android.support.v7.widget.CardView>
+ android:layout_width="match_parent"
+ android:layout_height="192dp"
+ android:layout_margin="8dp"
+ android:visibility="gone"
+ card_view:cardCornerRadius="4dp" />
</LinearLayout>
diff --git a/res/layout/mstaru_list.xml b/res/layout/mstaru_list.xml
new file mode 100644
index 00000000..d4b870f6
--- /dev/null
+++ b/res/layout/mstaru_list.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The CyanogenMod 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.
+-->
+
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/mstaru"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="16dp"
+ android:layout_marginTop="15dp"
+ android:layout_marginBottom="17dp"
+ android:textColor="@color/black_46"
+ android:textSize="14sp"
+ android:text="@string/frequent" />
+
+ <LinearLayout android:id="@+id/mstaru_list"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone">
+
+ <include layout="@layout/mstaru_row" />
+
+ <include layout="@layout/mstaru_row" />
+
+ <include layout="@layout/mstaru_row" />
+
+ <include layout="@layout/mstaru_row" />
+
+ <include layout="@layout/mstaru_row" />
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/mstaru_empty"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="49dp"
+ android:layout_marginBottom="61dp"
+ android:visibility="visible">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:background="@drawable/circle_large"
+ android:src="@drawable/ic_frequent_placeholder"
+ android:tint="@color/black_26"
+ android:backgroundTint="@color/off_white"
+ android:scaleType="center"/>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="19dp"
+ android:textColor="@color/black_26"
+ android:text="@string/access_the_files_you_use_the_most_here"/>
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/mstaru_row.xml b/res/layout/mstaru_row.xml
new file mode 100644
index 00000000..fde4e3d2
--- /dev/null
+++ b/res/layout/mstaru_row.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/material_selector">
+
+ <ImageView android:id="@+id/file_image"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_margin="16dp"
+ android:scaleType="centerCrop"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@+id/file_image"
+ android:layout_toLeftOf="@+id/file_details"
+ android:layout_centerVertical="true">
+
+ <TextView android:id="@+id/file_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|center_vertical"
+ android:textColor="@color/mstaru_primary"
+ android:textSize="16sp"
+ android:singleLine="true"
+ android:ellipsize="end"/>
+
+ <TextView android:id="@+id/file_parent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|center_vertical"
+ android:textColor="@color/mstaru_secondary"
+ android:textSize="14sp"
+ android:singleLine="true"
+ android:ellipsize="middle"/>
+ </LinearLayout>
+
+ <ImageView android:id="@+id/file_details"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:padding="18dp"
+ android:src="@drawable/ic_details"/>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/res/layout/navigation.xml b/res/layout/navigation.xml
index 0f3a1162..bb2338de 100644
--- a/res/layout/navigation.xml
+++ b/res/layout/navigation.xml
@@ -19,7 +19,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@color/navigation_drawer_background">
<include layout="@layout/home_fragment"
android:fitsSystemWindows="false" />
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 592b5007..ef3ee9fb 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -32,6 +32,11 @@
<!-- The default navigation drawer primary color. Used for settings etc. -->
<color name="misc_primary">#ff000000</color>
+ <!-- A Primary color for MStarU -->
+ <color name="mstaru_primary">#de000000</color>
+ <!-- A Secondary color for MStarU -->
+ <color name="mstaru_secondary">#8b000000</color>
+
<!-- The apps category color -->
<color name="category_apps">#8bc34a</color>
<!-- The archives category color -->
@@ -56,8 +61,15 @@
<!-- The default dissabled background color -->
<color name="default_background_disabled">#f2f2f2</color>
+ <color name="white">#ffffff</color>
+
+ <color name="off_white">#efefef</color>
+
<!-- A black color with some transparency -->
<color name="black_transparent">#8a000000</color>
+ <color name="black_46">#75000000</color>
+ <color name="black_26">#42000000</color>
+ <color name="black_11">#1C000000</color>
<!-- Default navigation drawer colors -->
<color name="navigation_drawer_title_default">#df000000</color>
diff --git a/res/values/ids.xml b/res/values/ids.xml
index d9a77162..fc500be6 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -23,4 +23,6 @@
<item type="id" name="navigation_item_protected" />
<item type="id" name="navigation_item_manage" />
<item type="id" name="navigation_item_settings" />
+ <!-- A ViewHolder tag -->
+ <item type="id" name="tag_viewholder" />
</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 24d6b2f5..f44cba21 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -472,8 +472,11 @@
<string name="waiting_dialog_compressing_msg"><![CDATA[<b>File</b>]]> <xliff:g id="file">%1$s</xliff:g></string>
<!-- Waiting dialog - Initializing the dialog -->
<string name="waiting_dialog_analizing_msg"><![CDATA[<b>Analyzing\u2026</b>]]></string>
+ <!-- Waiting dialog - Opening Storage Provider file title -->
+ <string name="waiting_dialog_opening_storage_provider_title">Opening\u2026</string>
<!-- Waiting dialog - Opening Storage Provider file message -->
<string name="waiting_dialog_opening_storage_provider_message_2">Opening\u2026</string>
+ <string name="waiting_dialog_opening_storage_provider_message"><![CDATA[<b>Opening</b>]]> <xliff:g id="file">%1$s</xliff:g><![CDATA[<br/>]]> <![CDATA[<b>From</b>]]> <xliff:g id="name">%2$s</xliff:g></string>
<!-- Extracting - Success message -->
<string name="msgs_extracting_success">The extracting operation was completed successfully. The data was extracted to <xliff:g id="destination">%1$s</xliff:g>.</string>
<!-- Compressing - Success message -->
@@ -924,7 +927,7 @@
<string name="snackbar_unable_to_complete">Unable to complete action</string>
<string name="snackbar_retry">RETRY</string>
<string name="snackbar_upgrade">UPGRADE</string>
-
+
<!-- File System info -->
<string name="file_system_info_unavailable">Unable to fetch file system info for this path</string>
@@ -950,4 +953,7 @@
<string name="moving_file_failed_generic">Tap to retry</string>
<string name="moving_file_failed_retry_action">Retry</string>
<string name="moving_file_failed_upgrade_action">Upgrade</string>
+ <!-- MStarU Frequent -->
+ <string name="frequent">Frequent</string>
+ <string name="access_the_files_you_use_the_most_here">Access the files you use the most here.</string>
</resources>
diff --git a/src/com/cyanogenmod/filemanager/FileManagerApplication.java b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
index e3c88d6c..245d4241 100644
--- a/src/com/cyanogenmod/filemanager/FileManagerApplication.java
+++ b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
@@ -32,6 +32,7 @@ import com.cyanogenmod.filemanager.console.ConsoleBuilder;
import com.cyanogenmod.filemanager.console.ConsoleHolder;
import com.cyanogenmod.filemanager.console.VirtualMountPointConsole;
import com.cyanogenmod.filemanager.console.shell.PrivilegedConsole;
+import com.cyanogenmod.filemanager.mstaru.IMostStarUsedFilesManager;
import com.cyanogenmod.filemanager.preferences.AccessMode;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier;
@@ -168,6 +169,8 @@ public final class FileManagerApplication extends Application {
}
};
+ private IMostStarUsedFilesManager mMStarUManager;
+
/**
* {@inheritDoc}
@@ -194,6 +197,7 @@ public final class FileManagerApplication extends Application {
// Schedule in case not scheduled (i.e. never booted with this app on device
SecureCacheCleanupService.scheduleCleanup(getApplicationContext());
+ mMStarUManager = IMostStarUsedFilesManager.Factory.newInstance(this);
}
/**
@@ -620,4 +624,8 @@ public final class FileManagerApplication extends Application {
"Failed to read optional shell commands.", e); //$NON-NLS-1$
}
}
+
+ public IMostStarUsedFilesManager getMStarUManager() {
+ return mMStarUManager;
+ }
}
diff --git a/src/com/cyanogenmod/filemanager/activities/MainActivity.java b/src/com/cyanogenmod/filemanager/activities/MainActivity.java
index a6bba46e..9b3a4c84 100755
--- a/src/com/cyanogenmod/filemanager/activities/MainActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/MainActivity.java
@@ -26,6 +26,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Outline;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.Bundle;
@@ -59,16 +64,22 @@ import com.cyanogenmod.filemanager.FileManagerApplication;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.activities.preferences.SettingsPreferences;
import com.cyanogenmod.filemanager.adapters.QuickSearchAdapter;
+import com.cyanogenmod.filemanager.controllers.MStarUController;
import com.cyanogenmod.filemanager.controllers.NavigationDrawerController;
import com.cyanogenmod.filemanager.model.Bookmark;
import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.mstaru.IMostStarUsedFilesManager;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.Preferences;
+import com.cyanogenmod.filemanager.ui.IconHolder;
import com.cyanogenmod.filemanager.ui.ThemeManager;
import com.cyanogenmod.filemanager.ui.fragments.NavigationFragment;
import com.cyanogenmod.filemanager.ui.fragments.NavigationFragment.OnGoHomeRequestListener;
+import com.cyanogenmod.filemanager.ui.policy.InfoActionPolicy;
+import com.cyanogenmod.filemanager.ui.policy.IntentsActionPolicy;
import com.cyanogenmod.filemanager.ui.widgets.NavigationView.OnBackRequestListener;
import com.cyanogenmod.filemanager.util.FileHelper;
+import com.cyanogenmod.filemanager.util.MimeTypeHelper;
import com.cyanogenmod.filemanager.util.StorageHelper;
import java.io.File;
@@ -89,7 +100,7 @@ import java.util.List;
* the app is killed, is restarted from his initial state.
*/
public class MainActivity extends ActionBarActivity
- implements OnItemClickListener, OnBackRequestListener, OnGoHomeRequestListener {
+ implements OnItemClickListener, OnBackRequestListener, OnGoHomeRequestListener, MStarUController.OnClickListener, IMostStarUsedFilesManager.IFileObserver {
private static final String TAG = MainActivity.class.getSimpleName();
@@ -244,6 +255,8 @@ public class MainActivity extends ActionBarActivity
}
};
+ private MStarUController mMStarUController;
+
/**
* {@inheritDoc}
*/
@@ -275,6 +288,14 @@ public class MainActivity extends ActionBarActivity
newFilter.addDataScheme(ContentResolver.SCHEME_FILE);
registerReceiver(mNotificationReceiver, newFilter);
+ mMStarUController = new MStarUController(this, findViewById(R.id.mstaru), this);
+
+ mToolBar = (Toolbar) findViewById(R.id.material_toolbar);
+ setSupportActionBar(mToolBar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
+
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationDrawer =
(NavigationView) findViewById(R.id.navigation_view);
@@ -370,6 +391,25 @@ public class MainActivity extends ActionBarActivity
searchView.setFocusable(false);
}
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ ((FileManagerApplication)getApplicationContext()).getMStarUManager().registerObserver(this);
+ }
+
+ @Override
+ public void onStop() {
+ ((FileManagerApplication)getApplicationContext()).getMStarUManager().unregisterObserver(this);
+
+ super.onStop();
+ }
+
+ @Override
+ public void onFilesChanged(List<FileSystemObject> files) {
+ mMStarUController.replaceData(files);
+ }
+
/**
* {@inheritDoc}
*/
@@ -532,17 +572,6 @@ public class MainActivity extends ActionBarActivity
}
}
- @Override
- protected void onStart() {
- super.onStart();
-
- mToolBar = (Toolbar) findViewById(R.id.material_toolbar);
- setSupportActionBar(mToolBar);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeButtonEnabled(true);
- getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
- }
-
private void initQuickSearch() {
GridView gridview = (GridView) findViewById(R.id.quick_search_view);
QuickSearchAdapter quickSearchAdapter = new QuickSearchAdapter(this, R.layout.quick_search_item);
@@ -729,4 +758,18 @@ public class MainActivity extends ActionBarActivity
public int getColorForPath(String path) {
return mNavigationDrawerController.getColorForPath(path);
}
+
+ private void showFrequentFiles(List<FileSystemObject> files) {
+ mMStarUController.replaceData(files);
+ }
+
+ @Override
+ public void onItemClick(FileSystemObject fso) {
+ IntentsActionPolicy.openFileSystemObject(this, null, fso, false, null);
+ }
+
+ @Override
+ public void onDetailsClick(FileSystemObject fso) {
+ InfoActionPolicy.showPropertiesDialog(this, fso, null);
+ }
}
diff --git a/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java b/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
index 6e91c14d..bb5f940d 100644
--- a/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
+++ b/src/com/cyanogenmod/filemanager/adapters/FileSystemObjectAdapter.java
@@ -546,12 +546,18 @@ public class FileSystemObjectAdapter
private void setFileIcon(ImageView view, final int iconId, FileSystemObject fso) {
// Use iconholder to check for thumbnail
final ICallback callback = new ICallback() {
+
+ @Override
+ public void onPreExecute(ImageView imageView) {
+
+ }
+
@Override
public void onLoaded(ImageView imageView, Drawable icon) {
if (icon == null) {
// Icon holder didn't have anything at the moment, set default.
int colorId = MimeTypeHelper.getIconColorFromIconId(getContext(), iconId);
- setIcon(mRes, imageView, mRes.getDrawable(iconId),
+ setIcon(mRes, imageView, mRes.getDrawable(iconId, null),
mRes.getColor(R.color.navigation_view_icon_unselected),
R.drawable.ic_icon_background,
mRes.getColor(colorId));
diff --git a/src/com/cyanogenmod/filemanager/controllers/MStarUController.java b/src/com/cyanogenmod/filemanager/controllers/MStarUController.java
new file mode 100644
index 00000000..74747a61
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/controllers/MStarUController.java
@@ -0,0 +1,129 @@
+package com.cyanogenmod.filemanager.controllers;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.cyanogenmod.filemanager.R;
+import com.cyanogenmod.filemanager.ui.IconRenderer;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
+import com.cyanogenmod.filemanager.preferences.Preferences;
+import com.cyanogenmod.filemanager.ui.IconHolder;
+import com.cyanogenmod.filemanager.util.MimeTypeHelper;
+
+import java.util.List;
+
+/**
+ * This is meant to make this section more transferable
+ */
+public class MStarUController {
+
+ public interface OnClickListener {
+ void onItemClick(FileSystemObject fso);
+ void onDetailsClick(FileSystemObject fso);
+ }
+
+ private class ViewHolder {
+ /* package */ ImageView fileImage;
+ /* package */ TextView fileName;
+ /* package */ TextView parent;
+ /* package */ View details;
+
+ FileSystemObject fso;
+
+ public ViewHolder(View row) {
+ fileImage = (ImageView)row.findViewById(R.id.file_image);
+ fileName = (TextView)row.findViewById(R.id.file_name);
+ parent = (TextView)row.findViewById(R.id.file_parent);
+ details = row.findViewById(R.id.file_details);
+ }
+ }
+
+ private View.OnClickListener mOnItemClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ MStarUController.ViewHolder h =
+ (MStarUController.ViewHolder)view.getTag(R.id.tag_viewholder);
+
+ if (mOnClickListener != null) {
+ switch (view.getId()) {
+ case R.id.file_details:
+ mOnClickListener.onDetailsClick(h.fso);
+ break;
+ default:
+ mOnClickListener.onItemClick(h.fso);
+ break;
+
+ }
+ }
+ }
+ };
+
+ private ViewGroup mStarUGroup;
+
+ private ViewGroup mStarUEmpty;
+
+ private MStarUController.OnClickListener mOnClickListener;
+
+ private Context mContext;
+
+ private IconHolder mImageLoader;
+
+ public MStarUController(Context context, View root, MStarUController.OnClickListener l) {
+ mContext = context;
+ mStarUGroup = (ViewGroup)root.findViewById(R.id.mstaru_list);
+ mStarUEmpty = (ViewGroup)root.findViewById(R.id.mstaru_empty);
+ // This is kind of crap since it won't pick up changes if we leave the screen and come back
+ FileManagerSettings displayThumbsPref = FileManagerSettings.SETTINGS_DISPLAY_THUMBS;
+ final boolean displayThumbs =
+ Preferences.getSharedPreferences().getBoolean(
+ displayThumbsPref.getId(),
+ ((Boolean)displayThumbsPref.getDefaultValue()).booleanValue());
+ mImageLoader = new IconHolder(context, displayThumbs);
+ mOnClickListener = l;
+ }
+
+ public void replaceData(List<FileSystemObject> files) {
+ if (files == null || files.isEmpty()) {
+ mStarUGroup.setVisibility(View.GONE);
+ mStarUEmpty.setVisibility(View.VISIBLE);
+ return;
+ }
+ mStarUGroup.setVisibility(View.VISIBLE);
+ mStarUEmpty.setVisibility(View.GONE);
+
+ int size = Math.min(files.size(), mStarUGroup.getChildCount());
+ int i = 0;
+ for (; i < size; i++) {
+ final View row = mStarUGroup.getChildAt(i);
+ final FileSystemObject fso = files.get(i);
+
+ row.setVisibility(View.VISIBLE);
+ MStarUController.ViewHolder h =
+ (MStarUController.ViewHolder)row.getTag(R.id.tag_viewholder);
+
+ if (h == null) {
+ h = new MStarUController.ViewHolder(row);
+ row.setTag(R.id.tag_viewholder, h);
+ row.setOnClickListener(mOnItemClickListener);
+ h.details.setOnClickListener(mOnItemClickListener);
+ h.details.setTag(R.id.tag_viewholder, h);
+ }
+ h.fso = fso;
+
+ final int mimeTypeIconId = MimeTypeHelper.getIcon(mContext, fso);
+ IconHolder.ICallback callback = new IconRenderer(mContext, mimeTypeIconId);
+ mImageLoader.loadDrawable(h.fileImage, fso, mimeTypeIconId, callback);
+
+ h.fileName.setText(fso.getName());
+ h.parent.setText(fso.getParent());
+ }
+ size = mStarUGroup.getChildCount();
+ for (; i < size; i++) {
+ View row = mStarUGroup.getChildAt(i);
+ row.setVisibility(View.GONE);
+ }
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/mstaru/IMostStarUsedFilesManager.java b/src/com/cyanogenmod/filemanager/mstaru/IMostStarUsedFilesManager.java
new file mode 100644
index 00000000..1ad6ff5c
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/mstaru/IMostStarUsedFilesManager.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.cyanogenmod.filemanager.mstaru;
+
+import android.content.Context;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+
+import java.util.List;
+
+public interface IMostStarUsedFilesManager {
+ class Factory {
+ public static IMostStarUsedFilesManager newInstance(Context context) {
+ return new MostFrequentlyUsedManager(context);
+ }
+
+ private Factory() {}
+ }
+
+ interface IFileObserver {
+ void onFilesChanged(List<FileSystemObject> files);
+ }
+
+ /**
+ * Registers that a file has been accessed.
+ *
+ * @param fso The file system object
+ *
+ * @return Whether the operation succeeded or not
+ */
+ boolean notifyAccessed(FileSystemObject fso);
+
+ void notifyAccessedAsync(FileSystemObject fso);
+
+ /**
+ * Registers that a file system object has been moved.
+ *
+ * @param from The original location of the object
+ * @param to The new location of the object
+ *
+ * @return Whether the operation succeeded or not
+ */
+ boolean notifyMoved(FileSystemObject from, FileSystemObject to);
+
+ void notifyMovedAsync(FileSystemObject from, FileSystemObject to);
+
+ /**
+ * Registers that a file system object has been deleted.
+ *
+ * @param fso The file system object
+ *
+ * @return Whether the operation succeeded or not
+ */
+ boolean notifyDeleted(FileSystemObject fso);
+
+ void notifyDeletedAsync(FileSystemObject fso);
+
+ /**
+ * Gets the list of important files we may want to show. If you need updates as things change
+ * consider using the register/unregister
+ *
+ * @return The list of files or null if there was a problem.
+ */
+ List<FileSystemObject> getFiles();
+
+ void registerObserver(IFileObserver observer);
+
+ void unregisterObserver(IFileObserver observer);
+}
diff --git a/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedContract.java b/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedContract.java
new file mode 100644
index 00000000..e3adbc35
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedContract.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.cyanogenmod.filemanager.mstaru;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Created by herriojr on 8/10/15.
+ */
+/* package */ interface MostFrequentlyUsedContract {
+ String AUTHORITY = "com.cyanogenmod.filemanager.mfu";
+
+ class Item implements BaseColumns {
+ /* package */ static final String TABLE_NAME = "items";
+
+ public static final String FOLDER = TABLE_NAME;
+
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/" + AUTHORITY + "." + FOLDER;
+
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + FOLDER);
+
+ /* package */ static final String _LAST_DEGRADE_TIMESTAMP = "_last_degrade";
+ public static final String KEY = "key";
+ public static final String COUNT = "count";
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedManager.java b/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedManager.java
new file mode 100644
index 00000000..63dd6695
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedManager.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.cyanogenmod.filemanager.mstaru;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.support.annotation.NonNull;
+import android.util.Log;
+import com.cyanogenmod.filemanager.FileManagerApplication;
+import com.cyanogenmod.filemanager.commands.shell.InvalidCommandDefinitionException;
+import com.cyanogenmod.filemanager.console.CommandNotFoundException;
+import com.cyanogenmod.filemanager.console.ConsoleAllocException;
+import com.cyanogenmod.filemanager.console.ExecutionException;
+import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
+import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
+import com.cyanogenmod.filemanager.console.OperationTimeoutException;
+import com.cyanogenmod.filemanager.model.FileSystemObject;
+import com.cyanogenmod.filemanager.mstaru.MostFrequentlyUsedContract.Item;
+import com.cyanogenmod.filemanager.util.CommandHelper;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This is meant to only be used with the Application Context. If you break it, you bought it.
+ */
+public class MostFrequentlyUsedManager implements IMostStarUsedFilesManager {
+ private static final String TAG = MostFrequentlyUsedManager.class.getSimpleName();
+
+ private static class UIHandler extends Handler {
+ public static final int MSG_ITEMS = 0;
+
+ private WeakReference<MostFrequentlyUsedManager> mMgr;
+
+ public UIHandler(MostFrequentlyUsedManager mgr) {
+ super(Looper.getMainLooper());
+ mMgr = new WeakReference<>(mgr);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case MSG_ITEMS:
+ Log.d(TAG, "Notifying of changes");
+ MostFrequentlyUsedManager mgr = mMgr.get();
+ if (mgr != null) {
+ mgr.notifyChange((List<FileSystemObject>) msg.obj);
+ }
+ break;
+ }
+ }
+ }
+
+ private static final String[] PROJECTION = {
+ Item.KEY
+ };
+ private static final int PROJECTION_KEY = 0;
+
+ private ContentResolver mResolver;
+
+ private ContentObserver mObserver;
+ private HandlerThread mThread;
+
+ private Handler mUIHandler = new UIHandler(this);
+
+ private Set<IFileObserver> mObservers;
+
+ private List<FileSystemObject> mFiles;
+
+ /* package */ MostFrequentlyUsedManager(@NonNull Context context) {
+ context = context.getApplicationContext();
+ mResolver = context.getContentResolver();
+ mObservers = new HashSet<>();
+ }
+
+ private static boolean isMainThread() {
+ return Looper.getMainLooper() == Looper.myLooper();
+ }
+
+ private static FileSystemObject parseKey(@NonNull String key) {
+ try {
+ return CommandHelper.getFileInfo(
+ FileManagerApplication.getInstance(), key, false, null);
+ } catch (InsufficientPermissionsException
+ | InvalidCommandDefinitionException
+ | ConsoleAllocException
+ | ExecutionException
+ | OperationTimeoutException
+ | NoSuchFileOrDirectory
+ | CommandNotFoundException
+ | IOException e) {
+ return null;
+ }
+ }
+
+ private static String keyFor(@NonNull FileSystemObject fso) {
+ Log.d(TAG, "Generating key for " + fso.getFullPath());
+ return fso.getFullPath();
+ }
+
+ @Override
+ public boolean notifyAccessed(@NonNull FileSystemObject fso) throws IllegalStateException {
+ if (isMainThread()) {
+ throw new IllegalStateException("Must not be invoked from the main thread.");
+ }
+
+ ContentValues values = new ContentValues();
+ values.put(MostFrequentlyUsedContract.Item.KEY, keyFor(fso));
+
+ mResolver.insert(Item.CONTENT_URI, values);
+ return true;
+ }
+
+ @Override
+ public void notifyAccessedAsync(@NonNull final FileSystemObject fso) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ public Void doInBackground(Void ... params) {
+ notifyAccessed(fso);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public boolean notifyMoved(@NonNull FileSystemObject from,
+ @NonNull FileSystemObject to) {
+ if (isMainThread()) {
+ throw new IllegalStateException("Must not be invoked from the main thread.");
+ }
+
+ ContentValues values = new ContentValues();
+ values.put(MostFrequentlyUsedContract.Item.KEY, keyFor(to));
+
+ mResolver.update(Item.CONTENT_URI,
+ values,
+ MostFrequentlyUsedContract.Item.KEY + "=?",
+ new String[]{
+ keyFor(from),
+ });
+ return true;
+ }
+
+ @Override
+ public void notifyMovedAsync(@NonNull final FileSystemObject from,
+ @NonNull final FileSystemObject to) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ public Void doInBackground(Void ... params) {
+ notifyMoved(from, to);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public boolean notifyDeleted(@NonNull FileSystemObject fso) {
+ if (isMainThread()) {
+ throw new IllegalStateException("Must not be invoked from the main thread.");
+ }
+
+ mResolver.delete(MostFrequentlyUsedContract.Item.CONTENT_URI,
+ MostFrequentlyUsedContract.Item.KEY + "=?",
+ new String[]{
+ keyFor(fso)
+ });
+ return true;
+ }
+
+ @Override
+ public void notifyDeletedAsync(@NonNull final FileSystemObject fso) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ public Void doInBackground(Void ... params) {
+ notifyDeleted(fso);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public List<FileSystemObject> getFiles() {
+ if (isMainThread()) {
+ throw new IllegalStateException("Must not be invoked from the main thread.");
+ }
+
+ ArrayList<FileSystemObject> files;
+ Cursor c = null;
+ try {
+ files = new ArrayList<FileSystemObject>();
+ c = mResolver.query(Item.CONTENT_URI, PROJECTION, null, null, null);
+ while (c.moveToNext()) {
+ FileSystemObject o = parseKey(c.getString(PROJECTION_KEY));
+ if (o != null) {
+ files.add(o);
+ }
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+
+ return files;
+ }
+
+ @Override
+ public void registerObserver(@NonNull IFileObserver observer) {
+ if (!isMainThread()) {
+ throw new IllegalStateException("Must be invoked on the main thread.");
+ }
+ mObservers.add(observer);
+
+ if (mObserver == null) {
+ mThread = new HandlerThread("FrequentObserver");
+ mThread.start();
+
+ mObserver = new ContentObserver(new Handler(mThread.getLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ List<FileSystemObject> files = getFiles();
+ Log.d(TAG, "Got " + files.size() + " items");
+ // post back to the main thread
+ mUIHandler.obtainMessage(UIHandler.MSG_ITEMS, files).sendToTarget();
+ }
+ };
+ mResolver.registerContentObserver(Item.CONTENT_URI, true, mObserver);
+ // kick it off, so we get the first item
+ mObserver.dispatchChange(false, Item.CONTENT_URI);
+ } else {
+ if (mFiles == null) {
+ notifyChange(mFiles);
+ } else {
+ // either we haven't received a response yet, or it was null, either way, we don't
+ // need to dispatch it again
+ }
+ }
+ }
+
+ @Override
+ public void unregisterObserver(@NonNull IFileObserver observer) {
+ if (!isMainThread()) {
+ throw new IllegalStateException("Must be invoked on the main thread.");
+ }
+
+ mObservers.remove(observer);
+ if (mObservers.isEmpty()) {
+ mResolver.unregisterContentObserver(mObserver);
+ mObserver = null;
+ mThread.getLooper().quit();
+ }
+ }
+
+ /* package */ void notifyChange(List<FileSystemObject> files) {
+ mFiles = files;
+ for (IFileObserver o : mObservers) {
+ o.onFilesChanged(files);
+ }
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedProvider.java b/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedProvider.java
new file mode 100644
index 00000000..552a796e
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/mstaru/MostFrequentlyUsedProvider.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.cyanogenmod.filemanager.mstaru;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
+import android.net.Uri;
+
+import android.util.Log;
+import com.cyanogenmod.filemanager.mstaru.MostFrequentlyUsedContract.Item;
+
+import java.util.HashMap;
+
+/**
+ * This provider provides access to help in keeping track and querying of the most frequently
+ * accessed items.
+ */
+public class MostFrequentlyUsedProvider extends ContentProvider {
+ private static final String TAG = MostFrequentlyUsedProvider.class.getSimpleName();
+
+ private static final boolean DEBUG = true;
+
+ private static class MFUOpenHelper extends SQLiteOpenHelper {
+
+ private static final String NAME = "mfu";
+ private static final int VERSION = 1;
+
+ /**
+ * {@inheritDoc}
+ */
+ public MFUOpenHelper(Context context) {
+ super(context, NAME, null, VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + MostFrequentlyUsedContract.Item.TABLE_NAME + "("
+ + MostFrequentlyUsedContract.Item._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + Item.KEY + " TEXT,"
+ + Item.COUNT + " INTEGER NOT NULL DEFAULT 1,"
+ + Item._LAST_DEGRADE_TIMESTAMP
+ + " INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ + "UNIQUE(" + MostFrequentlyUsedContract.Item.KEY + ')'
+ + ");"
+ );
+
+ db.execSQL("CREATE INDEX " + Item.TABLE_NAME + "_count_idx"
+ + " ON " + Item.TABLE_NAME + "(" + Item.COUNT + ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // No upgrades yet
+ }
+ }
+
+ private static final String STMT_UPDATE_COUNT = "UPDATE " + Item.TABLE_NAME
+ + " SET " + Item.COUNT + "=" + Item.COUNT + "+1, "
+ + Item._LAST_DEGRADE_TIMESTAMP + "=CURRENT_TIMESTAMP"
+ + " WHERE " + Item.KEY + "=?;";
+
+ private static final String STMT_DEGRADE_COUNT = "UPDATE " + Item.TABLE_NAME
+ + " SET " + Item.COUNT +"=" + Item.COUNT + "-CAST("
+ + "JULIANDAY(CURRENT_TIMESTAMP)"
+ + "-JULIANDAY(" + Item._LAST_DEGRADE_TIMESTAMP + ")"
+ + " AS INT),"
+ + Item._LAST_DEGRADE_TIMESTAMP + "=CURRENT_TIMESTAMP"
+ + " WHERE "
+ + "JULIANDAY() - JULIANDAY(" + Item._LAST_DEGRADE_TIMESTAMP + ") > 1;";
+
+
+ private static final int MAX_RESULTS = 10;
+
+ private static UriMatcher sUriMatcher;
+
+ private static final int MATCH_ITEMS = 0;
+
+ private static HashMap<String, String> sFilesProjectionMap;
+
+ static {
+ sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ sUriMatcher.addURI(MostFrequentlyUsedContract.AUTHORITY, "/" + Item.FOLDER, MATCH_ITEMS);
+
+ sFilesProjectionMap = new HashMap<String, String>();
+ sFilesProjectionMap.put(Item._ID, Item._ID);
+ sFilesProjectionMap.put(MostFrequentlyUsedContract.Item.KEY,
+ MostFrequentlyUsedContract.Item.KEY);
+ sFilesProjectionMap.put(Item.COUNT, Item.COUNT);
+ }
+
+ private MFUOpenHelper mOpenHelper;
+
+ private ContentResolver mResolver;
+
+ @Override
+ public boolean onCreate() {
+ mOpenHelper = new MFUOpenHelper(getContext());
+ mResolver = getContext().getContentResolver();
+
+ return true;
+ }
+
+ /**
+ * This degrades all columns by the number of days since the last degrade for each column.
+ *
+ * Eventually, everything will end up in the negatives, however, given our logic, we always keep
+ * at least {@link #MAX_RESULTS} items if that number exists.
+ *
+ * @param db
+ */
+ private int degrade(SQLiteDatabase db) {
+ try {
+ SQLiteStatement stmt = db.compileStatement(STMT_DEGRADE_COUNT);
+ int cnt = stmt.executeUpdateDelete();
+
+ if (DEBUG) Log.d(TAG, "Degraded " + cnt + " items");
+
+ return cnt;
+ } catch(SQLiteException e) {
+ Log.e(TAG, "Failed to degrade ", e);
+ // Do nothing, we'll try again some other time
+ }
+ return 0;
+ }
+
+ private int prune(SQLiteDatabase db) {
+ Cursor c;
+ try {
+ c = db.query(Item.TABLE_NAME, new String[]{Item._ID}, null, null, null, null,
+ Item.COUNT + " DESC", "" + MAX_RESULTS);
+ StringBuilder b = new StringBuilder();
+
+ String[] selectionArgs = new String[c.getCount()];
+ b.append(Item.COUNT)
+ .append(" < 0");
+ int i = 0;
+
+ while (c.moveToNext()) {
+ b.append(" AND ")
+ .append(Item._ID)
+ .append("!=?");
+ selectionArgs[i++] = "" + c.getLong(0);
+ }
+ int cnt = db.delete(Item.TABLE_NAME, b.toString(), selectionArgs);
+ if (DEBUG) Log.d(TAG, "Pruned " + cnt + " items");
+
+ return cnt;
+ } catch (SQLiteException e) {
+ // We can safely ignore this and just prune next time
+ }
+ return 0;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+ if (sortOrder == null) {
+ sortOrder = Item.COUNT + " DESC";
+ }
+
+ int which = sUriMatcher.match(uri);
+ switch(which) {
+ case MATCH_ITEMS:
+ qb.setTables(Item.TABLE_NAME);
+ qb.setProjectionMap(sFilesProjectionMap);
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri " + uri);
+ }
+
+ SQLiteDatabase db = null;
+ try {
+ db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ degrade(db);
+ prune(db);
+ db.setTransactionSuccessful();
+ } catch(SQLiteException e) {
+ // Do nothing
+ } finally {
+ if (db != null) db.endTransaction();
+ }
+
+ db = mOpenHelper.getWritableDatabase();
+
+ Cursor c = qb.query(
+ db,
+ projection,
+ selection,
+ selectionArgs,
+ null,
+ null,
+ sortOrder,
+ "" + MAX_RESULTS);
+ return c;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ switch(sUriMatcher.match(uri)) {
+ case MATCH_ITEMS:
+ return Item.CONTENT_TYPE;
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ int which = sUriMatcher.match(uri);
+ String table;
+ switch(which) {
+ case MATCH_ITEMS:
+ table = Item.TABLE_NAME;
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri " + uri);
+ }
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long id = db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_IGNORE);
+ if (id == -1) {
+ SQLiteStatement stmt = db.compileStatement(STMT_UPDATE_COUNT);
+ stmt.bindString(1, values.getAsString(Item.KEY));
+ int cnt = stmt.executeUpdateDelete();
+ if (cnt > 0) {
+ Cursor c = null;
+ try {
+ String selection = Item.KEY + "=?";
+ String[] selectionArgs = new String[]{
+ values.getAsString(Item.KEY),
+ };
+ c = db.query(MostFrequentlyUsedContract.Item.TABLE_NAME,
+ new String[]{Item._ID},
+ selection,
+ selectionArgs,
+ null, null, null, null);
+ if (c.moveToFirst()) {
+ id = c.getLong(0);
+ }
+ } finally {
+ if (c != null) c.close();
+ }
+ }
+ }
+ if (id > -1) {
+ mResolver.notifyChange(uri, null);
+ }
+ return Uri.withAppendedPath(uri, "" + id);
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int which = sUriMatcher.match(uri);
+ String table;
+ switch(which) {
+ case MATCH_ITEMS:
+ table = MostFrequentlyUsedContract.Item.TABLE_NAME;
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri " + uri);
+ }
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ int cnt = db.delete(table, selection, selectionArgs);
+ if (cnt > 0) {
+ mResolver.notifyChange(uri, null);
+ }
+ return cnt;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ int which = sUriMatcher.match(uri);
+ String table;
+ switch(which) {
+ case MATCH_ITEMS:
+ table = Item.TABLE_NAME;
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri " + uri);
+ }
+
+ values = new ContentValues(values);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ int cnt = db.update(table, values, selection, selectionArgs);
+ values.put(Item.COUNT, Item.COUNT + " + 1");
+ if (cnt > 0) {
+ mResolver.notifyChange(uri, null);
+ }
+ return cnt;
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/service/MoveFileService.java b/src/com/cyanogenmod/filemanager/service/MoveFileService.java
index 21decfd1..e86150b4 100644
--- a/src/com/cyanogenmod/filemanager/service/MoveFileService.java
+++ b/src/com/cyanogenmod/filemanager/service/MoveFileService.java
@@ -168,9 +168,8 @@ public class MoveFileService extends IntentService {
protected Boolean doInBackground(String... params) {
mSrcPath = params[0];
mDstPath = params[1];
- String fileName = mSrcPath.substring(mSrcPath.lastIndexOf(File.separator) + 1);
try {
- CommandHelper.move(MoveFileService.this, mSrcPath, mDstPath, fileName, null, null);
+ CommandHelper.move(MoveFileService.this, mSrcPath, mDstPath, null);
} catch (Exception e) {
return Boolean.FALSE;
}
diff --git a/src/com/cyanogenmod/filemanager/ui/IconHolder.java b/src/com/cyanogenmod/filemanager/ui/IconHolder.java
index 86443720..74b1fe55 100644
--- a/src/com/cyanogenmod/filemanager/ui/IconHolder.java
+++ b/src/com/cyanogenmod/filemanager/ui/IconHolder.java
@@ -38,6 +38,7 @@ import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
import com.cyanogenmod.filemanager.util.FileHelper;
import com.cyanogenmod.filemanager.util.MediaHelper;
+import com.cyanogenmod.filemanager.util.MimeTypeHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper.KnownMimeTypeResolver;
import java.lang.ref.WeakReference;
@@ -59,19 +60,21 @@ public class IconHolder {
private final Map<String, Drawable> mIcons; // Themes based
private final Map<String, Drawable> mAppIcons; // App based
- private Map<String, Long> mAlbums; // Media albums
-
private final WeakHashMap<ImageView, Loadable> mRequests;
private final Context mContext;
private final boolean mUseThumbs;
- private boolean mNeedAlbumUpdate = true;
private HandlerThread mWorkerThread;
private Handler mWorkerHandler;
public interface ICallback {
- public void onLoaded(ImageView imageView, Drawable icon);
+ void onPreExecute(ImageView imageView);
+ void onLoaded(ImageView imageView, Drawable icon);
+ }
+
+ public interface ITransform {
+ Drawable transform(Drawable d);
}
/**
@@ -79,8 +82,10 @@ public class IconHolder {
* TODO: Refactor this to have different loadables
*/
private static class Loadable {
+
private Context mContext;
private WeakReference<ICallback> mCallback;
+ private ITransform mTransform;
private static boolean sAlbumsDirty = true;
private static Map<String, Long> sAlbums;
@@ -88,16 +93,14 @@ public class IconHolder {
WeakReference<ImageView> view;
Drawable result;
- public Loadable(Context context, ImageView view, FileSystemObject fso) {
- this(context, view, fso, null);
- }
-
- public Loadable(Context context, ImageView view, FileSystemObject fso, ICallback callback) {
+ public Loadable(Context context, ImageView view, FileSystemObject fso, ICallback callback,
+ ITransform transform) {
this.mContext = context.getApplicationContext();
this.fso = fso;
- this.view = new WeakReference<ImageView>(view);
+ this.view = new WeakReference<>(view);
this.result = null;
- this.mCallback = new WeakReference<ICallback>(callback);
+ this.mCallback = new WeakReference<>(callback);
+ this.mTransform = transform;
}
private static synchronized Map<String, Long> getAlbums(Context context) {
@@ -113,7 +116,11 @@ public class IconHolder {
}
public boolean load() {
- return (result = loadDrawable(fso)) != null;
+ result = loadDrawable(fso);
+ if (mTransform != null) {
+ result = mTransform.transform(result);
+ }
+ return result != null;
}
private Drawable loadDrawable(FileSystemObject fso) {
@@ -271,8 +278,8 @@ public class IconHolder {
super();
this.mContext = context;
this.mUseThumbs = useThumbs;
- this.mRequests = new WeakHashMap<ImageView, Loadable>();
- this.mIcons = new HashMap<String, Drawable>();
+ this.mRequests = new WeakHashMap<>();
+ this.mIcons = new HashMap<>();
this.mAppIcons = new LinkedHashMap<String, Drawable>(MAX_CACHE, .75F, true) {
private static final long serialVersionUID = 1L;
@Override
@@ -280,7 +287,6 @@ public class IconHolder {
return size() > MAX_CACHE;
}
};
- this.mAlbums = new HashMap<String, Long>();
if (useThumbs) {
final ContentResolver cr = mContext.getContentResolver();
for (Uri uri : MediaHelper.RELEVANT_URIS) {
@@ -308,6 +314,10 @@ public class IconHolder {
return dw;
}
+ public void cancel(ImageView iconView) {
+ this.mRequests.remove(iconView);
+ }
+
/**
* Clearing the selected Icon Cache
* @param fso The Selected FileSystemObject reference
@@ -327,37 +337,20 @@ public class IconHolder {
* @param defaultIconId Resource ID to be used in case no specific drawable could be found
*/
public void loadDrawable(ImageView iconView, FileSystemObject fso, int defaultIconId) {
- if (!mUseThumbs) {
- iconView.setImageResource(defaultIconId);
- return;
- }
-
- // Is cached?
- final String filePath = MediaHelper.normalizeMediaPath(fso.getFullPath());
- if (this.mAppIcons.containsKey(filePath)) {
- iconView.setImageDrawable(this.mAppIcons.get(filePath));
- return;
- }
-
- if (mWorkerThread == null) {
- mWorkerThread = new HandlerThread("IconHolderLoader");
- mWorkerThread.start();
- mWorkerHandler = new WorkerHandler(mWorkerThread.getLooper());
- }
- Loadable previousForView = mRequests.get(iconView);
- if (previousForView != null) {
- mWorkerHandler.removeMessages(MSG_LOAD, previousForView);
- }
-
- Loadable loadable = new Loadable(mContext, iconView, fso);
- mRequests.put(iconView, loadable);
- iconView.setImageResource(defaultIconId);
-
- mWorkerHandler.obtainMessage(MSG_LOAD, loadable).sendToTarget();
+ loadDrawable(iconView, fso, defaultIconId, null);
}
- public void cancel(ImageView iconView) {
- this.mRequests.remove(iconView);
+ /**
+ * Method that returns a drawable reference of a FileSystemObject.
+ *
+ * @param iconView View to load the drawable into
+ * @param fso The FileSystemObject reference
+ * @param defaultIconId Resource ID to be used in case no specific drawable could be found
+ * @param callback ICallback to use when finished loading
+ */
+ public void loadDrawable(ImageView iconView, FileSystemObject fso, int defaultIconId,
+ ICallback callback) {
+ loadDrawable(iconView, fso, defaultIconId, callback, null);
}
/**
@@ -367,36 +360,43 @@ public class IconHolder {
* @param fso The FileSystemObject reference
* @param defaultIconId Resource ID to be used in case no specific drawable could be found
* @param callback ICallback to use when finished loading
+ * @param transform The transfromer to apply to the drawable
*/
public void loadDrawable(ImageView iconView, FileSystemObject fso, int defaultIconId,
- ICallback callback) {
- if (!mUseThumbs) {
- callback.onLoaded(iconView, null);
- return;
+ ICallback callback, ITransform transform) {
+ Drawable icon = null;
+ if (callback != null) {
+ callback.onPreExecute(iconView);
}
- // Is cached?
- final String filePath = MediaHelper.normalizeMediaPath(fso.getFullPath());
- if (this.mAppIcons.containsKey(filePath)) {
- callback.onLoaded(iconView, mAppIcons.get(filePath));
- return;
- }
+ if (!mUseThumbs) {
+ icon = mContext.getResources().getDrawable(defaultIconId, null);
+ } else {
+ // Is cached?
+ final String filePath = MediaHelper.normalizeMediaPath(fso.getFullPath());
+ if (this.mAppIcons.containsKey(filePath)) {
+ icon = mAppIcons.get(filePath);
+ } else {
- if (mWorkerThread == null) {
- mWorkerThread = new HandlerThread("IconHolderLoader");
- mWorkerThread.start();
- mWorkerHandler = new WorkerHandler(mWorkerThread.getLooper());
- }
- Loadable previousForView = mRequests.get(iconView);
- if (previousForView != null) {
- mWorkerHandler.removeMessages(MSG_LOAD, previousForView);
- }
+ if (mWorkerThread == null) {
+ mWorkerThread = new HandlerThread("IconHolderLoader");
+ mWorkerThread.start();
+ mWorkerHandler = new WorkerHandler(mWorkerThread.getLooper());
+ }
+ Loadable previousForView = mRequests.get(iconView);
+ if (previousForView != null) {
+ mWorkerHandler.removeMessages(MSG_LOAD, previousForView);
+ }
- Loadable loadable = new Loadable(mContext, iconView, fso, callback);
- mRequests.put(iconView, loadable);
- callback.onLoaded(iconView, null);
+ Loadable loadable = new Loadable(mContext, iconView, fso, callback, transform);
+ mRequests.put(iconView, loadable);
- mWorkerHandler.obtainMessage(MSG_LOAD, loadable).sendToTarget();
+ mWorkerHandler.obtainMessage(MSG_LOAD, loadable).sendToTarget();
+ }
+ }
+ if ( callback != null) {
+ callback.onLoaded(iconView, icon);
+ }
}
private class WorkerHandler extends Handler {
diff --git a/src/com/cyanogenmod/filemanager/ui/IconRenderer.java b/src/com/cyanogenmod/filemanager/ui/IconRenderer.java
new file mode 100644
index 00000000..cde1e462
--- /dev/null
+++ b/src/com/cyanogenmod/filemanager/ui/IconRenderer.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.cyanogenmod.filemanager.ui;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Outline;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.widget.ImageView;
+import com.cyanogenmod.filemanager.R;
+import com.cyanogenmod.filemanager.util.MimeTypeHelper;
+
+public class IconRenderer implements IconHolder.ICallback {
+ private Context mContext;
+
+ private int mIconId;
+
+ private ViewOutlineProvider mIconViewOutlineProvider;
+
+ public IconRenderer(Context context, int iconId) {
+ mContext = context.getApplicationContext();
+ mIconId = iconId;
+ mIconViewOutlineProvider = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ Resources res = mContext.getResources();
+ int size = res.getDimensionPixelSize(R.dimen.circle_icon_wh);
+ float radius = res.getDimension(R.dimen.rectangle_icon_radius);
+ outline.setRoundRect(0, 0, size, size, radius);
+ }
+ };
+ }
+
+ private static void setIcon(Resources resources, ImageView view, Drawable iconDrawable,
+ int iconColor, int backgroundId, int backgroundColor) {
+ StateListDrawable stateListDrawable = new StateListDrawable();
+// addSelected(resources, stateListDrawable);
+ addUnselected(stateListDrawable, iconDrawable, iconColor);
+
+ ColorStateList colorList = new ColorStateList(
+ new int[][]{new int[]{android.R.attr.state_selected},
+ new int[]{}},
+ new int[]{resources.getColor(R.color.navigation_view_icon_selected),
+ backgroundColor});
+
+ view.setBackgroundResource(backgroundId);
+ view.setBackgroundTintList(colorList);
+ view.setImageDrawable(stateListDrawable);
+ }
+
+ private static void addUnselected(StateListDrawable drawable, Drawable iconDrawable,
+ int color) {
+ iconDrawable.setTint(color);
+ drawable.addState(new int[0], iconDrawable);
+ }
+
+ private static void addUnselectedThumbnail(StateListDrawable drawable, Drawable iconDrawable) {
+ drawable.addState(new int[0], iconDrawable);
+ }
+
+ private void setIconThumbnail(Resources resources, ImageView view, Drawable iconDrawable) {
+ StateListDrawable stateListDrawable = new StateListDrawable();
+// addSelected(resources, stateListDrawable);
+ addUnselectedThumbnail(stateListDrawable, iconDrawable);
+
+ ColorStateList colorList = new ColorStateList(
+ new int[][]{new int[]{android.R.attr.state_selected},
+ new int[]{}},
+ new int[]{resources.getColor(R.color.navigation_view_icon_selected),
+ resources.getColor(R.color.navigation_view_icon_unselected)});
+
+ view.setBackgroundResource(R.drawable.ic_icon_background_rounded_rectagle);
+ view.setBackgroundTintList(colorList);
+ view.setImageDrawable(stateListDrawable);
+ }
+
+ @Override
+ public void onPreExecute(ImageView imageView) {
+ imageView.setOutlineProvider(mIconViewOutlineProvider);
+ imageView.setClipToOutline(true);
+ }
+
+ @Override
+ public void onLoaded(ImageView imageView, Drawable icon) {
+ Resources res = mContext.getResources();
+ if (icon == null) {
+ // Icon holder didn't have anything at the moment, set default.
+ int colorId = MimeTypeHelper.getIconColorFromIconId(mContext, mIconId);
+ setIcon(res, imageView, res.getDrawable(mIconId),
+ res.getColor(R.color.navigation_view_icon_unselected),
+ R.drawable.ic_icon_background,
+ res.getColor(colorId));
+ } else {
+ // Thumbnail present, set the background to rectangle to match better.
+ setIconThumbnail(res, imageView, icon);
+ }
+ }
+}
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java
index b869d751..2ed0a383 100644
--- a/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/DeleteActionPolicy.java
@@ -24,6 +24,7 @@ import android.text.Spanned;
import android.view.View;
import android.widget.Toast;
+import com.cyanogenmod.filemanager.FileManagerApplication;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.console.ExecutionException;
import com.cyanogenmod.filemanager.console.RelaunchableException;
@@ -379,6 +380,9 @@ public final class DeleteActionPolicy extends ActionsPolicy {
String.format(
"Failed to delete file: %s", fso.getFullPath())); //$NON-NLS-1$
}
+
+ ((FileManagerApplication)ctx.getApplicationContext())
+ .getMStarUManager().notifyDeletedAsync(fso);
}
};
ExceptionUtil.OnRelaunchCommandResult onRelaunchCommandResult =
diff --git a/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java b/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java
index 1eb2196f..e4c01b06 100755
--- a/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java
+++ b/src/com/cyanogenmod/filemanager/ui/policy/IntentsActionPolicy.java
@@ -31,6 +31,7 @@ import android.util.Log;
import android.view.View;
import android.widget.Toast;
+import com.cyanogenmod.filemanager.FileManagerApplication;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.activities.EditorActivity;
import com.cyanogenmod.filemanager.activities.ShortcutActivity;
@@ -150,6 +151,9 @@ public final class IntentsActionPolicy extends ActionsPolicy {
intent,
choose,
onDismissListener);
+
+ ((FileManagerApplication)ctx.getApplicationContext())
+ .getMStarUManager().notifyAccessedAsync(fso);
}
@Override
@@ -175,6 +179,9 @@ public final class IntentsActionPolicy extends ActionsPolicy {
// Resolve the intent
resolveIntent(ctx, intent, choose, onDismissListener);
+
+ ((FileManagerApplication)ctx.getApplicationContext())
+ .getMStarUManager().notifyAccessedAsync(fso);
} catch (Exception e) {
ExceptionUtil.translateException(ctx, e);
}
diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
index 215a2e5d..e8588edf 100644
--- a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
+++ b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java
@@ -52,6 +52,7 @@ import com.cyanogenmod.filemanager.model.FileSystemObject;
import com.cyanogenmod.filemanager.model.ParentDirectory;
import com.cyanogenmod.filemanager.model.RootDirectory;
import com.cyanogenmod.filemanager.model.Symlink;
+import com.cyanogenmod.filemanager.mstaru.IMostStarUsedFilesManager;
import com.cyanogenmod.filemanager.parcelables.NavigationViewInfoParcelable;
import com.cyanogenmod.filemanager.parcelables.SearchInfoParcelable;
import com.cyanogenmod.filemanager.preferences.AccessMode;
@@ -497,6 +498,8 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
*/
AdapterView<?> mAdapterView;
+ private IMostStarUsedFilesManager mMStarUManager;
+
//The layout for icons mode
private static final int RESOURCE_MODE_ICONS_LAYOUT = R.layout.navigation_view_icons;
private static final int RESOURCE_MODE_ICONS_ITEM = R.layout.navigation_view_icons_item;
@@ -1084,6 +1087,10 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
changeCurrentDir(newDir, true, false, false, null, null);
}
+ public void changeCurrentDir(final Directory newDir) {
+ changeCurrentDir(newDir.getFullPath());
+ }
+
/**
* Method that changes the current directory of the view.
*
@@ -1094,6 +1101,10 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
changeCurrentDir(newDir, addToHistory, false, false, null, null);
}
+ public void changeCurrentDir(final Directory newDir, boolean addToHistory) {
+ changeCurrentDir(newDir.getFullPath(), addToHistory);
+ }
+
/**
* Method that changes the current directory of the view.
*
@@ -1104,6 +1115,9 @@ BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRe
changeCurrentDir(newDir, true, false, false, searchInfo, null);
}
+ public void changeCurrentDir(final Directory newDir, SearchInfoParcelable searchInfo) {
+ changeCurrentDir(newDir.getFullPath(), searchInfo);
+ }
/**
* Method that changes the current directory of the view.
*