Commit 7b85a42e authored by idic's avatar idic

Fix scenario

parent c2949545
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
......
......@@ -11,6 +11,7 @@ import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.*;
import org.prlab.idic.privacypolicy.adapter.MessageRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.ble.BLECustomScript;
import org.prlab.idic.privacypolicy.pojo.Message;
......@@ -18,8 +19,10 @@ import org.prlab.idic.privacypolicy.schedule.Scheduled;
import org.prlab.idic.privacypolicy.storage.PrivacyPolicyStorageImpl;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static android.bluetooth.BluetoothGatt.GATT_SUCCESS;
......@@ -27,7 +30,6 @@ import static android.bluetooth.BluetoothGatt.GATT_SUCCESS;
public class DeviceOperatorActivity extends AppCompatActivity {
private static final String TAG = DeviceOperatorActivity.class.getSimpleName();
private UUID PRIVACY_POLICY_ACCEPT_UUID;
private PrivacyPolicyStorageImpl mPolicyStorage;
private String mTargetDeviceAddress;
......@@ -45,6 +47,15 @@ public class DeviceOperatorActivity extends AppCompatActivity {
private BroadcastReceiver mPairRequestReceiver;
private BroadcastReceiver mBondStateReceiver;
private final UUID PRIVACY_NEGOTIATION_UUID = UUID.fromString("22220000-2222-2222-2222-222222222222");
private final UUID PRIVACY_POLICY_UUID = UUID.fromString("2222aaaa-2222-2222-2222-222222222222");
private final UUID PRIVACY_ACTION_UUID = UUID.fromString("2222bbbb-2222-2222-2222-222222222222");
private final UUID PRIVACY_PREFERENCE_UUID = UUID.fromString("2222cccc-2222-2222-2222-222222222222");
private final int BLE_POLICY_QUERY = 0x00;
private final int BLE_POLICY_ACCEPT = 0x01;
private final int BLE_POLICY_DECLINE = 0x02;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -52,7 +63,6 @@ public class DeviceOperatorActivity extends AppCompatActivity {
mTargetDeviceAddress = getIntent().getStringExtra(getString(R.string.intent_target_address_key));
mPolicyStorage = new PrivacyPolicyStorageImpl(getContentResolver(), mTargetDeviceAddress);
PRIVACY_POLICY_ACCEPT_UUID = UUID.fromString(getString(R.string.uuid_accept_privacy_policy));
initView();
initBluetooth();
......@@ -90,11 +100,7 @@ public class DeviceOperatorActivity extends AppCompatActivity {
@Override
public void onClick(View v) {
if (mBluetoothGatt != null) {
BluetoothGattService service = mBluetoothGatt.getService(ROOT_UUID);
BluetoothGattCharacteristic temperature = service == null ? null : service.getCharacteristic(TEMPERATURE_UUID);
if (temperature != null) {
notifyTemperature();
}
notifyTemperature();
}
}
};
......@@ -158,101 +164,155 @@ public class DeviceOperatorActivity extends AppCompatActivity {
});
}
private List<Scheduled> mPermissionSettingQueue = new LinkedList<>();
private List<Scheduled> mPreferenceSettingQueue = new LinkedList<>();
volatile long startTime;
private BLECustomScript mBLECustomScript = new BLECustomScript() {
int expectedSuccessValue = 0;
int successValue = 0;
static final int SELECTION_LOWER_BOUND = 1;
static final int SELECTION_UPPER_BOUND = 3;
volatile int expectedSuccessValue = 0;
volatile int successValue = 0;
void requestServices() {
if (successValue == expectedSuccessValue) {
setMessageBar("Try to request services.");
addMessage("Request Services", "Try to get temperature & air purifier state.");
notifyTemperature();
}
}
BluetoothGattService permissionService;
BluetoothGattCharacteristic policyCharacteristic;
BluetoothGattCharacteristic actionCharacteristic;
BluetoothGattCharacteristic preferenceCharacteristic;
private boolean settingPermission() {
if (mPermissionSettingQueue.size() > 0) {
private boolean continueNegotiating() {
if (mPreferenceSettingQueue.size() > 0) {
Log.i(TAG, "Continue to work.");
mPermissionSettingQueue.remove(0).work();
Scheduled scheduled = mPreferenceSettingQueue.remove(0);
scheduled.work();
return false;
}
return true;
}
@Override
public void onDiscoverServiceCompleted(final BluetoothGatt gatt) {
public void onDiscoverServiceCompleted(BluetoothGatt gatt) {
expectedSuccessValue = 0;
successValue = 0;
permissionService = gatt.getService(PRIVACY_NEGOTIATION_UUID);
policyCharacteristic = permissionService.getCharacteristic(PRIVACY_POLICY_UUID);
actionCharacteristic = permissionService.getCharacteristic(PRIVACY_ACTION_UUID);
preferenceCharacteristic = permissionService.getCharacteristic(PRIVACY_PREFERENCE_UUID);
Set<Integer> acceptList = new HashSet<>();
List<List<Integer>> subAcceptList = new LinkedList<>();
setMessageBar("Enable privacy policy setting.");
for (BluetoothGattService service : gatt.getServices()) {
if (PRIVACY_NEGOTIATION_UUID.equals(service.getUuid()))
continue;
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(String.valueOf(service.getUuid()));
//Write service layer selection
int selection = mPolicyStorage.get(layerUUIDs);
if (selection != -1) {
final BluetoothGattCharacteristic characteristic = service.getCharacteristic(PRIVACY_POLICY_ACCEPT_UUID);
if (characteristic != null) {
final int finalSelection = selection;
mPermissionSettingQueue.add(new Scheduled() {
@Override
public void work() {
setCharacteristicPermission(mBluetoothGatt, characteristic, finalSelection);
}
});
addMessage("Policy Setting", "Set " + BaseUtils.stringList2ArrayString(layerUUIDs) + " to " + selection + ".");
}
List<Integer> selections = mPolicyStorage.get(layerUUIDs);
for (int selection : selections) {
acceptList.add(selection);
}
for (BluetoothGattCharacteristic characteristic2 : service.getCharacteristics()) {
layerUUIDs.add(String.valueOf(characteristic2.getUuid()));
//Write characteristic layer selection
selection = mPolicyStorage.get(layerUUIDs);
if (selection != -1) {
final BluetoothGattDescriptor descriptor = characteristic2.getDescriptor(PRIVACY_POLICY_ACCEPT_UUID);
if (descriptor != null) {
final int finalSelection1 = selection;
mPermissionSettingQueue.add(new Scheduled() {
@Override
public void work() {
setDescriptorPermission(gatt, descriptor, finalSelection1);
}
});
addMessage("Policy Setting", "Set " + BaseUtils.stringList2ArrayString(layerUUIDs) + " to " + selection + ".");
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
layerUUIDs.add(String.valueOf(characteristic.getUuid()));
selections = mPolicyStorage.get(layerUUIDs);
if (selections.size() > 0) {
List<Integer> list = new LinkedList<>();
for (int selection : selections) {
list.add(selection);
}
subAcceptList.add(list);
}
layerUUIDs.remove(layerUUIDs.size() - 1);
}
}
settingPermission();
if (subAcceptList.size() > 0) {
acceptList.clear();
for (List<Integer> list : subAcceptList) {
acceptList.addAll(list);
}
}
for (int selection = SELECTION_LOWER_BOUND; selection < SELECTION_UPPER_BOUND; selection++) {
if (acceptList.contains(selection)) {
addPreference(selection);
} else {
removePreference(selection);
}
}
continueNegotiating();
}
private void setCharacteristicPermission(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int selection) {
characteristic.setValue(new byte[]{(byte) selection});
Log.i(TAG, String.valueOf(selection));
gatt.writeCharacteristic(characteristic);
expectedSuccessValue++;
private void addPreference(final int selection) {
mPreferenceSettingQueue.add(new setTargetTask(selection));
mPreferenceSettingQueue.add(new acceptPreferenceTask());
mPreferenceSettingQueue.add(new checkPreferenceTask());
}
private void setDescriptorPermission(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int selection) {
descriptor.setValue(new byte[]{(byte) selection});
Log.i(TAG, String.valueOf(selection));
gatt.writeDescriptor(descriptor);
expectedSuccessValue++;
private void removePreference(final int selection) {
mPreferenceSettingQueue.add(new setTargetTask(selection));
mPreferenceSettingQueue.add(new declinePreferenceTask());
mPreferenceSettingQueue.add(new checkPreferenceTask());
}
class setTargetTask implements Scheduled {
private int selection;
setTargetTask(int selection) {
this.selection = selection;
}
@Override
public void work() {
policyCharacteristic.setValue(new byte[]{(byte) selection});
mBluetoothGatt.writeCharacteristic(policyCharacteristic);
expectedSuccessValue++;
}
}
class acceptPreferenceTask implements Scheduled {
@Override
public void work() {
actionCharacteristic.setValue(new byte[]{(byte) BLE_POLICY_ACCEPT});
mBluetoothGatt.writeCharacteristic(actionCharacteristic);
expectedSuccessValue++;
}
}
class declinePreferenceTask implements Scheduled {
@Override
public void work() {
actionCharacteristic.setValue(new byte[]{(byte) BLE_POLICY_DECLINE});
mBluetoothGatt.writeCharacteristic(actionCharacteristic);
expectedSuccessValue++;
}
}
class checkPreferenceTask implements Scheduled {
@Override
public void work() {
mBluetoothGatt.readCharacteristic(preferenceCharacteristic);
expectedSuccessValue++;
}
}
private volatile int target;
@Override
public void onWriteCharacteristicCompleted(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status, byte[] values) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(characteristic.getUuid())) {
if (PRIVACY_POLICY_UUID.equals(characteristic.getUuid())) {
successValue++;
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(characteristic.getService().getUuid().toString());
target = BaseUtils.bytesToInt(values);
addMessage("Policy Setting",
"Set " + BaseUtils.stringList2ArrayString(layerUUIDs) + (status == GATT_SUCCESS ? " success" : " failure") + " .");
if (settingPermission())
requestServices();
"Set target policy " + target + (status == GATT_SUCCESS ? " success" : " failure") + " .");
continueNegotiating();
} else if (PRIVACY_ACTION_UUID.equals(characteristic.getUuid())) {
int action = BaseUtils.bytesToInt(values);
addMessage("Policy Setting",
"Send policy " + target + " -> " +
(action == BLE_POLICY_ACCEPT ? " accept" : "decline") + ".");
continueNegotiating();
} else if (AIR_UUID.equals(characteristic.getUuid())) {
addMessage("Air Purifier Setting", "Try to turn " + (BaseUtils.bytesToInt(values) == 1 ? "on " : "off ") + "the air purifier" + ".");
requestAirPurifier();
......@@ -261,7 +321,13 @@ public class DeviceOperatorActivity extends AppCompatActivity {
@Override
public void onReadCharacteristicCompleted(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status, byte[] values) {
if (AIR_UUID.equals(characteristic.getUuid())) {
if (PRIVACY_PREFERENCE_UUID.equals(characteristic.getUuid())) {
int action = BaseUtils.bytesToInt(values);
addMessage("Policy Setting",
"Policy " + target + " -> " +
(action == BLE_POLICY_ACCEPT ? " is accepted" : "declined") + ".");
continueNegotiating();
} else if (AIR_UUID.equals(characteristic.getUuid())) {
resolveAirPurifier(BaseUtils.bytesToInt(values));
addMessage("Air Purifier Setting", "The air purifier is " + (BaseUtils.bytesToInt(values) == 1 ? "on" : "off") + ".");
}
......@@ -269,18 +335,9 @@ public class DeviceOperatorActivity extends AppCompatActivity {
@Override
public void onWriteDescriptorCompleted(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status, byte[] values) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(descriptor.getUuid())) {
successValue++;
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(descriptor.getCharacteristic().getService().getUuid().toString());
layerUUIDs.add(descriptor.getCharacteristic().getUuid().toString());
addMessage("Policy Setting", "Set " + BaseUtils.stringList2ArrayString(layerUUIDs) +
(status == GATT_SUCCESS ? " success" : " failure") + " .");
if (settingPermission())
requestServices();
} else if (CCCD_UUID.equals(descriptor.getUuid())) {
addMessage("Temperature Setting", (!isSubscribe ? "Subscribe" : "Unsubscribe")
+ " temperature data of air conditioner.");
if (CCCD_UUID.equals(descriptor.getUuid())) {
addMessage("Temperature Setting", (!isSubscribe ? "Subscribe" : "Unsubscribe") +
" temperature data of air conditioner.");
isSubscribe = !isSubscribe;
runOnUiThread(new Runnable() {
@Override
......@@ -288,8 +345,7 @@ public class DeviceOperatorActivity extends AppCompatActivity {
mTemperatureButton.setImageResource(isSubscribe ? R.drawable.ic_timer_off_black_24dp : R.drawable.ic_timer_black_24dp);
}
});
requestAirPurifier();
setMessageBar("Device setting finished.");
continueNegotiating();
}
}
......@@ -329,8 +385,9 @@ public class DeviceOperatorActivity extends AppCompatActivity {
String mac = gatt.getDevice().getAddress();
if (status == GATT_SUCCESS) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
gatt.discoverServices();
startTime = System.currentTimeMillis();
addMessage("Connection State Change ", "Device " + mac + " is connected.");
gatt.discoverServices();
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
mBluetoothGatt.close();
mBluetoothGatt = null;
......@@ -358,10 +415,6 @@ public class DeviceOperatorActivity extends AppCompatActivity {
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// if ((status & (BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION | BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION)) != 0) {
// boolean isSuccessful = gatt.getDevice().createBond();
// Log.i(TAG, "Create Bond is " + isSuccessful);
// }
mBLECustomScript.onReadCharacteristicCompleted(mBluetoothGatt, characteristic, status, characteristic.getValue());
}
......@@ -483,8 +536,9 @@ public class DeviceOperatorActivity extends AppCompatActivity {
});
}
private void addMessage(String event, String message) {
addMessage(event, message, false);
addMessage(String.format("%s - Time:[%s]", event, System.currentTimeMillis() - startTime), message, false);
}
private void addMessage(final String event, final String message, final boolean isMarked) {
......
......@@ -12,10 +12,13 @@ import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.prlab.idic.privacypolicy.adapter.IntegerButtonRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.adapter.StringButtonRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.pojo.report.Layer;
......@@ -106,7 +109,7 @@ public class ReportActivity extends Activity implements LoaderManager.LoaderCall
mSelectionRecyclerView.setAdapter(mSelectionRecyclerViewAdapter);
mLayerTitleTextView = (TextView) findViewById(R.id.text_report_child_layers_title);
mLayerRecyclerViewAdapter = new StringButtonRecyclerViewAdapter(getResources(), mChildLayersClickListener);
mLayerRecyclerViewAdapter = new StringButtonRecyclerViewAdapter(mChildLayersClickListener);
mLayerRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_report_child_layers);
mLayerRecyclerView.setAdapter(mLayerRecyclerViewAdapter);
}
......@@ -136,7 +139,7 @@ public class ReportActivity extends Activity implements LoaderManager.LoaderCall
public void onClick(View v) {
mPolicyStorage.remove(mLayerIDs);
mResetButton.setEnabled(false);
mSelectionRecyclerViewAdapter.setTarget(-1);
mSelectionRecyclerViewAdapter.resetTarget();
}
};
......@@ -146,9 +149,12 @@ public class ReportActivity extends Activity implements LoaderManager.LoaderCall
if (ACTIVITY_SELECTION_RESULT_ID == requestCode) {
if (RESULT_OK == resultCode) {
int selection = data.getIntExtra(getString(R.string.intent_policy_response_selection_key), -1);
mPolicyStorage.put(selection, mLayerIDs);
List<Integer> selections = mPolicyStorage.get(mLayerIDs);
selections.add(selection);
mPolicyStorage.remove(mLayerIDs);
mPolicyStorage.put(selections, mLayerIDs);
mResetButton.setEnabled(true);
mSelectionRecyclerViewAdapter.setTarget(selection);
mSelectionRecyclerViewAdapter.addTarget(selection);
}
}
}
......@@ -220,9 +226,11 @@ public class ReportActivity extends Activity implements LoaderManager.LoaderCall
mReportTitleTextView.setText(title);
mPolicyIDs = currentLayer.getPolicies();
mSelectionRecyclerViewAdapter.setItems(mPolicyIDs);
int target = mPolicyStorage.get(mLayerIDs);
mResetButton.setEnabled(target != -1);
mSelectionRecyclerViewAdapter.setTarget(target);
List<Integer> targets = mPolicyStorage.get(mLayerIDs);
mResetButton.setEnabled(targets.size() != 0);
mSelectionRecyclerViewAdapter.resetTarget();
for (Integer target : targets)
mSelectionRecyclerViewAdapter.addTarget(target);
checkEmpty(mPolicyIDs, mSelectionTitleTextView, mSelectionRecyclerView, mResetButton);
mChildLayerIDs = BaseUtils.layer2UUID(currentLayer.getSubLayers());
......@@ -249,7 +257,8 @@ public class ReportActivity extends Activity implements LoaderManager.LoaderCall
private Layer currentLayer(Layer root, int counter) {
if (mLayerIDs.size() - 1 == counter) return root;
for (Layer subLayer : root.getSubLayers()) {
if (subLayer.getUUID().equals(mLayerIDs.get(counter + 1))) return currentLayer(subLayer, counter + 1);
if (subLayer.getUUID().equals(mLayerIDs.get(counter + 1)))
return currentLayer(subLayer, counter + 1);
}
return root;
}
......
......@@ -6,8 +6,10 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import org.prlab.idic.privacypolicy.R;
import java.util.LinkedList;
import java.util.List;
/**
......@@ -18,7 +20,7 @@ public class IntegerButtonRecyclerViewAdapter extends RecyclerView.Adapter<Integ
private final String PRIVACY_POLICY_TITLE;
private ListItemClickListener listItemClickListener;
private List<Integer> items;
private Integer target = -1;
private List<Integer> target = new LinkedList<>();
public IntegerButtonRecyclerViewAdapter(Resources resources, ListItemClickListener listItemClickListener) {
this.PRIVACY_POLICY_TITLE = resources.getString(R.string.message_policy_title);
......@@ -30,16 +32,14 @@ public class IntegerButtonRecyclerViewAdapter extends RecyclerView.Adapter<Integ
notifyDataSetChanged();
}
public void setTarget(Integer target) {
int index = items.indexOf(this.target);
if (index != -1)
notifyItemChanged(index);
this.target = target;
public void addTarget(Integer target) {
this.target.add(target);
notifyDataSetChanged();
}
index = items.indexOf(this.target);
if (index != -1)
notifyItemChanged(index);
public void resetTarget() {
this.target.clear();
notifyDataSetChanged();
}
public interface ListItemClickListener {
......@@ -81,7 +81,7 @@ public class IntegerButtonRecyclerViewAdapter extends RecyclerView.Adapter<Integ
int item = items.get(listIndex);
String message = IntegerButtonRecyclerViewAdapter.this.PRIVACY_POLICY_TITLE + String.valueOf(item);
button.setText(message);
button.setEnabled(item != target);
button.setEnabled(!target.contains(item));
}
}
......
......@@ -32,7 +32,7 @@ public class StatementRecyclerViewAdapter extends RecyclerView.Adapter<Statement
private List<Statement> statements;
public StatementRecyclerViewAdapter(Resources resources, List<Statement> statements) {
CONSEQUENCE_TITLE = resources.getString(R.string.policy_statement_consequence_title);
CONSEQUENCE_TITLE = resources.getString(R.string.policy_statement_related_uuid_title);
PURPOSE_TYPE_TITLE = resources.getString(R.string.policy_statement_purpose_type);
PURPOSE_DESCRIPTION_TITLE = resources.getString(R.string.policy_statement_purpose_description);
......@@ -76,7 +76,7 @@ public class StatementRecyclerViewAdapter extends RecyclerView.Adapter<Statement
ViewHolder(View itemView) {
super(itemView);
mConsequenceTextView = (TextView) itemView.findViewById(R.id.recycler_view_statement_consequence);
mConsequenceTextView = (TextView) itemView.findViewById(R.id.recycler_view_statement_related_uuid);
mPurposesRecyclerView = (RecyclerView) itemView.findViewById(R.id.recycler_view_statement_purposes);
mDataRecyclerView = (RecyclerView) itemView.findViewById(R.id.recycler_view_statement_data);
mRemediesTextView = (TextView) itemView.findViewById(R.id.text_statement_remedies);
......@@ -84,7 +84,7 @@ public class StatementRecyclerViewAdapter extends RecyclerView.Adapter<Statement
mRetentionTextView = (TextView) itemView.findViewById(R.id.text_statement_retention);
}
private void bindConsequence(String consequence) {
private void bindRelatedUUID(String consequence) {
mConsequenceTextView.setText(consequence);
}
......@@ -142,7 +142,7 @@ public class StatementRecyclerViewAdapter extends RecyclerView.Adapter<Statement
void bind(int listIndex) {
Statement statement = statements.get(listIndex);
bindConsequence(statement.getConsequence());
bindRelatedUUID(statement.getRelatedUUID());
bindPurposes(statement.getPurposes());
bindData(statement.getData());
bindRemedies(statement.getRemedies());
......
package org.prlab.idic.privacypolicy.adapter;
import android.content.res.Resources;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
......@@ -19,7 +18,7 @@ public class StringButtonRecyclerViewAdapter extends RecyclerView.Adapter<String
private List<String> items;
private String target;
public StringButtonRecyclerViewAdapter(Resources resources, ListItemClickListener listItemClickListener) {
public StringButtonRecyclerViewAdapter(ListItemClickListener listItemClickListener) {
this.listItemClickListener = listItemClickListener;
}
......
......@@ -11,7 +11,7 @@ import java.util.List;
*/
public class Statement implements Parcelable {
private String consequence;
private String relatedUUID;
private List<Purpose> purposes = new LinkedList<>();
private List<Datum> data = new LinkedList<>();
private List<Recipient> recipients = new LinkedList<>();
......@@ -22,7 +22,7 @@ public class Statement implements Parcelable {
}
private Statement(Parcel in) {
consequence = in.readString();
relatedUUID = in.readString();
purposes = in.createTypedArrayList(Purpose.CREATOR);
data = in.createTypedArrayList(Datum.CREATOR);
recipients = in.createTypedArrayList(Recipient.CREATOR);
......@@ -49,7 +49,7 @@ public class Statement implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(consequence);
dest.writeString(relatedUUID);
dest.writeTypedList(purposes);
dest.writeTypedList(data);
dest.writeTypedList(recipients);
......@@ -57,12 +57,12 @@ public class Statement implements Parcelable {
dest.writeParcelable(retention, flags);
}
public String getConsequence() {
return consequence;
public String getRelatedUUID() {
return relatedUUID;
}
public Statement setConsequence(String consequence) {
this.consequence = consequence;
public Statement setRelatedUUID(String relatedUUID) {
this.relatedUUID = relatedUUID;
return this;
}
......@@ -138,7 +138,7 @@ public class Statement implements Parcelable {
Statement statement = (Statement) o;
if (consequence != null ? !consequence.equals(statement.consequence) : statement.consequence != null)
if (relatedUUID != null ? !relatedUUID.equals(statement.relatedUUID) : statement.relatedUUID != null)
return false;
if (purposes != null ? !purposes.equals(statement.purposes) : statement.purposes != null) return false;
if (data != null ? !data.equals(statement.data) : statement.data != null) return false;
......@@ -149,7 +149,7 @@ public class Statement implements Parcelable {
@Override
public int hashCode() {
int result = consequence != null ? consequence.hashCode() : 0;
int result = relatedUUID != null ? relatedUUID.hashCode() : 0;
result = 31 * result + (purposes != null ? purposes.hashCode() : 0);
result = 31 * result + (data != null ? data.hashCode() : 0);
result = 31 * result + (recipients != null ? recipients.hashCode() : 0);
......
......@@ -7,12 +7,12 @@ import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by IDIC on 2017/2/18.
*/
public class PrivacyPolicyDbHelper extends SQLiteOpenHelper {
class PrivacyPolicyDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "privacy_policy.db";
private static final int DATABASE_VERSION = 1;
public PrivacyPolicyDbHelper(Context context) {
PrivacyPolicyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
......@@ -21,9 +21,7 @@ public class PrivacyPolicyDbHelper extends SQLiteOpenHelper {
db.execSQL("CREATE TABLE " + PrivacyPolicyContract.PolicyEntry.TABLE_NAME + " (" +
PrivacyPolicyContract.PolicyEntry.COLUMN_MAC + " CHAR(12) NOT NULL, " +
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " TEXT NOT NULL, " +
PrivacyPolicyContract.PolicyEntry.COLUMN_PREFERENCE + " TEXT," + "PRIMARY KEY (" +
PrivacyPolicyContract.PolicyEntry.COLUMN_MAC + ", " +
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + "));");
PrivacyPolicyContract.PolicyEntry.COLUMN_PREFERENCE + " TEXT);");
}
@Override
......
......@@ -5,10 +5,13 @@ import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* Created by IDIC on 2017/2/15.
......@@ -47,49 +50,56 @@ public class PrivacyPolicyStorageImpl implements StorageInterface<Integer, Strin
PrivacyPolicyContract.getSqlSelectForMACAndUUIDsOnwards(),
new String[]{mTargetDeviceMAC, layerUUIDs}
);
removeChildLayerPolicies(layerUUIDs);
Log.i(TAG, "Remove [" + layerUUIDs + "] " + (impactRow == 1 ? "success" : "failure") + ".");
}
private void removeChildLayerPolicies(String layerUUIDs) {
List<String> subUUIDs = getRelatedUUIDs(true, layerUUIDs);
for (String subUUID : subUUIDs) {
remove(subUUID);
}
}
@Override
public StorageInterface put(Integer selection, List<String> layerUUIDs) {
public StorageInterface put(List<Integer> selection, List<String> layerUUIDs) {
put(selection, BaseUtils.stringList2ArrayString(layerUUIDs));
return this;
}
private void put(Integer selection, String layerUUIDs) {
ContentValues updateContentValues = new ContentValues();
updateContentValues.put(PrivacyPolicyContract.PolicyEntry.COLUMN_PREFERENCE, selection);
private void put(List<Integer> selection, String layerUUIDs) {
for (int s : selection) {
ContentValues updateContentValues = new ContentValues();
updateContentValues.put(PrivacyPolicyContract.PolicyEntry.COLUMN_PREFERENCE, s);
ContentValues insertContentValues = new ContentValues(updateContentValues);
insertContentValues.put(PrivacyPolicyContract.PolicyEntry.COLUMN_MAC, mTargetDeviceMAC);
insertContentValues.put(PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs, layerUUIDs);
Uri mNewUri = mContentResolver.insert(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
insertContentValues
);
if (mNewUri == null) {
int count = mContentResolver.update(
ContentValues insertContentValues = new ContentValues(updateContentValues);
insertContentValues.put(PrivacyPolicyContract.PolicyEntry.COLUMN_MAC, mTargetDeviceMAC);
insertContentValues.put(PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs, layerUUIDs);
Uri mNewUri = mContentResolver.insert(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
updateContentValues,
PrivacyPolicyContract.getSqlSelectForMACAndUUIDsOnwards(),
new String[]{mTargetDeviceMAC, layerUUIDs}
insertContentValues
);
Log.i(TAG, "Update " + String.valueOf(selection) + " to [" + layerUUIDs + "] " + (count == 1 ? "success" : "failure") + ".");
} else {
Log.i(TAG, "Put " + String.valueOf(selection) + " to [" + layerUUIDs + "] success.");
}
List<String> subUUIDs = getRelatedUUIDs(false, layerUUIDs);
for (String subUUID : subUUIDs) {
remove(subUUID);
if (mNewUri == null) {
int count = mContentResolver.update(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
updateContentValues,
PrivacyPolicyContract.getSqlSelectForMACAndUUIDsOnwards(),
new String[]{mTargetDeviceMAC, layerUUIDs}
);
Log.i(TAG, "Update " + String.valueOf(s) + " to [" + layerUUIDs + "] " + (count == 1 ? "success" : "failure") + ".");
} else {
Log.i(TAG, "Put " + String.valueOf(s) + " to [" + layerUUIDs + "] success.");
}
removeChildLayerPolicies(layerUUIDs);
}
}
@Override
public Integer get(List<String> layerUUIDs) {
public List<Integer> get(List<String> layerUUIDs) {
return get(BaseUtils.stringList2ArrayString(layerUUIDs));
}
private Integer get(String UUIDs) {
private List<Integer> get(String UUIDs) {
try (Cursor cursor = mContentResolver.query(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
PRIVACY_POLICY_PROJECTION,
......@@ -97,20 +107,37 @@ public class PrivacyPolicyStorageImpl implements StorageInterface<Integer, Strin
new String[]{mTargetDeviceMAC, UUIDs},
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " ASC")) {
if (cursor.getCount() == 1) {
List<Integer> targets = new LinkedList<>();
Set<Integer> targetSet = new HashSet<>();
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
String target = cursor.getString(INDEX_POLICY_PREFERENCE);
Log.i(TAG, "Get [" + UUIDs + "] -> [" + String.valueOf(target) + "]");
if (target == null) return null;
return Integer.valueOf(target);
do {
String target = cursor.getString(INDEX_POLICY_PREFERENCE);
Log.i(TAG, "Get [" + UUIDs + "] -> [" + String.valueOf(target) + "]");
if (target == null) return null;
targetSet.add(Integer.valueOf(target));
} while (cursor.moveToNext());
}
targetSet.addAll(getChildLayerPolicies(UUIDs));
targets.addAll(targetSet);
Log.i(TAG, "Get [" + UUIDs + "] -> null");
return -1;
return targets;
}
}
private List<Integer> getChildLayerPolicies(String layerUUIDs) {
List<Integer> selections = new LinkedList<>();
List<Integer> selectionSet = new LinkedList<>();
List<String> subUUIDs = getRelatedUUIDs(true, layerUUIDs);
for (String subUUID : subUUIDs) {
List<Integer> subSelections = get(subUUID);
if (subSelections != null)
selectionSet.addAll(subSelections);
}
selections.addAll(selectionSet);
return selections;
}
private List<String> getRelatedUUIDs(boolean isLower, String UUIDs) {
List<String> UUIDList = new LinkedList<>();
if (isLower) {
......@@ -120,10 +147,11 @@ public class PrivacyPolicyStorageImpl implements StorageInterface<Integer, Strin
PrivacyPolicyContract.getSqlSelectForMACAndRelatedUUIDsOnwards(),
new String[]{mTargetDeviceMAC, UUIDs + "_%"},
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " ASC")) {
while (cursor.moveToNext()) {
String targetUUIDs = cursor.getString(INDEX_POLICY_UUIDs);
UUIDList.add(targetUUIDs);
}
if (cursor != null)
while (cursor.moveToNext()) {
String targetUUIDs = cursor.getString(INDEX_POLICY_UUIDs);
UUIDList.add(targetUUIDs);
}
}
} else {
if (UUIDs.contains(", ")) {
......@@ -134,10 +162,11 @@ public class PrivacyPolicyStorageImpl implements StorageInterface<Integer, Strin
PrivacyPolicyContract.getSqlSelectForMACAndRelatedUUIDsOnwards(),
new String[]{mTargetDeviceMAC, "%" + UUIDs},
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " ASC")) {
while (cursor.moveToNext()) {
String targetUUIDs = cursor.getString(INDEX_POLICY_UUIDs);
UUIDList.add(targetUUIDs);
}
if (cursor != null)
while (cursor.moveToNext()) {
String targetUUIDs = cursor.getString(INDEX_POLICY_UUIDs);
UUIDList.add(targetUUIDs);
}
}
}
}
......
......@@ -9,8 +9,8 @@ interface StorageInterface<Result, Key> {
StorageInterface remove(List<Key> layerUUIDs);
StorageInterface put(Result choices, List<Key> layerUUIDs);
StorageInterface put(List<Result> choices, List<Key> layerUUIDs);
Result get(List<Key> layerUUIDs);
List<Result> get(List<Key> layerUUIDs);
}
......@@ -14,7 +14,7 @@
android:layout_height="wrap_content">
<TextView
android:text="@string/policy_statement_consequence_title"
android:text="@string/policy_statement_related_uuid_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
......@@ -26,7 +26,7 @@
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_view_statement_consequence"/>
android:id="@+id/recycler_view_statement_related_uuid"/>
<View
android:background="@color/colorSeparator"
......
<resources>
<string name="app_name">BLEPrivacyPolicyNegotiator</string>
<string name="uuid_accept_privacy_policy">22222222-2222-2222-2222-222222222222</string>
<string name="content_authority"
translatable="false">org.prlab.idic.privacypolicy</string>
<string name="action_enable_scan">Start Scanning</string>
<string name="action_disable_scan">Stop Scanning</string>
<string name="action_connect">Connect</string>
<string name="content_authority">org.prlab.idic.privacypolicy</string>
<string name="message_privacy_policy">Display Privacy Policy</string>
<string name="message_device_position_picture">Device Position Picture</string>
......@@ -36,8 +36,10 @@
<string name="bluetooth_bonded">BONDED</string>
<string name="bluetooth_not_bonded">NOT BONDED</string>
<string name="get_policy_url">http://140.118.110.172:4567/policy.json</string>
<string name="get_policy_id_parameter_key">id</string>
<string name="get_policy_url"
translatable="false">http://192.168.0.157:4567/policy.json</string>
<string name="get_policy_id_parameter_key"
translatable="false">id</string>
<string name="policy_information_title">Report</string>
<string name="policy_selections_title">Selection</string>
......@@ -46,16 +48,26 @@
<string name="policy_report_description_title">Description</string>
<string name="policy_report_device_information">Device Information</string>
<string name="device_udn_key">UDN</string>
<string name="device_name_key">Name</string>
<string name="device_type_key">Type</string>
<string name="device_manufacturer_name_key">Manufacturer Name</string>
<string name="device_manufacturer_url_key">Manufacturer Url</string>
<string name="device_manufacturer_serial_number_key">Serial Number</string>
<string name="device_model_name_key">Model Name</string>
<string name="device_model_url_key">Model Url</string>
<string name="device_model_description_key">Model Description</string>
<string name="device_upc_key">UPC</string>
<string name="device_udn_key"
translatable="false">UDN</string>
<string name="device_name_key"
translatable="false">Name</string>
<string name="device_type_key"
translatable="false">Type</string>
<string name="device_manufacturer_name_key"
translatable="false">Manufacturer Name</string>
<string name="device_manufacturer_url_key"
translatable="false">Manufacturer Url</string>
<string name="device_manufacturer_serial_number_key"
translatable="false">Serial Number</string>
<string name="device_model_name_key"
translatable="false">Model Name</string>
<string name="device_model_url_key"
translatable="false">Model Url</string>
<string name="device_model_description_key"
translatable="false">Model Description</string>
<string name="device_upc_key"
translatable="false">UPC</string>
<string name="policy_statement_collector_title">Collector</string>
<string name="policy_statement_dispute_title">Dispute</string>
......@@ -79,19 +91,27 @@
<string name="policy_statement_dispute_related_organization">Organization</string>
<string name="policy_statement_dispute_resolution_type">Type</string>
<string name="policy_statement_consequence_title">Consequence</string>
<string name="policy_statement_related_uuid_title">RelatedUUID</string>
<string name="policy_statement_access_title">Access</string>
<string name="policy_statement_remedies">Remedies</string>
<string name="policy_statement_title">Statement</string>
<string name="policy_statement_retention">Retention</string>
<string name="intent_report_id_key">REPORT_TARGET_ID</string>
<string name="intent_report_mac_key">REPORT_TARGET_MAC</string>
<string name="intent_policy_response_selection_key">POLICY_RESPONSE_SELECTION_ID</string>
<string name="intent_target_address_key">DEVICE_TARGET_ADDRESS</string>
<string name="intent_device_info_key">DEVICE_INFO_KEY</string>
<string name="intent_policy_info_key">POLICY_INFO_KEY</string>
<string name="unit_temperature">°C</string>
<string name="unit_rssi">dBm</string>
<string name="intent_report_id_key"
translatable="false">REPORT_TARGET_ID</string>
<string name="intent_report_mac_key"
translatable="false">REPORT_TARGET_MAC</string>
<string name="intent_policy_response_selection_key"
translatable="false">POLICY_RESPONSE_SELECTION_ID</string>
<string name="intent_target_address_key"
translatable="false">DEVICE_TARGET_ADDRESS</string>
<string name="intent_device_info_key"
translatable="false">DEVICE_INFO_KEY</string>
<string name="intent_policy_info_key"
translatable="false">POLICY_INFO_KEY</string>
<string name="unit_temperature"
translatable="false">°C</string>
<string name="unit_rssi"
translatable="false">dBm</string>
</resources>
......@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.android.tools.build:gradle:2.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......
#Mon Dec 28 10:00:20 PST 2015
#Thu May 18 10:50:44 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment