Skip to content

Commit

Permalink
#259 Implemented "Sync over WiFi only"
Browse files Browse the repository at this point in the history
  • Loading branch information
yvolk committed May 17, 2016
1 parent 795cd18 commit 90ab243
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 93 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2016 yvolk (Yuri Volkov), http://yurivolkov.com
*
* 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 org.andstatus.app.context;

import android.test.InstrumentationTestCase;

import org.andstatus.app.service.ConnectionRequired;
import org.andstatus.app.service.ConnectionState;

/**
* @author yvolk@yurivolkov.com
*/
public class ConnectionStateTest extends InstrumentationTestCase {

@Override
protected void setUp() throws Exception {
super.setUp();
TestSuite.initialize(this);
}

public void testIsConnectionStateOkFor() {
TestSuite.getMyContextForTest().setConnectionState(ConnectionState.OFFLINE);
assertEquals(ConnectionState.OFFLINE, MyContextHolder.get().getConnectionState());

assertTrueFor(ConnectionRequired.OFFLINE);
assertTrueFor(ConnectionRequired.ANY);
assertFalseFor(ConnectionRequired.SYNC);
assertFalseFor(ConnectionRequired.DOWNLOAD_ATTACHMENT);

TestSuite.getMyContextForTest().setConnectionState(ConnectionState.ONLINE);
assertEquals(ConnectionState.ONLINE, MyContextHolder.get().getConnectionState());

assertFalseFor(ConnectionRequired.OFFLINE);
assertTrueFor(ConnectionRequired.ANY);

MyPreferences.setDownloadAttachmentsOverWiFiOnly(false);
MyPreferences.setIsSyncOverWiFiOnly(true);
assertFalseFor(ConnectionRequired.SYNC);
assertFalseFor(ConnectionRequired.DOWNLOAD_ATTACHMENT);
MyPreferences.setIsSyncOverWiFiOnly(false);
assertTrueFor(ConnectionRequired.SYNC);
assertTrueFor(ConnectionRequired.DOWNLOAD_ATTACHMENT);
MyPreferences.setDownloadAttachmentsOverWiFiOnly(true);
assertTrueFor(ConnectionRequired.SYNC);
assertFalseFor(ConnectionRequired.DOWNLOAD_ATTACHMENT);

TestSuite.getMyContextForTest().setConnectionState(ConnectionState.WIFI);
assertFalseFor(ConnectionRequired.OFFLINE);
assertTrueFor(ConnectionRequired.ANY);
assertTrueFor(ConnectionRequired.SYNC);
assertTrueFor(ConnectionRequired.DOWNLOAD_ATTACHMENT);
}

private void assertTrueFor(ConnectionRequired connectionRequired) {
assertTrue(isConnectionStateOkFor(connectionRequired));
}

private void assertFalseFor(ConnectionRequired connectionRequired) {
assertFalse(isConnectionStateOkFor(connectionRequired));
}

private boolean isConnectionStateOkFor(ConnectionRequired connectionRequired) {
return connectionRequired.isConnectionStateOk(MyContextHolder.get().getConnectionState());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.andstatus.app.data.TimelineType;
import org.andstatus.app.net.http.HttpConnection;
import org.andstatus.app.origin.PersistentOrigins;
import org.andstatus.app.service.ConnectionRequired;
import org.andstatus.app.service.ConnectionState;
import org.andstatus.app.util.MyLog;

import java.util.Locale;
Expand All @@ -44,7 +44,7 @@ public class MyContextForTest implements MyContext {
private final Set<AssertionData> dataSet = new CopyOnWriteArraySet<>();
private volatile Class<? extends HttpConnection> httpConnectionMockClass = null;
private volatile HttpConnection httpConnectionMockInstance = null;
private volatile ConnectionRequired mOnline = ConnectionRequired.ANY;
private volatile ConnectionState mockedConnectionState = ConnectionState.UNKNOWN;
private final Map<TimelineType, Notification> notifications = new ConcurrentHashMap<>();

public MyContextForTest setContext(MyContext myContextIn) {
Expand Down Expand Up @@ -193,26 +193,17 @@ public HttpConnection getHttpConnectionMock() {
}

@Override
public boolean isOnline(ConnectionRequired connectionRequired) {
switch (mOnline) {
case ANY:
return myContext.isOnline(connectionRequired);
public ConnectionState getConnectionState() {
switch (mockedConnectionState) {
case UNKNOWN:
return myContext.getConnectionState();
default:
switch (connectionRequired) {
case ONLINE:
return (mOnline == ConnectionRequired.ONLINE || mOnline == ConnectionRequired.WIFI);
case WIFI:
return (mOnline == ConnectionRequired.WIFI);
case OFFLINE:
return (mOnline == ConnectionRequired.OFFLINE);
default:
return true;
}
return mockedConnectionState;
}
}

public void setOnline(ConnectionRequired connectionState) {
this.mOnline = connectionState;
public void setConnectionState(ConnectionState connectionState) {
this.mockedConnectionState = connectionState;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void setUp(String accountName) {
} else {
TestSuite.setHttpConnectionMockClass(HttpConnectionMock.class);
}
TestSuite.getMyContextForTest().setOnline(ConnectionRequired.WIFI);
TestSuite.getMyContextForTest().setConnectionState(ConnectionState.WIFI);
MyAccountTest.fixPersistentAccounts();
// In order for the mocked connection to have effect:
MyContextHolder.get().persistentAccounts().initialize();
Expand Down Expand Up @@ -165,7 +165,7 @@ public void tearDown() {
serviceConnector.unregisterReceiver(MyContextHolder.get().context());
TestSuite.setHttpConnectionMockClass(null);
TestSuite.setHttpConnectionMockInstance(null);
TestSuite.getMyContextForTest().setOnline(ConnectionRequired.ANY);
TestSuite.getMyContextForTest().setConnectionState(ConnectionState.UNKNOWN);
MyContextHolder.get().persistentAccounts().initialize();
MyLog.v(this, "tearDown ended");
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/org/andstatus/app/context/MyContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.andstatus.app.data.TimelineType;
import org.andstatus.app.net.http.HttpConnection;
import org.andstatus.app.origin.PersistentOrigins;
import org.andstatus.app.service.ConnectionRequired;
import org.andstatus.app.service.ConnectionState;

import java.util.Locale;

Expand All @@ -50,7 +50,7 @@ public interface MyContext {
void release();
boolean isExpired();
void setExpired();
boolean isOnline(ConnectionRequired connectionRequired);
ConnectionState getConnectionState();
/** Is our application in Foreground now? **/
boolean isInForeground();
void setInForeground(boolean inForeground);
Expand Down
68 changes: 24 additions & 44 deletions app/src/main/java/org/andstatus/app/context/MyContextImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import org.andstatus.app.net.http.TlsSniSocketFactory;
import org.andstatus.app.origin.PersistentOrigins;
import org.andstatus.app.os.AsyncTaskLauncher;
import org.andstatus.app.service.ConnectionRequired;
import org.andstatus.app.service.ConnectionState;
import org.andstatus.app.util.MyLog;
import org.andstatus.app.util.RelativeTime;
import org.andstatus.app.util.SharedPreferencesUtil;
Expand Down Expand Up @@ -270,56 +270,36 @@ public HttpConnection getHttpConnectionMock() {
return null;
}

@Override
public boolean isOnline(ConnectionRequired connectionRequired) {
final String method = "isOnline";
switch (connectionRequired) {
case ONLINE:
if (isOnlineNotLogged(false)) {
return true;
}
MyLog.v(this, method + "; No Internet Connection");
return false;
case WIFI:
boolean prefWiFiOnly = SharedPreferencesUtil.getBoolean(
MyPreferences.KEY_DOWNLOAD_ATTACHMENTS_OVER_WIFI_ONLY, true);
if (isOnlineNotLogged(prefWiFiOnly)) {
return true;
}
MyLog.v(this, method + "; "
+ (prefWiFiOnly ? "WiFi is not connected"
: "No Internet Connection (WiFi not required)"));
return false;
case OFFLINE:
if (!isOnlineNotLogged(false)) {
return true;
}
MyLog.v(this, method + "; Not offline");
return false;
default:
return true;
}
}

/**
* Based on http://stackoverflow.com/questions/1560788/how-to-check-internet-access-on-android-inetaddress-never-timeouts
*/
private boolean isOnlineNotLogged(boolean wiFiOnly) {
boolean is = false;
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@Override
public ConnectionState getConnectionState() {
ConnectivityManager connectivityManager =
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
return false;
return ConnectionState.UNKNOWN;
}
ConnectionState state = ConnectionState.OFFLINE;
NetworkInfo networkInfoOnline = connectivityManager.getActiveNetworkInfo();
if (networkInfoOnline == null) {
return state;
}
if (networkInfoOnline.isAvailable() && networkInfoOnline.isConnected()) {
state = ConnectionState.ONLINE;
} else {
return state;
}
NetworkInfo networkInfo = wiFiOnly ? connectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI) : connectivityManager
.getActiveNetworkInfo();
if (networkInfo == null) {
return false;
NetworkInfo networkInfoWiFi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfoWiFi == null) {
return state;
}
is = networkInfo.isAvailable() && networkInfo.isConnected();
return is;
if (networkInfoWiFi.isAvailable() && networkInfoWiFi.isConnected()) {
state = ConnectionState.WIFI;
}
return state;
}

@Override
public boolean isInForeground() {
if (!mInForeground
Expand Down
18 changes: 17 additions & 1 deletion app/src/main/java/org/andstatus/app/context/MyPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class MyPreferences {
// Syncing
public static final String KEY_SYNC_FREQUENCY_SECONDS = "fetch_frequency";
private static final long SYNC_FREQUENCY_DEFAULT_SECONDS = 180;
public static final String KEY_SYNC_OVER_WIFI_ONLY = "sync_over_wifi_only";
public static final String KEY_SYNC_WHILE_USING_APPLICATION = "sync_while_using_application";
public static final String KEY_SYNC_INDICATOR_ON_TIMELINE = "sync_indicator_on_timeline";
public static final String KEY_SYNC_AFTER_MESSAGE_WAS_SENT = "sync_after_message_was_sent";
Expand Down Expand Up @@ -158,10 +159,26 @@ public static long getSyncFrequencySeconds() {
SYNC_FREQUENCY_DEFAULT_SECONDS);
}

public static boolean isSyncOverWiFiOnly() {
return SharedPreferencesUtil.getBoolean(KEY_SYNC_OVER_WIFI_ONLY, false);
}

public static void setIsSyncOverWiFiOnly(boolean overWiFi) {
SharedPreferencesUtil.putBoolean(KEY_SYNC_OVER_WIFI_ONLY, overWiFi);
}

public static boolean isSyncWhileUsingApplicationEnabled() {
return SharedPreferencesUtil.getBoolean(KEY_SYNC_WHILE_USING_APPLICATION, true);
}

public static boolean isDownloadAttachmentsOverWiFiOnly() {
return SharedPreferencesUtil.getBoolean(KEY_DOWNLOAD_ATTACHMENTS_OVER_WIFI_ONLY, true);
}

public static void setDownloadAttachmentsOverWiFiOnly(boolean overWiFi) {
SharedPreferencesUtil.putBoolean(KEY_DOWNLOAD_ATTACHMENTS_OVER_WIFI_ONLY, overWiFi);
}

public static boolean isLongPressToOpenContextMenu() {
return SharedPreferencesUtil.getBoolean(KEY_LONG_PRESS_TO_OPEN_CONTEXT_MENU, false);
}
Expand Down Expand Up @@ -225,5 +242,4 @@ public static void onPreferencesChanged() {
new BackupManager(context).dataChanged();
}
}

}
40 changes: 20 additions & 20 deletions app/src/main/java/org/andstatus/app/service/CommandEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,42 +44,42 @@ public enum CommandEnum {
/**
* The action to fetch all usual timelines in the background.
*/
AUTOMATIC_UPDATE("automatic-update", 0, 12, ConnectionRequired.ONLINE),
AUTOMATIC_UPDATE("automatic-update", 0, 12, ConnectionRequired.SYNC),
/**
* Fetch timeline(s) of the specified type for the specified MyAccount.
*/
FETCH_TIMELINE("fetch-timeline", 0, 4, ConnectionRequired.ONLINE),
FETCH_TIMELINE("fetch-timeline", 0, 4, ConnectionRequired.SYNC),

/**
* Fetch avatar for the specified user
*/
FETCH_AVATAR("fetch-avatar", R.string.title_command_fetch_avatar, 9, ConnectionRequired.ONLINE),
FETCH_ATTACHMENT("fetch-attachment", R.string.title_command_fetch_attachment, 11, ConnectionRequired.WIFI),
FETCH_AVATAR("fetch-avatar", R.string.title_command_fetch_avatar, 9, ConnectionRequired.SYNC),
FETCH_ATTACHMENT("fetch-attachment", R.string.title_command_fetch_attachment, 11, ConnectionRequired.DOWNLOAD_ATTACHMENT),

CREATE_FAVORITE("create-favorite", R.string.menu_item_favorite, 0, ConnectionRequired.ONLINE),
DESTROY_FAVORITE("destroy-favorite", R.string.menu_item_destroy_favorite, 0, ConnectionRequired.ONLINE),
CREATE_FAVORITE("create-favorite", R.string.menu_item_favorite, 0, ConnectionRequired.SYNC),
DESTROY_FAVORITE("destroy-favorite", R.string.menu_item_destroy_favorite, 0, ConnectionRequired.SYNC),

GET_USER("get-user", R.string.get_user, -5, ConnectionRequired.ONLINE),
FOLLOW_USER("follow-user", R.string.command_follow_user, 0, ConnectionRequired.ONLINE),
STOP_FOLLOWING_USER("stop-following-user", R.string.command_stop_following_user, 0, ConnectionRequired.ONLINE),
GET_FOLLOWERS("get-followers", R.string.get_followers, -5, ConnectionRequired.ONLINE),
GET_FRIENDS("get-friends", R.string.get_friends, -5, ConnectionRequired.ONLINE),
GET_USER("get-user", R.string.get_user, -5, ConnectionRequired.SYNC),
FOLLOW_USER("follow-user", R.string.command_follow_user, 0, ConnectionRequired.SYNC),
STOP_FOLLOWING_USER("stop-following-user", R.string.command_stop_following_user, 0, ConnectionRequired.SYNC),
GET_FOLLOWERS("get-followers", R.string.get_followers, -5, ConnectionRequired.SYNC),
GET_FRIENDS("get-friends", R.string.get_friends, -5, ConnectionRequired.SYNC),

/**
* This command is for sending both public and direct messages
*/
UPDATE_STATUS("update-status", R.string.button_create_message, -10, ConnectionRequired.ONLINE),
DESTROY_STATUS("destroy-status", R.string.menu_item_destroy_status, -3, ConnectionRequired.ONLINE),
GET_STATUS("get-status", R.string.title_command_get_status, -5, ConnectionRequired.ONLINE),
UPDATE_STATUS("update-status", R.string.button_create_message, -10, ConnectionRequired.SYNC),
DESTROY_STATUS("destroy-status", R.string.menu_item_destroy_status, -3, ConnectionRequired.SYNC),
GET_STATUS("get-status", R.string.title_command_get_status, -5, ConnectionRequired.SYNC),
/** see http://gstools.org/api/doc/ */
GET_OPEN_INSTANCES("get_open_instances", R.string.get_open_instances_title, -1, ConnectionRequired.ONLINE),
GET_OPEN_INSTANCES("get_open_instances", R.string.get_open_instances_title, -1, ConnectionRequired.SYNC),

SEARCH_MESSAGE("search-message", R.string.options_menu_search, 4, ConnectionRequired.ONLINE),
SEARCH_MESSAGE("search-message", R.string.options_menu_search, 4, ConnectionRequired.SYNC),

REBLOG("reblog", R.string.menu_item_reblog, -9, ConnectionRequired.ONLINE),
DESTROY_REBLOG("destroy-reblog", R.string.menu_item_destroy_reblog, -3, ConnectionRequired.ONLINE),
REBLOG("reblog", R.string.menu_item_reblog, -9, ConnectionRequired.SYNC),
DESTROY_REBLOG("destroy-reblog", R.string.menu_item_destroy_reblog, -3, ConnectionRequired.SYNC),

RATE_LIMIT_STATUS("rate-limit-status", 0, 0, ConnectionRequired.ONLINE),
RATE_LIMIT_STATUS("rate-limit-status", 0, 0, ConnectionRequired.SYNC),

/**
* Notify User about commands in the Queue
Expand Down Expand Up @@ -186,7 +186,7 @@ public int getPriority() {
return priority;
}

public ConnectionRequired getConnetionRequired() {
public ConnectionRequired getConnectionRequired() {
return connectionRequired;
}
}

0 comments on commit 90ab243

Please sign in to comment.