diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 565057b..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: android
-android:
- components:
- # Uncomment the lines below if you want to
- # use the latest revision of Android SDK Tools
- # - tools
- # - platform-tools
-
- # The BuildTools version used by your project
- #- build-tools-26.0.2
-
- # The SDK version used to compile your project
- - android-16
-
- # Additional components
- #- extra-google-google_play_services
- #- extra-google-m2repository
- #- extra-android-m2repository
-
- # Specify at least one system image,
- # if you need to run emulator(s) during your tests
- #- sys-img-x86-android-26
- #- sys-img-armeabi-v7a-android-17
-before_script:
- - chmod +x ./DarkChatter/gradlew
-
-script:
- - ./DarkChatter/gradlew tasks
- - ./DarkChatter/gradlew build connectedCheck --stacktrace
diff --git a/DarkChatter/.idea/misc.xml b/DarkChatter/.idea/misc.xml
index e0d5b93..c0f68ed 100644
--- a/DarkChatter/.idea/misc.xml
+++ b/DarkChatter/.idea/misc.xml
@@ -5,31 +5,27 @@
-
+
diff --git a/DarkChatter/.idea/vcs.xml b/DarkChatter/.idea/vcs.xml
deleted file mode 100644
index 6c0b863..0000000
--- a/DarkChatter/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/AndroidManifest.xml b/DarkChatter/app/src/main/AndroidManifest.xml
index 4b29d91..b959a0b 100644
--- a/DarkChatter/app/src/main/AndroidManifest.xml
+++ b/DarkChatter/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
+
+
+
-
+
+
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/ChatActivity.java b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/ChatActivity.java
new file mode 100644
index 0000000..d41daf9
--- /dev/null
+++ b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/ChatActivity.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package comdarkchatter.github.darkchatter;
+
+import android.app.Activity;
+import android.net.nsd.NsdServiceInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.support.design.widget.Snackbar;
+import comdarkchatter.github.darkchatter.NsdHelper;
+
+public class ChatActivity extends Activity {
+
+ NsdHelper mNsdHelper;
+
+ private TextView mStatusView;
+ private Handler mUpdateHandler;
+
+ public static final String TAG = "NsdChat";
+
+ ChatConnection mConnection;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d(TAG, "Creating chat activity");
+ setContentView(R.layout.main);
+ mStatusView = (TextView) findViewById(R.id.status);
+
+ mUpdateHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ String chatLine = msg.getData().getString("msg");
+ addChatLine(chatLine);
+ }
+ };
+
+ }
+
+ public void clickAdvertise(View v) {
+ // Register service
+ if(mConnection.getLocalPort() > -1) {
+ mNsdHelper.registerService(mConnection.getLocalPort());
+ } else {
+ //User-side warning when register fails
+ Snackbar registerError = Snackbar.make(v, "Unable to register!", Snackbar.LENGTH_SHORT);
+ registerError.show();
+ Log.d(TAG, "ServerSocket isn't bound.");
+ }
+ }
+
+ public void clickDiscover(View v) {
+ mNsdHelper.discoverServices();
+ }
+
+ public void clickConnect(View v) {
+ NsdServiceInfo service = mNsdHelper.getChosenServiceInfo();
+ if (service != null) {
+ Log.d(TAG, "Connecting.");
+ mConnection.connectToServer(service.getHost(),
+ service.getPort());
+ } else {
+ //User-side warning when connect fails
+ Snackbar connectError = Snackbar.make(v, "Unable to connect! There is a problem with the service.", Snackbar.LENGTH_SHORT);
+ connectError.show();
+ Log.d(TAG, "No service to connect to!");
+ }
+ }
+
+ public void clickSend(View v) {
+ EditText messageView = (EditText) this.findViewById(R.id.chatInput);
+ if (messageView != null) {
+ String messageString = messageView.getText().toString();
+ if (!messageString.isEmpty()) {
+ boolean messageSent = mConnection.sendMessage(messageString);
+ if (!messageSent){
+ //User-side warning when connect fails
+ Snackbar messageSentError = Snackbar.make(v, "Message was not sent. There is a problem with the service.", Snackbar.LENGTH_SHORT);
+ messageSentError.show();
+ }
+ }
+ messageView.setText("");
+ }
+ }
+
+ public void addChatLine(String line) {
+ mStatusView.append("\n" + line);
+ }
+
+ @Override
+ protected void onStart() {
+ Log.d(TAG, "Starting.");
+ mConnection = new ChatConnection(mUpdateHandler);
+
+ mNsdHelper = new NsdHelper(this);
+ mNsdHelper.initializeNsd();
+ super.onStart();
+ }
+
+
+ @Override
+ protected void onPause() {
+ Log.d(TAG, "Pausing.");
+ if (mNsdHelper != null) {
+ mNsdHelper.stopDiscovery();
+ }
+ super.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ Log.d(TAG, "Resuming.");
+ super.onResume();
+ if (mNsdHelper != null) {
+ mNsdHelper.discoverServices();
+ }
+ }
+
+
+ // For KitKat and earlier releases, it is necessary to remove the
+ // service registration when the application is stopped. There's
+ // no guarantee that the onDestroy() method will be called (we're
+ // killable after onStop() returns) and the NSD service won't remove
+ // the registration for us if we're killed.
+
+ // In L and later, NsdService will automatically unregister us when
+ // our connection goes away when we're killed, so this step is
+ // optional (but recommended).
+
+ @Override
+ protected void onStop() {
+ Log.d(TAG, "Being stopped.");
+ mNsdHelper.tearDown();
+ mConnection.tearDown();
+ mNsdHelper = null;
+ mConnection = null;
+ super.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ Log.d(TAG, "Being destroyed.");
+ super.onDestroy();
+ }
+}
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/ChatConnection.java b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/ChatConnection.java
new file mode 100644
index 0000000..98f7eb0
--- /dev/null
+++ b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/ChatConnection.java
@@ -0,0 +1,301 @@
+
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package comdarkchatter.github.darkchatter;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.design.widget.Snackbar;
+import android.util.Log;
+import android.view.View;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+public class ChatConnection {
+
+ private Handler mUpdateHandler;
+ private ChatServer mChatServer;
+ private ChatClient mChatClient;
+
+ private static final String TAG = "ChatConnection";
+
+ private Socket mSocket;
+ private int mPort = -1;
+
+ public ChatConnection(Handler handler) {
+ mUpdateHandler = handler;
+ mChatServer = new ChatServer(handler);
+ }
+
+ public void tearDown() {
+ mChatServer.tearDown();
+ if (mChatClient != null) {
+ mChatClient.tearDown();
+ }
+ }
+
+ public void connectToServer(InetAddress address, int port) {
+ mChatClient = new ChatClient(address, port);
+ }
+
+ //send message returns true if sent, false if not sent
+ public boolean sendMessage(String msg) {
+ if (mChatClient != null) {
+ return mChatClient.sendMessage(msg);
+ }
+ return false;
+ }
+
+ public int getLocalPort() {
+ return mPort;
+ }
+
+ public void setLocalPort(int port) {
+ mPort = port;
+ }
+
+
+ public synchronized void updateMessages(String msg, boolean local) {
+ Log.e(TAG, "Updating message: " + msg);
+
+ if (local) {
+ msg = "me: " + msg;
+ } else {
+ msg = "them: " + msg;
+ }
+
+ Bundle messageBundle = new Bundle();
+ messageBundle.putString("msg", msg);
+
+ Message message = new Message();
+ message.setData(messageBundle);
+ mUpdateHandler.sendMessage(message);
+
+ }
+
+ private synchronized void setSocket(Socket socket) {
+ Log.d(TAG, "setSocket being called.");
+ if (socket == null) {
+ Log.d(TAG, "Setting a null socket.");
+ }
+ if (mSocket != null) {
+ if (mSocket.isConnected()) {
+ try {
+ mSocket.close();
+ } catch (IOException e) {
+ // TODO(alexlucas): Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ mSocket = socket;
+ }
+
+ private Socket getSocket() {
+ return mSocket;
+ }
+
+ private class ChatServer {
+ ServerSocket mServerSocket = null;
+ Thread mThread = null;
+
+ public ChatServer(Handler handler) {
+ mThread = new Thread(new ServerThread());
+ mThread.start();
+ }
+
+ public void tearDown() {
+ mThread.interrupt();
+ try {
+ mServerSocket.close();
+ } catch (IOException ioe) {
+ Log.e(TAG, "Error when closing server socket.");
+ }
+ }
+
+ class ServerThread implements Runnable {
+
+ @Override
+ public void run() {
+
+ try {
+ // Since discovery will happen via Nsd, we don't need to care which port is
+ // used. Just grab an available one and advertise it via Nsd.
+ mServerSocket = new ServerSocket(0);
+ setLocalPort(mServerSocket.getLocalPort());
+
+ while (!Thread.currentThread().isInterrupted()) {
+ Log.d(TAG, "ServerSocket Created, awaiting connection");
+ setSocket(mServerSocket.accept());
+ Log.d(TAG, "Connected.");
+ if (mChatClient == null) {
+ int port = mSocket.getPort();
+ InetAddress address = mSocket.getInetAddress();
+ connectToServer(address, port);
+ }
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Error creating ServerSocket: ", e);
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private class ChatClient {
+
+ private InetAddress mAddress;
+ private int PORT;
+
+ private final String CLIENT_TAG = "ChatClient";
+
+ private Thread mSendThread;
+ private Thread mRecThread;
+
+ public ChatClient(InetAddress address, int port) {
+
+ Log.d(CLIENT_TAG, "Creating chatClient");
+ this.mAddress = address;
+ this.PORT = port;
+
+ mSendThread = new Thread(new SendingThread());
+ mSendThread.start();
+ }
+
+ class SendingThread implements Runnable {
+
+ BlockingQueue mMessageQueue;
+ private int QUEUE_CAPACITY = 10;
+
+ public SendingThread() {
+ mMessageQueue = new ArrayBlockingQueue(QUEUE_CAPACITY);
+ }
+
+ @Override
+ public void run() {
+ try {
+ if (getSocket() == null) {
+ setSocket(new Socket(mAddress, PORT));
+ Log.d(CLIENT_TAG, "Client-side socket initialized.");
+
+ } else {
+ Log.d(CLIENT_TAG, "Socket already initialized. skipping!");
+ }
+
+ mRecThread = new Thread(new ReceivingThread());
+ mRecThread.start();
+
+ } catch (UnknownHostException e) {
+ Log.d(CLIENT_TAG, "Initializing socket failed, UHE", e);
+ } catch (IOException e) {
+ Log.d(CLIENT_TAG, "Initializing socket failed, IOE.", e);
+ }
+
+ while (true) {
+ try {
+ String msg = mMessageQueue.take();
+ sendMessage(msg);
+ } catch (InterruptedException ie) {
+ Log.d(CLIENT_TAG, "Message sending loop interrupted, exiting");
+ }
+ }
+ }
+ }
+
+ class ReceivingThread implements Runnable {
+
+ @Override
+ public void run() {
+
+ BufferedReader input;
+ try {
+ input = new BufferedReader(new InputStreamReader(
+ mSocket.getInputStream()));
+ while (!Thread.currentThread().isInterrupted()) {
+
+ String messageStr = null;
+ messageStr = input.readLine();
+ if (messageStr != null) {
+ Log.d(CLIENT_TAG, "Read from the stream: " + messageStr);
+ updateMessages(messageStr, false);
+ } else {
+ Log.d(CLIENT_TAG, "The nulls! The nulls!");
+ break;
+ }
+ }
+ input.close();
+
+ } catch (IOException e) {
+ Log.e(CLIENT_TAG, "Server loop error: ", e);
+ }
+ }
+ }
+
+ public void tearDown() {
+ try {
+ getSocket().close();
+ } catch (IOException ioe) {
+ Log.e(CLIENT_TAG, "Error when closing server socket.");
+ }
+ }
+
+ public boolean sendMessage(String msg) {
+ //boolean to check if the message was sent without errors
+ boolean messageSent = true;
+ try {
+ Socket socket = getSocket();
+ if (socket == null) {
+ Log.d(CLIENT_TAG, "Socket is null");
+ } else if (socket.getOutputStream() == null) {
+ Log.d(CLIENT_TAG, "Socket output stream is null");
+ }
+
+ PrintWriter out = new PrintWriter(
+ new BufferedWriter(
+ new OutputStreamWriter(getSocket().getOutputStream())), true);
+ out.println(msg);
+ out.flush();
+ updateMessages(msg, true);
+
+ } catch (UnknownHostException e) {
+ Log.d(CLIENT_TAG, "Unknown Host", e);
+ messageSent = false;
+ } catch (IOException e) {
+ Log.d(CLIENT_TAG, "I/O Exception", e);
+ messageSent = false;
+ } catch (Exception e) {
+ Log.d(CLIENT_TAG, "Error3", e);
+ messageSent = false;
+ }
+
+ Log.d(CLIENT_TAG, "Client sent message: " + msg);
+ return messageSent;
+ }
+ }
+}
diff --git a/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/GroupActivity.java b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/GroupActivity.java
index 04f5acb..d7c0621 100644
--- a/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/GroupActivity.java
+++ b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/GroupActivity.java
@@ -1,5 +1,9 @@
package comdarkchatter.github.darkchatter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
@@ -11,6 +15,11 @@
public class GroupActivity extends AppCompatActivity {
+ private Context activity;
+ private WifiP2pManager manager;
+ private WifiP2pManager.Channel channel;
+ private BroadcastReceiver receiver;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -18,12 +27,17 @@ protected void onCreate(Bundle savedInstanceState) {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
+ activity = this.activity;
+
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
+
@Override
public void onClick(View view) {
- Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
- .setAction("Action", null).show();
+ Intent chat = new Intent(GroupActivity.this, ChatActivity.class);
+ //GroupActivity.this.startActivity(chat);
+ startActivity(chat);
+
}
});
}
@@ -48,4 +62,4 @@ public boolean onOptionsItemSelected(MenuItem item) {
}
return super.onOptionsItemSelected(item);
}
-}
+}
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/NsdHelper.java b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/NsdHelper.java
new file mode 100644
index 0000000..354232d
--- /dev/null
+++ b/DarkChatter/app/src/main/java/comdarkchatter/github/darkchatter/NsdHelper.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package comdarkchatter.github.darkchatter;
+
+import android.content.Context;
+import android.net.nsd.NsdServiceInfo;
+import android.net.nsd.NsdManager;
+import android.util.Log;
+
+public class NsdHelper {
+
+ Context mContext;
+
+ NsdManager mNsdManager;
+ NsdManager.ResolveListener mResolveListener;
+ NsdManager.DiscoveryListener mDiscoveryListener;
+ NsdManager.RegistrationListener mRegistrationListener;
+
+ public static final String SERVICE_TYPE = "_http._tcp.";
+
+ public static final String TAG = "NsdHelper";
+ public String mServiceName = "NsdChat";
+
+ NsdServiceInfo mService;
+
+ public NsdHelper(Context context) {
+ mContext = context;
+ mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
+ }
+
+ public void initializeNsd() {
+ initializeResolveListener();
+
+ //mNsdManager.init(mContext.getMainLooper(), this);
+
+ }
+
+ public void initializeDiscoveryListener() {
+ mDiscoveryListener = new NsdManager.DiscoveryListener() {
+
+ @Override
+ public void onDiscoveryStarted(String regType) {
+ Log.d(TAG, "Service discovery started");
+ }
+
+ @Override
+ public void onServiceFound(NsdServiceInfo service) {
+ Log.d(TAG, "Service discovery success" + service);
+ if (!service.getServiceType().equals(SERVICE_TYPE)) {
+ Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
+ } else if (service.getServiceName().equals(mServiceName)) {
+ Log.d(TAG, "Same machine: " + mServiceName);
+ } else if (service.getServiceName().contains(mServiceName)){
+ mNsdManager.resolveService(service, mResolveListener);
+ }
+ }
+
+ @Override
+ public void onServiceLost(NsdServiceInfo service) {
+ Log.e(TAG, "service lost" + service);
+ if (mService == service) {
+ mService = null;
+ }
+ }
+
+ @Override
+ public void onDiscoveryStopped(String serviceType) {
+ Log.i(TAG, "Discovery stopped: " + serviceType);
+ }
+
+ @Override
+ public void onStartDiscoveryFailed(String serviceType, int errorCode) {
+ Log.e(TAG, "Discovery failed: Error code:" + errorCode);
+ }
+
+ @Override
+ public void onStopDiscoveryFailed(String serviceType, int errorCode) {
+ Log.e(TAG, "Discovery failed: Error code:" + errorCode);
+ }
+ };
+ }
+
+ public void initializeResolveListener() {
+ mResolveListener = new NsdManager.ResolveListener() {
+
+ @Override
+ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
+ Log.e(TAG, "Resolve failed" + errorCode);
+ }
+
+ @Override
+ public void onServiceResolved(NsdServiceInfo serviceInfo) {
+ Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
+
+ if (serviceInfo.getServiceName().equals(mServiceName)) {
+ Log.d(TAG, "Same IP.");
+ return;
+ }
+ mService = serviceInfo;
+ }
+ };
+ }
+
+ public void initializeRegistrationListener() {
+ mRegistrationListener = new NsdManager.RegistrationListener() {
+
+ @Override
+ public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
+ mServiceName = NsdServiceInfo.getServiceName();
+ Log.d(TAG, "Service registered: " + mServiceName);
+ }
+
+ @Override
+ public void onRegistrationFailed(NsdServiceInfo arg0, int arg1) {
+ Log.d(TAG, "Service registration failed: " + arg1);
+ }
+
+ @Override
+ public void onServiceUnregistered(NsdServiceInfo arg0) {
+ Log.d(TAG, "Service unregistered: " + arg0.getServiceName());
+ }
+
+ @Override
+ public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+ Log.d(TAG, "Service unregistration failed: " + errorCode);
+ }
+
+ };
+ }
+
+ public void registerService(int port) {
+ tearDown(); // Cancel any previous registration request
+ initializeRegistrationListener();
+ NsdServiceInfo serviceInfo = new NsdServiceInfo();
+ serviceInfo.setPort(port);
+ serviceInfo.setServiceName(mServiceName);
+ serviceInfo.setServiceType(SERVICE_TYPE);
+
+ mNsdManager.registerService(
+ serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+
+ }
+
+ public void discoverServices() {
+ stopDiscovery(); // Cancel any existing discovery request
+ initializeDiscoveryListener();
+ mNsdManager.discoverServices(
+ SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
+ }
+
+ public void stopDiscovery() {
+ if (mDiscoveryListener != null) {
+ try {
+ mNsdManager.stopServiceDiscovery(mDiscoveryListener);
+ } finally {
+ }
+ mDiscoveryListener = null;
+ }
+ }
+
+ public NsdServiceInfo getChosenServiceInfo() {
+ return mService;
+ }
+
+ public void tearDown() {
+ if (mRegistrationListener != null) {
+ try {
+ mNsdManager.unregisterService(mRegistrationListener);
+ } finally {
+ }
+ mRegistrationListener = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/res/layout/content_chat.xml b/DarkChatter/app/src/main/res/layout/content_chat.xml
new file mode 100644
index 0000000..96c6252
--- /dev/null
+++ b/DarkChatter/app/src/main/res/layout/content_chat.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/res/layout/main.xml b/DarkChatter/app/src/main/res/layout/main.xml
new file mode 100644
index 0000000..aeeff1d
--- /dev/null
+++ b/DarkChatter/app/src/main/res/layout/main.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/res/menu/menu_chat.xml b/DarkChatter/app/src/main/res/menu/menu_chat.xml
new file mode 100644
index 0000000..188b19d
--- /dev/null
+++ b/DarkChatter/app/src/main/res/menu/menu_chat.xml
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/DarkChatter/app/src/main/res/values/strings.xml b/DarkChatter/app/src/main/res/values/strings.xml
index 2c51980..aa31d4b 100644
--- a/DarkChatter/app/src/main/res/values/strings.xml
+++ b/DarkChatter/app/src/main/res/values/strings.xml
@@ -89,5 +89,10 @@
"For example, position the FAB to one side of stream of a cards so the FAB won’t interfere "
"when a user tries to pick up one of cards.\n\n"
+ Connect
+ Discover
+ Register
+ Send
Settings
-
+ DarkChatter
+
\ No newline at end of file