• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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.android.terminal;
18 
19 import static com.android.terminal.Terminal.TAG;
20 
21 import android.app.Activity;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.ServiceConnection;
26 import android.os.Bundle;
27 import android.os.IBinder;
28 import android.os.Parcelable;
29 import android.support.v4.view.PagerAdapter;
30 import android.support.v4.view.PagerTitleStrip;
31 import android.support.v4.view.ViewPager;
32 import android.util.Log;
33 import android.util.SparseArray;
34 import android.view.Menu;
35 import android.view.MenuItem;
36 import android.view.View;
37 import android.view.ViewGroup;
38 
39 /**
40  * Activity that displays all {@link Terminal} instances running in a bound
41  * {@link TerminalService}.
42  */
43 public class TerminalActivity extends Activity {
44 
45     private TerminalService mService;
46 
47     private ViewPager mPager;
48     private PagerTitleStrip mTitles;
49 
50     private final ServiceConnection mServiceConn = new ServiceConnection() {
51         @Override
52         public void onServiceConnected(ComponentName name, IBinder service) {
53             mService = ((TerminalService.ServiceBinder) service).getService();
54 
55             final int size = mService.getTerminals().size();
56             Log.d(TAG, "Bound to service with " + size + " active terminals");
57 
58             // Give ourselves at least one terminal session
59             if (size == 0) {
60                 mService.createTerminal();
61             }
62 
63             // Bind UI to known terminals
64             mTermAdapter.notifyDataSetChanged();
65             invalidateOptionsMenu();
66         }
67 
68         @Override
69         public void onServiceDisconnected(ComponentName name) {
70             mService = null;
71             throw new RuntimeException("Service in same process disconnected?");
72         }
73     };
74 
75     private final PagerAdapter mTermAdapter = new PagerAdapter() {
76         private SparseArray<SparseArray<Parcelable>>
77                 mSavedState = new SparseArray<SparseArray<Parcelable>>();
78 
79         @Override
80         public int getCount() {
81             if (mService != null) {
82                 return mService.getTerminals().size();
83             } else {
84                 return 0;
85             }
86         }
87 
88         @Override
89         public Object instantiateItem(ViewGroup container, int position) {
90             final TerminalView view = new TerminalView(container.getContext());
91             view.setId(android.R.id.list);
92 
93             final Terminal term = mService.getTerminals().valueAt(position);
94             view.setTerminal(term);
95 
96             final SparseArray<Parcelable> state = mSavedState.get(term.key);
97             if (state != null) {
98                 view.restoreHierarchyState(state);
99             }
100 
101             container.addView(view);
102             return view;
103         }
104 
105         @Override
106         public void destroyItem(ViewGroup container, int position, Object object) {
107             final TerminalView view = (TerminalView) object;
108 
109             final int key = view.getTerminal().key;
110             SparseArray<Parcelable> state = mSavedState.get(key);
111             if (state == null) {
112                 state = new SparseArray<Parcelable>();
113                 mSavedState.put(key, state);
114             }
115             view.saveHierarchyState(state);
116 
117             view.setTerminal(null);
118             container.removeView(view);
119         }
120 
121         @Override
122         public int getItemPosition(Object object) {
123             final TerminalView view = (TerminalView) object;
124             final int key = view.getTerminal().key;
125             final int index = mService.getTerminals().indexOfKey(key);
126             if (index == -1) {
127                 return POSITION_NONE;
128             } else {
129                 return index;
130             }
131         }
132 
133         @Override
134         public boolean isViewFromObject(View view, Object object) {
135             return view == object;
136         }
137 
138         @Override
139         public CharSequence getPageTitle(int position) {
140             return mService.getTerminals().valueAt(position).getTitle();
141         }
142     };
143 
144     @Override
onCreate(Bundle savedInstanceState)145     protected void onCreate(Bundle savedInstanceState) {
146         super.onCreate(savedInstanceState);
147 
148         setContentView(R.layout.activity);
149 
150         mPager = (ViewPager) findViewById(R.id.pager);
151         mTitles = (PagerTitleStrip) findViewById(R.id.titles);
152 
153         mPager.setAdapter(mTermAdapter);
154     }
155 
156     @Override
onStart()157     protected void onStart() {
158         super.onStart();
159         bindService(
160                 new Intent(this, TerminalService.class), mServiceConn, Context.BIND_AUTO_CREATE);
161     }
162 
163     @Override
onStop()164     protected void onStop() {
165         super.onStop();
166         unbindService(mServiceConn);
167     }
168 
169     @Override
onCreateOptionsMenu(Menu menu)170     public boolean onCreateOptionsMenu(Menu menu) {
171         getMenuInflater().inflate(R.menu.activity, menu);
172         return true;
173     }
174 
175     @Override
onPrepareOptionsMenu(Menu menu)176     public boolean onPrepareOptionsMenu(Menu menu) {
177         super.onPrepareOptionsMenu(menu);
178         menu.findItem(R.id.menu_close_tab).setEnabled(mTermAdapter.getCount() > 0);
179         return true;
180     }
181 
182     @Override
onOptionsItemSelected(MenuItem item)183     public boolean onOptionsItemSelected(MenuItem item) {
184         switch (item.getItemId()) {
185             case R.id.menu_new_tab: {
186                 mService.createTerminal();
187                 mTermAdapter.notifyDataSetChanged();
188                 invalidateOptionsMenu();
189                 final int index = mService.getTerminals().size() - 1;
190                 mPager.setCurrentItem(index, true);
191                 return true;
192             }
193             case R.id.menu_close_tab: {
194                 final int index = mPager.getCurrentItem();
195                 final int key = mService.getTerminals().keyAt(index);
196                 mService.destroyTerminal(key);
197                 mTermAdapter.notifyDataSetChanged();
198                 invalidateOptionsMenu();
199                 return true;
200             }
201         }
202         return false;
203     }
204 }
205