Move Sync to foreground service

pull/286/head
Alinson S. Xavier 9 years ago
parent 3da996b8a4
commit 293d838d80

@ -17,36 +17,29 @@
~ You should have received a copy of the GNU General Public License along ~ You should have received a copy of the GNU General Public License along
~ with this program. If not, see <http://www.gnu.org/licenses/>. ~ with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<manifest package="org.isoron.uhabits"
<manifest
package="org.isoron.uhabits"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="28" android:versionCode="28"
android:versionName="1.7.1"> android:versionName="1.7.1">
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission <uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/> android:maxSdkVersion="18"/>
<uses-permission <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/> android:maxSdkVersion="18"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:name="HabitsApplication" android:name=".HabitsApplication"
android:allowBackup="true" android:allowBackup="true"
android:backupAgent=".HabitsBackupAgent" android:backupAgent=".HabitsBackupAgent"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/main_activity_title" android:label="@string/main_activity_title"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppBaseTheme"> android:theme="@style/AppBaseTheme">
<meta-data <meta-data
android:name="com.google.android.backup.api_key" android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAI6aeWncbnMNo8E5GWeZ44dlc5cQ7tCROwFhOtiw"/> android:value="AEdPqrEAAAAI6aeWncbnMNo8E5GWeZ44dlc5cQ7tCROwFhOtiw"/>
@ -64,6 +57,7 @@
android:targetActivity=".activities.habits.list.ListHabitsActivity"> android:targetActivity=".activities.habits.list.ListHabitsActivity">
<intent-filter android:label="@string/app_name"> <intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity-alias> </activity-alias>
@ -75,7 +69,6 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.habits.list.ListHabitsActivity"/> android:value=".activities.habits.list.ListHabitsActivity"/>
</activity> </activity>
<activity <activity
android:name=".activities.settings.SettingsActivity" android:name=".activities.settings.SettingsActivity"
android:label="@string/settings"> android:label="@string/settings">
@ -83,12 +76,10 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.habits.list.ListHabitsActivity"/> android:value=".activities.habits.list.ListHabitsActivity"/>
</activity> </activity>
<activity <activity
android:name=".activities.intro.IntroActivity" android:name=".activities.intro.IntroActivity"
android:label="" android:label=""
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/> android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity <activity
android:name=".widgets.HabitPickerDialog" android:name=".widgets.HabitPickerDialog"
android:theme="@style/Theme.AppCompat.Light.Dialog"> android:theme="@style/Theme.AppCompat.Light.Dialog">
@ -96,7 +87,6 @@
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".activities.about.AboutActivity" android:name=".activities.about.AboutActivity"
android:label="@string/about"> android:label="@string/about">
@ -116,7 +106,6 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/widget_checkmark_info"/> android:resource="@xml/widget_checkmark_info"/>
</receiver> </receiver>
<receiver <receiver
android:name=".widgets.HistoryWidgetProvider" android:name=".widgets.HistoryWidgetProvider"
android:label="@string/history"> android:label="@string/history">
@ -128,7 +117,6 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/widget_history_info"/> android:resource="@xml/widget_history_info"/>
</receiver> </receiver>
<receiver <receiver
android:name=".widgets.ScoreWidgetProvider" android:name=".widgets.ScoreWidgetProvider"
android:label="@string/habit_strength"> android:label="@string/habit_strength">
@ -140,7 +128,6 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/widget_score_info"/> android:resource="@xml/widget_score_info"/>
</receiver> </receiver>
<receiver <receiver
android:name=".widgets.StreakWidgetProvider" android:name=".widgets.StreakWidgetProvider"
android:label="@string/streaks"> android:label="@string/streaks">
@ -152,7 +139,6 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/widget_streak_info"/> android:resource="@xml/widget_streak_info"/>
</receiver> </receiver>
<receiver <receiver
android:name=".widgets.FrequencyWidgetProvider" android:name=".widgets.FrequencyWidgetProvider"
android:label="@string/frequency"> android:label="@string/frequency">
@ -164,33 +150,35 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/widget_frequency_info"/> android:resource="@xml/widget_frequency_info"/>
</receiver> </receiver>
<receiver android:name=".receivers.ReminderReceiver"> <receiver android:name=".receivers.ReminderReceiver">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.WidgetReceiver"> <receiver android:name=".receivers.WidgetReceiver">
<intent-filter> <intent-filter>
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
<action android:name="org.isoron.uhabits.ACTION_TOGGLE_REPETITION"/> <action android:name="org.isoron.uhabits.ACTION_TOGGLE_REPETITION"/>
<data <data
android:host="org.isoron.uhabits" android:host="org.isoron.uhabits"
android:scheme="content"/> android:scheme="content"/>
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
<action android:name="org.isoron.uhabits.ACTION_ADD_REPETITION"/> <action android:name="org.isoron.uhabits.ACTION_ADD_REPETITION"/>
<data <data
android:host="org.isoron.uhabits" android:host="org.isoron.uhabits"
android:scheme="content"/> android:scheme="content"/>
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
<action android:name="org.isoron.uhabits.ACTION_REMOVE_REPETITION"/> <action android:name="org.isoron.uhabits.ACTION_REMOVE_REPETITION"/>
<data <data
android:host="org.isoron.uhabits" android:host="org.isoron.uhabits"
android:scheme="content"/> android:scheme="content"/>
@ -211,8 +199,7 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"> android:label="@string/app_name">
<intent-filter> <intent-filter>
<action <action android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING"/>
android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING"/>
</intent-filter> </intent-filter>
</activity> </activity>
@ -235,5 +222,11 @@
android:resource="@xml/file_paths"/> android:resource="@xml/file_paths"/>
</provider> </provider>
<service
android:name=".sync.SyncService"
android:enabled="true"
android:exported="false">
</service>
</application> </application>
</manifest> </manifest>

@ -19,6 +19,7 @@
package org.isoron.uhabits.activities.habits.list; package org.isoron.uhabits.activities.habits.list;
import android.content.*;
import android.os.*; import android.os.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
@ -47,8 +48,6 @@ public class ListHabitsActivity extends BaseActivity
private MidnightTimer midnightTimer; private MidnightTimer midnightTimer;
private SyncManager syncManager;
public ListHabitsComponent getListHabitsComponent() public ListHabitsComponent getListHabitsComponent()
{ {
return component; return component;
@ -84,7 +83,9 @@ public class ListHabitsActivity extends BaseActivity
rootView.setController(controller, selectionMenu); rootView.setController(controller, selectionMenu);
midnightTimer = component.getMidnightTimer(); midnightTimer = component.getMidnightTimer();
syncManager = app.getComponent().getSyncManager();
if(prefs.isSyncFeatureEnabled())
startService(new Intent(this, SyncService.class));
setScreen(screen); setScreen(screen);
controller.onStartup(); controller.onStartup();
@ -93,7 +94,6 @@ public class ListHabitsActivity extends BaseActivity
@Override @Override
protected void onPause() protected void onPause()
{ {
syncManager.stopListening();
midnightTimer.onPause(); midnightTimer.onPause();
screen.onDettached(); screen.onDettached();
adapter.cancelRefresh(); adapter.cancelRefresh();
@ -107,7 +107,6 @@ public class ListHabitsActivity extends BaseActivity
screen.onAttached(); screen.onAttached();
rootView.postInvalidate(); rootView.postInvalidate();
midnightTimer.onResume(); midnightTimer.onResume();
syncManager.startListening();
if (prefs.getTheme() == ThemeSwitcher.THEME_DARK && if (prefs.getTheme() == ThemeSwitcher.THEME_DARK &&
prefs.isPureBlackEnabled() != pureBlack) prefs.isPureBlackEnabled() != pureBlack)

@ -242,9 +242,10 @@ public class Preferences
} }
if (key.equals("pref_sticky_notifications")) if (key.equals("pref_sticky_notifications"))
{
for (Listener l : listeners) l.onNotificationsChanged(); for (Listener l : listeners) l.onNotificationsChanged();
}
if (key.equals("pref_feature_sync"))
for (Listener l : listeners) l.onSyncFeatureChanged();
} }
public void removeListener(Listener listener) public void removeListener(Listener listener)
@ -306,5 +307,7 @@ public class Preferences
default void onCheckmarkOrderChanged() {} default void onCheckmarkOrderChanged() {}
default void onNotificationsChanged() {} default void onNotificationsChanged() {}
default void onSyncFeatureChanged() {}
} }
} }

@ -30,6 +30,8 @@ import com.getpebble.android.kit.util.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
@ -51,6 +53,8 @@ public class PebbleReceiver extends PebbleDataReceiver
private HabitList filteredHabits; private HabitList filteredHabits;
private Preferences prefs;
public PebbleReceiver() public PebbleReceiver()
{ {
super(WATCHAPP_UUID); super(WATCHAPP_UUID);
@ -69,9 +73,14 @@ public class PebbleReceiver extends PebbleDataReceiver
HabitsApplication app = HabitsApplication app =
(HabitsApplication) context.getApplicationContext(); (HabitsApplication) context.getApplicationContext();
commandRunner = app.getComponent().getCommandRunner(); AppComponent component = app.getComponent();
taskRunner = app.getComponent().getTaskRunner(); commandRunner = component.getCommandRunner();
allHabits = app.getComponent().getHabitList(); taskRunner = component.getTaskRunner();
allHabits = component.getHabitList();
prefs = component.getPreferences();
if(prefs.isSyncFeatureEnabled())
context.startService(new Intent(context, SyncService.class));
HabitMatcher build = new HabitMatcherBuilder() HabitMatcher build = new HabitMatcherBuilder()
.setArchivedAllowed(false) .setArchivedAllowed(false)

@ -24,6 +24,8 @@ import android.util.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.intents.*; import org.isoron.uhabits.intents.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.sync.*;
import dagger.*; import dagger.*;
@ -59,6 +61,10 @@ public class WidgetReceiver extends BroadcastReceiver
IntentParser parser = app.getComponent().getIntentParser(); IntentParser parser = app.getComponent().getIntentParser();
WidgetController controller = component.getWidgetController(); WidgetController controller = component.getWidgetController();
Preferences prefs = app.getComponent().getPreferences();
if(prefs.isSyncFeatureEnabled())
context.startService(new Intent(context, SyncService.class));
try try
{ {

@ -26,17 +26,13 @@ import android.util.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.utils.*;
import org.json.*; import org.json.*;
import java.io.*;
import java.net.*; import java.net.*;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.*;
import java.util.*; import java.util.*;
import javax.inject.*; import javax.inject.*;
import javax.net.ssl.*;
import io.socket.client.*; import io.socket.client.*;
import io.socket.client.Socket; import io.socket.client.Socket;
@ -58,8 +54,10 @@ public class SyncManager implements CommandRunner.Listener
public static final String EVENT_POST_EVENT = "postEvent"; public static final String EVENT_POST_EVENT = "postEvent";
@NonNull
private String clientId; private String clientId;
@NonNull
private String groupKey; private String groupKey;
@NonNull @NonNull
@ -69,16 +67,17 @@ public class SyncManager implements CommandRunner.Listener
private LinkedList<Event> pendingConfirmation; private LinkedList<Event> pendingConfirmation;
@NonNull @NonNull
private List<Event> pendingEmit; private LinkedList<Event> pendingEmit;
private boolean readyToEmit = false; private boolean readyToEmit = false;
private Context context; @NonNull
private final Preferences prefs; private final Preferences prefs;
@NonNull
private CommandRunner commandRunner; private CommandRunner commandRunner;
@NonNull
private CommandParser commandParser; private CommandParser commandParser;
@Inject @Inject
@ -87,47 +86,19 @@ public class SyncManager implements CommandRunner.Listener
@NonNull CommandRunner commandRunner, @NonNull CommandRunner commandRunner,
@NonNull CommandParser commandParser) @NonNull CommandParser commandParser)
{ {
this.context = context;
this.prefs = prefs; this.prefs = prefs;
this.commandRunner = commandRunner; this.commandRunner = commandRunner;
this.commandParser = commandParser; this.commandParser = commandParser;
pendingConfirmation = new LinkedList<>(); pendingConfirmation = new LinkedList<>();
pendingEmit = Event.getAll(); pendingEmit = new LinkedList<>(Event.getAll());
groupKey = prefs.getSyncKey(); groupKey = prefs.getSyncKey();
clientId = prefs.getSyncClientId(); clientId = prefs.getSyncClientId();
String serverURL = prefs.getSyncAddress(); String serverURL = prefs.getSyncAddress();
Log.d("SyncManager", clientId); Log.d("SyncManager", clientId);
connect(context, serverURL);
try
{
IO.setDefaultSSLContext(getCACertSSLContext());
socket = IO.socket(serverURL);
logSocketEvent(socket, EVENT_CONNECT, "Connected");
logSocketEvent(socket, EVENT_CONNECT_TIMEOUT, "Connect timeout");
logSocketEvent(socket, EVENT_CONNECTING, "Connecting...");
logSocketEvent(socket, EVENT_CONNECT_ERROR, "Connect error");
logSocketEvent(socket, EVENT_DISCONNECT, "Disconnected");
logSocketEvent(socket, EVENT_RECONNECT, "Reconnected");
logSocketEvent(socket, EVENT_RECONNECT_ATTEMPT, "Reconnecting...");
logSocketEvent(socket, EVENT_RECONNECT_ERROR, "Reconnect error");
logSocketEvent(socket, EVENT_RECONNECT_FAILED, "Reconnect failed");
logSocketEvent(socket, EVENT_DISCONNECT, "Disconnected");
logSocketEvent(socket, EVENT_PING, "Ping");
logSocketEvent(socket, EVENT_PONG, "Pong");
socket.on(EVENT_CONNECT, new OnConnectListener());
socket.on(EVENT_DISCONNECT, new OnDisconnectListener());
socket.on(EVENT_EXECUTE_EVENT, new OnExecuteCommandListener());
socket.on(EVENT_AUTH_OK, new OnAuthOKListener());
socket.on(EVENT_FETCH_OK, new OnFetchOKListener());
}
catch (URISyntaxException e)
{
throw new RuntimeException(e);
}
} }
@Override @Override
@ -162,47 +133,52 @@ public class SyncManager implements CommandRunner.Listener
socket.close(); socket.close();
} }
private void emitPending() private void connect(@AppContext @NonNull Context context, String serverURL)
{ {
try try
{ {
for (Event e : pendingEmit) IO.setDefaultSSLContext(SSLUtils.getCACertSSLContext(context));
{ socket = IO.socket(serverURL);
Log.i("SyncManager", "Emitting: " + e.message);
socket.emit(EVENT_POST_EVENT, new JSONObject(e.message));
pendingConfirmation.add(e);
}
pendingEmit.clear(); logSocketEvent(socket, EVENT_CONNECT, "Connected");
logSocketEvent(socket, EVENT_CONNECT_TIMEOUT, "Connect timeout");
logSocketEvent(socket, EVENT_CONNECTING, "Connecting...");
logSocketEvent(socket, EVENT_CONNECT_ERROR, "Connect error");
logSocketEvent(socket, EVENT_DISCONNECT, "Disconnected");
logSocketEvent(socket, EVENT_RECONNECT, "Reconnected");
logSocketEvent(socket, EVENT_RECONNECT_ATTEMPT, "Reconnecting...");
logSocketEvent(socket, EVENT_RECONNECT_ERROR, "Reconnect error");
logSocketEvent(socket, EVENT_RECONNECT_FAILED, "Reconnect failed");
logSocketEvent(socket, EVENT_DISCONNECT, "Disconnected");
logSocketEvent(socket, EVENT_PING, "Ping");
logSocketEvent(socket, EVENT_PONG, "Pong");
socket.on(EVENT_CONNECT, new OnConnectListener());
socket.on(EVENT_DISCONNECT, new OnDisconnectListener());
socket.on(EVENT_EXECUTE_EVENT, new OnExecuteCommandListener());
socket.on(EVENT_AUTH_OK, new OnAuthOKListener());
socket.on(EVENT_FETCH_OK, new OnFetchOKListener());
} }
catch (JSONException e) catch (URISyntaxException e)
{ {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
private SSLContext getCACertSSLContext() private void emitPending()
{ {
try try
{ {
CertificateFactory cf = CertificateFactory.getInstance("X.509"); for (Event e : pendingEmit)
InputStream caInput = context.getAssets().open("cacert.pem"); {
Certificate ca = cf.generateCertificate(caInput); Log.i("SyncManager", "Emitting: " + e.message);
socket.emit(EVENT_POST_EVENT, new JSONObject(e.message));
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); pendingConfirmation.add(e);
ks.load(null, null); }
ks.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
return ctx; pendingEmit.clear();
} }
catch (Exception e) catch (JSONException e)
{ {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -283,6 +259,8 @@ public class SyncManager implements CommandRunner.Listener
public void call(Object... args) public void call(Object... args)
{ {
readyToEmit = false; readyToEmit = false;
for(Event e : pendingConfirmation) pendingEmit.add(e);
pendingConfirmation.clear();
} }
} }

@ -0,0 +1,81 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker 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 should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.sync;
import android.app.*;
import android.content.*;
import android.os.*;
import android.support.v7.app.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.preferences.*;
public class SyncService extends Service implements Preferences.Listener
{
private SyncManager syncManager;
private Preferences prefs;
public SyncService()
{
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
Intent notificationIntent = new Intent(this, SyncService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Loop Habit Tracker")
.setContentText("Sync service running")
.setSmallIcon(R.drawable.ic_notification)
.setPriority(NotificationCompat.PRIORITY_MIN)
.setContentIntent(pendingIntent)
.build();
startForeground(99999, notification);
HabitsApplication app = (HabitsApplication) getApplicationContext();
syncManager = app.getComponent().getSyncManager();
syncManager.startListening();
prefs = app.getComponent().getPreferences();
prefs.addListener(this);
}
@Override
public void onSyncFeatureChanged()
{
if(!prefs.isSyncFeatureEnabled()) stopSelf();
}
@Override
public void onDestroy()
{
syncManager.stopListening();
}
}

@ -0,0 +1,61 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker 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 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker 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 should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.utils;
import android.content.*;
import android.support.annotation.*;
import java.io.*;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.*;
import javax.net.ssl.*;
public abstract class SSLUtils
{
public static SSLContext getCACertSSLContext(@NonNull Context context)
{
try
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getAssets().open("cacert.pem");
Certificate ca = cf.generateCertificate(caInput);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
return ctx;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
Loading…
Cancel
Save