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.activity; 18 19 import android.app.AlertDialog; 20 import android.app.ListActivity; 21 import android.content.Context; 22 import android.content.DialogInterface; 23 import android.content.DialogInterface.OnClickListener; 24 import android.content.Intent; 25 import android.content.SharedPreferences; 26 import android.database.DataSetObserver; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.preference.PreferenceManager; 30 import android.view.LayoutInflater; 31 import android.view.Menu; 32 import android.view.MenuItem; 33 import android.view.SubMenu; 34 import android.view.View; 35 import android.view.ViewGroup; 36 import android.widget.BaseAdapter; 37 import android.widget.ImageView; 38 import android.widget.LinearLayout; 39 import android.widget.ListView; 40 import android.widget.TextView; 41 42 import com.googlecode.android_scripting.ActivityFlinger; 43 import com.googlecode.android_scripting.BaseApplication; 44 import com.googlecode.android_scripting.Constants; 45 import com.googlecode.android_scripting.FeaturedInterpreters; 46 import com.googlecode.android_scripting.R; 47 import com.googlecode.android_scripting.interpreter.Interpreter; 48 import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; 49 import com.googlecode.android_scripting.interpreter.InterpreterConfiguration.ConfigurationObserver; 50 51 import java.net.URL; 52 import java.util.ArrayList; 53 import java.util.List; 54 55 public class InterpreterManager extends ListActivity { 56 57 private InterpreterManagerAdapter mAdapter; 58 private InterpreterListObserver mObserver; 59 private List<Interpreter> mInterpreters; 60 private List<String> mFeaturedInterpreters; 61 private InterpreterConfiguration mConfiguration; 62 private SharedPreferences mPreferences; 63 64 private static enum MenuId { 65 HELP, ADD, NETWORK, PREFERENCES; getId()66 public int getId() { 67 return ordinal() + Menu.FIRST; 68 } 69 } 70 71 @Override onCreate(Bundle savedInstanceState)72 public void onCreate(Bundle savedInstanceState) { 73 super.onCreate(savedInstanceState); 74 CustomizeWindow.requestCustomTitle(this, "Interpreters", R.layout.interpreter_manager); 75 mConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); 76 mInterpreters = new ArrayList<Interpreter>(); 77 mAdapter = new InterpreterManagerAdapter(); 78 mObserver = new InterpreterListObserver(); 79 mAdapter.registerDataSetObserver(mObserver); 80 setListAdapter(mAdapter); 81 ActivityFlinger.attachView(getListView(), this); 82 ActivityFlinger.attachView(getWindow().getDecorView(), this); 83 mFeaturedInterpreters = FeaturedInterpreters.getList(); 84 mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 85 } 86 87 @Override onStart()88 public void onStart() { 89 super.onStart(); 90 mConfiguration.registerObserver(mObserver); 91 mAdapter.notifyDataSetInvalidated(); 92 } 93 94 @Override onResume()95 protected void onResume() { 96 super.onResume(); 97 mAdapter.notifyDataSetInvalidated(); 98 } 99 100 @Override onStop()101 public void onStop() { 102 super.onStop(); 103 mConfiguration.unregisterObserver(mObserver); 104 } 105 106 @Override onPrepareOptionsMenu(Menu menu)107 public boolean onPrepareOptionsMenu(Menu menu) { 108 menu.clear(); 109 buildInstallLanguagesMenu(menu); 110 menu.add(Menu.NONE, MenuId.NETWORK.getId(), Menu.NONE, "Start Server").setIcon( 111 android.R.drawable.ic_menu_share); 112 menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon( 113 android.R.drawable.ic_menu_preferences); 114 return super.onPrepareOptionsMenu(menu); 115 } 116 buildInstallLanguagesMenu(Menu menu)117 private void buildInstallLanguagesMenu(Menu menu) { 118 SubMenu installMenu = 119 menu.addSubMenu(Menu.NONE, MenuId.ADD.getId(), Menu.NONE, "Add").setIcon( 120 android.R.drawable.ic_menu_add); 121 int i = MenuId.values().length + Menu.FIRST; 122 for (String interpreterName : mFeaturedInterpreters) { 123 installMenu.add(Menu.NONE, i++, Menu.NONE, interpreterName); 124 } 125 } 126 127 @Override onOptionsItemSelected(MenuItem item)128 public boolean onOptionsItemSelected(MenuItem item) { 129 int itemId = item.getItemId(); 130 if (itemId == MenuId.NETWORK.getId()) { 131 AlertDialog.Builder dialog = new AlertDialog.Builder(this); 132 dialog.setItems(new CharSequence[] { "Public", "Private" }, new OnClickListener() { 133 @Override 134 public void onClick(DialogInterface dialog, int which) { 135 launchService(which == 0 /* usePublicIp */); 136 } 137 }); 138 dialog.show(); 139 } else if (itemId == MenuId.PREFERENCES.getId()) { 140 startActivity(new Intent(this, Preferences.class)); 141 } else if (itemId >= MenuId.values().length + Menu.FIRST) { 142 int i = itemId - MenuId.values().length - Menu.FIRST; 143 if (i < mFeaturedInterpreters.size()) { 144 URL url = FeaturedInterpreters.getUrlForName(mFeaturedInterpreters.get(i)); 145 Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url.toString())); 146 startActivity(viewIntent); 147 } 148 } 149 return true; 150 } 151 getPrefInt(String key, int defaultValue)152 private int getPrefInt(String key, int defaultValue) { 153 int result = defaultValue; 154 String value = mPreferences.getString(key, null); 155 if (value != null) { 156 try { 157 result = Integer.parseInt(value); 158 } catch (NumberFormatException e) { 159 result = defaultValue; 160 } 161 } 162 return result; 163 } 164 launchService(boolean usePublicIp)165 private void launchService(boolean usePublicIp) { 166 Intent intent = new Intent(this, ScriptingLayerService.class); 167 intent.setAction(Constants.ACTION_LAUNCH_SERVER); 168 intent.putExtra(Constants.EXTRA_USE_EXTERNAL_IP, usePublicIp); 169 intent.putExtra(Constants.EXTRA_USE_SERVICE_PORT, getPrefInt("use_service_port", 0)); 170 startService(intent); 171 } 172 launchTerminal(Interpreter interpreter)173 private void launchTerminal(Interpreter interpreter) { 174 Intent intent = new Intent(this, ScriptingLayerService.class); 175 intent.setAction(Constants.ACTION_LAUNCH_INTERPRETER); 176 intent.putExtra(Constants.EXTRA_INTERPRETER_NAME, interpreter.getName()); 177 startService(intent); 178 } 179 180 @Override onListItemClick(ListView list, View view, int position, long id)181 protected void onListItemClick(ListView list, View view, int position, long id) { 182 Interpreter interpreter = (Interpreter) list.getItemAtPosition(position); 183 launchTerminal(interpreter); 184 } 185 186 @Override onDestroy()187 public void onDestroy() { 188 super.onDestroy(); 189 mConfiguration.unregisterObserver(mObserver); 190 } 191 192 private class InterpreterListObserver extends DataSetObserver implements ConfigurationObserver { 193 @Override onInvalidated()194 public void onInvalidated() { 195 mInterpreters = mConfiguration.getInteractiveInterpreters(); 196 } 197 198 @Override onChanged()199 public void onChanged() { 200 mInterpreters = mConfiguration.getInteractiveInterpreters(); 201 } 202 203 @Override onConfigurationChanged()204 public void onConfigurationChanged() { 205 runOnUiThread(new Runnable() { 206 @Override 207 public void run() { 208 mAdapter.notifyDataSetChanged(); 209 } 210 }); 211 } 212 } 213 214 private class InterpreterManagerAdapter extends BaseAdapter { 215 216 @Override getCount()217 public int getCount() { 218 return mInterpreters.size(); 219 } 220 221 @Override getItem(int position)222 public Object getItem(int position) { 223 return mInterpreters.get(position); 224 } 225 226 @Override getItemId(int position)227 public long getItemId(int position) { 228 return position; 229 } 230 231 @Override getView(int position, View convertView, ViewGroup parent)232 public View getView(int position, View convertView, ViewGroup parent) { 233 LinearLayout container; 234 235 Interpreter interpreter = mInterpreters.get(position); 236 237 if (convertView == null) { 238 LayoutInflater inflater = 239 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 240 container = (LinearLayout) inflater.inflate(R.layout.list_item, null); 241 } else { 242 container = (LinearLayout) convertView; 243 } 244 ImageView img = (ImageView) container.findViewById(R.id.list_item_icon); 245 246 int imgId = 247 FeaturedInterpreters.getInterpreterIcon(InterpreterManager.this, 248 interpreter.getExtension()); 249 if (imgId == 0) { 250 imgId = R.drawable.sl4a_logo_32; 251 } 252 253 img.setImageResource(imgId); 254 255 TextView text = (TextView) container.findViewById(R.id.list_item_title); 256 257 text.setText(interpreter.getNiceName()); 258 return container; 259 } 260 } 261 } 262