1 /******************************************************************************* 2 * This file is part of BOINC. 3 * http://boinc.berkeley.edu 4 * Copyright (C) 2012 University of California 5 * 6 * BOINC is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU Lesser General Public License 8 * as published by the Free Software Foundation, 9 * either version 3 of the License, or (at your option) any later version. 10 * 11 * BOINC is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * See the GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with BOINC. If not, see <http://www.gnu.org/licenses/>. 18 ******************************************************************************/ 19 20 package edu.berkeley.boinc.attach; 21 22 import edu.berkeley.boinc.BOINCActivity; 23 import edu.berkeley.boinc.R; 24 import edu.berkeley.boinc.utils.*; 25 import android.app.Dialog; 26 import android.app.Service; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.ServiceConnection; 31 import android.net.ConnectivityManager; 32 import android.net.NetworkInfo; 33 import android.os.AsyncTask; 34 import android.os.Bundle; 35 import android.os.IBinder; 36 import android.support.v4.app.DialogFragment; 37 import android.util.Log; 38 import android.view.LayoutInflater; 39 import android.view.View; 40 import android.view.View.OnClickListener; 41 import android.view.ViewGroup; 42 import android.view.Window; 43 import android.widget.ArrayAdapter; 44 import android.widget.Button; 45 import android.widget.EditText; 46 import android.widget.LinearLayout; 47 import android.widget.Spinner; 48 import android.widget.TextView; 49 import android.widget.Toast; 50 51 public class AcctMgrFragment extends DialogFragment{ 52 53 private ProjectAttachService attachService = null; 54 private boolean asIsBound = false; 55 56 private Spinner urlSpinner; 57 private EditText nameInput; 58 private EditText pwdInput; 59 private TextView warning; 60 private LinearLayout ongoingWrapper; 61 private Button continueB; 62 63 private boolean returnToMainActivity = false; 64 65 private AttachProjectAsyncTask asyncTask; 66 67 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)68 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 69 if(Logging.DEBUG) Log.d(Logging.TAG, "AcctMgrFragment onCreateView"); 70 doBindService(); 71 View v = inflater.inflate(R.layout.attach_project_acctmgr_dialog, container, false); 72 73 urlSpinner = (Spinner) v.findViewById(R.id.url_spinner); 74 ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(),R.array.acct_mgr_url_list, android.R.layout.simple_spinner_item); 75 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 76 urlSpinner.setAdapter(adapter); 77 78 nameInput = (EditText) v.findViewById(R.id.name_input); 79 pwdInput = (EditText) v.findViewById(R.id.pwd_input); 80 warning = (TextView) v.findViewById(R.id.warning); 81 ongoingWrapper = (LinearLayout) v.findViewById(R.id.ongoing_wrapper); 82 continueB = (Button) v.findViewById(R.id.continue_button); 83 continueB.setOnClickListener(new OnClickListener() { 84 @Override 85 public void onClick(View arg0) { 86 if(Logging.DEBUG) Log.d(Logging.TAG, "AcctMgrFragment continue clicked"); 87 if(!checkDeviceOnline()) return; 88 if(asIsBound) { 89 90 // get user input 91 String url = urlSpinner.getSelectedItem().toString(); 92 String name = nameInput.getText().toString(); 93 String pwd = pwdInput.getText().toString(); 94 95 // verify input 96 int res; 97 if((res = verifyInput(url, name, pwd)) != 0){ 98 warning.setText(res); 99 warning.setVisibility(View.VISIBLE); 100 return; 101 } 102 103 // adapt layout 104 continueB.setVisibility(View.GONE); 105 warning.setVisibility(View.GONE); 106 ongoingWrapper.setVisibility(View.VISIBLE); 107 108 String[] params = new String[3]; 109 params[0] = url; 110 params[1] = name; 111 params[2] = pwd; 112 asyncTask = new AttachProjectAsyncTask(); 113 asyncTask.execute(params); 114 115 } else if(Logging.DEBUG) Log.d(Logging.TAG, "AcctMgrFragment service not bound, do nothing..."); 116 } 117 }); 118 119 return v; 120 } 121 122 @Override onDestroyView()123 public void onDestroyView() { 124 doUnbindService(); 125 if(asyncTask != null) asyncTask.cancel(true); 126 super.onDestroyView(); 127 } 128 129 @Override onCreateDialog(Bundle savedInstanceState)130 public Dialog onCreateDialog(Bundle savedInstanceState) { 131 Dialog dialog = super.onCreateDialog(savedInstanceState); 132 133 // request a window without the title 134 dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); 135 return dialog; 136 } 137 setReturnToMainActivity()138 public void setReturnToMainActivity() { 139 returnToMainActivity = true; 140 } 141 verifyInput(String url, String name, String pwd)142 private int verifyInput(String url, String name, String pwd) { 143 int stringResource = 0; 144 145 // check input 146 if(url.length() == 0) { 147 stringResource = R.string.attachproject_error_no_url; 148 } 149 else if(name.length() == 0) { 150 stringResource = R.string.attachproject_error_no_name; 151 } 152 else if(pwd.length() == 0) { 153 stringResource = R.string.attachproject_error_no_pwd; 154 } 155 156 return stringResource; 157 } 158 159 // check whether device is online before starting connection attempt 160 // as needed for AttachProjectLoginActivity (retrieval of ProjectConfig) 161 // note: available internet does not imply connection to project server 162 // is possible! checkDeviceOnline()163 private Boolean checkDeviceOnline() { 164 ConnectivityManager connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); 165 NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 166 Boolean online = activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting(); 167 if(!online) { 168 Toast toast = Toast.makeText(getActivity(), R.string.attachproject_list_no_internet, Toast.LENGTH_SHORT); 169 toast.show(); 170 if(Logging.DEBUG) Log.d(Logging.TAG, "AttachProjectListActivity not online, stop!"); 171 } 172 return online; 173 } 174 175 private ServiceConnection mASConnection = new ServiceConnection() { 176 public void onServiceConnected(ComponentName className, IBinder service) { 177 // This is called when the connection with the service has been established, getService returns 178 // the Monitor object that is needed to call functions. 179 attachService = ((ProjectAttachService.LocalBinder)service).getService(); 180 asIsBound = true; 181 } 182 183 public void onServiceDisconnected(ComponentName className) { 184 // This should not happen 185 attachService = null; 186 asIsBound = false; 187 } 188 }; 189 doBindService()190 private void doBindService() { 191 // bind to attach service 192 getActivity().bindService(new Intent(getActivity(), ProjectAttachService.class), mASConnection, Service.BIND_AUTO_CREATE); 193 } 194 doUnbindService()195 private void doUnbindService() { 196 if (asIsBound) { 197 // Detach existing connection. 198 getActivity().unbindService(mASConnection); 199 asIsBound = false; 200 } 201 } 202 mapErrorNumToString(int code)203 private String mapErrorNumToString(int code) { 204 if(Logging.DEBUG) Log.d(Logging.TAG,"mapErrorNumToString for error: " + code); 205 int stringResource; 206 switch (code) { 207 case BOINCErrors.ERR_DB_NOT_FOUND: 208 stringResource = R.string.attachproject_error_wrong_name; 209 break; 210 case BOINCErrors.ERR_GETHOSTBYNAME: 211 stringResource = R.string.attachproject_error_no_internet; 212 break; 213 case BOINCErrors.ERR_NONUNIQUE_EMAIL: // treat the same as -137, ERR_DB_NOT_UNIQUE 214 // no break!! 215 case BOINCErrors.ERR_DB_NOT_UNIQUE: 216 stringResource = R.string.attachproject_error_email_in_use; 217 break; 218 case BOINCErrors.ERR_PROJECT_DOWN: 219 stringResource = R.string.attachproject_error_project_down; 220 break; 221 case BOINCErrors.ERR_BAD_EMAIL_ADDR: 222 stringResource = R.string.attachproject_error_email_bad_syntax; 223 break; 224 case BOINCErrors.ERR_BAD_PASSWD: 225 stringResource = R.string.attachproject_error_bad_pwd; 226 break; 227 case BOINCErrors.ERR_BAD_USER_NAME: 228 stringResource = R.string.attachproject_error_bad_username; 229 break; 230 case BOINCErrors.ERR_ACCT_CREATION_DISABLED: 231 stringResource = R.string.attachproject_error_creation_disabled; 232 break; 233 case BOINCErrors.ERR_INVALID_URL: 234 stringResource = R.string.attachproject_error_invalid_url; 235 break; 236 default: 237 stringResource = R.string.attachproject_error_unknown; 238 break; 239 } 240 return getString(stringResource); 241 } 242 243 private class AttachProjectAsyncTask extends AsyncTask<String, Void, Integer> { 244 245 @Override onPreExecute()246 protected void onPreExecute() { 247 super.onPreExecute(); 248 } 249 250 @Override doInBackground(String... arg0)251 protected Integer doInBackground(String... arg0) { 252 253 String url = arg0[0]; 254 String name = arg0[1]; 255 String pwd = arg0[2]; 256 257 return attachService.attachAcctMgr(url,name,pwd); 258 } 259 260 @Override onPostExecute(Integer result)261 protected void onPostExecute(Integer result) { 262 super.onPostExecute(result); 263 if(Logging.DEBUG) Log.d(Logging.TAG, "AcctMgrFragment.AttachProjectAsyncTask onPostExecute, returned: " + result); 264 if(result == BOINCErrors.ERR_OK) { 265 dismiss(); 266 if(returnToMainActivity) { 267 if(Logging.DEBUG) Log.d(Logging.TAG, "AcctMgrFragment.AttachProjectAsyncTask onPostExecute, start main activity"); 268 Intent intent = new Intent(getActivity(), BOINCActivity.class); 269 // add flags to return to main activity and clearing all others and clear the back stack 270 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 271 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 272 intent.putExtra("targetFragment", R.string.tab_projects); // make activity display projects fragment 273 startActivity(intent); 274 } 275 } 276 else { 277 ongoingWrapper.setVisibility(View.GONE); 278 continueB.setVisibility(View.VISIBLE); 279 warning.setVisibility(View.VISIBLE); 280 warning.setText(mapErrorNumToString(result)); 281 } 282 } 283 } 284 } 285