/** * Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET * (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije * informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE * COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp., * INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM * ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC)) * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.societies.android.platform.useragent.feedback; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.*; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.CompoundButton.OnCheckedChangeListener; import org.societies.android.api.comms.IMethodCallback; import org.societies.android.api.comms.xmpp.VCardParcel; import org.societies.android.api.events.IAndroidSocietiesEvents; import org.societies.android.api.events.IPlatformEventsCallback; import org.societies.android.api.events.PlatformEventsHelperNotConnectedException; import org.societies.android.platform.useragent.feedback.constants.UserFeedbackActivityIntentExtra; import org.societies.android.remote.helper.EventsHelper; import org.societies.api.internal.schema.useragent.feedback.UserFeedbackAccessControlEvent; import org.societies.api.schema.identity.RequestorBean; import org.societies.api.schema.identity.RequestorServiceBean; import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.Condition; import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.RequestItem; import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.ResponseItem; import java.util.List; public class AccessControlActivity extends Activity implements OnItemSelectedListener { private static final String LOG_TAG = AccessControlActivity.class.getCanonicalName(); private EventsHelper eventsHelper; private UserFeedbackAccessControlEvent accessControlEvent = null; private boolean isEventsConnected = false; private TableLayout[] tblConditions; private ScrollView svScroll; private boolean published = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_negotiation); eventsHelper = new EventsHelper(this); //GET EVENT OBJECT Intent intent = getIntent(); Bundle bundle = intent.getExtras(); accessControlEvent = bundle.getParcelable(UserFeedbackActivityIntentExtra.EXTRA_PRIVACY_POLICY); //SET HEADER INFO RequestorBean requestor = accessControlEvent.getRequestor(); Log.d(LOG_TAG, String.format("Requestor is of type %s", requestor != null ? requestor.getClass().getSimpleName() : "[null]")); String sRequestorType = "community"; if (requestor instanceof RequestorServiceBean) { sRequestorType = "installed service"; } TextView lblHeader = (TextView) findViewById(R.id.txtHeader); //lblHeader.setText(sHeader + "\r\n has requested access to the following data:"); lblHeader.setText("The " + sRequestorType + " is requesting access to your personal info for the following uses. Please select what you would like to allow:"); //GENERATE RESOURCE SPINNER final List<ResponseItem> responses = accessControlEvent.getResponseItems(); String[] resourceItems = new String[responses.size()]; for (int i = 0; i < responses.size(); i++) { resourceItems[i] = responses.get(i).getRequestItem().getResource().getDataType(); } Spinner spinResources = (Spinner) findViewById(R.id.spinResource); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, resourceItems); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinResources.setAdapter(adapter); spinResources.setOnItemSelectedListener(this); //PROCESS EACH RESPONSE tblConditions = new TableLayout[responses.size()]; populateResponseGuiTable(responses); //ADD FIRST TABLE OF CONDITIONS TO SCROLL VIEW - OTHERS ADDED ON CHANGE EVENT svScroll = (ScrollView) findViewById(R.id.svConditions); svScroll.addView(tblConditions[0]); //ACCEPT BUTTON EVENT HANDLER Button btnAccept = (Button) findViewById(R.id.btnAccept); btnAccept.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { publishEvent(); finish(); } }); //CANCEL BUTTON EVENT HANDLER Button btnCancel = (Button) findViewById(R.id.btnCancel); btnCancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); //BASICALLY, IGNORE REQUEST } }); //ADD IMAGE - IF AVAILABLE populateAvatar(); } private void populateAvatar() { try { VCardParcel vCard = getIntent().getParcelableExtra(UserFeedbackActivityIntentExtra.EXTRA_CSS_VCARD); byte[] avatarBytes = vCard.getAvatar(); if (avatarBytes != null) { Bitmap bMap = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length); ImageView image = (ImageView) findViewById(R.id.imageProfile); image.setImageBitmap(bMap); } } catch (Exception ex) { Log.w(LOG_TAG, "Error loading avatar", ex); } } private void populateResponseGuiTable(List<ResponseItem> responses) { for (int response_idx = 0; response_idx < responses.size(); response_idx++) { ResponseItem response = responses.get(response_idx); RequestItem request = response.getRequestItem(); List<Condition> conditions = request.getConditions(); TableLayout tblCondition = new TableLayout(this); tblCondition.setBackgroundResource(R.color.Grey); View[] requestControls = new View[conditions.size()]; //EACH CONDITION for (int condition_idx = 0; condition_idx < conditions.size(); condition_idx++) { Condition condition = conditions.get(condition_idx); String contentDescription = response_idx + "_" + condition_idx; View newControl = createGuiControlFromCondition(responses, condition, contentDescription); requestControls[condition_idx] = newControl; TableRow row = new TableRow(this); row.setId(condition_idx); //row.addView(requestLabels[i]); TextView label = new TextView(this); label.setText(condition.getConditionConstant().value()); row.addView(label); row.addView(requestControls[condition_idx]); tblCondition.addView(row); } tblConditions[response_idx] = tblCondition; } } private View createGuiControlFromCondition(final List<ResponseItem> responses, Condition condition, String contentDescription) { //DATA TYPE - CHECKBOX/TEXTBOX if (condition.getConditionConstant().value().startsWith("data")) { final EditText textbox = new EditText(this); textbox.setText(condition.getValue()); textbox.setContentDescription(contentDescription); textbox.addTextChangedListener(new TextWatcher() { EditText thisTextBox = textbox; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { String textValue = thisTextBox.getText().toString(); String posValues = (String) thisTextBox.getContentDescription(); String[] positions = posValues.split("_"); int responsePos = Integer.parseInt(positions[0]); int conditionPos = Integer.parseInt(positions[1]); responses.get(responsePos).getRequestItem().getConditions().get(conditionPos).setValue(textValue); } }); return textbox; } else { CheckBox checkbox = new CheckBox(this); checkbox.setChecked(true); checkbox.setEnabled(condition.isOptional()); checkbox.setContentDescription(contentDescription); checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { String conditionValue = (isChecked ? "1" : "0"); String posValues = (String) buttonView.getContentDescription(); String[] positions = posValues.split("_"); int responsePos = Integer.parseInt(positions[0]); int conditionPos = Integer.parseInt(positions[1]); responses.get(responsePos).getRequestItem().getConditions().get(conditionPos).setValue(conditionValue); } }); return checkbox; } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_negotiation, menu); return true; } /* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long) */ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { svScroll.removeAllViews(); svScroll.addView(tblConditions[position]); } /* @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView) */ @Override public void onNothingSelected(AdapterView<?> parent) { } @Override public void onDestroy() { Log.d(LOG_TAG, "AccessControlActivity terminating"); if (isEventsConnected) { eventsHelper.tearDownService(new IMethodCallback() { @Override public void returnException(String result) { } @Override public void returnAction(String result) { } @Override public void returnAction(boolean resultFlag) { } }); } super.onDestroy(); } private void publishEvent() { if (!published) { //EVENT IS BEING PUBLISHED MULTIPLE TIMES if (!isEventsConnected) { eventsHelper.setUpService(new IMethodCallback() { @Override public void returnException(String result) { } @Override public void returnAction(String result) { } @Override public void returnAction(boolean resultFlag) { if (resultFlag) { try { isEventsConnected = true; published = true; eventsHelper.publishEvent(IAndroidSocietiesEvents.UF_ACCESS_CONTROL_RESPONSE_INTENT, AccessControlActivity.this.accessControlEvent, new IPlatformEventsCallback() { @Override public void returnException(int exception) { Log.e(LOG_TAG, "Error received after publishing response event: " + exception); } @Override public void returnAction(int result) { Log.i(LOG_TAG, "Action received after publishing response event: " + result); } @Override public void returnAction(boolean resultFlag) { Log.i(LOG_TAG, "Action received after publishing response event: " + resultFlag); } }); } catch (PlatformEventsHelperNotConnectedException e) { Log.e(LOG_TAG, "Error publishing AC response event", e); e.printStackTrace(); } } } }); } } } }