Android Open Source - Android-Apps Remote Session






From Project

Back to project page Android-Apps.

License

The source code is released under:

Apache License

If you think the Android project Android-Apps listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *  Copyright (C) 2011  Tom Quist//  www.  j  a  va2s.  c o m
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You can get the GNU General Public License at
 *  http://www.gnu.org/licenses/gpl.html
 */
package de.quist.samy.remocon;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.concurrent.TimeoutException;

import android.util.Log;

public class RemoteSession {

  public static final String REPORT_TAG = "report";

  private static final String APP_STRING = "iphone.iapp.samsung";
  private static final String TV_APP_STRING = "iphone..iapp.samsung";

  private static final char[] ALLOWED_BYTES = new char[] { 0x64, 0x00, 0x01,
      0x00 };
  private static final char[] DENIED_BYTES = new char[] { 0x64, 0x00, 0x00,
      0x00 };
  private static final char[] TIMEOUT_BYTES = new char[] { 0x65, 0x00 };

  public static final String ALLOWED = "ALLOWED";
  public static final String DENIED = "DENIED";
  public static final String TIMEOUT = "TIMEOUT";
  private static final String TAG = RemoteSession.class.getSimpleName();

  private String applicationName;
  private String uniqueId;
  private String host;
  private int port;

  private Socket socket;

  private InputStreamReader reader;

  private BufferedWriter writer;

  private RemoteSession(String applicationName, String uniqueId, String host,
      int port) {
    this.applicationName = applicationName;
    this.uniqueId = uniqueId;
    if (uniqueId == null) {
      uniqueId = "";
    }
    this.host = host;
    this.port = port;
  }

  public static RemoteSession create(String applicationName, String uniqueId,
      String host, int port) throws IOException,
      ConnectionDeniedException, TimeoutException {
    RemoteSession session = new RemoteSession(applicationName, uniqueId,
        host, port);
    String result = session.initialize();
    if (result.equals(ALLOWED)) {
      return session;
    } else if (result.equals(DENIED)) {
      throw new ConnectionDeniedException();
    } else if (result.equals(TIMEOUT)) {
      throw new TimeoutException();
    } else {
      return session; // TODO For now we just assume to be connected
      // throw new UnknownError("TV returned " + result);
    }
  }

  private String initialize() throws UnknownHostException, IOException {
    Log.v(TAG, "Creating socket for host " + host + " on port " + port);
    socket = new Socket(host, port);
    Log.v(TAG, "Socket successfully created and connected");
    InetAddress localAddress = socket.getLocalAddress();
    Log.v(TAG, "Local address is " + localAddress.getHostAddress());

    Log.v(TAG, "Sending registration message");
    writer = new BufferedWriter(new OutputStreamWriter(
        socket.getOutputStream()));
    writer.append((char) 0x00);
    writeText(writer, APP_STRING);
    writeText(writer, getRegistrationPayload(localAddress.getHostAddress()));
    writer.flush();

    InputStream in = socket.getInputStream();
    reader = new InputStreamReader(in);
    String result = readRegistrationReply(reader);
    // sendPart2();
    int i;
    while ((i = in.available()) > 0) {
      in.skip(i);
    }
    return result;
  }

  private void sendPart2() throws IOException {
    writer.append((char) 0x00);
    writeText(writer, TV_APP_STRING);
    writeText(writer, new String(new char[] { 0xc8, 0x00 }));
  }

  private void checkConnection() throws UnknownHostException, IOException {
    if (socket.isClosed() || !socket.isConnected()) {
      Log.v(TAG, "Connection closed, trying to reconnect...");
      try {
        socket.close();
      } catch (IOException e) {
        // Ignore any exception
      }
      initialize();
      Log.v(TAG, "Reconnected to server");
    }
  }

  public void destroy() {
    try {
      socket.close();
    } catch (IOException e) {
      // Ignore exception
    }
  }

  private String readRegistrationReply(Reader reader) throws IOException {
    Log.v(TAG, "Reading registration reply");
    reader.read(); // Unknown byte 0x02
    String text1 = readText(reader); // Read
                      // "unknown.livingroom.iapp.samsung"
                      // for new RC and "iapp.samsung" for
                      // already registered RC
    Log.v(TAG, "Received ID: " + text1);
    char[] result = readCharArray(reader); // Read result sequence
    if (Arrays.equals(result, ALLOWED_BYTES)) {
      Log.v(TAG, "Registration successfull");
      return ALLOWED;
    } else if (Arrays.equals(result, DENIED_BYTES)) {
      Log.w(TAG, "Registration denied");
      return DENIED;
    } else if (Arrays.equals(result, TIMEOUT_BYTES)) {
      Log.w(TAG, "Registration timed out");
      return TIMEOUT;
    } else {
      StringBuilder sb = new StringBuilder();
      for (char c : result) {
        sb.append(Integer.toHexString(c));
        sb.append(' ');
      }
      String hexReturn = sb.toString();
      Log.e(REPORT_TAG, "Received unknown registration reply: "
          + hexReturn);
      return hexReturn;
    }
  }

  private String getRegistrationPayload(String ip) throws IOException {
    StringWriter writer = new StringWriter();
    writer.append((char) 0x64);
    writer.append((char) 0x00);
    writeBase64Text(writer, ip);
    writeBase64Text(writer, uniqueId);
    writeBase64Text(writer, applicationName);
    writer.flush();
    return writer.toString();
  }

  private static String readText(Reader reader) throws IOException {
    char[] buffer = readCharArray(reader);
    return new String(buffer);
  }

  private static char[] readCharArray(Reader reader) throws IOException {
    if (reader.markSupported())
      reader.mark(1024);
    int length = reader.read();
    int delimiter = reader.read();
    if (delimiter != 0) {
      if (reader.markSupported())
        reader.reset();
      throw new IOException("Unsupported reply exception");
    }
    char[] buffer = new char[length];
    reader.read(buffer);
    return buffer;
  }

  private static Writer writeText(Writer writer, String text)
      throws IOException {
    return writer.append((char) text.length()).append((char) 0x00)
        .append(text);
  }

  private static Writer writeBase64Text(Writer writer, String text)
      throws IOException {
    String b64 = Base64.encodeBytes(text.getBytes());
    return writeText(writer, b64);
  }

  private void internalSendKey(Key key) throws IOException {
    writer.append((char) 0x00);
    writeText(writer, TV_APP_STRING);
    writeText(writer, getKeyPayload(key));
    writer.flush();
    int i = reader.read(); // Unknown byte 0x00
    String t = readText(reader); // Read "iapp.samsung"
    char[] c = readCharArray(reader);
    System.out.println(i);
    System.out.println(t);
    for (char a : c)
      System.out.println(Integer.toHexString(a));
    // System.out.println(c);
  }

  public void sendKey(Key key) throws IOException {
    Log.v(TAG, "Sending key " + key.getValue() + "...");
    checkConnection();
    try {
      internalSendKey(key);
    } catch (SocketException e) {
      Log.v(TAG,
          "Could not send key because the server closed the connection. Reconnecting...");
      initialize();
      Log.v(TAG, "Sending key " + key.getValue() + " again...");
      internalSendKey(key);
    }
    Log.v(TAG, "Successfully sent key " + key.getValue());
  }

  private String getKeyPayload(Key key) throws IOException {
    StringWriter writer = new StringWriter();
    writer.append((char) 0x00);
    writer.append((char) 0x00);
    writer.append((char) 0x00);
    writeBase64Text(writer, key.getValue());
    writer.flush();
    return writer.toString();
  }

  private void internalSendText(String text) throws IOException {
    writer.append((char) 0x01);
    writeText(writer, TV_APP_STRING);
    writeText(writer, getTextPayload(text));
    writer.flush();
    if (!reader.ready()) {
      return;
    }
    int i = reader.read(); // Unknown byte 0x02
    System.out.println(i);
    String t = readText(reader); // Read "iapp.samsung"
    char[] c = readCharArray(reader);
    System.out.println(i);
    System.out.println(t);
    for (char a : c)
      System.out.println(Integer.toHexString(a));
  }

  public void sendText(String text) throws IOException {
    Log.v(TAG, "Sending text \"" + text + "\"...");
    checkConnection();
    try {
      internalSendText(text);
    } catch (SocketException e) {
      Log.v(TAG,
          "Could not send key because the server closed the connection. Reconnecting...");
      initialize();
      Log.v(TAG, "Sending text \"" + text + "\" again...");
      internalSendText(text);
    }
    Log.v(TAG, "Successfully sent text \"" + text + "\"");
  }

  private String getTextPayload(String text) throws IOException {
    StringWriter writer = new StringWriter();
    writer.append((char) 0x01);
    writer.append((char) 0x00);
    writeBase64Text(writer, text);
    writer.flush();
    return writer.toString();
  }

}




Java Source Code List

com.kniezrec.remoterecorder.Communication.java
com.kniezrec.remoterecorder.MainServiceConnection.java
com.kniezrec.remoterecorder.MainService.java
com.kniezrec.remoterecorder.RequestType.java
com.kniezrec.remoterecorder.Request.java
com.kniezrec.voiceremote2.BSeriesKeyCodeSenderFactory.java
com.kniezrec.voiceremote2.BSeriesSender.java
com.kniezrec.voiceremote2.CSeriesButtons.java
com.kniezrec.voiceremote2.CSeriesKeyCodeSenderFactory.java
com.kniezrec.voiceremote2.CSeriesSender.java
com.kniezrec.voiceremote2.CommandsFragment.java
com.kniezrec.voiceremote2.Commands.java
com.kniezrec.voiceremote2.Discovery.java
com.kniezrec.voiceremote2.FSeriesButtons.java
com.kniezrec.voiceremote2.Group.java
com.kniezrec.voiceremote2.HelpFragment.java
com.kniezrec.voiceremote2.HostnamePreference.java
com.kniezrec.voiceremote2.KeyCodeSender.java
com.kniezrec.voiceremote2.ListActionsFragment.java
com.kniezrec.voiceremote2.MainActivity.java
com.kniezrec.voiceremote2.MainFragment.java
com.kniezrec.voiceremote2.Mapper.java
com.kniezrec.voiceremote2.MyExpandableListAdapter.java
com.kniezrec.voiceremote2.NewActionEdit.java
com.kniezrec.voiceremote2.NewActionSingleEdit.java
com.kniezrec.voiceremote2.NewAction.java
com.kniezrec.voiceremote2.RemoteButton.java
com.kniezrec.voiceremote2.SenderFactory.java
com.kniezrec.voiceremote2.Sender.java
com.kniezrec.voiceremote2.SettingsActivity.java
com.kniezrec.voiceremote2.TextSender.java
com.kniezrec.voiceremotefree.BSeriesKeyCodeSenderFactory.java
com.kniezrec.voiceremotefree.BSeriesSender.java
com.kniezrec.voiceremotefree.CSeriesButtons.java
com.kniezrec.voiceremotefree.CSeriesKeyCodeSenderFactory.java
com.kniezrec.voiceremotefree.CSeriesSender.java
com.kniezrec.voiceremotefree.Commands.java
com.kniezrec.voiceremotefree.Discovery.java
com.kniezrec.voiceremotefree.FSeriesButtons.java
com.kniezrec.voiceremotefree.HelpActivity.java
com.kniezrec.voiceremotefree.HostnamePreference.java
com.kniezrec.voiceremotefree.KeyCodeSender.java
com.kniezrec.voiceremotefree.ListActionsActivity.java
com.kniezrec.voiceremotefree.MainActivity.java
com.kniezrec.voiceremotefree.Mapper.java
com.kniezrec.voiceremotefree.NewActionEdit.java
com.kniezrec.voiceremotefree.NewActionSingleEdit.java
com.kniezrec.voiceremotefree.NewAction.java
com.kniezrec.voiceremotefree.RemoteButton.java
com.kniezrec.voiceremotefree.SenderFactory.java
com.kniezrec.voiceremotefree.Sender.java
com.kniezrec.voiceremotefree.Setings.java
com.kniezrec.voiceremotefree.SettingsActivity.java
com.kniezrec.voiceremotefree.TextSender.java
com.kniezrec.xbmcgear.connection.AndroidApplication.java
com.kniezrec.xbmcgear.connection.Connection.java
com.kniezrec.xbmcgear.connection.GearJSON.java
com.kniezrec.xbmcgear.connection.JSONRPCRequest.java
com.kniezrec.xbmcgear.connection.JSONRequestFactory.java
com.kniezrec.xbmcgear.connection.NSDResolve.java
com.kniezrec.xbmcgear.connection.NSDSearch.java
com.kniezrec.xbmcgear.connection.ProviderConnection.java
com.kniezrec.xbmcgear.connection.ProviderService.java
com.kniezrec.xbmcgear.connection.ResponseParser.java
com.kniezrec.xbmcgear.connection.WakeOnLan.java
com.kniezrec.xbmcgear.player.Kodi.java
com.kniezrec.xbmcgear.player.Player.java
com.kniezrec.xbmcgear.player.Playlist.java
com.kniezrec.xbmcgear.player.Song.java
com.kniezrec.xbmcgear.player.Video.java
com.kniezrec.xbmcgear.preferences.HostTable.java
com.kniezrec.xbmcgear.preferences.Host.java
com.kniezrec.xbmcgear.preferences.HostsDataSource.java
com.kniezrec.xbmcgear.preferences.HostsDatabaseHelper.java
com.kniezrec.xbmcgear.preferences.SharedPreferencesUtil.java
com.kniezrec.xbmcgear.presentation.AnimationManager.java
com.kniezrec.xbmcgear.presentation.AutoConfigurationActivity.java
com.kniezrec.xbmcgear.presentation.HostSetActivity.java
com.kniezrec.xbmcgear.presentation.InstanceActivity.java
com.kniezrec.xbmcgear.presentation.MainActivity.java
com.kniezrec.xbmcgear.presentation.StyleDialogFragment.java
com.kniezrec.xbmcgear.presentation.ViewMode.java
com.uraroji.garage.android.lame.SimpleLame.java
com.uraroji.garage.android.mp3recvoice.RecMicToMp3.java
de.quist.samy.remocon.Base64.java
de.quist.samy.remocon.Base64.java
de.quist.samy.remocon.ConnectionDeniedException.java
de.quist.samy.remocon.ConnectionDeniedException.java
de.quist.samy.remocon.Key.java
de.quist.samy.remocon.Key.java
de.quist.samy.remocon.Loggable.java
de.quist.samy.remocon.Loggable.java
de.quist.samy.remocon.RemoteReader.java
de.quist.samy.remocon.RemoteReader.java
de.quist.samy.remocon.RemoteSession.java
de.quist.samy.remocon.RemoteSession.java