1 /* 2 * Copyright (C) 2016 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * 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 * @author Alexey Reznichenko (alexey.reznichenko (at) gmail.com) 43 */ 44 public abstract class InterpreterProvider extends ContentProvider { 45 46 private static final int PROPERTIES = 1; 47 private static final int ENVIRONMENT_VARIABLES = 2; 48 private static final int ARGUMENTS = 3; 49 50 private UriMatcher mUriMatcher; 51 private SharedPreferences mPreferences; 52 53 private InterpreterDescriptor mDescriptor; 54 private Context mContext; 55 56 public static final String MIME = "vnd.android.cursor.item/vnd.googlecode.interpreter"; 57 58 public InterpreterProvider() { 59 mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 60 String auth = this.getClass().getName().toLowerCase(); 61 mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_PROPERTIES, PROPERTIES); 62 mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ENVIRONMENT_VARIABLES, 63 ENVIRONMENT_VARIABLES); 64 mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ARGUMENTS, ARGUMENTS); 65 } 66 67 /** 68 * Returns an instance of the class that implements the desired {@link InterpreterDescriptor}. 69 */ 70 protected abstract InterpreterDescriptor getDescriptor(); 71 72 @Override 73 public int delete(Uri uri, String selection, String[] selectionArgs) { 74 return 0; 75 } 76 77 @Override 78 public String getType(Uri uri) { 79 return MIME; 80 } 81 82 @Override 83 public Uri insert(Uri uri, ContentValues values) { 84 return null; 85 } 86 87 @Override 88 public boolean onCreate() { 89 mDescriptor = getDescriptor(); 90 mContext = getContext(); 91 mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); 92 return false; 93 } 94 95 @Override 96 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 97 String sortOrder) { 98 if (!isInterpreterInstalled()) { 99 return null; 100 } 101 Map<String, String> map; 102 switch (mUriMatcher.match(uri)) { 103 case PROPERTIES: 104 map = getProperties(); 105 break; 106 case ENVIRONMENT_VARIABLES: 107 map = getEnvironmentVariables(); 108 break; 109 case ARGUMENTS: 110 map = getArguments(); 111 break; 112 default: 113 map = null; 114 } 115 return buildCursorFromMap(map); 116 } 117 118 @Override 119 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 120 return 0; 121 } 122 123 private boolean isInterpreterInstalled() { 124 return mPreferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false); 125 } 126 127 private Cursor buildCursorFromMap(Map<String, String> map) { 128 if (map == null) { 129 return null; 130 } 131 MatrixCursor cursor = new MatrixCursor(map.keySet().toArray(new String[map.size()])); 132 cursor.addRow(map.values()); 133 return cursor; 134 } 135 136 private Map<String, String> getProperties() { 137 Map<String, String> values = new HashMap<String, String>(); 138 values.put(InterpreterPropertyNames.NAME, mDescriptor.getName()); 139 values.put(InterpreterPropertyNames.NICE_NAME, mDescriptor.getNiceName()); 140 values.put(InterpreterPropertyNames.EXTENSION, mDescriptor.getExtension()); 141 values.put(InterpreterPropertyNames.BINARY, mDescriptor.getBinary(mContext).getAbsolutePath()); 142 values.put(InterpreterPropertyNames.INTERACTIVE_COMMAND, mDescriptor 143 .getInteractiveCommand(mContext)); 144 values.put(InterpreterPropertyNames.SCRIPT_COMMAND, mDescriptor.getScriptCommand(mContext)); 145 values.put(InterpreterPropertyNames.HAS_INTERACTIVE_MODE, Boolean.toString(mDescriptor 146 .hasInteractiveMode())); 147 return values; 148 } 149 150 private Map<String, String> getEnvironmentVariables() { 151 Map<String, String> values = new HashMap<String, String>(); 152 values.putAll(mDescriptor.getEnvironmentVariables(mContext)); 153 return values; 154 } 155 156 private Map<String, String> getArguments() { 157 Map<String, String> values = new LinkedHashMap<String, String>(); 158 int column = 0; 159 for (String argument : mDescriptor.getArguments(mContext)) { 160 values.put(Integer.toString(column), argument); 161 column++; 162 } 163 return values; 164 } 165 } 166