replace symlink silliness ant required with gradle commands to sign
debug builds with the checked-in (local file) debug keystore. Make
it possible for an environment variable to override in case somebody
wants to use his own.
Looks like there are battery drainage issues with the current half-done
implementation, so add option to turn it off. Only takes effect on
restart, and only matters on dbg variant now since it's compile-time
disabled on the main variant.
Also add discovery machine state to ConnState printout, stop running the
machine over and over (likely the battery problem), but add ability to
restart it triggered by the ConnState's "reconnect" button.
Also start persisting the most recently seen set of peers. If service
discovery and not connecting is the problem having these available to
try to connect to on startup might help.
Build different jni code (into different obj and libs directories) for
the different release/debug and xw4/xw4dbg combinations. This works when
only one build is done, but when doing two some later task tries to put
both multiple same-named libraries into the .apk and so fails. I still
think it's worth adding this to keep from using the wrong binary, but
that needs to be fixed.
cleanNDK just nukes all the directories. Easier than invoking build-ndk
clean...
Merging of AndroidManifest.xml files meant the dbg flavor was getting
its C2D_MESSAGE permission and the main flavor's, which on recent OS
versions meant it couldn't be installed. Use substitution from gradle to
fix.
GamesList menu was in a bad state after a game closed because hadn't
been rebuilt. It's simplest to invalidate it surgically, when the
BoardDelegate notifies that the board's closed, though doing in in
onWindowFocusChanged() might catch more edge cases. We'll see. I want a
low-risk impact right now.
but not on emulator running same OS version (or close). And in spite of
an exception being thrown the work being done, hiding a preference,
still succeeds. Whatever.
Fixes case where user has received invitations but not allowed SMS then
decides to do so. It's a hack giving Perms23 class knowledge of how to
send moves etc. Instead I should be letting interested parties register
for perms-granted events, but that can happen later, and is less
valueable while SMS is the only "dangerous" permission and the only one
that blocks message sends.
JSONObject(<string>, null) clears out any existing entry but doesn't add
a new one. So store missing names as "" instead. Not sure how this
worked when I first tested it....
My old asking for permission to turn on/off SMS is confusing and adds no
value when the OS separates out permissions and is confusing. So get rid
of it on Marshmallow and later, always returning true from the old API
and hiding the preference in that case.
The write-red-on-it thing doesn't work for the notify.png file used in
notifications (I think because I can't find a color Android doesn't
strip out.) So use a rotation transform instead. Users will never see
this anyway.
Move connection options READ_PHONE_STATE check from ConnViaViewLayout to
GameConfigDelegate and give it a rationale. Preferences stuff can't do
permissions because it can't override onRequestPermissionsResult (base
activity is of wrong class). Should fix that at some point, either by
moving to preference fragments or with a dummy activity to go over the
top.
Explicit "ask again" and "skip" buttons in alert showing rationale;
check/ask for permission before sending invitation via SMS; warn each
time SMS-enabled game is opened without permission but allow it to stay
open and if necessary send an invitation.
add "close game" button to warning about lack of comms, and do that on
dismiss too. Nothing good can come from having the thing stay open.
Eventually the "close" should turn into "edit" and launch GameConfig on
the game with the comms selector up, but that's hard, as currently the
launch only happens from GamesList and is via
startActivityForResult. Might be easiest to close and send an intent to
GamesList to cause it to launch GameConfig that way. Not for this release.
An edge case, but: doing "new from" on a game without any connection
types crashed because of an assertion in comms that assumed
addr_setType() was being called on zero-initialized flags, which
shouldn't have been a requirement. Pulled that as well as java code that
added RELAY-type connectivity to any game that had none. If a game has
none, leave it that way.
replace dlgButtonClicked() with separate methods for positive and
negative buttons and alert dismissal. I was making too many mistakes
because the old method was getting called twice (e.g. for negative and
then dismissal) and I hadn't needed to differentiate until adding that
new Action. There should be no behavior change with this, but it's
pervasive and replaces some spaghetti.
Let OS ask for STORAGE when user chooses Downloads dict storage option,
but do nothing if it's not granted. Existing code asks again when the
actual move is to done.
If an game's open that uses a wordlist kept in Downloads and permission
is revoked, close cleanly. On re-opening the user will be prompted by
existing code to download again. (Note: not prompted to turn STORAGE
permission back on. It would't be easy to detect that case, and I'm not
spending time helping people who are perverse.)
Add new static method that takes a request, rationale and Action, offers
the rationale if required and then, if user hasn't cancelled, asks for
permission. Eventually the Action is issued with either POSITIVE or
NEGATIVE. Use this to ask for STORAGE when downloading upgrades and
moving wordlists to the downloads area.
You need PHONE permission to start and play an SMS game but not to have
started it in response to an invitation. But to rematch you need it. So
ask, including offering a rationale that differs depending on whether
there's a way for the game to communicate once SMS is removed.
They were hacks for debugging SMS early on, probably infrequently
seen. Instead post messages. BUT: they aren't being received because of
how listeners get cleared in onPause(). Needs to be fixed, but there's
no harm in having them dangle for now.
Sometimes when a new game is created the board winds up with the toolbar
drawn over the tray. That's because when it was laid out the game wasn't
running yet and so none of the toolbar buttons was enabled, giving the
toolbar a height of 0. So now the first time the updated toolbar reports
that at least one button is enabled we force the board to lay itself out
again.
Little hack to dismiss a game when the invitations dialog was cancelled
broke invitations altogether. Revert that change, and simply check on
getting focus whether all players are present; if they're not, put up
the "invite or wait" dialog. This is a big change, but in 10 minutes of
testing I can't get the wrong thing to happen.
Remove strings that no longer exist in English, add missing "other"
quantities in Japanese (taking a guess from context that it's ok to use
generic counters), and in a couple of languages fix typos in format
specifiers that would have caused crashes.
It wasn't even checking all languages. Now it does, lets you specify
which ones if a subset's desired, and differentiates between sets of
format specifiers mismatching in a way that'll cause a
crash (e.g. expecting int in one and string in another) and just having
some missing.
Let's make it easier to add to the set of available BT devices from the
place where the user sees the need. TODO: update the descriptive text,
but not this release since it'll break existing localizations.
Channel wasn't a thing back then. Catch the ClassNotFound exception and
set the same boolean as when permissions aren't available (in manifest),
which means nothing else tries to run.
Add cancelled notification to invite choices dialog. Look for that in
board delegate and close the game. Makes the inviting experience more
consistent, the goal being that you never look at a game that's missing
players without some intervening dialog preventing you from trying to
play.
Use an array of actual objects rather than indices, and add an equals()
method, so checkbox status can survive changes in the set of available
items and even be reproduced when the objects backing them change (as
happens after a new BT scan finishes.)
Control whether wifi direct is enabled from build.xml, a file that's
already different for the two variants. The point here is to do a
release with permissions changes but without having to fix everything
wrong with wifi direct.
If user hasn't granted READ_CONTACTS permission, use the pairing of
numbers/names that's come from Contacts via the SMS invitation dialog.
Sometimes it'll have names for numbers that arrived via invitations. Do
some cleanup while at it to prevent stored BT mac addresses from being
looked up as phone numbers.
On launching SMS invite dialog, ask for READ_CONTACTS permission. Where
it's needed, though, is for the user-invisible process of translating
phone numbers to names (not launching the Contacts app via an
Intent). This just seems like the best place to ask since the user's
thinking about contacts and phone numbers.
InviteDelegate superclass now tracks whether something is checked,
though it's not doing as well as subclasses did before, e.g. when SMS
would uncheck everything but a newly added contact.
Add post-open test for SMS and then ask for SMS permission, giving
rationale if the OS says I should. Meant adding a new interface for
rationales and wiring that in. It's a bit spaghetti and I may think of a
cleaner way later.
When opening a game that sends via SMS, check if it has permission and
offer to remove the config if it doesn't, removing a similar check from
pre-opening code. (Here it'll catch e.g. games opened from the
GameConfig process.) Sends/receives without SMS permission are already
caught by existing catch{} blocks, so there's no crash.
Moving stuff into superclass and trying in general to simplify
things. BT and SMS invitation work, but the option to have more than one
player per device isn't available. RelayID invitation is a mess, but was
before I think. WiDir invitation crashes in assert because I can't
debug it on this branch. Lots of work and cleanup still required.
rewrite perms23 class to use Builder pattern, making it easier to pass
more than one required permission. Use that (with hard-coded set for
now) to check and ask for permissions a game needs to communicate. Offer
to remove the comms methods the user doesn't want to permit (but that's
not implemented yet.)
First, needed to remove some state caching since though a non-SMS
phone will never become one my ability to ask changes over time. Then
changed population of communication options to first ask for the
permission needed in order to find out what's supported, then to find
out what's supported via methods that will return false without
permission. Can't think of a better way right now....
Add a compile-time option to send commands in json as strings rather
than ordinals (ints) for easier reading of logs. And log/keep track of
when discovery's turned off or on in case it's useful for making all
this work.
In handling resend for a newly available transport, if the lock can't be
obtained see if that's because the game's currently open and if so post
to its thread.
Each time we get a socket to a peer, try sending all pending wifi direct
messages. It's a hack, but trying to send isn't that expensive and the
experience is much improved.
When contacting opponents, iterate over opponent addresses rather than
information cached in the summary. Start implementing for BT, but that
needs more work. Change enum names in WiDirService state machine. P2p
opponent notification untested because apparently an open hotspot, which
you can't prevent devices from connecting to, breaks P2P connectivity.
Rewrite to use new XWPacket class that wraps JSONObject but could later
support a binary format, and reply with new message when packet arrives
for a game that does not exist. Code already present turns that into an
invitation to delete the game.
fix race condition in accept thread; only call wifimgr.connect() on
guest side. Connectivity now works reliably if the guest starts, or is
restarted, when the group owner is running. If owner is restarted the
guest seems never to connect (without restart.)
Two crashes reported on the Google Play store in the 112 version have at
least easy work-arounds: catching exceptions and doing nothing. In both
cases that should be harmless, so assuming the causes are rare it's a
good move.
Make it a trivial state machine that implements Runnable and
ActionListener so it can be scheduled and notified easily. Removes a
bunch of code. Connecting still happens unreliably, but it should be
easier to tweak things now.