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.interpreter; 18 19 import android.content.ContentProvider; 20 import android.content.ContentValues; 21 import android.content.Context; 22 import android.content.SharedPreferences; 23 import android.content.UriMatcher; 24 import android.database.Cursor; 25 import android.database.MatrixCursor; 26 import android.net.Uri; 27 import android.preference.PreferenceManager; 28 29 import java.util.HashMap; 30 import java.util.LinkedHashMap; 31 import java.util.Map; 32 33 /** 34 * A provider that can be queried to obtain execution-related interpreter info. 35 * 36 * <p> 37 * To create an interpreter APK, please extend this content provider and implement getDescriptor() 38 * and getEnvironmentSettings().<br> 39 * Please declare the provider in the android manifest xml (the authority values has to be set to 40 * your_package_name.provider_name). 41 * 42 */ 43 public abstract class InterpreterProvider extends ContentProvider { 44 45 private static final int PROPERTIES = 1; 46 private static final int ENVIRONMENT_VARIABLES = 2; 47 private static final int ARGUMENTS = 3; 48 49 private UriMatcher mUriMatcher; 50 private SharedPreferences mPreferences; 51 52 private InterpreterDescriptor mDescriptor; 53 private Context mContext; 54 55 public static final String MIME = "vnd.android.cursor.item/vnd.googlecode.interpreter"; 56 57 public InterpreterProvider() { 58 mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 59 String auth = this.getClass().getName().toLowerCase(); 60 mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_PROPERTIES, PROPERTIES); 61 mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ENVIRONMENT_VARIABLES, 62 ENVIRONMENT_VARIABLES); 63 mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ARGUMENTS, ARGUMENTS); 64 } 65 66 /** 67 * Returns an instance of the class that implements the desired {@link InterpreterDescriptor}. 68 */ 69 protected abstract InterpreterDescriptor getDescriptor(); 70 71 @Override 72 public int delete(Uri uri, String selection, String[] selectionArgs) { 73 return 0; 74 } 75 76 @Override 77 public String getType(Uri uri) { 78 return MIME; 79 } 80 81 @Override 82 public Uri insert(Uri uri, ContentValues values) { 83 return null; 84 } 85 86 @Override 87 public boolean onCreate() { 88 mDescriptor = getDescriptor(); 89 mContext = getContext(); 90 mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); 91 return false; 92 } 93 94 @Override 95 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 96 String sortOrder) { 97 if (!isInterpreterInstalled()) { 98 return null; 99 } 100 Map<String, String> map; 101 switch (mUriMatcher.match(uri)) { 102 case PROPERTIES: 103 map = getProperties(); 104 break; 105 case ENVIRONMENT_VARIABLES: 106 map = getEnvironmentVariables(); 107 break; 108 case ARGUMENTS: 109 map = getArguments(); 110 break; 111 default: 112 map = null; 113 } 114 return buildCursorFromMap(map); 115 } 116 117 @Override 118 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 119 return 0; 120 } 121 122 private boolean isInterpreterInstalled() { 123 return mPreferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false); 124 } 125 126 private Cursor buildCursorFromMap(Map<String, String> map) { 127 if (map == null) { 128 return null; 129 } 130 MatrixCursor cursor = new MatrixCursor(map.keySet().toArray(new String[map.size()])); 131 cursor.addRow(map.values()); 132 return cursor; 133 } 134 135 private Map<String, String> getProperties() { 136 Map<String, String> values = new HashMap<String, String>(); 137 values.put(InterpreterPropertyNames.NAME, mDescriptor.getName()); 138 values.put(InterpreterPropertyNames.NICE_NAME, mDescriptor.getNiceName()); 139 values.put(InterpreterPropertyNames.EXTENSION, mDescriptor.getExtension()); 140 values.put(InterpreterPropertyNames.BINARY, mDescriptor.getBinary(mContext).getAbsolutePath()); 141 values.put(InterpreterPropertyNames.INTERACTIVE_COMMAND, mDescriptor 142 .getInteractiveCommand(mContext)); 143 values.put(InterpreterPropertyNames.SCRIPT_COMMAND, mDescriptor.getScriptCommand(mContext)); 144 values.put(InterpreterPropertyNames.HAS_INTERACTIVE_MODE, Boolean.toString(mDescriptor 145 .hasInteractiveMode())); 146 return values; 147 } 148 149 private Map<String, String> getEnvironmentVariables() { 150 Map<String, String> values = new HashMap<String, String>(); 151 values.putAll(mDescriptor.getEnvironmentVariables(mContext)); 152 return values; 153 } 154 155 private Map<String, String> getArguments() { 156 Map<String, String> values = new LinkedHashMap<String, String>(); 157 int column = 0; 158 for (String argument : mDescriptor.getArguments(mContext)) { 159 values.put(Integer.toString(column), argument); 160 column++; 161 } 162 return values; 163 } 164 } 165