Continue conversion of alerts that required blocking the JNI thread. Now
board_commitTurn() takes a second boolean indicating whether phonies
found have been approved by user. Common code informs user, and if he
approves client code calls board_commitTurn() again. In case where
turn's lost there's no call to make back, but there's the undesirable
change that if a robot moves next its move will be reported on top of
the turn-lost alert. Ideally new alerts would appear under, not on top
of, those that have not yet been dismissed.
Next step in converting util_ methods that required blocking: blank tile
assignment. Now post a query and add a method that the client code can
call when the user's decided. Include enough state (col, row, and
playerNum) so that it's probably pretty safe.
Probably breaks curses build, but for gtk and Android
turn move and trade confirmation into a two-step process, making
board_commitTurn() non-interactive when called with a second
parameter. The old blocking util methods now return void and it's up to
the client code to interact (on the main thread) then re-call
board_commitTurn() if appropriate.
First attempt to stop blocking the jni thread: instead of returning a
password from a util_ method, have it include enough state that the UI
can return, put up a dialog, and then pass that state and the password
back and have them matched up again. I think this will work for the
remaining blocking Alerts too.
Includes a hack in DBAlert that's required I think because
GameConfigDelegate is launched "for result". onCreateDialog() always
fails after a rotation the first time because GameConfigDelegate isn't
there to have its makeDialog() dispatched to. So it puts up a dummy
alert and then post()s code that is successful in calling makeDialog()
to get an alert from GameConfigDelegate that can replace the
dummy. Nothing shows on the screen on simulator anyway.
The major problem remaining is that blocking alerts in BoardDelegate are
recreated after rotation but the thread that was blocking has been freed
so nothing can be done after the new alert returns. E.g. blank tile
picker will be posted again, user will pick a tile, but the common
code's not in a state to do anything with that choice (which cannot even
be "returned.") Options are to find a way to make the JNIThread survive
the configuration change without unblocking or to rewrite all the common
code to not expect return values from util_ methods.
This commit is not well tested, and diffs don't allow a thorough check
of the conversion of each DlgID type.
New way of adding onDismiss listener to DialogFragment-based alerts
required API change to DBAlert and the makeDialog() method. Fixes
customizing default player name.
Had left out dispatch of "negative" buttons populated from an
ActionPair. Tested for offer to remove redundant new game buttons at
bottom of games list.
For GamesListDelegate only so far, replace calling <activity>.show(int)
to launch an Alert with something producing and showing a
DialogFragment. Replaces passing and saving state inside the
DelegateBase subclass with saving it as part of the fragment's bundle,
and it looks as if a single class will work for nearly all of the alerts
managed by DelegateBase.{onCreateDialog,prepareDialog}(), which will
eventually go away. The beauty is that the implementations of
onCreateDialog and onPrepareDialog remain, but as the body of a new
makeDialog() that's called by the fragment's onCreateView. Less code
changes, but now it's all called every time an alert's created.
Since associated DlgDelegate instance doesn't survive a rotation, needed
to pipe results through a DlgClickNotify implementation on XWActivity
that then dispatches in the DualpaneDelegate case to all visible
fragments. I hope this turns out to work for all DlgClickNotify
implementations as I switch them over. We'll see.
Add script that when copied to device and run from 'adb shell' captures
all app and OS logs to file. Next: add code to XWApp.java to copy it
from assets/ and run it on launch.
On 2.3 anyway there's a java.lang.VerifyError trying to load that
class. So wrap the loading in a new class that catches the error and
sets a boolean so subsequent calls don't need it. There are other calls
that could load the class, but they may not be reachable. To be tested.
Required to fix alerts going away now that orientations are handled by
the OS (which in turn is the preferred way to do things now since not
ALL config changes CAN be handled by the OS.) With this change some
alerts will probably cause crashes during a rotation. Those all need to
be fixed.
Add listener interface to DBUtils and hook StudyListDelegate into it so
that if a word is added while the list is being displayed the new word
shows up immediately.
wordlist browser selection and downloaded info about downloadable
wordlists didn't survive rotation. They do now, the latter as a huge
serialized array. To make selection work I save the keySet() of a
mapping of selected names to the views that represent them. Now the
presence of a key, even if the value is (temporarily) null, signals that
something's selected.
Old code that didn't rotate properly was meant to associate view IDs
with fragments so I could iterate over them, e.g. to dispatch
intents. To replace that the common superclass of all fragments now
keeps a set of active ones and provides a method that uses that to find
the fragment that owns a view. So I can iterate over fragments based on
the dualcontainer-contained views as before.
Remove the generated FrameLayout that was breaking restoration after a
config change. Set layout_weight=1 for all fragment root views so they
get half the screen in landscape mode. Remove some code. Problems
remain, first among them that notification intents aren't dispatched correctly.
A group that's closed stays closed even if a game's added to it. The
change flushed out a bug where the groups cache wasn't being invalided
on a game move, so fix that too.
Name file and set internal constant sent to server to use same git rev
string so that the script will correctly identify whether the version I
have is the latest it has available. Fixes server offering to replace
with what I already have.
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.