android: quick settings tile states and widget sizes as in the Final 2026 mockup
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
53623ebb4a
commit
f193661e68
5 files changed
+58
-19
No files matched your search
@@ -23,6 +23,7 @@ import org.strongswan.android.logic.updates.UpdateManager;
|
|||||||
import org.strongswan.android.ui.compose.ShxAppKt;
|
import org.strongswan.android.ui.compose.ShxAppKt;
|
||||||
import org.strongswan.android.ui.compose.ShxNavigation;
|
import org.strongswan.android.ui.compose.ShxNavigation;
|
||||||
import org.strongswan.android.ui.compose.ShxTab;
|
import org.strongswan.android.ui.compose.ShxTab;
|
||||||
|
import android.service.quicksettings.TileService;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.splashscreen.SplashScreen;
|
import androidx.core.splashscreen.SplashScreen;
|
||||||
@@ -121,6 +122,11 @@ public class MainActivity extends AppCompatActivity
|
|||||||
intent.removeExtra(EXTRA_ADD_SERVER);
|
intent.removeExtra(EXTRA_ADD_SERVER);
|
||||||
ShxNavigation.INSTANCE.requestAddServer();
|
ShxNavigation.INSTANCE.requestAddServer();
|
||||||
}
|
}
|
||||||
|
if (intent != null && TileService.ACTION_QS_TILE_PREFERENCES.equals(intent.getAction()))
|
||||||
|
{
|
||||||
|
intent.setAction(null);
|
||||||
|
ShxNavigation.INSTANCE.request(ShxTab.PROFILES);
|
||||||
|
}
|
||||||
if (intent != null && intent.getBooleanExtra(EXTRA_OPEN_SERVERS, false))
|
if (intent != null && intent.getBooleanExtra(EXTRA_OPEN_SERVERS, false))
|
||||||
{
|
{
|
||||||
intent.removeExtra(EXTRA_OPEN_SERVERS);
|
intent.removeExtra(EXTRA_OPEN_SERVERS);
|
||||||
|
|||||||
+39
-17
@@ -152,7 +152,12 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
|||||||
{ /* always get the plain profile without cached password */
|
{ /* always get the plain profile without cached password */
|
||||||
profile = mDataSource.getVpnProfile(profile.getUUID());
|
profile = mDataSource.getVpnProfile(profile.getUUID());
|
||||||
}
|
}
|
||||||
/* reconnect the profile in case of an error */
|
/* a problem: the tap opens the app, which explains it (F_QsTile) */
|
||||||
|
if (mService.getErrorState() != VpnStateService.ErrorState.NO_ERROR)
|
||||||
|
{
|
||||||
|
openApp(new Intent(this, MainActivity.class));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mService.getErrorState() == VpnStateService.ErrorState.NO_ERROR)
|
if (mService.getErrorState() == VpnStateService.ErrorState.NO_ERROR)
|
||||||
{
|
{
|
||||||
switch (mService.getState())
|
switch (mService.getState())
|
||||||
@@ -212,11 +217,16 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
/* no servers yet: straight to «Add server» */
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
openApp(new Intent(this, MainActivity.class).putExtra(MainActivity.EXTRA_ADD_SERVER, getProfile() == null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openApp(Intent intent)
|
||||||
|
{
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
{
|
{
|
||||||
startActivityAndCollapse(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE));
|
startActivityAndCollapse(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -255,11 +265,28 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* F_QsTile: always «SHX VPN», the state in the subtitle */
|
||||||
|
tile.setLabel(getString(R.string.tile_label));
|
||||||
|
String subtitle;
|
||||||
if (error != VpnStateService.ErrorState.NO_ERROR)
|
if (error != VpnStateService.ErrorState.NO_ERROR)
|
||||||
{
|
{
|
||||||
tile.setState(Tile.STATE_INACTIVE);
|
tile.setState(Tile.STATE_INACTIVE);
|
||||||
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification_warning));
|
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification_warning));
|
||||||
tile.setLabel(getString(R.string.tile_connect));
|
switch (error)
|
||||||
|
{
|
||||||
|
case UNREACHABLE:
|
||||||
|
case LOOKUP_FAILED:
|
||||||
|
subtitle = getString(R.string.tile_no_answer);
|
||||||
|
break;
|
||||||
|
case AUTH_FAILED:
|
||||||
|
case PEER_AUTH_FAILED:
|
||||||
|
case PASSWORD_MISSING:
|
||||||
|
subtitle = getString(R.string.tile_auth_error);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
subtitle = getString(R.string.tile_problem);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -269,30 +296,25 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
|||||||
case DISABLED:
|
case DISABLED:
|
||||||
tile.setState(Tile.STATE_INACTIVE);
|
tile.setState(Tile.STATE_INACTIVE);
|
||||||
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification_disconnected));
|
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification_disconnected));
|
||||||
tile.setLabel(getString(R.string.tile_connect));
|
subtitle = getString(R.string.tile_off);
|
||||||
break;
|
break;
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
tile.setState(Tile.STATE_ACTIVE);
|
tile.setState(Tile.STATE_ACTIVE);
|
||||||
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification_connecting));
|
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification_connecting));
|
||||||
tile.setLabel(getString(R.string.tile_disconnect));
|
subtitle = getString(R.string.tile_connecting);
|
||||||
break;
|
break;
|
||||||
case CONNECTED:
|
case CONNECTED:
|
||||||
|
default:
|
||||||
tile.setState(Tile.STATE_ACTIVE);
|
tile.setState(Tile.STATE_ACTIVE);
|
||||||
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification));
|
tile.setIcon(Icon.createWithResource(this, R.drawable.ic_notification));
|
||||||
tile.setLabel(getString(R.string.tile_disconnect));
|
/* the server name, unless the screen is locked */
|
||||||
|
subtitle = profile != null && !isSecure() ? profile.getName() : getString(R.string.status_protected);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (profile != null && !isSecure())
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
tile.setSubtitle(subtitle);
|
||||||
{ /* keep the action label, show the profile as the tile subtitle */
|
|
||||||
tile.setSubtitle(profile.getName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tile.setLabel(profile.getName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tile.updateTile();
|
tile.updateTile();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -160,8 +160,8 @@ object ShxWidgetState
|
|||||||
|
|
||||||
/* the sizes of F_Widgets: 1×1 status icon, 2×1 status and button, 4×2 detailed */
|
/* the sizes of F_Widgets: 1×1 status icon, 2×1 status and button, 4×2 detailed */
|
||||||
private val ICON = DpSize(56.dp, 56.dp)
|
private val ICON = DpSize(56.dp, 56.dp)
|
||||||
private val SMALL = DpSize(150.dp, 64.dp)
|
private val SMALL = DpSize(110.dp, 48.dp)
|
||||||
private val LARGE = DpSize(250.dp, 150.dp)
|
private val LARGE = DpSize(220.dp, 110.dp)
|
||||||
|
|
||||||
/** Home screen widget as on F_Widgets, in three sizes. */
|
/** Home screen widget as on F_Widgets, in three sizes. */
|
||||||
class ShxWidget : GlanceAppWidget()
|
class ShxWidget : GlanceAppWidget()
|
||||||
|
|||||||
@@ -1021,4 +1021,9 @@
|
|||||||
<string name="widget_problem">Проблема</string>
|
<string name="widget_problem">Проблема</string>
|
||||||
<string name="widget_tap_to">тап — %1$s</string>
|
<string name="widget_tap_to">тап — %1$s</string>
|
||||||
<string name="widget_pause">Пауза</string>
|
<string name="widget_pause">Пауза</string>
|
||||||
|
<string name="tile_off">Выключен</string>
|
||||||
|
<string name="tile_connecting">Подключаемся…</string>
|
||||||
|
<string name="tile_no_answer">Сервер не отвечает</string>
|
||||||
|
<string name="tile_auth_error">Ошибка входа</string>
|
||||||
|
<string name="tile_problem">Проблема с подключением</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1006,4 +1006,10 @@
|
|||||||
<string name="widget_problem">Problem</string>
|
<string name="widget_problem">Problem</string>
|
||||||
<string name="widget_tap_to">tap — %1$s</string>
|
<string name="widget_tap_to">tap — %1$s</string>
|
||||||
<string name="widget_pause">Pause</string>
|
<string name="widget_pause">Pause</string>
|
||||||
|
<string name="tile_off">Off</string>
|
||||||
|
<string name="tile_connecting">Connecting…</string>
|
||||||
|
<string name="tile_no_answer">Server not responding</string>
|
||||||
|
<string name="tile_auth_error">Sign-in failed</string>
|
||||||
|
<string name="tile_problem">Connection problem</string>
|
||||||
|
<string name="tile_label" translatable="false">SHX VPN</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in new issue
Block a user