Skip to content
Snippets Groups Projects
Commit 188b51c0 authored by Lennart Goedhart's avatar Lennart Goedhart
Browse files

Merge branch 'master' into develop

* master:
  [Gradle Release Plugin] - new version commit:  'v0.5.0-SNAPSHOT'.
  [Gradle Release Plugin] - pre tag commit:  'v0.4.0'.
  Remove CareLink login code. Prepare for release.
parents fce0ad0e 084cebf7
No related branches found
No related tags found
No related merge requests found
version=0.4.0-SNAPSHOT
version=0.5.0-SNAPSHOT
......@@ -62,19 +62,8 @@ import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
*/
public class GetHmacAndKeyActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
// TODO - Replace with Rx.Java
private GetHmacAndKey mHmacAndKeyTask = null;
// UI references.
private EditText mUsernameView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
private TextView mRegisteredStickView;
private MenuItem mLoginMenuItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -82,25 +71,8 @@ public class GetHmacAndKeyActivity extends AppCompatActivity implements LoaderCa
setContentView(R.layout.activity_login);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Register USB");
getSupportActionBar().setTitle("Registered Devices");
// Set up the login form.
mUsernameView = (EditText) findViewById(R.id.username);
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == EditorInfo.IME_ACTION_DONE) {
attemptLogin();
return true;
}
return false;
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
mRegisteredStickView = (TextView) findViewById(R.id.registered_usb_devices);
showRegisteredSticks();
......@@ -108,21 +80,12 @@ public class GetHmacAndKeyActivity extends AppCompatActivity implements LoaderCa
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_register_usb, menu);
mLoginMenuItem = menu.findItem(R.id.action_menu_login);
mLoginMenuItem.setIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_cloud_download).color(Color.WHITE).actionBar());
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_menu_login:
attemptLogin();
break;
case android.R.id.home:
finish();
break;
......@@ -135,96 +98,12 @@ public class GetHmacAndKeyActivity extends AppCompatActivity implements LoaderCa
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid username, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
if (mHmacAndKeyTask != null || !checkOnline("Please connect to the Internet", "You must be online to register your USB stick.")) {
return;
}
// Reset errors.
mUsernameView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String username = mUsernameView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (TextUtils.isEmpty(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid username address.
if (TextUtils.isEmpty(username)) {
mUsernameView.setError(getString(R.string.error_field_required));
focusView = mUsernameView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mHmacAndKeyTask = new GetHmacAndKey(username, password);
mHmacAndKeyTask.execute((Void) null);
}
}
/**
* Shows the progress UI and hides the login form.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
private void showRegisteredSticks() {
Realm realm = Realm.getDefaultInstance();
RealmResults<ContourNextLinkInfo> results = realm.where(ContourNextLinkInfo.class).findAll();
String deviceTableHtml = "<big><b>Registered Devices</b></big><br/>";
String deviceTableHtml = "";
for (ContourNextLinkInfo info : results) {
String longSerial = info.getSerialNumber();
......@@ -236,29 +115,6 @@ public class GetHmacAndKeyActivity extends AppCompatActivity implements LoaderCa
mRegisteredStickView.setText(Html.fromHtml(deviceTableHtml));
}
private boolean checkOnline(String title, String message) {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
boolean isOnline = (netInfo != null && netInfo.isConnectedOrConnecting());
if (!isOnline) {
new AlertDialog.Builder(this, R.style.AppTheme)
.setTitle(title)
.setMessage(message)
.setCancelable(false)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
return isOnline;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return null;
......@@ -271,115 +127,4 @@ public class GetHmacAndKeyActivity extends AppCompatActivity implements LoaderCa
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class GetHmacAndKey extends AsyncTask<Void, Void, Boolean> {
private final String mUsername;
private final String mPassword;
GetHmacAndKey(String username, String password) {
mUsername = username;
mPassword = password;
}
@Override
protected Boolean doInBackground(final Void... params) {
try {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost loginPost = new HttpPost("https://carelink.minimed.eu/patient/j_security_check");
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("j_username", mUsername));
nameValuePairs.add(new BasicNameValuePair("j_password", mPassword));
nameValuePairs.add(new BasicNameValuePair("j_character_encoding", "UTF-8"));
loginPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
HttpResponse response = client.execute(loginPost);
if (response.getStatusLine().getStatusCode() == 200) {
// Get the HMAC/keys for every serial we have seen
Realm realm = Realm.getDefaultInstance();
RealmResults<ContourNextLinkInfo> results = realm.where(ContourNextLinkInfo.class).findAll();
for (ContourNextLinkInfo info : results) {
String longSerial = info.getSerialNumber();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream hmacRequest = new ObjectOutputStream(buffer);
hmacRequest.writeInt(0x1c);
hmacRequest.writeObject(longSerial.replaceAll("\\d+-", ""));
HttpPost hmacPost = new HttpPost("https://carelink.minimed.eu/patient/secure/SnapshotServer/");
hmacPost.setEntity(new ByteArrayEntity(buffer.toByteArray()));
hmacPost.setHeader("Content-type", "application/octet-stream");
response = client.execute(hmacPost);
ByteArrayInputStream inputBuffer = new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity()));
ObjectInputStream hmacResponse = new ObjectInputStream(inputBuffer);
byte[] hmacBytes = (byte[]) hmacResponse.readObject();
ArrayUtils.reverse(hmacBytes);
String hmac = MessageUtils.byteArrayToHexString(hmacBytes);
buffer.reset();
inputBuffer.reset();
ObjectOutputStream keyRequest = new ObjectOutputStream(buffer);
keyRequest.writeInt(0x1f);
keyRequest.writeObject(longSerial);
HttpPost keyPost = new HttpPost("https://carelink.minimed.eu/patient/secure/SnapshotServer/");
keyPost.setEntity(new ByteArrayEntity(buffer.toByteArray()));
keyPost.setHeader("Content-type", "application/octet-stream");
response = client.execute(keyPost);
inputBuffer = new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity()));
ObjectInputStream keyResponse = new ObjectInputStream(inputBuffer);
keyResponse.readInt(); // Throw away the first int. Not sure what it does
String key = MessageUtils.byteArrayToHexString((byte[]) keyResponse.readObject());
realm.beginTransaction();
info.setKey(key);
realm.commitTransaction();
}
return true;
}
} catch (ClientProtocolException e) {
return false;
} catch (IOException e) {
return false;
} catch (ClassNotFoundException e) {
return false;
}
return false;
}
@Override
protected void onPostExecute(final Boolean success) {
mHmacAndKeyTask = null;
if (success) {
showRegisteredSticks();
mLoginMenuItem.setVisible(false);
mLoginFormView.setVisibility(View.GONE);
mProgressView.setVisibility(View.GONE);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mLoginFormView.getWindowToken(), 0);
} else {
showProgress(false);
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
protected void onCancelled() {
mHmacAndKeyTask = null;
showProgress(false);
}
}
}
\ No newline at end of file
......@@ -176,7 +176,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
.withIcon(GoogleMaterial.Icon.gmd_settings)
.withSelectable(false);
final PrimaryDrawerItem itemRegisterUsb = new PrimaryDrawerItem()
.withName("Register Contour Next Link")
.withName("Registered Devices")
.withIcon(GoogleMaterial.Icon.gmd_usb)
.withSelectable(false);
final PrimaryDrawerItem itemStopCollecting = new PrimaryDrawerItem()
......@@ -273,8 +273,8 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
private boolean hasDetectedCnl() {
if (mRealm.where(ContourNextLinkInfo.class).count() == 0) {
new AlertDialog.Builder(this, R.style.AppTheme)
.setTitle("Contour Next Link not detected")
.setMessage("To register a Contour Next Link you must first plug it in.")
.setTitle("No registered Contour Next Link devices")
.setMessage("To register a Contour Next Link you must first plug it in, and get a reading from the pump.")
.setCancelable(false)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
......@@ -293,7 +293,6 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
UsbDevice cnlDevice = UsbHidDriver.getUsbDevice(usbManager, MedtronicCnlIntentService.USB_VID, MedtronicCnlIntentService.USB_PID);
return !(usbManager != null && cnlDevice != null && !usbManager.hasPermission(cnlDevice));
}
private void waitForUsbPermission() {
......
......@@ -162,25 +162,6 @@ public class MedtronicCnlIntentService extends IntentService {
cnlReader.getPumpSession().setStickSerial(info.getSerialNumber());
/*
String hmac = info.getHmac();
String key = info.getKey();
if (hmac == null || key == null) {
// Must commit the transaction before we send the Registration activation message
realm.commitTransaction();
sendMessage(Constants.ACTION_USB_REGISTER);
realm.close();
MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
// TODO - throw, don't return
return;
}
cnlReader.getPumpSession().setHMAC(MessageUtils.hexStringToByteArray(hmac));
cnlReader.getPumpSession().setKey(MessageUtils.hexStringToByteArray(key));
*/
cnlReader.enterControlMode();
try {
......
app/src/main/res/drawable/drawer_header.jpg

47.3 KiB | W: | H:

app/src/main/res/drawable/drawer_header.jpg

62.7 KiB | W: | H:

app/src/main/res/drawable/drawer_header.jpg
app/src/main/res/drawable/drawer_header.jpg
app/src/main/res/drawable/drawer_header.jpg
app/src/main/res/drawable/drawer_header.jpg
  • 2-up
  • Swipe
  • Onion skin
......@@ -11,13 +11,6 @@
tools:context=".medtronic.GetHmacAndKeyActivity">
<!-- Login progress -->
<ProgressBar
android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:visibility="gone"/>
<ScrollView
android:layout_width="match_parent"
......@@ -28,52 +21,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/prompt_carelink_username_password" />
<AutoCompleteTextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_username"
android:inputType="text"
android:imeOptions="actionNext"
android:maxLines="1"
android:singleLine="true"/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionDone|actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/registered_usb_devices" />
</LinearLayout>
</LinearLayout>
</ScrollView>
......
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_menu_login"
android:title="Login"
android:orderInCategory="100"
app:showAsAction="always"
/>
</menu>
\ No newline at end of file
......@@ -30,7 +30,7 @@
<string name="preference_api_secret">API SECRET</string>
<string name="prompt_carelink_username_password">Please enter your CareLink details.\nThey will not be stored.</string>
<string name="close">Close</string>
<string name="register_contour_next_link">Register Contour Next Link</string>
<string name="register_contour_next_link">Registered Devices</string>
<string name="preferences_enable_crashlytics">prefs_enable_crashlytics</string>
<string name="preferences_enable_answers">prefs_enable_answers</string>
<string name="preferences_enable_remote_logcat">prefs_enable_remote_logcat</string>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment