Home | History | Annotate | Download | only in interpreter
      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