diff --git a/app/src/main/java/haus/nightmare/GlassTesla/MainActivity.java b/app/src/main/java/haus/nightmare/GlassTesla/MainActivity.java index 7cfab1f..578430f 100644 --- a/app/src/main/java/haus/nightmare/GlassTesla/MainActivity.java +++ b/app/src/main/java/haus/nightmare/GlassTesla/MainActivity.java @@ -19,66 +19,111 @@ import android.widget.AdapterView; import org.conscrypt.Conscrypt; +import java.io.IOException; import java.net.URL; import java.security.Security; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import javax.net.ssl.SSLException; +import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; +import okhttp3.RequestBody; import okhttp3.Response; +import okio.BufferedSink; public class MainActivity extends Activity { private CardScrollView cardScroller; - private View view; private TeslaResponse vehicleData; private SharedPreferences prefs; + + private ArrayList scrollerViews = new ArrayList(); + + @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); prefs = getPreferences(MODE_PRIVATE); - view = buildStatusView(); - view.setKeepScreenOn(true); + scrollerViews.add(buildStatusView()); + scrollerViews.add(buildLocksView()); + scrollerViews.add(buildControlView()); + cardScroller = new CardScrollView(this); cardScroller.setAdapter(new CardScrollAdapter() { @Override public int getCount() { - return 1; + return scrollerViews.size(); } @Override public Object getItem(int position) { - return view; + return scrollerViews.get(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { - return view; + return scrollerViews.get(position); } @Override public int getPosition(Object item) { - if (view.equals(item)) { - return 0; - } - return AdapterView.INVALID_POSITION; + return scrollerViews.indexOf(item); } }); cardScroller.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { + + if (position == 2) { + postCommand("flash_lights"); + } + + if (position == 1) { + if (vehicleData.vehicle_state.locked) { + postCommand("door_unlock"); + } else { + postCommand("door_lock"); + } + scrollerViews.set(1, buildLocksView()); + } + + if (position == 0) { + scrollerViews.set(0, buildStatusView()); + } + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); am.playSoundEffect(Sounds.TAP); } + + }); + cardScroller.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + + if (position == 2) { + return postCommand("honk_horn"); + } + if (position == 1) { + return postCommand("set_sentry_mode?on=" + !vehicleData.vehicle_state.sentry_mode); + } + if (position == 0) { + return postCommand("remote_start_drive?password=" + prefs.getString("auth_password", "")); + } + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + am.playSoundEffect(Sounds.DISALLOWED); + return false; + } }); setContentView(cardScroller); } @@ -95,8 +140,28 @@ public class MainActivity extends Activity { super.onPause(); } - private View buildStatusView() { - if (vehicleData == null) { + private View buildControlView() { + CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT); + card.setText("Tap to flash lights, long press to honk."); + return card.getView(); + } + + private View buildLocksView() { + updateIfNeeded(); + + CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT); + String body = vehicleData.vehicle_state.locked ? "Tap to unlock" : "Tap to lock"; + body += "\nLong press to "; + body += vehicleData.vehicle_state.sentry_mode ? "disable" : "enable"; + body += " Sentry Mode"; + card.setText(body); + return card.getView(); + } + + private void updateIfNeeded() { + Calendar expire = Calendar.getInstance(); + expire.add(Calendar.MINUTE, -5); + if (vehicleData == null || new Date(vehicleData.vehicle_state.timestamp).after(expire.getTime())) { try { getVehicleData(); } catch(Exception e) { @@ -105,6 +170,10 @@ public class MainActivity extends Activity { System.exit(0); // Shouldn't be reached, but just in case let's kill it dead } } + } + + private View buildStatusView() { + updateIfNeeded(); CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT); String chargeDuration = ""; @@ -133,20 +202,49 @@ public class MainActivity extends Activity { ); card.setFootnote(String.format("%s last updated: %s", vehicleData.display_name, - new SimpleDateFormat("hh:mm").format(vehicleData.charge_state.timestamp) + new SimpleDateFormat("hh:mm").format(vehicleData.vehicle_state.timestamp) )); - - return card.getView(); + View v = card.getView(); + v.setKeepScreenOn(true); + return v; } // /api/1/vehicles/{id}/vehicle_data public void getVehicleData() { String vehicleId = prefs.getString("vehicle_id", ""); - String json = getResponseFromJsonURL("https://owner-api.teslamotors.com/api/1/vehicles/" + vehicleId +"/vehicle_data"); + String json = getResponseFromJsonURL("https://owner-api.teslamotors.com/api/1/vehicles/" + + vehicleId +"/vehicle_data"); Gson gson = new Gson(); ResponseRoot root = gson.fromJson(json, ResponseRoot.class); vehicleData = root.response; } + + + public boolean postCommand(String command) { + try { + String token = prefs.getString("bearer_token", ""); + String vehicleId = prefs.getString("vehicle_id", ""); + URL object = new URL("https://owner-api.teslamotors.com/api/1/vehicles/" + + vehicleId +"/command/" + command); + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url(object) + .method("POST", RequestBody.create(null, new byte[]{})) + .addHeader("Authorization", "Bearer " + token) + .addHeader("User-Agent", "Tesla-GLASS") + .addHeader("Content-Type", "application/json") + .build(); + + + Response response = client.newCall(request).execute(); + + return response.code() == 200; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + public String getResponseFromJsonURL(String url) { String token = prefs.getString("bearer_token", "");