19f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li/* 2f04335f899f2cce69f843692a3cb9cec229683c2tturney * Copyright (C) 2017 The Android Open Source Project 39f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 4f04335f899f2cce69f843692a3cb9cec229683c2tturney * Licensed under the Apache License, Version 2.0 (the "License"); 5f04335f899f2cce69f843692a3cb9cec229683c2tturney * you may not use this file except in compliance with the License. 6f04335f899f2cce69f843692a3cb9cec229683c2tturney * You may obtain a copy of the License at 79f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 8f04335f899f2cce69f843692a3cb9cec229683c2tturney * http://www.apache.org/licenses/LICENSE-2.0 99f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * 109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Unless required by applicable law or agreed to in writing, software 11f04335f899f2cce69f843692a3cb9cec229683c2tturney * distributed under the License is distributed on an "AS IS" BASIS, 12f04335f899f2cce69f843692a3cb9cec229683c2tturney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f04335f899f2cce69f843692a3cb9cec229683c2tturney * See the License for the specific language governing permissions and 14f04335f899f2cce69f843692a3cb9cec229683c2tturney * limitations under the License. 159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */ 169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Lipackage com.googlecode.android_scripting.activity; 189f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 199f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.app.AlertDialog; 209f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.app.ListActivity; 219f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.DialogInterface; 229f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.Intent; 239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.DialogInterface.OnClickListener; 249f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.os.Bundle; 259f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.view.ContextMenu; 269f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.view.Menu; 279f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.view.MenuItem; 289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.view.View; 299f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.view.ViewGroup; 309f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.view.ContextMenu.ContextMenuInfo; 319f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.widget.AdapterView; 329f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.widget.BaseAdapter; 339f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.widget.ListView; 349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.widget.TextView; 359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.google.common.collect.Lists; 379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.ActivityFlinger; 389f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.BaseApplication; 399f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.Constants; 409f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.Log; 419f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.R; 429f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.facade.FacadeConfiguration; 439f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.rpc.MethodDescriptor; 449f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.trigger.ScriptTrigger; 459f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.trigger.Trigger; 469f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.trigger.TriggerRepository; 479f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.trigger.TriggerRepository.TriggerRepositoryObserver; 489f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 499f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.io.File; 509f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.util.Collections; 519f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.util.List; 529f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.util.Map; 539f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 549f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Lipublic class TriggerManager extends ListActivity { 559f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private final List<ScriptTrigger> mTriggers = Lists.newArrayList(); 569f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 579f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private ScriptTriggerAdapter mAdapter; 589f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private TriggerRepository mTriggerRepository; 599f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 609f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private static enum ContextMenuId { 619f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li REMOVE; 629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public int getId() { 639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return ordinal() + Menu.FIRST; 649f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 659f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 669f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private static enum MenuId { 689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ADD, PREFERENCES, HELP; 699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public int getId() { 709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return ordinal() + Menu.FIRST; 719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 759f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li protected void onCreate(Bundle savedInstanceState) { 769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li super.onCreate(savedInstanceState); 779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li CustomizeWindow.requestCustomTitle(this, "Triggers", R.layout.trigger_manager); 789f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ScriptTriggerListObserver observer = new ScriptTriggerListObserver(); 799f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mAdapter = new ScriptTriggerAdapter(); 809f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li setListAdapter(mAdapter); 819f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li registerForContextMenu(getListView()); 829f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggerRepository = ((BaseApplication) getApplication()).getTriggerRepository(); 839f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggerRepository.bootstrapObserver(observer); 849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ActivityFlinger.attachView(getListView(), this); 859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ActivityFlinger.attachView(getWindow().getDecorView(), this); 869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 899f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public boolean onCreateOptionsMenu(Menu menu) { 909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li menu.add(Menu.NONE, MenuId.ADD.getId(), Menu.NONE, "Add").setIcon( 919f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li android.R.drawable.ic_menu_add); 929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon( 939f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li android.R.drawable.ic_menu_preferences); 949f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return true; 959f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 979f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 989f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public boolean onOptionsItemSelected(MenuItem item) { 999f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li int itemId = item.getItemId(); 1009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (itemId == MenuId.PREFERENCES.getId()) { 1019f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li startActivity(new Intent(this, Preferences.class)); 1029f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } else if (itemId != Menu.NONE) { 1039f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Intent intent = new Intent(this, ScriptPicker.class); 1049f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li intent.setAction(Intent.ACTION_PICK); 1059f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li startActivityForResult(intent, itemId); 1069f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1079f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return true; 1089f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1099f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1119f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 1129f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li menu.add(Menu.NONE, ContextMenuId.REMOVE.getId(), Menu.NONE, "Remove"); 1139f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1149f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public boolean onContextItemSelected(MenuItem item) { 1179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li AdapterView.AdapterContextMenuInfo info; 1189f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li try { 1199f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 1209f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } catch (ClassCastException e) { 1219f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.e("Bad menuInfo", e); 1229f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return false; 1239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1249f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1259f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Trigger trigger = mAdapter.getItem(info.position); 1269f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (trigger == null) { 1279f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Log.v("No trigger selected."); 1289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return false; 1299f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1309f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1319f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (item.getItemId() == ContextMenuId.REMOVE.getId()) { 1329f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggerRepository.remove(trigger); 1339f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return true; 1359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1389f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onListItemClick(ListView l, View v, int position, long id) { 1399f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mAdapter.notifyDataSetInvalidated(); 1409f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1419f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1429f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private class ScriptTriggerListObserver implements TriggerRepositoryObserver { 1439f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1449f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1459f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onPut(Trigger trigger) { 1469f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggers.add((ScriptTrigger) trigger); 1479f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mAdapter.notifyDataSetInvalidated(); 1489f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1499f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1509f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1519f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onRemove(Trigger trigger) { 1529f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggers.remove(trigger); 1539f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mAdapter.notifyDataSetInvalidated(); 1549f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1559f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1569f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1579f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li private class ScriptTriggerAdapter extends BaseAdapter { 1589f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1599f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1609f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public int getCount() { 1619f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return mTriggers.size(); 1629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1649f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1659f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public Trigger getItem(int position) { 1669f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return mTriggers.get(position); 1679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public long getItemId(int position) { 1719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return position; 1729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1759f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public View getView(final int position, View convertView, ViewGroup parent) { 1769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li ScriptTrigger trigger = mTriggers.get(position); 1779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li TextView textView = new TextView(TriggerManager.this); 1789f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li textView.setText(trigger.getEventName() + " " + trigger.getScript().getName()); 1799f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li return textView; 1809f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1819f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1829f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 1839f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li protected void onActivityResult(int requestCode, int resultCode, Intent data) { 1859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (resultCode == RESULT_OK) { 1869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li final File script = new File(data.getStringExtra(Constants.EXTRA_SCRIPT_PATH)); 1879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li if (requestCode == MenuId.ADD.getId()) { 1889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Map<String, MethodDescriptor> eventMethodDescriptors = 1899f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li FacadeConfiguration.collectStartEventMethodDescriptors(); 1909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li final List<String> eventNames = Lists.newArrayList(eventMethodDescriptors.keySet()); 1919f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li Collections.sort(eventNames); 1929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li AlertDialog.Builder builder = new AlertDialog.Builder(this); 1939f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li builder.setItems(eventNames.toArray(new CharSequence[eventNames.size()]), 1949f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li new OnClickListener() { 1959f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li @Override 1969f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void onClick(DialogInterface dialog, int position) { 1979f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggerRepository.put(new ScriptTrigger(eventNames.get(position), script)); 1989f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 1999f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li }); 2009f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li builder.show(); 2019f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2029f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2039f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2049f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li 2059f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li public void clickCancel(View v) { 2069f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li for (Trigger t : mTriggerRepository.getAllTriggers().values()) { 2079f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li mTriggerRepository.remove(t); 2089f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2099f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li } 2109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li} 211