Commit a85fa243 authored by idic's avatar idic

Initial commit

parents
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData">
<serverData>
<paths name="PiTomcat">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintContentDescription" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AndroidLintCutPasteId" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AndroidLintLabelFor" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</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">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/BLEPrivacyPolicyNegotiator.iml" filepath="$PROJECT_DIR$/BLEPrivacyPolicyNegotiator.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "org.prlab.idic.bleprivacypolicynegotiator"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support:recyclerview-v7:25.1.1'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.google.code.gson:gson:2.8.0'
testCompile 'junit:junit:4.12'
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\android-sdk-windows/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep mOptions here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
package org.prlab.idic.privacypolicy;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("org.prlab.idic.bleprivacypolicynegotiator", appContext.getPackageName());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.prlab.idic.privacypolicy">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".ReportActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo"/>
<activity
android:name=".DialogPolicyDetailActivity"
android:theme="@android:style/Theme.Holo.Dialog"/>
<activity
android:name=".DialogDeviceInfoActivity"
android:label="@string/message_device_information"
android:theme="@android:style/Theme.Holo.Dialog"/>
<provider
android:name=".storage.PrivacyPolicyProvider"
android:authorities="@string/content_authority"
android:exported="false"/>
<activity
android:name=".DeviceOperatorActivity"/>
</application>
</manifest>
\ No newline at end of file
package org.prlab.idic.privacypolicy;
import android.bluetooth.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import org.prlab.idic.privacypolicy.adapter.MessageRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.ble.BLECustomScript;
import org.prlab.idic.privacypolicy.pojo.Message;
import org.prlab.idic.privacypolicy.storage.PrivacyPolicyStorageImpl;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.util.LinkedList;
import java.util.List;
import static android.bluetooth.BluetoothGatt.GATT_SUCCESS;
public class DeviceOperatorActivity extends AppCompatActivity {
private static final String TAG = DeviceOperatorActivity.class.getSimpleName();
private String PRIVACY_POLICY_ACCEPT_UUID;
private PrivacyPolicyStorageImpl mPolicyStorage;
private String mTargetDeviceAddress;
private List<Message> messages = new LinkedList<>();
private TextView mMessageBarTextView;
private EditText mTemperatureEditText;
private Button mTemperatureButton;
private Switch mAirPurifierSwitch;
private RecyclerView mMessageRecyclerView;
private RecyclerView.Adapter mMessageRecyclerViewAdapter;
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mBluetoothGatt;
private BroadcastReceiver mPairRequestReceiver;
private BroadcastReceiver mBondStateReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_operator);
mTargetDeviceAddress = getIntent().getStringExtra(getString(R.string.intent_target_address_key));
mPolicyStorage = new PrivacyPolicyStorageImpl(getContentResolver(), mTargetDeviceAddress);
PRIVACY_POLICY_ACCEPT_UUID = getString(R.string.uuid_accept_privacy_policy);
initView();
initBluetooth();
}
private void initView() {
mMessageBarTextView = (TextView) findViewById(R.id.text_operation_message_bar);
mTemperatureEditText = (EditText) findViewById(R.id.);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_operation_info);
mMessageRecyclerViewAdapter = new MessageRecyclerViewAdapter(getResources(), messages);
mMessageRecyclerView.setAdapter(mMessageRecyclerViewAdapter);
}
private void initBluetooth() {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager != null) {
mBluetoothAdapter = mBluetoothManager.getAdapter();
}
}
private BLECustomScript mBLECustomScript = new BLECustomScript() {
@Override
public void onDiscoverServiceCompleted(BluetoothGatt gatt) {
for (BluetoothGattService service : gatt.getServices()) {
List<String> layerUUIDs = new LinkedList<>();
layerUUIDs.add(String.valueOf(service.getUuid()));
//Write service layer selection
int selection = mPolicyStorage.get(layerUUIDs);
if (selection != -1) {
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(characteristic.getUuid().toString())) {
characteristic.setValue(BaseUtils.intArrray2ByteArray(selection));
gatt.writeCharacteristic(characteristic);
}
}
}
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
layerUUIDs.add(String.valueOf(characteristic.getUuid()));
//Write characteristic layer selection
selection = mPolicyStorage.get(layerUUIDs);
if (selection != -1) {
for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) {
if (PRIVACY_POLICY_ACCEPT_UUID.equals(descriptor.getUuid().toString())) {
descriptor.setValue(BaseUtils.intArrray2ByteArray(selection));
gatt.writeDescriptor(descriptor);
}
}
}
layerUUIDs.remove(layerUUIDs.size() - 1);
}
}
}
@Override
public void onWriteCompleted(BluetoothGatt gatt, int status, byte[] values) {
}
@Override
public void onReadCompleted(BluetoothGatt gatt, int status, byte[] values) {
}
@Override
public void onPairRequestReceived(BluetoothDevice device, int pin) {
}
@Override
public void onPaired(BluetoothDevice device) {
}
@Override
public void onUnpaired(BluetoothDevice device) {
}
};
private BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String mac = gatt.getDevice().getAddress();
if (status == GATT_SUCCESS) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
gatt.discoverServices();
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
mBluetoothGatt.close();
mBluetoothGatt = null;
}
}
//重連機制,但好像只會一直bind住。
else if (status == 133 && newState == BluetoothGatt.STATE_DISCONNECTED) {
mBluetoothGatt.close();
connect();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == GATT_SUCCESS) {
mBLECustomScript.onDiscoverServiceCompleted(gatt);
}
}
@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);
} else {
mBLECustomScript.onReadCompleted(mBluetoothGatt, status, characteristic.getValue());
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
mBLECustomScript.onWriteCompleted(mBluetoothGatt, status, characteristic.getValue());
}
};
private void registerPairRequestReceiver() {
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
Log.d(TAG, "PIN " + intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 0));
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int pin = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 0);
mBLECustomScript.onPairRequestReceived(device, pin);
}
}
};
registerReceiver(receiver, intentFilter);
mPairRequestReceiver = receiver;
}
private void unregisterPairRequestReceiver() {
if (mPairRequestReceiver != null) {
unregisterReceiver(mPairRequestReceiver);
mPairRequestReceiver = null;
}
}
private void registerBondStateReceiver() {
// mMessageCallback.displayMessage("Pair", "Ready to pair " + mTargetAddress, true);
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int preState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
Log.i(TAG, "Bond [" + preState + " to " + state + "].");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (state == BluetoothDevice.BOND_BONDED && preState == BluetoothDevice.BOND_BONDING) {
mBLECustomScript.onPaired(device);
} else if (state == BluetoothDevice.BOND_NONE && preState == BluetoothDevice.BOND_BONDED) {
mBLECustomScript.onUnpaired(device);
}
}
}
};
registerReceiver(receiver, intentFilter);
mBondStateReceiver = receiver;
}
private void unregisterBondStateReceiver() {
if (mBondStateReceiver != null) {
unregisterReceiver(mBondStateReceiver);
mBondStateReceiver = null;
}
}
private boolean connect() {
if (mBluetoothAdapter == null) return false;
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mTargetDeviceAddress);
int connectionState = mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);
Log.i(TAG, "Device connection status is " + connectionState + ".");
if (device != null && connectionState == BluetoothProfile.STATE_DISCONNECTED) {
mBluetoothGatt = device.connectGatt(this, false, mBluetoothGattCallback);
return mBluetoothGatt != null;
} else {
return false;
}
}
private void disconnect() {
if (mBluetoothGatt != null) {
int connectionState = mBluetoothManager.getConnectionState(mBluetoothGatt.getDevice(), BluetoothProfile.GATT);
Log.i(TAG, "Device connection status is " + connectionState + ".");
if (connectionState == BluetoothProfile.STATE_CONNECTED) {
boolean isBonded = mBluetoothAdapter.getBondedDevices().contains(mBluetoothGatt.getDevice());
Log.i(TAG, "Device is already bonded. :" + isBonded);
// try {
// Method method = mBluetoothGatt.getDevice().getClass().getMethod("removeBond", (Class[]) null);
// method.invoke(mBluetoothGatt.getDevice(), (Object[]) null);
// } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
// e.printStackTrace();
// }
mBluetoothGatt.disconnect();
}
}
}
}
package org.prlab.idic.privacypolicy;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import org.prlab.idic.privacypolicy.adapter.InfoItemRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.pojo.report.InfoItem;
import org.prlab.idic.privacypolicy.pojo.report.device.Device;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/22.
*/
public class DialogDeviceInfoActivity extends Activity {
private Device mDevice;
private List<InfoItem> items = new LinkedList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actiivty_dialog_device_info);
mDevice = getIntent().getParcelableExtra(getString(R.string.intent_device_info_key));
initInfo();
initView();
}
private void initInfo() {
items.add(new InfoItem()
.setKey(getString(R.string.device_udn_key))
.setValue(mDevice.getUDN()));
items.add(new InfoItem()
.setKey(getString(R.string.device_name_key))
.setValue(mDevice.getName()));
items.add(new InfoItem()
.setKey(getString(R.string.device_type_key))
.setValue(mDevice.getType().name()));
items.add(new InfoItem()
.setKey(getString(R.string.device_manufacturer_name_key))
.setValue(mDevice.getManufacturer().getName()));
items.add(new InfoItem()
.setKey(getString(R.string.device_manufacturer_url_key))
.setValue(mDevice.getManufacturer().getUrl()));
items.add(new InfoItem()
.setKey(getString(R.string.device_manufacturer_serial_number_key))
.setValue(mDevice.getManufacturer().getSerialNumber()));
items.add(new InfoItem()
.setKey(getString(R.string.device_model_name_key))
.setValue(mDevice.getModel().getName()));
items.add(new InfoItem()
.setKey(getString(R.string.device_model_url_key))
.setValue(mDevice.getModel().getUrl()));
items.add(new InfoItem()
.setKey(getString(R.string.device_model_description_key))
.setValue(mDevice.getModel().getDescription()));
items.add(new InfoItem()
.setKey(getString(R.string.device_upc_key))
.setValue(mDevice.getUPC()));
}
private void initView() {
RecyclerView mInfoRecyclerView = (RecyclerView) findViewById(R.id.layout_device_info);
RecyclerView.Adapter mInfoRecyclerViewAdapter = new InfoItemRecyclerViewAdapter(items, false);
mInfoRecyclerView.setAdapter(mInfoRecyclerViewAdapter);
// RecyclerView mIconRecyclerView = (RecyclerView) findViewById(R.id.layout_device_icon);
// if (mDevice.getIcons() != null && mDevice.getIcons().size() > 0) {
// RecyclerView.Adapter mIconRecyclerViewAdapter = new IconItemRecyclerViewAdapter(mDevice.getIcons());
// mIconRecyclerView.setAdapter(mIconRecyclerViewAdapter);
// } else {
// mIconRecyclerView.setVisibility(View.GONE);
// }
}
public void onBackButtonClick(View view) {
finish();
}
}
package org.prlab.idic.privacypolicy;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import org.prlab.idic.privacypolicy.adapter.InfoItemRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.adapter.StatementRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.pojo.report.InfoItem;
import org.prlab.idic.privacypolicy.pojo.report.PrivacyPolicy;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/17.
*/
public class DialogPolicyDetailActivity extends Activity {
private PrivacyPolicy mPrivacyPolicy;
private RecyclerView mCollectorRecyclerView;
private TextView mAccessTextView;
private RecyclerView mDisputeRecyclerView;
private RecyclerView mStatementsRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog_policy);
mPrivacyPolicy = getIntent().getParcelableExtra(getString(R.string.intent_policy_info_key));
setTitle(getString(R.string.message_policy_title) + mPrivacyPolicy.getId());
initView();
}
private void initView() {
initCollector();
initAccess();
initDispute();
initStatements();
}
private void initCollector() {
mCollectorRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_statement_collector);
List<InfoItem> collector = new LinkedList<>();
collector.add(new InfoItem()
.setKey(getString(R.string.policy_statement_collector_name))
.setValue(mPrivacyPolicy.getCollector().getName()));
collector.add(new InfoItem()
.setKey(getString(R.string.policy_statement_collector_email))
.setValue(mPrivacyPolicy.getCollector().getEmail()));
collector.add(new InfoItem()
.setKey(getString(R.string.policy_statement_collector_phone))
.setValue(mPrivacyPolicy.getCollector().getPhone()));
mCollectorRecyclerView.setAdapter(new InfoItemRecyclerViewAdapter(collector));
}
private void initAccess() {
mAccessTextView = (TextView) findViewById(R.id.recycler_view_statement_access);
mAccessTextView.setText(BaseUtils.fixTypeName(mPrivacyPolicy.getAccess().name()));
}
private void initDispute() {
mDisputeRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_statement_dispute);
List<InfoItem> dispute = new LinkedList<>();
dispute.add(new InfoItem()
.setKey(getString(R.string.policy_statement_dispute_resolution_type))
.setValue(getString(R.string.policy_statement_dispute_related_organization)));
dispute.add(new InfoItem()
.setKey(BaseUtils.fixTypeName(mPrivacyPolicy.getDispute().getType().name()))
.setValue(mPrivacyPolicy.getDispute().getRelatedOrganization()));
mDisputeRecyclerView.setAdapter(new InfoItemRecyclerViewAdapter(dispute));
}
private void initStatements() {
mStatementsRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_statement_content);
mStatementsRecyclerView.setAdapter(new StatementRecyclerViewAdapter(getResources(), mPrivacyPolicy.getStatements()));
}
public void onAgreeButtonClick(View view) {
Intent intent = new Intent();
intent.putExtra(getString(R.string.intent_policy_response_selection_key), mPrivacyPolicy.getId());
setResult(RESULT_OK, intent);
finish();
}
public void onDenyButtonClick(View view) {
finish();
}
}
package org.prlab.idic.privacypolicy;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.*;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import org.prlab.idic.privacypolicy.adapter.ScanResultRecyclerViewAdapter;
import org.prlab.idic.privacypolicy.ble.BluetoothDeviceInformation;
import org.prlab.idic.privacypolicy.tool.beacon.BeaconType;
import org.prlab.idic.privacypolicy.tool.beacon.BeaconUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_CENTRAL_REQUEST_CODE = 87;
private static final String TAG = MainActivity.class.getSimpleName();
private TextView mMessageBarTextView;
private RecyclerView mScanResultRecyclerView;
private RecyclerView.Adapter mScanResultRecyclerViewAdapter;
private List<BluetoothDeviceInformation> mInformationList = new ArrayList<>();
private boolean isScanning = false;
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private ScanSettings.Builder mScanSettingsBuilder = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_BALANCED);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setupPermissions();
}
private void initBluetooth() {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager != null) {
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter != null) {
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
}
}
private void initView() {
mMessageBarTextView = (TextView) findViewById(R.id.text_main_message_bar);
displayMessage(getString(R.string.message_press_scan_first));
mScanResultRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_main_result);
mScanResultRecyclerViewAdapter = new ScanResultRecyclerViewAdapter(getResources(), mOnDisplayPolicyClickListener, mOnConnectDeviceClickListener, mInformationList);
mScanResultRecyclerView.setAdapter(mScanResultRecyclerViewAdapter);
}
private ScanResultRecyclerViewAdapter.ListItemClickListener mOnDisplayPolicyClickListener = new ScanResultRecyclerViewAdapter.ListItemClickListener() {
@Override
public void onListItemClick(int clickedItemIndex) {
BluetoothDeviceInformation device = mInformationList.get(clickedItemIndex);
if (null != device.getReportUUID()) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, ReportActivity.class);
intent.putExtra(getString(R.string.intent_report_id_key), device.getReportUUID());
intent.putExtra(getString(R.string.intent_report_mac_key), device.getAddress());
startActivity(intent);
}
}
};
private ScanResultRecyclerViewAdapter.ListItemClickListener mOnConnectDeviceClickListener = new ScanResultRecyclerViewAdapter.ListItemClickListener() {
@Override
public void onListItemClick(int clickedItemIndex) {
BluetoothDeviceInformation device = mInformationList.get(clickedItemIndex);
if (null != device.getReportUUID()) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, DeviceOperatorActivity.class);
intent.putExtra(getString(R.string.intent_target_address_key), device.getAddress());
startActivity(intent);
}
}
};
private static String[] permissionsWeNeed = new String[]{
Manifest.permission.INTERNET,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
private void setupPermissions() {
// If we don't have the record audio permission...
boolean isGranted = true;
for (String permission : permissionsWeNeed) {
isGranted &= ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
}
if (!isGranted) {
// And if we're on SDK M or later...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Ask again, nicely, for the permissions.
requestPermissions(permissionsWeNeed, PERMISSION_CENTRAL_REQUEST_CODE);
}
} else {
// Otherwise, permissions were granted and we are ready to go!
initBluetooth();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_CENTRAL_REQUEST_CODE: {
// If request is cancelled, the result arrays are empty.
boolean isGranted = grantResults.length > 0;
for (int grantResult : grantResults) {
isGranted &= grantResult == PackageManager.PERMISSION_GRANTED;
}
if (isGranted) {
initBluetooth();
} else {
Toast.makeText(this, "Permission for BLE central device not granted. Central device APP can't run.", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
/**
* Methods for setting up the menu
**/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
menu.getItem(0).setIcon(isScanning ? R.mipmap.ic_bluetooth_disabled : R.mipmap.ic_bluetooth_searching);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_search) {
Drawable drawable = getDrawable(R.mipmap.ic_bluetooth_searching);
if (item.getIcon() != null && item.getIcon().getConstantState() != null && drawable != null) {
if (item.getIcon().getConstantState().equals(drawable.getConstantState())) {
displayMessage(getString(R.string.message_scan_start));
if (startScan()) {
item.setIcon(R.mipmap.ic_bluetooth_disabled);
} else {
if (!mBluetoothAdapter.isEnabled()) {
displayMessage(getString(R.string.message_enable_first));
if (mBluetoothAdapter.enable())
initBluetooth();
}
}
} else {
if (stopScan()) {
displayMessage(getString(R.string.message_scan_stop));
item.setIcon(R.mipmap.ic_bluetooth_searching);
}
}
}
}
return super.onOptionsItemSelected(item);
}
private ScanCallback mLeScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDeviceInformation information = toBluetoothDeviceInformation(result);
int index = mInformationList.indexOf(information);
if (index != -1) {
mInformationList.set(index, information);
mScanResultRecyclerViewAdapter.notifyItemChanged(index);
} else {
mInformationList.add(information);
mScanResultRecyclerViewAdapter.notifyItemInserted(mInformationList.size() - 1);
}
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult result : results) {
onScanResult(0, result);
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e(TAG, "Failed to scan : " + errorCode);
}
};
private static BluetoothDeviceInformation toBluetoothDeviceInformation(ScanResult result) {
SparseArray<byte[]> manufacturerSpecificDataSparseArray = result.getScanRecord().getManufacturerSpecificData();
byte[] manufacturerData = null;
for (int i = 0; i < manufacturerSpecificDataSparseArray.size(); i++) {
int key = manufacturerSpecificDataSparseArray.keyAt(0);
manufacturerData = manufacturerSpecificDataSparseArray.get(key);
}
String uuid = null;
if (null != manufacturerData && BeaconType.NORMAL_BEACON == BeaconUtils.getBeaconType(manufacturerData)) {
uuid = BeaconUtils.calculateUuidString(Arrays.copyOfRange(manufacturerData, 2, 18));
}
BluetoothDevice device = result.getDevice();
return new BluetoothDeviceInformation()
.setName(device == null ? null : device.getName())
.setAddress(device == null ? null : device.getAddress())
.setRssi(result.getRssi())
.setBonded(device != null && device.getBondState() == BluetoothDevice.BOND_BONDED)
.setReportUUID(uuid);
}
private boolean startScan() {
if (mBluetoothLeScanner != null) {
mBluetoothLeScanner.startScan(new LinkedList<ScanFilter>(), mScanSettingsBuilder.build(), mLeScanCallback);
isScanning = true;
return true;
}
return false;
}
private boolean stopScan() {
if (mBluetoothLeScanner != null) {
mBluetoothLeScanner.stopScan(mLeScanCallback);
isScanning = false;
return true;
}
return false;
}
private void displayMessage(String message) {
mMessageBarTextView.setText(message);
}
}
package org.prlab.idic.privacypolicy;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
import android.content.Intent;
import android.content.Loader;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
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;
import org.prlab.idic.privacypolicy.pojo.report.PrivacyPolicyReport;
import org.prlab.idic.privacypolicy.storage.PrivacyPolicyStorageImpl;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import static org.prlab.idic.privacypolicy.tool.NegotiatorConstants.ACTIVITY_SELECTION_RESULT_ID;
/**
* Created by IDIC on 2017/2/16.
*/
public class ReportActivity extends Activity
implements LoaderManager.LoaderCallbacks<PrivacyPolicyReport> {
private LinearLayout mReportLayout;
private TextView mReportTitleTextView;
private TextView mVersionTextView;
private TextView mDescriptionTextView;
private Button mDeviceInfoButton;
private Button mResetButton;
private TextView mSelectionTitleTextView;
private RecyclerView mSelectionRecyclerView;
private IntegerButtonRecyclerViewAdapter mSelectionRecyclerViewAdapter;
private TextView mLayerTitleTextView;
private RecyclerView mLayerRecyclerView;
private StringButtonRecyclerViewAdapter mLayerRecyclerViewAdapter;
private Button mBackButton;
private Gson gson = new Gson();
private PrivacyPolicyStorageImpl mPolicyStorage;
private List<String> mLayerIDs;
private PrivacyPolicyReport mPrivacyPolicyReport;
private String mReportId;
private List<Integer> mPolicyIDs;
private List<String> mChildLayerIDs;
private static final int PRIVACY_POLICY_LOADER_ID = 87;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report);
resolveData();
initView();
}
private void resolveData() {
mLayerIDs = new LinkedList<>();
Intent intent = getIntent();
mReportId = intent.getStringExtra(getString(R.string.intent_report_id_key));
mPolicyStorage = new PrivacyPolicyStorageImpl(getContentResolver(), intent.getStringExtra(getString(R.string.intent_report_mac_key)));
getLoaderManager().initLoader(PRIVACY_POLICY_LOADER_ID, null, this);
}
private void initView() {
mReportLayout = (LinearLayout) findViewById(R.id.layout_report_info);
mReportTitleTextView = (TextView) findViewById(R.id.text_report_title);
View mVersionView = findViewById(R.id.item_report_version);
((TextView) mVersionView.findViewById(R.id.text_key)).setText(getString(R.string.policy_report_version_title));
mVersionTextView = (TextView) mVersionView.findViewById(R.id.text_value);
View mDescriptionView = findViewById(R.id.item_report_description);
((TextView) mDescriptionView.findViewById(R.id.text_key)).setText(getString(R.string.policy_report_description_title));
mDescriptionTextView = (TextView) mDescriptionView.findViewById(R.id.text_value);
mDeviceInfoButton = (Button) findViewById(R.id.button_report_device);
mBackButton = (Button) findViewById(R.id.button_report_back);
mResetButton = (Button) findViewById(R.id.button_report_reset);
mResetButton.setOnClickListener(mResetButtonClickListener);
mSelectionTitleTextView = (TextView) findViewById(R.id.text_report_policies_title);
mSelectionRecyclerViewAdapter = new IntegerButtonRecyclerViewAdapter(getResources(), mSelectionClickListener);
mSelectionRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_report_policies);
mSelectionRecyclerView.setAdapter(mSelectionRecyclerViewAdapter);
mLayerTitleTextView = (TextView) findViewById(R.id.text_report_child_layers_title);
mLayerRecyclerViewAdapter = new StringButtonRecyclerViewAdapter(getResources(), mChildLayersClickListener);
mLayerRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_report_child_layers);
mLayerRecyclerView.setAdapter(mLayerRecyclerViewAdapter);
}
private IntegerButtonRecyclerViewAdapter.ListItemClickListener mSelectionClickListener = new IntegerButtonRecyclerViewAdapter.ListItemClickListener() {
@Override
public void onListItemClick(int clickedItemIndex) {
Intent intent = new Intent();
intent.setClass(ReportActivity.this, DialogPolicyDetailActivity.class);
int policyId = mPolicyIDs.get(clickedItemIndex);
intent.putExtra(getString(R.string.intent_policy_info_key), mPrivacyPolicyReport.getPolicies().get(policyId));
startActivityForResult(intent, ACTIVITY_SELECTION_RESULT_ID);
}
};
private StringButtonRecyclerViewAdapter.ListItemClickListener mChildLayersClickListener = new StringButtonRecyclerViewAdapter.ListItemClickListener() {
@Override
public void onListItemClick(int clickedItemIndex) {
String layerID = mChildLayerIDs.get(clickedItemIndex);
mLayerIDs.add(layerID);
setView();
}
};
private View.OnClickListener mResetButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
mPolicyStorage.remove(mLayerIDs);
mResetButton.setEnabled(false);
mSelectionRecyclerViewAdapter.setTarget(-1);
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
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);
mResetButton.setEnabled(true);
mSelectionRecyclerViewAdapter.setTarget(selection);
}
}
}
@Override
public Loader<PrivacyPolicyReport> onCreateLoader(int id, Bundle args) {
return new AsyncTaskLoader<PrivacyPolicyReport>(this) {
@Override
protected void onStartLoading() {
if (null == mPrivacyPolicyReport) {
forceLoad();
}
}
@Override
public PrivacyPolicyReport loadInBackground() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(getString(R.string.get_policy_url))
.post(new FormBody.Builder()
.add(getString(R.string.get_policy_id_parameter_key), mReportId)
.build())
.build();
try {
return gson.fromJson(client.newCall(request).execute().body().string(), PrivacyPolicyReport.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
}
@Override
public void onLoadFinished(Loader<PrivacyPolicyReport> loader, PrivacyPolicyReport report) {
mPrivacyPolicyReport = report;
mLayerIDs.add(report.getRoot().getUUID());
setView();
}
@Override
public void onLoaderReset(Loader<PrivacyPolicyReport> loader) {
}
private void setView() {
Layer currentLayer = currentLayer();
String title;
if (mPrivacyPolicyReport.getRoot().equals(currentLayer)) {
mVersionTextView.setText(mPrivacyPolicyReport.getVersion());
mDescriptionTextView.setText(mPrivacyPolicyReport.getDescription());
// mReportLayout.setVisibility(View.VISIBLE);
// mDeviceInfoButton.setVisibility(View.VISIBLE);
mBackButton.setVisibility(View.GONE);
title = getString(R.string.policy_information_title);
} else {
title = currentLayer.getUUID();
// mReportLayout.setVisibility(View.GONE);
// mDeviceInfoButton.setVisibility(View.GONE);
mBackButton.setVisibility(View.VISIBLE);
}
mReportTitleTextView.setText(title);
mPolicyIDs = currentLayer.getPolicies();
mSelectionRecyclerViewAdapter.setItems(mPolicyIDs);
int target = mPolicyStorage.get(mLayerIDs);
mResetButton.setEnabled(target != -1);
mSelectionRecyclerViewAdapter.setTarget(target);
checkEmpty(mPolicyIDs, mSelectionTitleTextView, mSelectionRecyclerView, mResetButton);
mChildLayerIDs = BaseUtils.layer2UUID(currentLayer.getSubLayers());
mLayerRecyclerViewAdapter.setItems(mChildLayerIDs);
checkEmpty(mChildLayerIDs, mLayerTitleTextView, mLayerRecyclerView);
}
private void checkEmpty(List list, View title, View... views) {
if (list.isEmpty()) {
title.setVisibility(View.GONE);
for (View view : views)
view.setVisibility(View.GONE);
} else {
title.setVisibility(View.VISIBLE);
for (View view : views)
view.setVisibility(View.VISIBLE);
}
}
private Layer currentLayer() {
return currentLayer(mPrivacyPolicyReport.getRoot(), 0);
}
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);
}
return root;
}
public void onDeviceInfoButtonClicked(View view) {
Intent intent = new Intent();
intent.setClass(ReportActivity.this, DialogDeviceInfoActivity.class);
intent.putExtra(getString(R.string.intent_device_info_key), mPrivacyPolicyReport.getDevice());
startActivity(intent);
}
public void onBackButtonClicked(View view) {
mLayerIDs.remove(mLayerIDs.size() - 1);
setView();
}
}
package org.prlab.idic.privacypolicy.adapter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.prlab.idic.privacypolicy.R;
import org.prlab.idic.privacypolicy.pojo.report.device.Icon;
import java.util.List;
/**
* Created by IDIC on 2017/2/23.
*/
public class IconItemRecyclerViewAdapter extends RecyclerView.Adapter<IconItemRecyclerViewAdapter.ViewHolder> {
private List<Icon> icons;
public IconItemRecyclerViewAdapter(List<Icon> icons) {
this.icons = icons;
}
@Override
public IconItemRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item_horizontally, parent, false);
return new IconItemRecyclerViewAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return null == icons ? 0 : icons.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView mIconImageView;
ViewHolder(View itemView) {
super(itemView);
mIconImageView = (ImageView) itemView.findViewById(R.id.image_icon);
}
void bind(int listIndex) {
Icon icon = icons.get(listIndex);
Bitmap bitmap = BitmapFactory.decodeByteArray(icon.getBytes(), 0, icon.getBytes().length);
mIconImageView.setImageBitmap(bitmap);
}
}
}
package org.prlab.idic.privacypolicy.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.prlab.idic.privacypolicy.R;
import org.prlab.idic.privacypolicy.pojo.report.InfoItem;
import java.util.List;
/**
* Created by IDIC on 2017/2/23.
*/
public class InfoItemRecyclerViewAdapter extends RecyclerView.Adapter<InfoItemRecyclerViewAdapter.ViewHolder> {
private List<InfoItem> items;
private boolean isVertical;
public InfoItemRecyclerViewAdapter(List<InfoItem> items) {
this.isVertical = true;
this.items = items;
}
public InfoItemRecyclerViewAdapter(List<InfoItem> items, boolean isVertical) {
this.isVertical = isVertical;
this.items = items;
}
@Override
public InfoItemRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item_horizontally, parent, false);
return new InfoItemRecyclerViewAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return null == items ? 0 : items.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView mKeyTextView;
private TextView mValueTextView;
ViewHolder(View itemView) {
super(itemView);
View view = itemView.findViewById(R.id.item_info);
mKeyTextView = (TextView) view.findViewById(R.id.text_key);
mValueTextView = (TextView) view.findViewById(R.id.text_value);
}
void bind(int listIndex) {
InfoItem item = items.get(listIndex);
mKeyTextView.setText(item.getKey());
mValueTextView.setText(item.getValue());
if (isVertical && listIndex == 0) {
// title box
}
}
}
}
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;
import android.view.ViewGroup;
import android.widget.Button;
import org.prlab.idic.privacypolicy.R;
import java.util.List;
/**
* Created by IDIC on 2017/2/16.
*/
public class IntegerButtonRecyclerViewAdapter extends RecyclerView.Adapter<IntegerButtonRecyclerViewAdapter.ViewHolder> {
private final String PRIVACY_POLICY_TITLE;
private ListItemClickListener listItemClickListener;
private List<Integer> items;
private Integer target = -1;
public IntegerButtonRecyclerViewAdapter(Resources resources, ListItemClickListener listItemClickListener) {
this.PRIVACY_POLICY_TITLE = resources.getString(R.string.message_policy_title);
this.listItemClickListener = listItemClickListener;
}
public void setItems(List<Integer> items) {
this.items = items;
notifyDataSetChanged();
}
public void setTarget(Integer target) {
int index = items.indexOf(this.target);
if (index != -1)
notifyItemChanged(index);
this.target = target;
index = items.indexOf(this.target);
if (index != -1)
notifyItemChanged(index);
}
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item, parent, false);
return new IntegerButtonRecyclerViewAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return null != items ? items.size() : 0;
}
class ViewHolder extends RecyclerView.ViewHolder {
private Button button;
ViewHolder(View itemView) {
super(itemView);
button = (Button) itemView.findViewById(R.id.button_item);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
IntegerButtonRecyclerViewAdapter.this.listItemClickListener.onListItemClick(getAdapterPosition());
}
});
}
void bind(int listIndex) {
int item = items.get(listIndex);
String message = IntegerButtonRecyclerViewAdapter.this.PRIVACY_POLICY_TITLE + String.valueOf(item);
button.setText(message);
button.setEnabled(item != target);
}
}
}
package org.prlab.idic.privacypolicy.adapter;
import android.content.res.Resources;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.prlab.idic.privacypolicy.R;
import org.prlab.idic.privacypolicy.pojo.Message;
import java.util.List;
/**
* Created by IDIC on 2017/1/20.
*/
public class MessageRecyclerViewAdapter extends RecyclerView.Adapter<MessageRecyclerViewAdapter.ViewHolder> {
private final int COLOR_MARKED;
private final int COLOR_TEXT;
private List<Message> messages;
public MessageRecyclerViewAdapter(Resources resources, List<Message> messages) {
this.COLOR_MARKED = ResourcesCompat.getColor(resources, R.color.colorAccent, null);
this.COLOR_TEXT = ResourcesCompat.getColor(resources, R.color.colorText, null);
this.messages = messages;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_message_item, parent, false);
return new MessageRecyclerViewAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return messages.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView mEventTextView;
private TextView mContentTextView;
ViewHolder(View itemView) {
super(itemView);
mEventTextView = (TextView) itemView.findViewById(R.id.text_view_message_event);
mContentTextView = (TextView) itemView.findViewById(R.id.text_view_message_content);
}
void bind(int listIndex) {
Message message = messages.get(listIndex);
mEventTextView.setText(String.valueOf(message.getEvent()));
mContentTextView.setText(String.valueOf(message.getContent()));
mContentTextView.setTextColor(message.isMarked() ? COLOR_MARKED : COLOR_TEXT);
}
}
}
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;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import org.prlab.idic.privacypolicy.R;
import org.prlab.idic.privacypolicy.ble.BluetoothDeviceInformation;
import java.util.List;
/**
* Created by IDIC on 2017/1/20.
*/
public class ScanResultRecyclerViewAdapter extends RecyclerView.Adapter<ScanResultRecyclerViewAdapter.ViewHolder> {
private static final String TAG = ScanResultRecyclerViewAdapter.class.getSimpleName();
private final String BONDED_STRING;
private final String NOT_BONDED_STRING;
final private ListItemClickListener mOnPolicyImageClickListener;
final private ListItemClickListener mOnConnectButtonClickListener;
final private String RSSI_UNIT;
private List<BluetoothDeviceInformation> devices;
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
public ScanResultRecyclerViewAdapter(Resources resources,
ListItemClickListener mOnPolicyImageClickListener,
ListItemClickListener mOnConnectButtonClickListener,
List<BluetoothDeviceInformation> devices) {
this.BONDED_STRING = resources.getString(R.string.bluetooth_bonded);
this.NOT_BONDED_STRING = resources.getString(R.string.bluetooth_not_bonded);
this.RSSI_UNIT = " " + resources.getString(R.string.rssi_unit);
this.mOnPolicyImageClickListener = mOnPolicyImageClickListener;
this.mOnConnectButtonClickListener = mOnConnectButtonClickListener;
this.devices = devices;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_scan_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return devices.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView mPolicyButton;
private TextView mNameTextView;
private TextView mMACTextView;
private TextView mBondedTextView;
private TextView mRssiTextView;
private Button mConnectButton;
ViewHolder(View itemView) {
super(itemView);
mPolicyButton = (ImageView) itemView.findViewById(R.id.image_scan_allowed);
mNameTextView = (TextView) itemView.findViewById(R.id.text_scan_device_name);
mMACTextView = (TextView) itemView.findViewById(R.id.text_scan_device_mac);
mBondedTextView = (TextView) itemView.findViewById(R.id.text_scan_is_bonded);
mRssiTextView = (TextView) itemView.findViewById(R.id.text_scan_rssi);
mConnectButton = (Button) itemView.findViewById(R.id.button_scan_connect);
}
private View.OnClickListener mOnPolicyClickAdapter = new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnPolicyImageClickListener.onListItemClick(getAdapterPosition());
}
};
private View.OnClickListener mOnConnectClickAdapter = new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnConnectButtonClickListener.onListItemClick(getAdapterPosition());
}
};
void bind(int listIndex) {
BluetoothDeviceInformation device = devices.get(listIndex);
mPolicyButton.setImageResource(null != device.getReportUUID() ? R.drawable.rounded_yes : R.drawable.rounded_no);
mPolicyButton.setOnClickListener(mOnPolicyClickAdapter);
mNameTextView.setText(String.valueOf(device.getName()));
mMACTextView.setText(String.valueOf(device.getAddress()));
mBondedTextView.setText(device.isBonded() ? BONDED_STRING : NOT_BONDED_STRING);
mRssiTextView.setText(String.valueOf(device.getRssi() + RSSI_UNIT));
mConnectButton.setOnClickListener(mOnConnectClickAdapter);
}
}
}
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;
import android.view.ViewGroup;
import android.widget.TextView;
import org.prlab.idic.privacypolicy.R;
import org.prlab.idic.privacypolicy.pojo.report.InfoItem;
import org.prlab.idic.privacypolicy.pojo.report.p3p.*;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/23.
*/
public class StatementRecyclerViewAdapter extends RecyclerView.Adapter<StatementRecyclerViewAdapter.ViewHolder> {
private final String CONSEQUENCE_TITLE;
private final String PURPOSE_TYPE_TITLE;
private final String PURPOSE_DESCRIPTION_TITLE;
private final String DATUM_TYPE_TITLE;
private final String DATUM_DESCRIPTION_TITLE;
private final String REMEDIES_TITLE;
private final String RECIPIENT_TYPE_TITLE;
private final String RECIPIENT_DESCRIPTION_TITLE;
private final String RETENTION_TITLE;
private List<Statement> statements;
public StatementRecyclerViewAdapter(Resources resources, List<Statement> statements) {
CONSEQUENCE_TITLE = resources.getString(R.string.policy_statement_consequence_title);
PURPOSE_TYPE_TITLE = resources.getString(R.string.policy_statement_purpose_type);
PURPOSE_DESCRIPTION_TITLE = resources.getString(R.string.policy_statement_purpose_description);
DATUM_TYPE_TITLE = resources.getString(R.string.policy_statement_data_type);
DATUM_DESCRIPTION_TITLE = resources.getString(R.string.policy_statement_data_description);
REMEDIES_TITLE = resources.getString(R.string.policy_statement_remedies);
RECIPIENT_TYPE_TITLE = resources.getString(R.string.policy_statement_recipient_type);
RECIPIENT_DESCRIPTION_TITLE = resources.getString(R.string.policy_statement_recipient_description);
RETENTION_TITLE = resources.getString(R.string.policy_statement_retention);
this.statements = statements;
}
@Override
public StatementRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_statement, parent, false);
return new StatementRecyclerViewAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return null == statements ? 0 : statements.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView mConsequenceTextView;
private RecyclerView mPurposesRecyclerView;
private RecyclerView mDataRecyclerView;
private TextView mRemediesTextView;
private RecyclerView mRecipientsRecyclerView;
private TextView mRetentionTextView;
ViewHolder(View itemView) {
super(itemView);
mConsequenceTextView = (TextView) itemView.findViewById(R.id.recycler_view_statement_consequence);
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);
mRecipientsRecyclerView = (RecyclerView) itemView.findViewById(R.id.recycler_view_statement_recipients);
mRetentionTextView = (TextView) itemView.findViewById(R.id.text_statement_retention);
}
private void bindConsequence(String consequence) {
mConsequenceTextView.setText(consequence);
}
private void bindPurposes(List<Purpose> purposes) {
List<InfoItem> infoItems = new LinkedList<>();
infoItems.add(new InfoItem()
.setKey(PURPOSE_TYPE_TITLE)
.setValue(PURPOSE_DESCRIPTION_TITLE));
for (Purpose purpose : purposes) {
infoItems.add(new InfoItem()
.setKey(BaseUtils.fixTypeName(purpose.getType().name()))
.setValue(purpose.getDescription()));
}
mPurposesRecyclerView.setAdapter(new InfoItemRecyclerViewAdapter(infoItems));
}
private void bindData(List<Datum> data) {
List<InfoItem> infoItems = new LinkedList<>();
infoItems.add(new InfoItem()
.setKey(DATUM_TYPE_TITLE)
.setValue(DATUM_DESCRIPTION_TITLE));
for (Datum datum : data) {
infoItems.add(new InfoItem()
.setKey(BaseUtils.fixTypeName(datum.getType().name()))
.setValue(datum.getDescription()));
}
mDataRecyclerView.setAdapter(new InfoItemRecyclerViewAdapter(infoItems));
}
private void bindRemedies(List<Remedy> remedies) {
StringBuilder builder = new StringBuilder();
for (Remedy remedy : remedies) {
builder.append(BaseUtils.fixTypeName(remedy.name())).append(", ");
}
builder.delete(builder.length() - 2, builder.length());
mRemediesTextView.setText(builder.toString());
}
private void bindRecipients(List<Recipient> recipients) {
List<InfoItem> infoItems = new LinkedList<>();
infoItems.add(new InfoItem()
.setKey(RECIPIENT_TYPE_TITLE)
.setValue(RECIPIENT_DESCRIPTION_TITLE));
for (Recipient recipient : recipients) {
infoItems.add(new InfoItem()
.setKey(BaseUtils.fixTypeName(recipient.getType().name()))
.setValue(recipient.getDescription()));
}
mRecipientsRecyclerView.setAdapter(new InfoItemRecyclerViewAdapter(infoItems));
}
private void bindRetention(Retention retention) {
mRetentionTextView.setText(BaseUtils.fixTypeName(retention.name()));
}
void bind(int listIndex) {
Statement statement = statements.get(listIndex);
bindConsequence(statement.getConsequence());
bindPurposes(statement.getPurposes());
bindData(statement.getData());
bindRemedies(statement.getRemedies());
bindRecipients(statement.getRecipients());
bindRetention(statement.getRetention());
}
}
}
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;
import android.view.ViewGroup;
import android.widget.Button;
import org.prlab.idic.privacypolicy.R;
import java.util.List;
/**
* Created by IDIC on 2017/2/16.
*/
public class StringButtonRecyclerViewAdapter extends RecyclerView.Adapter<StringButtonRecyclerViewAdapter.ViewHolder> {
private ListItemClickListener listItemClickListener;
private List<String> items;
private String target;
public StringButtonRecyclerViewAdapter(Resources resources, ListItemClickListener listItemClickListener) {
this.listItemClickListener = listItemClickListener;
}
public void setItems(List<String> items) {
this.items = items;
notifyDataSetChanged();
}
public void setTarget(String target) {
this.target = target;
notifyItemChanged(items.indexOf(target));
}
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item, parent, false);
return new StringButtonRecyclerViewAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return null != items ? items.size() : 0;
}
class ViewHolder extends RecyclerView.ViewHolder {
private Button button;
ViewHolder(View itemView) {
super(itemView);
button = (Button) itemView.findViewById(R.id.button_item);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
StringButtonRecyclerViewAdapter.this.listItemClickListener.onListItemClick(getAdapterPosition());
}
});
}
void bind(int listIndex) {
String item = items.get(listIndex);
button.setText(item);
button.setEnabled(!item.equals(target));
}
}
}
package org.prlab.idic.privacypolicy.ble;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
/**
* Created by IDIC on 2017/2/21.
*/
public interface BLECustomScript {
void onDiscoverServiceCompleted(BluetoothGatt gatt);
void onWriteCompleted(BluetoothGatt gatt, int status, byte[] values);
void onReadCompleted(BluetoothGatt gatt, int status, byte[] values);
void onPairRequestReceived(BluetoothDevice device, int pin);
void onPaired(BluetoothDevice device);
void onUnpaired(BluetoothDevice device);
}
package org.prlab.idic.privacypolicy.ble;
/**
* Created by IDIC on 2017/1/20.
*/
public class BluetoothDeviceInformation {
private String name;
private String address;
private int rssi;
private boolean isBonded;
private String reportUUID;
public BluetoothDeviceInformation() {
}
public String getName() {
return name;
}
public BluetoothDeviceInformation setName(String name) {
this.name = name;
return this;
}
public String getAddress() {
return address;
}
public BluetoothDeviceInformation setAddress(String address) {
this.address = address;
return this;
}
public int getRssi() {
return rssi;
}
public BluetoothDeviceInformation setRssi(int rssi) {
this.rssi = rssi;
return this;
}
public boolean isBonded() {
return isBonded;
}
public BluetoothDeviceInformation setBonded(boolean bonded) {
isBonded = bonded;
return this;
}
public String getReportUUID() {
return reportUUID;
}
public BluetoothDeviceInformation setReportUUID(String reportUUID) {
this.reportUUID = reportUUID;
return this;
}
@Override
public boolean equals(Object obj) {
return obj instanceof BluetoothDeviceInformation &&
getAddress() != null &&
getAddress().equals(((BluetoothDeviceInformation) obj).address);
}
@Override
public int hashCode() {
return String.valueOf(getAddress()).hashCode();
}
@Override
public String toString() {
return "{" +
"\"name\" : \"" + String.valueOf(name) +
"\", \"address\" : \"" + String.valueOf(address) +
"\", \"rssi\" : " + String.valueOf(rssi) +
"\", \"isAllowed\" : " + String.valueOf(null == reportUUID) +
"\", \"isBonded\" : " + String.valueOf(isBonded) +
"}";
}
}
package org.prlab.idic.privacypolicy.pojo;
/**
* Created by IDIC on 2017/1/20.
*/
public class Message {
private String event;
private String content;
private boolean isMarked = false;
public Message() {
}
public String getEvent() {
return event;
}
public Message setEvent(String event) {
this.event = event;
return this;
}
public String getContent() {
return content;
}
public Message setContent(String content) {
this.content = content;
return this;
}
public boolean isMarked() {
return isMarked;
}
public Message setMarked(boolean marked) {
isMarked = marked;
return this;
}
}
package org.prlab.idic.privacypolicy.pojo.report;
/**
* Created by IDIC on 2017/2/23.
*/
public class InfoItem {
private String key;
private String value;
public InfoItem() {
}
public String getKey() {
return key;
}
public InfoItem setKey(String key) {
this.key = key;
return this;
}
public String getValue() {
return value;
}
public InfoItem setValue(String value) {
this.value = value;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InfoItem infoItem = (InfoItem) o;
if (key != null ? !key.equals(infoItem.key) : infoItem.key != null) return false;
return value != null ? value.equals(infoItem.value) : infoItem.value == null;
}
@Override
public int hashCode() {
int result = key != null ? key.hashCode() : 0;
result = 31 * result + (value != null ? value.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/22.
*/
public class Layer {
private String UUID;
private List<Integer> policies = new LinkedList<>();
private List<Layer> subLayers = new LinkedList<>();
public String getUUID() {
return UUID;
}
public Layer setUUID(String UUID) {
this.UUID = UUID;
return this;
}
public List<Integer> getPolicies() {
return policies;
}
public Layer setPolicies(List<Integer> policies) {
this.policies = policies;
return this;
}
public List<Layer> getSubLayers() {
return subLayers;
}
public Layer setSubLayers(List<Layer> subLayers) {
this.subLayers = subLayers;
return this;
}
public Layer addPrivacyPolicy(Integer policy) {
if (null != policies) this.policies.add(policy);
return this;
}
public Layer addSubLayer(Layer layer) {
if (null != subLayers) this.subLayers.add(layer);
return this;
}
public int getLayerLevel() {
if (null == subLayers || subLayers.isEmpty()) return 0;
List<Integer> counter = new LinkedList<>();
for (Layer layer : subLayers) {
counter.add(1 + layer.getLayerLevel());
}
return Collections.max(counter);
}
}
package org.prlab.idic.privacypolicy.pojo.report;
import android.os.Parcel;
import android.os.Parcelable;
import org.prlab.idic.privacypolicy.pojo.report.p3p.*;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/16.
*/
public class PrivacyPolicy implements Parcelable {
private int id;
private String description;
private Collector collector;
private Dispute dispute;
private Access access;
private List<Statement> statements = new LinkedList<>();
public PrivacyPolicy() {
}
private PrivacyPolicy(Parcel in) {
id = in.readInt();
description = in.readString();
collector = in.readParcelable(Collector.class.getClassLoader());
dispute = in.readParcelable(Dispute.class.getClassLoader());
access = in.readParcelable(Access.class.getClassLoader());
statements = in.createTypedArrayList(Statement.CREATOR);
}
public static final Creator<PrivacyPolicy> CREATOR = new Creator<PrivacyPolicy>() {
@Override
public PrivacyPolicy createFromParcel(Parcel in) {
return new PrivacyPolicy(in);
}
@Override
public PrivacyPolicy[] newArray(int size) {
return new PrivacyPolicy[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(description);
dest.writeParcelable(collector, flags);
dest.writeParcelable(dispute, flags);
dest.writeParcelable(access, flags);
dest.writeTypedList(statements);
}
public int getId() {
return id;
}
public PrivacyPolicy setId(int id) {
this.id = id;
return this;
}
public String getDescription() {
return description;
}
public PrivacyPolicy setDescription(String description) {
this.description = description;
return this;
}
public Collector getCollector() {
return collector;
}
public PrivacyPolicy setCollector(Collector collector) {
this.collector = collector;
return this;
}
public Dispute getDispute() {
return dispute;
}
public PrivacyPolicy setDispute(Dispute dispute) {
this.dispute = dispute;
return this;
}
public Access getAccess() {
return access;
}
public PrivacyPolicy setAccess(Access access) {
this.access = access;
return this;
}
public List<Statement> getStatements() {
return statements;
}
public PrivacyPolicy setStatements(List<Statement> statements) {
this.statements = statements;
return this;
}
public PrivacyPolicy addStatement(Statement statement) {
if (null != this.statements) this.statements.add(statement);
return this;
}
}
package org.prlab.idic.privacypolicy.pojo.report;
import org.prlab.idic.privacypolicy.pojo.report.device.Device;
import java.util.HashMap;
import java.util.Map;
/**
* Created by IDIC on 2017/2/13.
*/
public class PrivacyPolicyReport {
private String version;
private String description;
private Device device;
private Map<Integer, PrivacyPolicy> policies = new HashMap<>();
private Layer root;
public String getVersion() {
return version;
}
public PrivacyPolicyReport setVersion(String version) {
this.version = version;
return this;
}
public String getDescription() {
return description;
}
public PrivacyPolicyReport setDescription(String description) {
this.description = description;
return this;
}
public Device getDevice() {
return device;
}
public PrivacyPolicyReport setDevice(Device device) {
this.device = device;
return this;
}
public Map<Integer, PrivacyPolicy> getPolicies() {
return policies;
}
public PrivacyPolicyReport setPolicies(Map<Integer, PrivacyPolicy> policies) {
this.policies = policies;
return this;
}
public PrivacyPolicyReport addPrivacyPolicy(PrivacyPolicy policy) {
if (null != policies) this.policies.put(policy.getId(), policy);
return this;
}
public Layer getRoot() {
return root;
}
public PrivacyPolicyReport setRoot(Layer root) {
this.root = root;
return this;
}
}
package org.prlab.idic.privacypolicy.pojo.report.device;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/22.
*/
public class Device implements Parcelable {
private String UDN;
private String name;
private Type type;
private Manufacturer manufacturer;
private Model model;
private String UPC;
private List<Icon> icons = new LinkedList<>();
public Device() {
}
private Device(Parcel in) {
UDN = in.readString();
name = in.readString();
type = Device.Type.valueOf(in.readString());
manufacturer = in.readParcelable(Manufacturer.class.getClassLoader());
model = in.readParcelable(Model.class.getClassLoader());
UPC = in.readString();
icons = in.createTypedArrayList(Icon.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(UDN);
dest.writeString(name);
dest.writeString(type.name());
dest.writeParcelable(manufacturer, flags);
dest.writeParcelable(model, flags);
dest.writeString(UPC);
dest.writeTypedList(icons);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Device> CREATOR = new Creator<Device>() {
@Override
public Device createFromParcel(Parcel in) {
return new Device(in);
}
@Override
public Device[] newArray(int size) {
return new Device[size];
}
};
public String getUDN() {
return UDN;
}
public Device setUDN(String UDN) {
this.UDN = UDN;
return this;
}
public Type getType() {
return type;
}
public Device setType(Type type) {
this.type = type;
return this;
}
public String getName() {
return name;
}
public Device setName(String name) {
this.name = name;
return this;
}
public Manufacturer getManufacturer() {
return manufacturer;
}
public Device setManufacturer(Manufacturer manufacturer) {
this.manufacturer = manufacturer;
return this;
}
public Model getModel() {
return model;
}
public Device setModel(Model model) {
this.model = model;
return this;
}
public String getUPC() {
return UPC;
}
public Device setUPC(String UPC) {
this.UPC = UPC;
return this;
}
public List<Icon> getIcons() {
return icons;
}
public Device setIcons(List<Icon> icons) {
this.icons = icons;
return this;
}
public Device addIcon(Icon icon) {
if (null != this.icons) this.icons.add(icon);
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Device device = (Device) o;
if (UDN != null ? !UDN.equals(device.UDN) : device.UDN != null) return false;
if (name != null ? !name.equals(device.name) : device.name != null) return false;
if (type != device.type) return false;
if (manufacturer != null ? !manufacturer.equals(device.manufacturer) : device.manufacturer != null)
return false;
if (model != null ? !model.equals(device.model) : device.model != null) return false;
if (UPC != null ? !UPC.equals(device.UPC) : device.UPC != null) return false;
return icons != null ? icons.equals(device.icons) : device.icons == null;
}
@Override
public int hashCode() {
int result = UDN != null ? UDN.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (type != null ? type.hashCode() : 0);
result = 31 * result + (manufacturer != null ? manufacturer.hashCode() : 0);
result = 31 * result + (model != null ? model.hashCode() : 0);
result = 31 * result + (UPC != null ? UPC.hashCode() : 0);
result = 31 * result + (icons != null ? icons.hashCode() : 0);
return result;
}
public enum Type {
Sensor, Actuator, Mixed, Other
}
}
package org.prlab.idic.privacypolicy.pojo.report.device;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays;
/**
* Created by IDIC on 2017/2/22.
*/
public class Icon implements Parcelable {
private byte[] bytes;
public Icon() {
}
private Icon(Parcel in) {
bytes = in.createByteArray();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(bytes);
}
public static final Creator<Icon> CREATOR = new Creator<Icon>() {
@Override
public Icon createFromParcel(Parcel in) {
return new Icon(in);
}
@Override
public Icon[] newArray(int size) {
return new Icon[size];
}
};
public byte[] getBytes() {
return bytes;
}
public Icon setBytes(byte[] bytes) {
this.bytes = bytes;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Icon icon = (Icon) o;
return Arrays.equals(bytes, icon.bytes);
}
@Override
public int hashCode() {
return Arrays.hashCode(bytes);
}
}
package org.prlab.idic.privacypolicy.pojo.report.device;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/22.
*/
public class Manufacturer implements Parcelable {
private String name;
private String url;
private String serialNumber;
public Manufacturer() {
}
private Manufacturer(Parcel in) {
name = in.readString();
url = in.readString();
serialNumber = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(url);
dest.writeString(serialNumber);
}
public static final Creator<Manufacturer> CREATOR = new Creator<Manufacturer>() {
@Override
public Manufacturer createFromParcel(Parcel in) {
return new Manufacturer(in);
}
@Override
public Manufacturer[] newArray(int size) {
return new Manufacturer[size];
}
};
public String getName() {
return name;
}
public Manufacturer setName(String name) {
this.name = name;
return this;
}
public String getUrl() {
return url;
}
public Manufacturer setUrl(String url) {
this.url = url;
return this;
}
public String getSerialNumber() {
return serialNumber;
}
public Manufacturer setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Manufacturer that = (Manufacturer) o;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (url != null ? !url.equals(that.url) : that.url != null) return false;
return serialNumber != null ? serialNumber.equals(that.serialNumber) : that.serialNumber == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (url != null ? url.hashCode() : 0);
result = 31 * result + (serialNumber != null ? serialNumber.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report.device;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/22.
*/
public class Model implements Parcelable{
private String name;
private String url;
private String description;
public Model() {
}
private Model(Parcel in) {
name = in.readString();
url = in.readString();
description = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(url);
dest.writeString(description);
}
public static final Creator<Model> CREATOR = new Creator<Model>() {
@Override
public Model createFromParcel(Parcel in) {
return new Model(in);
}
@Override
public Model[] newArray(int size) {
return new Model[size];
}
};
public String getName() {
return name;
}
public Model setName(String name) {
this.name = name;
return this;
}
public String getUrl() {
return url;
}
public Model setUrl(String url) {
this.url = url;
return this;
}
public String getDescription() {
return description;
}
public Model setDescription(String description) {
this.description = description;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Model model = (Model) o;
if (name != null ? !name.equals(model.name) : model.name != null) return false;
if (url != null ? !url.equals(model.url) : model.url != null) return false;
return description != null ? description.equals(model.description) : model.description == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (url != null ? url.hashCode() : 0);
result = 31 * result + (description != null ? description.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public enum Access implements Parcelable {
NON_IDENT, ALL, CONTACT_AND_OTHER, IDENT_CONTACT, OTHER_IDENT, NONE;
Access() {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name());
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Access> CREATOR = new Creator<Access>() {
@Override
public Access createFromParcel(Parcel in) {
return Access.valueOf(in.readString());
}
@Override
public Access[] newArray(int size) {
return new Access[size];
}
};
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public class Collector implements Parcelable {
private String name;
private String phone;
private String email;
public Collector() {
}
protected Collector(Parcel in) {
name = in.readString();
phone = in.readString();
email = in.readString();
}
public static final Creator<Collector> CREATOR = new Creator<Collector>() {
@Override
public Collector createFromParcel(Parcel in) {
return new Collector(in);
}
@Override
public Collector[] newArray(int size) {
return new Collector[size];
}
};
public String getName() {
return name;
}
public Collector setName(String name) {
this.name = name;
return this;
}
public String getPhone() {
return phone;
}
public Collector setPhone(String phone) {
this.phone = phone;
return this;
}
public String getEmail() {
return email;
}
public Collector setEmail(String email) {
this.email = email;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Collector collector = (Collector) o;
if (name != null ? !name.equals(collector.name) : collector.name != null) return false;
if (phone != null ? !phone.equals(collector.phone) : collector.phone != null) return false;
return email != null ? email.equals(collector.email) : collector.email == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (phone != null ? phone.hashCode() : 0);
result = 31 * result + (email != null ? email.hashCode() : 0);
return result;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(phone);
dest.writeString(email);
}
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public class Datum implements Parcelable {
private Type type;
private String description;
public Datum() {
}
private Datum(Parcel in) {
description = in.readString();
type = Type.valueOf(in.readString());
}
public static final Creator<Datum> CREATOR = new Creator<Datum>() {
@Override
public Datum createFromParcel(Parcel in) {
return new Datum(in);
}
@Override
public Datum[] newArray(int size) {
return new Datum[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(description);
dest.writeString(type.name());
}
public Type getType() {
return type;
}
public Datum setType(Type type) {
this.type = type;
return this;
}
public String getDescription() {
return description;
}
public Datum setDescription(String description) {
this.description = description;
return this;
}
public enum Type {
PHSICAL, ONLINE, UNIQUEID, PURCHASE,
FINANCIAL, COMPUTER, NAVIGATION, INTERACTIVE,
DEMOGRAPHIC, CONTENT, STATE, POLITICAL,
HEALTH, PREFERENCE, LOCATION, GOVERNMENT, OTHER_CATEGORY
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Datum datum = (Datum) o;
if (type != datum.type) return false;
return description != null ? description.equals(datum.description) : datum.description == null;
}
@Override
public int hashCode() {
int result = type != null ? type.hashCode() : 0;
result = 31 * result + (description != null ? description.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public class Dispute implements Parcelable {
private String relatedOrganization;
private Type type;
public Dispute() {
}
protected Dispute(Parcel in) {
relatedOrganization = in.readString();
type = Type.valueOf(in.readString());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(relatedOrganization);
dest.writeString(type.name());
}
public static final Creator<Dispute> CREATOR = new Creator<Dispute>() {
@Override
public Dispute createFromParcel(Parcel in) {
return new Dispute(in);
}
@Override
public Dispute[] newArray(int size) {
return new Dispute[size];
}
};
public String getRelatedOrganization() {
return relatedOrganization;
}
public Dispute setRelatedOrganization(String relatedOrganization) {
this.relatedOrganization = relatedOrganization;
return this;
}
public Type getType() {
return type;
}
public Dispute setType(Type type) {
this.type = type;
return this;
}
public enum Type {
SERVICE, INDEPENDENT, COURT, LAW
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dispute dispute = (Dispute) o;
if (relatedOrganization != null ? !relatedOrganization.equals(dispute.relatedOrganization) : dispute.relatedOrganization != null)
return false;
return type == dispute.type;
}
@Override
public int hashCode() {
int result = relatedOrganization != null ? relatedOrganization.hashCode() : 0;
result = 31 * result + (type != null ? type.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public class Purpose implements Parcelable {
private Type type;
private String description;
public Purpose() {
}
protected Purpose(Parcel in) {
description = in.readString();
type = Type.valueOf(in.readString());
}
public static final Creator<Purpose> CREATOR = new Creator<Purpose>() {
@Override
public Purpose createFromParcel(Parcel in) {
return new Purpose(in);
}
@Override
public Purpose[] newArray(int size) {
return new Purpose[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(description);
dest.writeString(type.name());
}
public Type getType() {
return type;
}
public Purpose setType(Type type) {
this.type = type;
return this;
}
public String getDescription() {
return description;
}
public Purpose setDescription(String description) {
this.description = description;
return this;
}
public enum Type {
CURRENT, ADMIN, DEVELOP, TAILORING,
PSEUDO_ANALYSIS, PSEUDO_DECISION, INDIVIDUAL_ANALYSIS, INDIVIDUAL_DECISION,
CONTACT, HISTORICAL, TELEMARKETING, OTHER_PURPOSE
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Purpose purpose = (Purpose) o;
if (type != purpose.type) return false;
return description != null ? description.equals(purpose.description) : purpose.description == null;
}
@Override
public int hashCode() {
int result = type != null ? type.hashCode() : 0;
result = 31 * result + (description != null ? description.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public class Recipient implements Parcelable {
private Type type;
private String description;
public Recipient() {
}
private Recipient(Parcel in) {
description = in.readString();
type = Type.valueOf(in.readString());
}
public static final Creator<Recipient> CREATOR = new Creator<Recipient>() {
@Override
public Recipient createFromParcel(Parcel in) {
return new Recipient(in);
}
@Override
public Recipient[] newArray(int size) {
return new Recipient[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(description);
dest.writeString(type.name());
}
public Type getType() {
return type;
}
public Recipient setType(Type type) {
this.type = type;
return this;
}
public String getDescription() {
return description;
}
public Recipient setDescription(String description) {
this.description = description;
return this;
}
public enum Type {
OURS, DELIVERY, SAME, UNRELATED, PUBLIC, OTHER_RECIPIENT
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Recipient recipient = (Recipient) o;
if (type != recipient.type) return false;
return description != null ? description.equals(recipient.description) : recipient.description == null;
}
@Override
public int hashCode() {
int result = type != null ? type.hashCode() : 0;
result = 31 * result + (description != null ? description.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public enum Remedy implements Parcelable {
CORRECT, MONEY, LAW;
Remedy() {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name());
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Remedy> CREATOR = new Creator<Remedy>() {
@Override
public Remedy createFromParcel(Parcel in) {
return Remedy.valueOf(in.readString());
}
@Override
public Remedy[] newArray(int size) {
return new Remedy[size];
}
};
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by IDIC on 2017/2/16.
*/
public enum Retention implements Parcelable {
NO_RETENTION, STATED_PURPOSE, LEGAL_REQUIREMENT, INDEFINITELY, BUSINESS_PRACTICES;
Retention() {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name());
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Retention> CREATOR = new Creator<Retention>() {
@Override
public Retention createFromParcel(Parcel in) {
return Retention.valueOf(in.readString());
}
@Override
public Retention[] newArray(int size) {
return new Retention[size];
}
};
}
package org.prlab.idic.privacypolicy.pojo.report.p3p;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/2/22.
*/
public class Statement implements Parcelable {
private String consequence;
private List<Purpose> purposes = new LinkedList<>();
private List<Datum> data = new LinkedList<>();
private List<Recipient> recipients = new LinkedList<>();
private List<Remedy> remedies = new LinkedList<>();
private Retention retention;
public Statement() {
}
private Statement(Parcel in) {
consequence = in.readString();
purposes = in.createTypedArrayList(Purpose.CREATOR);
data = in.createTypedArrayList(Datum.CREATOR);
recipients = in.createTypedArrayList(Recipient.CREATOR);
remedies = in.createTypedArrayList(Remedy.CREATOR);
retention = in.readParcelable(Retention.class.getClassLoader());
}
public static final Creator<Statement> CREATOR = new Creator<Statement>() {
@Override
public Statement createFromParcel(Parcel in) {
return new Statement(in);
}
@Override
public Statement[] newArray(int size) {
return new Statement[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(consequence);
dest.writeTypedList(purposes);
dest.writeTypedList(data);
dest.writeTypedList(recipients);
dest.writeTypedList(remedies);
dest.writeParcelable(retention, flags);
}
public String getConsequence() {
return consequence;
}
public Statement setConsequence(String consequence) {
this.consequence = consequence;
return this;
}
public List<Purpose> getPurposes() {
return purposes;
}
public Statement setPurposes(List<Purpose> purposes) {
this.purposes = purposes;
return this;
}
public Statement addPurpose(Purpose purpose) {
if (null != this.purposes) this.purposes.add(purpose);
return this;
}
public List<Datum> getData() {
return data;
}
public Statement setData(List<Datum> data) {
this.data = data;
return this;
}
public Statement addDatum(Datum datum) {
if (null != this.data) this.data.add(datum);
return this;
}
public List<Recipient> getRecipients() {
return recipients;
}
public Statement setRecipients(List<Recipient> recipients) {
this.recipients = recipients;
return this;
}
public Statement addRecipient(Recipient recipient) {
if (null != this.recipients) this.recipients.add(recipient);
return this;
}
public List<Remedy> getRemedies() {
return remedies;
}
public Statement setRemedies(List<Remedy> remedies) {
this.remedies = remedies;
return this;
}
public Statement addRemedy(Remedy remedy) {
if (null != this.remedies) this.remedies.add(remedy);
return this;
}
public Retention getRetention() {
return retention;
}
public Statement setRetention(Retention retention) {
this.retention = retention;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Statement statement = (Statement) o;
if (consequence != null ? !consequence.equals(statement.consequence) : statement.consequence != 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;
if (recipients != null ? !recipients.equals(statement.recipients) : statement.recipients != null) return false;
if (remedies != null ? !remedies.equals(statement.remedies) : statement.remedies != null) return false;
return retention == statement.retention;
}
@Override
public int hashCode() {
int result = consequence != null ? consequence.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);
result = 31 * result + (remedies != null ? remedies.hashCode() : 0);
result = 31 * result + (retention != null ? retention.hashCode() : 0);
return result;
}
}
package org.prlab.idic.privacypolicy.storage;
import android.net.Uri;
import android.provider.BaseColumns;
/**
* Created by IDIC on 2017/2/18.
*/
public class PrivacyPolicyContract {
public static final String CONTENT_AUTHORITY = "org.prlab.idic.privacypolicy";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_PRIVACY_POLICY = "privacy_policy";
public static final class PolicyEntry implements BaseColumns {
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
.appendPath(PATH_PRIVACY_POLICY)
.build();
public static final String TABLE_NAME = "policies";
public static final String COLUMN_MAC = "mac";
public static final String COLUMN_UUIDs = "uuid";
public static final String COLUMN_PREFERENCE = "preference";
}
public static String getSqlSelectForMACAndUUIDsOnwards() {
return PolicyEntry.COLUMN_MAC + " = ? " + " AND " +
PolicyEntry.COLUMN_UUIDs + " = ? ";
}
public static String getSqlSelectForMACAndRelatedUUIDsOnwards() {
return PolicyEntry.COLUMN_MAC + " = ? " + " AND " +
PolicyEntry.COLUMN_UUIDs + " LIKE ? ";
}
}
package org.prlab.idic.privacypolicy.storage;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by IDIC on 2017/2/18.
*/
public class PrivacyPolicyDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "privacy_policy.db";
private static final int DATABASE_VERSION = 1;
public PrivacyPolicyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
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 + "));");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + PrivacyPolicyContract.PolicyEntry.TABLE_NAME);
onCreate(db);
}
}
package org.prlab.idic.privacypolicy.storage;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.NonNull;
import static org.prlab.idic.privacypolicy.storage.PrivacyPolicyContract.PolicyEntry.TABLE_NAME;
/**
* Created by IDIC on 2017/2/18.
*/
public class PrivacyPolicyProvider extends ContentProvider {
public static final int CODE_PRIVACY_POLICY = 100;
/*
* The URI Matcher used by this content provider. The leading "s" in this variable name
* signifies that this UriMatcher is a static member variable of WeatherProvider and is a
* common convention in Android programming.
*/
private static final UriMatcher sUriMatcher = buildUriMatcher();
private PrivacyPolicyDbHelper mOpenHelper;
@Override
public boolean onCreate() {
mOpenHelper = new PrivacyPolicyDbHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor cursor;
switch (sUriMatcher.match(uri)) {
case CODE_PRIVACY_POLICY: {
cursor = db.query(
TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
break;
}
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(@NonNull Uri uri, @NonNull ContentValues values) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
switch (sUriMatcher.match(uri)) {
case CODE_PRIVACY_POLICY:
db.beginTransaction();
try {
long _id = db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_IGNORE);
if (_id == -1) break;
db.setTransactionSuccessful();
Uri curr = ContentUris.withAppendedId(PrivacyPolicyContract.PolicyEntry.CONTENT_URI, _id);
//將新插入的資料uri進行通知,以便獲取最新的資料
getContext().getContentResolver().notifyChange(curr, null);
return curr;
} finally {
db.endTransaction();
}
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
/* Users of the delete method will expect the number of rows deleted to be returned. */
int numRowsDeleted;
/*
* If we pass null as the selection to SQLiteDatabase#delete, our entire table will be
* deleted. However, if we do pass null and delete all of the rows in the table, we won't
* know how many rows were deleted. According to the documentation for SQLiteDatabase,
* passing "1" for the selection will delete all rows and return the number of rows
* deleted, which is what the caller of this method expects.
*/
if (null == selection) selection = "1";
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
switch (sUriMatcher.match(uri)) {
case CODE_PRIVACY_POLICY:
numRowsDeleted = db.delete(
TABLE_NAME,
selection,
selectionArgs);
db.setTransactionSuccessful();
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
db.endTransaction();
/* If we actually deleted any rows, notify that a change has occurred to this URI */
if (numRowsDeleted != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return numRowsDeleted;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case CODE_PRIVACY_POLICY:
db.beginTransaction();
count = db.update(TABLE_NAME,
values,
selection,
selectionArgs);
db.setTransactionSuccessful();
db.endTransaction();
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
private static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = PrivacyPolicyContract.CONTENT_AUTHORITY;
matcher.addURI(authority, PrivacyPolicyContract.PATH_PRIVACY_POLICY, CODE_PRIVACY_POLICY);
return matcher;
}
}
package org.prlab.idic.privacypolicy.storage;
import android.content.ContentResolver;
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.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
/**
* Created by IDIC on 2017/2/15.
*/
public class PrivacyPolicyStorageImpl implements StorageInterface<Integer, String> {
private static final String TAG = PrivacyPolicyStorageImpl.class.getSimpleName();
private ContentResolver mContentResolver;
private String mTargetDeviceMAC;
public static final String[] PRIVACY_POLICY_PROJECTION = {
PrivacyPolicyContract.PolicyEntry.COLUMN_MAC,
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs,
PrivacyPolicyContract.PolicyEntry.COLUMN_PREFERENCE
};
public static final int INDEX_POLICY_MAC = 0;
public static final int INDEX_POLICY_UUIDs = 1;
public static final int INDEX_POLICY_PREFERENCE = 2;
public PrivacyPolicyStorageImpl(ContentResolver contentResolver, String targetDeviceMAC) {
this.mContentResolver = contentResolver;
this.mTargetDeviceMAC = BaseUtils.shortMAC(targetDeviceMAC);
}
@Override
public StorageInterface remove(List<String> layerUUIDs) {
remove(BaseUtils.stringList2ArrayString(layerUUIDs));
return this;
}
private void remove(String layerUUIDs) {
int impactRow = mContentResolver.delete(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
PrivacyPolicyContract.getSqlSelectForMACAndUUIDsOnwards(),
new String[]{mTargetDeviceMAC, layerUUIDs}
);
Log.i(TAG, "Remove [" + layerUUIDs + "] " + (impactRow == 1 ? "success" : "failure") + ".");
}
@Override
public StorageInterface put(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);
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(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
updateContentValues,
PrivacyPolicyContract.getSqlSelectForMACAndUUIDsOnwards(),
new String[]{mTargetDeviceMAC, layerUUIDs}
);
Log.i(TAG, "Update " + String.valueOf(selection) + " to [" + layerUUIDs + "] " + (count == 1 ? "success" : "failure") + ".");
} else {
Log.i(TAG, "Put " + String.valueOf(selection) + " to [" + layerUUIDs + "] success.");
}
}
@Override
public Integer get(List<String> layerUUIDs) {
return get(BaseUtils.stringList2ArrayString(layerUUIDs));
}
private Integer get(String UUIDs) {
try (Cursor cursor = mContentResolver.query(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
PRIVACY_POLICY_PROJECTION,
PrivacyPolicyContract.getSqlSelectForMACAndUUIDsOnwards(),
new String[]{mTargetDeviceMAC, UUIDs},
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " ASC")) {
if (cursor.getCount() == 1) {
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);
}
Log.i(TAG, "Get [" + UUIDs + "] -> null");
return -1;
}
}
private List<String> getRelatedUUIDs(boolean isLower, String UUIDs) {
List<String> UUIDList = new LinkedList<>();
if (isLower) {
try (Cursor cursor = mContentResolver.query(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
PRIVACY_POLICY_PROJECTION,
PrivacyPolicyContract.getSqlSelectForMACAndRelatedUUIDsOnwards(),
new String[]{mTargetDeviceMAC, UUIDs + "_%"},
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " ASC")) {
while (cursor.moveToNext()) {
String targetUUIDs = cursor.getString(INDEX_POLICY_UUIDs);
UUIDList.add(targetUUIDs);
}
}
} else {
if (UUIDs.contains(", ")) {
UUIDs = UUIDs.substring(0, UUIDs.lastIndexOf(", "));
try (Cursor cursor = mContentResolver.query(
PrivacyPolicyContract.PolicyEntry.CONTENT_URI,
PRIVACY_POLICY_PROJECTION,
PrivacyPolicyContract.getSqlSelectForMACAndRelatedUUIDsOnwards(),
new String[]{mTargetDeviceMAC, "%" + UUIDs},
PrivacyPolicyContract.PolicyEntry.COLUMN_UUIDs + " ASC")) {
while (cursor.moveToNext()) {
String targetUUIDs = cursor.getString(INDEX_POLICY_UUIDs);
UUIDList.add(targetUUIDs);
}
}
}
}
return UUIDList;
}
}
package org.prlab.idic.privacypolicy.storage;
import java.util.List;
/**
* Created by IDIC on 2017/2/15.
*/
interface StorageInterface<Result, Key> {
StorageInterface remove(List<Key> layerUUIDs);
StorageInterface put(Result choices, List<Key> layerUUIDs);
Result get(List<Key> layerUUIDs);
}
package org.prlab.idic.privacypolicy.tool;
import org.prlab.idic.privacypolicy.pojo.report.Layer;
import org.prlab.idic.privacypolicy.pojo.report.PrivacyPolicy;
import org.prlab.idic.privacypolicy.pojo.report.p3p.Remedy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IDIC on 2017/1/20.
*/
public class BaseUtils {
private BaseUtils() {
}
public static String bytesToHex(byte[] in) {
if (in == null || in.length == 0) return "null";
final StringBuilder builder = new StringBuilder();
if (in.length > 0) builder.append("0x");
for (byte b : in) builder.append(String.format("%02x", b));
return builder.toString();
}
public static boolean isArrayBeginWith(final byte[] array, final byte[] prefix) {
if (array.length < prefix.length) {
return false;
}
for (int i = 0; i < prefix.length; i++) {
if (array[i] != prefix[i]) {
return false;
}
}
return true;
}
public static int getIntFromByte(final byte bite) {
return bite & 0xFF;
}
public static String convertRemedies2String(List<Remedy> enums) {
if (enums.size() <= 0) return "";
StringBuilder builder = new StringBuilder();
for (Enum e : enums) {
builder.append(e.name()).append(", ");
}
builder.delete(builder.length() - 2, builder.length());
return builder.toString();
}
private static final String SPLIT_STRING = ", ";
public static List<String> arrayString2stringArray(String arrayString) {
return BaseUtils.arrayString2objectArray(arrayString, new BaseUtils.ObjectConverter<String>() {
@Override
public String convert(String string) {
return string;
}
}
);
}
public static List<Integer> arrayString2intArray(String arrayString) {
return BaseUtils.arrayString2objectArray(arrayString, new BaseUtils.ObjectConverter<Integer>() {
@Override
public Integer convert(String string) {
return Integer.parseInt(string);
}
}
);
}
public static <T> List<T> arrayString2objectArray(String arrayString, ObjectConverter<T> converter) {
List<T> list = new ArrayList<>();
if (arrayString != null) {
String[] splits = arrayString.split(SPLIT_STRING);
for (String split : splits) {
list.add(converter.convert(split));
}
}
return list;
}
public interface ObjectConverter<T> {
T convert(String string);
}
public static String intList2ArrayString(List<Integer> integers) {
return BaseUtils.objectArray2ArrayString(integers);
}
public static String stringList2ArrayString(List<String> strings) {
return BaseUtils.objectArray2ArrayString(strings);
}
public static <T> String objectArray2ArrayString(List<T> objects) {
StringBuilder builder = new StringBuilder();
return objects != null ?
builder.append(String.valueOf(objects)).deleteCharAt(0).deleteCharAt(builder.length() - 1).toString() : "";
}
public static String shortMAC(String mac) {
return mac.replaceAll(":", "");
}
public static String fixTypeName(String name) {
if (name.length() <= 1) return "";
name = name.replaceAll("_", " ");
StringBuilder builder = new StringBuilder(name);
builder.delete(1, builder.length());
builder.append(name.toLowerCase());
builder.delete(1, 2);
return builder.toString();
}
public static List<String> layer2UUID(List<Layer> layers) {
List<String> UUIDs = new LinkedList<>();
if (null == layers || layers.isEmpty()) return UUIDs;
for (Layer layer : layers)
UUIDs.add(layer.getUUID());
return UUIDs;
}
public static byte[] intArrray2ByteArray(int i) {
return ByteBuffer.allocate(4).putInt(1695609641).array();
}
}
package org.prlab.idic.privacypolicy.tool;
/**
* Created by IDIC on 2017/2/17.
*/
public class NegotiatorConstants {
public static final int ACTIVITY_SELECTION_RESULT_ID = 86;
}
package org.prlab.idic.privacypolicy.tool.beacon;
/**
* Created by IDIC on 2017/2/14.
*/
public enum BeaconType {
NOT_A_BEACON,
NORMAL_BEACON,
}
package org.prlab.idic.privacypolicy.tool.beacon;
import org.prlab.idic.privacypolicy.tool.BaseUtils;
/**
* Created by IDIC on 2017/2/14.
*/
public final class BeaconUtils {
public static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = {0x4C, 0x00, 0x02, 0x15};
private BeaconUtils() {
// TO AVOID INSTANTIATION
}
/**
* Ascertains whether a Manufacturer Data byte array belongs to a known Beacon type;
*
* @param manufacturerData a Bluetooth LE device's raw manufacturerData.
* @return the {@link BeaconType}
*/
public static BeaconType getBeaconType(final byte[] manufacturerData) {
if (manufacturerData == null || manufacturerData.length == 0) {
return BeaconType.NOT_A_BEACON;
}
if (isBeacon(manufacturerData)) {
return BeaconType.NORMAL_BEACON;
} else {
return BeaconType.NOT_A_BEACON;
}
}
private static boolean isBeacon(byte[] manufacturerData) {
// An iBeacon record must be at least 25 chars long
return manufacturerData.length >= 23;
}
public static String calculateUuidString(final byte[] uuid) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < uuid.length; i++) {
if (i == 4 | i == 6 | i == 8 | i == 10) {
sb.append('-');
}
final int intFromByte = BaseUtils.getIntFromByte(uuid[i]);
if (intFromByte <= 0xF) {
sb.append('0');
}
sb.append(Integer.toHexString(intFromByte));
}
return sb.toString();
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/colorPrimaryLight" android:state_pressed="true" />
<item android:drawable="@color/colorPrimaryLight" android:state_activated="true" />
<item android:drawable="@color/colorPrimaryLight" android:state_selected="true" />
<item android:drawable="@color/colorTransparent"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="@dimen/small_size"
android:right="@dimen/small_size"
android:left="@dimen/small_size"
android:bottom="@dimen/small_size">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke android:width="0dp"/>
<solid android:color="@color/colorAccent"/>
</shape>
</item>
<item android:top="@dimen/median_size"
android:right="@dimen/median_size"
android:left="@dimen/median_size"
android:bottom="@dimen/median_size"
android:drawable="@mipmap/ic_no"/>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="@dimen/small_size"
android:right="@dimen/small_size"
android:left="@dimen/small_size"
android:bottom="@dimen/small_size">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke android:width="0dp"/>
<solid android:color="@color/colorPrimary"/>
</shape>
</item>
<item android:top="@dimen/median_size"
android:right="@dimen/median_size"
android:left="@dimen/median_size"
android:bottom="@dimen/median_size"
android:drawable="@mipmap/ic_yes"/>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
tools:listitem="@layout/recycler_view_item_horizontally"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="@+id/layout_device_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:visibility="gone"
tools:listitem="@layout/recycler_view_icon"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="@+id/layout_device_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_marginTop="@dimen/median_size"
android:layout_marginBottom="@dimen/median_size"
android:layout_gravity="center"
android:text="@string/message_back"
android:onClick="onBackButtonClick"
android:id="@+id/button_device_back"
android:textSize="@dimen/font_bigger_size"
android:layout_width="@dimen/button_width_size"
android:layout_height="@dimen/item_size"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_device_operator"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.prlab.idic.privacypolicy.DeviceOperatorActivity">
<TextView
tools:text="123456"
android:gravity="center"
android:textColor="@color/colorObvious"
android:background="@color/colorImplicit"
android:id="@+id/text_operation_message_bar"
android:layout_alignParentTop="true"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="@dimen/small_item_size"/>
<RelativeLayout
android:id="@+id/layout_operation_temperature"
android:layout_below="@id/text_operation_message_bar"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="@dimen/item_size">
<Button
android:id="@+id/button_operation_send_temperature"
android:layout_alignParentEnd="true"
android:layout_width="@dimen/item_size"
android:layout_height="@dimen/item_size"/>
<TextView
android:id="@+id/text_operation_temperature_unit"
android:text="@string/unit_temperature"
android:gravity="center_vertical|start"
android:layout_toStartOf="@id/button_operation_send_temperature"
android:textSize="@dimen/font_bigger_size"
android:textColor="@color/colorText"
android:layout_width="@dimen/item_size"
android:layout_height="@dimen/item_size"/>
<TextView
android:id="@+id/text_operation_current_temperature"
android:text="@string/message_current_temperature"
android:gravity="center"
android:textSize="@dimen/font_bigger_size"
android:layout_alignParentStart="true"
android:textColor="@color/colorText"
android:layout_width="wrap_content"
android:layout_height="@dimen/item_size"/>
<EditText
android:id="@+id/edit_operation_current_temperature"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_toStartOf="@id/text_operation_temperature_unit"
android:layout_toEndOf="@id/text_operation_current_temperature"
tools:text="12"
android:textSize="@dimen/font_bigger_size"
android:gravity="center_vertical|end"
android:layout_width="match_parent"
android:layout_height="@dimen/item_size"
android:labelFor="@id/text_operation_current_temperature"
android:inputType="number"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/layout_operation_air_purifier"
android:layout_below="@id/layout_operation_temperature"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="@dimen/item_size">
<Switch
android:id="@+id/switch_operation_air_purifier"
android:layout_alignParentEnd="true"
android:layout_width="@dimen/item_size"
android:layout_height="@dimen/item_size"/>
<TextView
android:id="@+id/text_operation_current_air_purifier"
android:text="@string/message_air_purifier_status"
android:gravity="center"
android:textSize="@dimen/font_bigger_size"
android:layout_alignParentStart="true"
android:textColor="@color/colorText"
android:layout_width="wrap_content"
android:layout_height="@dimen/item_size"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_below="@id/layout_operation_air_purifier"
android:background="@color/colorImplicit" />
<android.support.v7.widget.RecyclerView
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:layout_below="@id/layout_operation_air_purifier"
tools:listitem="@layout/recycler_view_message_item"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="@+id/recycler_view_operation_info"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_alignParentBottom="true"
android:id="@+id/layout_policy_choose_buttons"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="@dimen/small_size"
android:paddingBottom="@dimen/small_size"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:text="@string/message_agree"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:onClick="onAgreeButtonClick"
android:textSize="@dimen/font_bigger_size"
android:layout_width="@dimen/button_width_size"
android:layout_height="@dimen/item_size"/>
<Button
android:text="@string/message_deny"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:onClick="onDenyButtonClick"
android:textSize="@dimen/font_bigger_size"
android:layout_width="@dimen/button_width_size"
android:layout_height="@dimen/item_size"/>
</LinearLayout>
<ScrollView
android:layout_alignParentTop="true"
android:layout_above="@id/layout_policy_choose_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="@string/policy_statement_collector_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_statement_collector"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_item_horizontally"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_access_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_marginTop="@dimen/small_size"
android:id="@+id/recycler_view_statement_access"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_dispute_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_statement_dispute"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_item_horizontally"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/statement_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_statement"
android:id="@+id/recycler_view_statement_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="org.prlab.idic.privacypolicy.MainActivity">
<TextView
tools:text="123456"
android:gravity="center"
android:textColor="@color/colorObvious"
android:background="@color/colorImplicit"
android:id="@+id/text_main_message_bar"
android:layout_alignParentTop="true"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="@dimen/small_item_size"/>
<android.support.v7.widget.RecyclerView
android:layout_marginTop="@dimen/small_size"
tools:listitem="@layout/recycler_view_scan_item"
android:layout_below="@id/text_main_message_bar"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view_main_result"/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/text_report_title"
android:text="@string/policy_information_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_below="@id/text_report_title"
android:id="@+id/layout_report_info"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/item_report_version"
layout="@layout/item_key_value_horizontally"/>
<include
android:id="@+id/item_report_description"
layout="@layout/item_key_value_horizontally"/>
</LinearLayout>
<Button
android:id="@+id/button_report_device"
android:onClick="onDeviceInfoButtonClicked"
android:layout_below="@id/layout_report_info"
android:text="@string/policy_report_device_information"
android:textSize="@dimen/font_middle_size"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button_report_back"
android:onClick="onBackButtonClicked"
android:visibility="gone"
android:layout_alignParentBottom="true"
android:text="@string/message_back"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="vertical"
android:layout_below="@id/button_report_device"
android:layout_above="@id/button_report_back"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_marginTop="@dimen/median_size"
android:text="@string/message_collect_data"
android:id="@+id/text_report_policies_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button_report_reset"
android:text="@string/message_reset"
android:textSize="@dimen/font_middle_size"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
tools:listitem="@layout/recycler_view_item"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="@+id/recycler_view_report_policies"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
<TextView
android:layout_marginTop="@dimen/median_size"
android:text="@string/message_more_detail"
android:id="@+id/text_report_child_layers_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_bigger_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
tools:listitem="@layout/recycler_view_item"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="@+id/recycler_view_report_child_layers"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"/>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
tools:text="key"
android:gravity="center"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:id="@+id/text_key"
android:textSize="@dimen/font_normal_size"
android:minHeight="@dimen/small_item_size"
android:layout_width="@dimen/text_key_size"
android:layout_height="wrap_content"/>
<TextView
tools:text="value"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:id="@+id/text_value"
android:layout_marginStart="@dimen/median_size"
android:layout_toEndOf="@id/text_key"
android:layout_alignParentEnd="true"
android:textSize="@dimen/font_normal_size"
android:minHeight="@dimen/small_item_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_marginStart="@dimen/activity_vertical_margin"
android:layout_marginEnd="@dimen/activity_vertical_margin"
tools:text="key"
android:gravity="center_vertical"
android:layout_alignParentStart="true"
android:id="@+id/text_key"
android:textSize="@dimen/font_normal_size"
android:minHeight="@dimen/small_item_size"
android:layout_width="@dimen/text_key_size"
android:layout_height="wrap_content"/>
<TextView
tools:text="value"
android:gravity="center_vertical"
android:id="@+id/text_value"
android:layout_marginStart="@dimen/median_size"
android:layout_toEndOf="@id/text_key"
android:layout_alignParentEnd="true"
android:textSize="@dimen/font_normal_size"
android:minHeight="@dimen/small_item_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
tools:text="12345678-1234-1234-1234-12345678"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:id="@+id/button_child_policy"
android:textSize="@dimen/font_normal_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
tools:src="@drawable/rounded_no"
android:id="@+id/image_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
tools:text="111111111111-1111-1111-1111-11111111"
android:gravity="center"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:id="@+id/button_item"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="@dimen/item_size"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_marginTop="@dimen/small_size"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/item_info"
layout="@layout/item_key_value_horizontally"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tool="http://schemas.android.com/tools"
android:background="@drawable/list_item_selector"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/linear_layout_connect_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/image_view_message_event"
android:layout_width="20dp"
android:layout_height="20dp"
android:scaleType="fitCenter"
android:layout_centerVertical="true"
android:src="@drawable/ic_arrow_forward_black_24dp" />
<TextView
android:id="@+id/text_view_message_event"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/image_view_message_event"
android:textSize="18sp"
tool:text="Event" />
</RelativeLayout>
<TextView
android:id="@+id/text_view_message_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:textSize="13sp"
tool:text="Message" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/linear_layout_connect_info"
android:background="@color/colorPrimaryDark" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tool="http://schemas.android.com/tools">
<RelativeLayout
android:id="@+id/linear_layout_scan_info"
android:layout_width="wrap_content"
android:layout_height="@dimen/item_size" android:layout_marginLeft="@dimen/small_size"
android:layout_marginRight="@dimen/small_size" android:layout_centerVertical="true"
android:layout_centerHorizontal="true">
<ImageView
android:id="@+id/image_scan_allowed"
android:scaleType="centerInside"
tool:src="@drawable/rounded_yes"
android:layout_width="@dimen/item_size"
android:layout_height="@dimen/item_size"
android:contentDescription="@string/message_privacy_policy"/>
<Button
android:id="@+id/button_scan_connect"
android:text="@string/action_connect"
android:layout_marginStart="@dimen/median_size"
android:textSize="@dimen/font_normal_size"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:gravity="center_vertical"
android:layout_toEndOf="@id/image_scan_allowed"
android:layout_toStartOf="@id/button_scan_connect"
android:id="@+id/text_scan_device_name"
tool:text="nRF Temperature Monitor"
android:textSize="@dimen/font_normal_size"
android:layout_width="wrap_content"
android:layout_height="15sp"/>
<TextView
android:gravity="center_vertical"
android:layout_toEndOf="@id/image_scan_allowed"
android:layout_toStartOf="@id/button_scan_connect"
android:layout_below="@id/text_scan_device_name"
android:id="@+id/text_scan_device_mac"
android:textSize="@dimen/font_normal_size"
tool:text="AA:AA:AA:AA:AA:AA"
android:layout_width="wrap_content"
android:layout_height="15sp"/>
<TextView
android:gravity="center_vertical"
android:layout_toEndOf="@id/image_scan_allowed"
android:layout_below="@id/text_scan_device_mac"
android:id="@+id/text_scan_is_bonded"
android:textSize="@dimen/font_normal_size"
tool:text="@string/bluetooth_bonded"
android:layout_width="wrap_content"
android:layout_height="15sp"/>
<TextView
android:gravity="center_vertical|end"
android:layout_toEndOf="@id/text_scan_is_bonded"
android:layout_toStartOf="@id/button_scan_connect"
android:layout_below="@id/text_scan_device_name"
android:id="@+id/text_scan_rssi"
android:textSize="@dimen/font_normal_size"
tool:text="-48 dBm"
android:layout_width="wrap_content"
android:layout_height="15sp"/>
</RelativeLayout>
<View
android:layout_below="@id/linear_layout_scan_info"
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="@string/policy_statement_consequence_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_marginTop="@dimen/small_size"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_view_statement_consequence"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_purpose_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_statement_purposes"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_item_horizontally"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_data_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_statement_data"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_item_horizontally"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_remedies"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
tools:text="123"
android:gravity="center"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text_statement_remedies"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_recipient_title"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_statement_recipients"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_item_horizontally"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:text="@string/policy_statement_retention"
android:gravity="center_vertical"
android:textSize="@dimen/font_middle_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_marginTop="@dimen/small_size"
android:gravity="center"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text_statement_retention"/>
<View
android:background="@color/colorSeparator"
android:layout_width="match_parent"
android:layout_height="1dp"/>
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:orderInCategory="100"
android:icon="@mipmap/ic_bluetooth_searching"
android:title="@string/action_enable_scan"
app:showAsAction="ifRoom" />
</menu>
\ No newline at end of file
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorPrimaryLight">#7484ea</color>
<color name="colorAccent">#FF4081</color>
<color name="colorSeparator">#898989</color>
<color name="colorImplicit">#4c9737</color>
<color name="colorObvious">#ffffff</color>
<color name="colorText">#000000</color>
<color name="colorTransparent">#00000000</color>
</resources>
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="small_size">5dp</dimen>
<dimen name="median_size">8dp</dimen>
<dimen name="item_size">50sp</dimen>
<dimen name="small_item_size">30sp</dimen>
<dimen name="font_bigger_size">20sp</dimen>
<dimen name="font_middle_size">16sp</dimen>
<dimen name="font_normal_size">12sp</dimen>
<dimen name="text_key_size">120sp</dimen>
<dimen name="min_width_size">120dp</dimen>
<dimen name="button_width_size">120dp</dimen>
</resources>
<resources>
<string name="app_name">BLEPrivacyPolicyNegotiator</string>
<string name="uuid_accept_privacy_policy">22222222&#8211;2222&#8211;2222&#8211;2222&#8211;222222222222</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>
<string name="message_device_information">Device Information</string>
<string name="message_press_scan_first">Start scanning first.</string>
<string name="message_scan_start">There are BLE sensors around you as follow.</string>
<string name="message_scan_stop">Stop scanning.</string>
<string name="message_enable_first">Enable Bluetooth first. Press scanning button again.</string>
<string name="message_choose_policy">The policies you need to choose as follows.</string>
<string name="message_collect_data">We may collect data as follows.</string>
<string name="message_more_detail">More Detail</string>
<string name="message_policy_title">Policy</string>
<string name="message_back">Back</string>
<string name="message_agree">Agree</string>
<string name="message_deny">Deny</string>
<string name="message_reset">Reset</string>
<string name="report_policy_information">Policy Information</string>
<string name="bluetooth_bonded">BONDED</string>
<string name="bluetooth_not_bonded">NOT BONDED</string>
<string name="rssi_unit">dBm</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="policy_information_title">Report</string>
<string name="policy_selections_title">Selection</string>
<string name="policy_report_version_title">Version</string>
<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="policy_statement_collector_title">Collector</string>
<string name="policy_statement_dispute_title">Dispute</string>
<string name="policy_statement_recipient_title">Recipient</string>
<string name="policy_statement_purpose_title">Purpose</string>
<string name="policy_statement_data_title">Data</string>
<string name="policy_statement_collector_name">Name</string>
<string name="policy_statement_collector_phone">Phone</string>
<string name="policy_statement_collector_email">Email</string>
<string name="policy_statement_data_type">Type</string>
<string name="policy_statement_data_description">Description</string>
<string name="policy_statement_purpose_type">Type</string>
<string name="policy_statement_purpose_description">Description</string>
<string name="policy_statement_recipient_type">Type</string>
<string name="policy_statement_recipient_description">Description</string>
<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_access_title">Access</string>
<string name="policy_statement_remedies">Remedies</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="statement_title">Statements</string>
<string name="policy_statement_retention">Retention</string>
<string name="unit_temperature">°C</string>
<string name="message_current_temperature">Current temperature</string>
<string name="message_air_purifier_status">Air Purifier status</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
package org.prlab.idic.privacypolicy;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Mon Dec 28 10:00:20 PST 2015
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
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM mOptions here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM mOptions to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add mOptions to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM mOptions here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM mOptions to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
include ':app'
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