diff --git a/app/gradle.properties b/app/gradle.properties index 0db303f3a5e5d10435a82acd862bec04bc146452..1dd0e26d2b59d84aa9b32ab72e3c5b99065efabe 100644 --- a/app/gradle.properties +++ b/app/gradle.properties @@ -1 +1 @@ -version=0.4.0-SNAPSHOT +version=0.5.0-SNAPSHOT diff --git a/app/src/main/java/info/nightscout/android/medtronic/GetHmacAndKeyActivity.java b/app/src/main/java/info/nightscout/android/medtronic/GetHmacAndKeyActivity.java index f283f844fbee0a6529dfaa5ab52e549bec048f92..dfd43740a7f4ce86fafde82fc746d661476fd109 100644 --- a/app/src/main/java/info/nightscout/android/medtronic/GetHmacAndKeyActivity.java +++ b/app/src/main/java/info/nightscout/android/medtronic/GetHmacAndKeyActivity.java @@ -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"); - - // Set up the login form. - mUsernameView = (EditText) findViewById(R.id.username); + getSupportActionBar().setTitle("Registered Devices"); - 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 diff --git a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java index 16cc8d6070d9beb0ca425becf0396b40e2d58dbf..5be35edfe6a0a28c34a650c6627c3c4e7addefbe 100644 --- a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java +++ b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java @@ -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() { diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java index 1c72020c489f95ef9f5196f85bac3e7931283094..d8c3319efa8a3b4bdd3a9868ae5c93d234d88f52 100644 --- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java +++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java @@ -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 { diff --git a/app/src/main/res/drawable/drawer_header.jpg b/app/src/main/res/drawable/drawer_header.jpg index e3f8ab881ebc761afbfdad7ae6b554adb658d83a..251abd5c8a8ee193ef484393a966c891c8f5478a 100644 Binary files a/app/src/main/res/drawable/drawer_header.jpg and b/app/src/main/res/drawable/drawer_header.jpg differ diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 56ac4a9c6e3a449922fac8c1bcedbd368be5f4a1..84cc07b2b8603da6a558869fe53fa029ae140bcd 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -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" + <TextView 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> + android:id="@+id/registered_usb_devices" /> </LinearLayout> </ScrollView> diff --git a/app/src/main/res/menu/menu_register_usb.xml b/app/src/main/res/menu/menu_register_usb.xml deleted file mode 100644 index 81a6c5646903e8d5f192edbd9d651e4b025c70dc..0000000000000000000000000000000000000000 --- a/app/src/main/res/menu/menu_register_usb.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?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 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 548128d84781081ed0d7961587f84f4c51d63845..7045ebb5bf07e743c80a57420796b46290abf78a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -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>