1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.googlecode.android_scripting.provider; 18 19 import android.app.SearchManager; 20 import android.content.ContentProvider; 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.UriMatcher; 25 import android.content.Intent.ShortcutIconResource; 26 import android.database.Cursor; 27 import android.database.MatrixCursor; 28 import android.net.Uri; 29 import android.provider.BaseColumns; 30 import android.provider.LiveFolders; 31 32 import com.googlecode.android_scripting.FeaturedInterpreters; 33 import com.googlecode.android_scripting.IntentBuilders; 34 import com.googlecode.android_scripting.R; 35 import com.googlecode.android_scripting.ScriptStorageAdapter; 36 import com.googlecode.android_scripting.interpreter.Interpreter; 37 import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; 38 import com.googlecode.android_scripting.interpreter.InterpreterConstants; 39 40 import java.io.File; 41 42 public class ScriptProvider extends ContentProvider { 43 44 public static final String SINGLE_MIME = "vnd.android.cursor.item/vnd.sl4a.script"; 45 public static final String MULTIPLE_MIME = "vnd.android.cursor.dir/vnd.sl4a.script"; 46 47 private static final int LIVEFOLDER_ID = 1; 48 private static final int SUGGESTIONS_ID = 2; 49 50 public static final String AUTHORITY = ScriptProvider.class.getName().toLowerCase(); 51 public static final String LIVEFOLDER = "liveFolder"; 52 public static final String SUGGESTIONS = "searchSuggestions/*/*"; 53 54 private final UriMatcher mUriMatcher; 55 56 private Context mContext; 57 private InterpreterConfiguration mConfiguration; 58 59 public ScriptProvider() { 60 mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 61 mUriMatcher.addURI(AUTHORITY, LIVEFOLDER, LIVEFOLDER_ID); 62 mUriMatcher.addURI(AUTHORITY, SUGGESTIONS, SUGGESTIONS_ID); 63 } 64 65 @Override 66 public int delete(Uri uri, String selection, String[] selectionArgs) { 67 return 0; 68 } 69 70 @Override 71 public String getType(Uri uri) { 72 if (uri.getLastPathSegment().equals("scripts")) { 73 return MULTIPLE_MIME; 74 } 75 return SINGLE_MIME; 76 } 77 78 @Override 79 public Uri insert(Uri uri, ContentValues values) { 80 return null; 81 } 82 83 @Override 84 public boolean onCreate() { 85 mContext = getContext(); 86 mConfiguration = new InterpreterConfiguration(mContext); 87 mConfiguration.startDiscovering(); 88 return true; 89 } 90 91 @Override 92 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 93 String sortOrder) { 94 switch (mUriMatcher.match(uri)) { 95 case LIVEFOLDER_ID: 96 return queryLiveFolder(); 97 case SUGGESTIONS_ID: 98 String query = uri.getLastPathSegment().toLowerCase(); 99 return querySearchSuggestions(query); 100 default: 101 return null; 102 } 103 } 104 105 private Cursor querySearchSuggestions(String query) { 106 String[] columns = 107 { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, 108 SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_ICON_2, 109 SearchManager.SUGGEST_COLUMN_QUERY, SearchManager.SUGGEST_COLUMN_SHORTCUT_ID }; 110 MatrixCursor cursor = new MatrixCursor(columns); 111 int index = 0; 112 for (File script : ScriptStorageAdapter.listExecutableScripts(null, mConfiguration)) { 113 String scriptName = script.getName().toLowerCase(); 114 if (!scriptName.contains(query)) { 115 continue; 116 } 117 Interpreter interpreter = mConfiguration.getInterpreterForScript(scriptName); 118 String secondLine = interpreter.getNiceName(); 119 int icon = FeaturedInterpreters.getInterpreterIcon(mContext, interpreter.getExtension()); 120 Object[] row = 121 { index, scriptName, secondLine, icon, scriptName, 122 SearchManager.SUGGEST_NEVER_MAKE_SHORTCUT }; 123 cursor.addRow(row); 124 ++index; 125 } 126 return cursor; 127 } 128 129 private Cursor queryLiveFolder() { 130 String[] columns = 131 { BaseColumns._ID, LiveFolders.NAME, LiveFolders.INTENT, LiveFolders.ICON_RESOURCE, 132 LiveFolders.ICON_PACKAGE, LiveFolders.DESCRIPTION }; 133 MatrixCursor cursor = new MatrixCursor(columns); 134 int index = 0; 135 for (File script : ScriptStorageAdapter.listExecutableScriptsRecursively(null, mConfiguration)) { 136 int iconId = 0; 137 if (script.isDirectory()) { 138 iconId = R.drawable.folder; 139 } else { 140 iconId = FeaturedInterpreters.getInterpreterIcon(mContext, script.getName()); 141 if (iconId == 0) { 142 iconId = R.drawable.sl4a_logo_32; 143 } 144 } 145 ShortcutIconResource icon = ShortcutIconResource.fromContext(mContext, iconId); 146 Intent intent = IntentBuilders.buildStartInBackgroundIntent(script); 147 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 148 String description = script.getAbsolutePath(); 149 if (description.startsWith(InterpreterConstants.SCRIPTS_ROOT)) { 150 description = description.replaceAll(InterpreterConstants.SCRIPTS_ROOT, "scripts/"); 151 } 152 Object[] row = 153 { index, script.getName(), intent.toURI(), icon.resourceName, icon.packageName, 154 description }; 155 cursor.addRow(row); 156 ++index; 157 } 158 return cursor; 159 } 160 161 @Override 162 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 163 return 0; 164 } 165 166 } 167