From d385c7e9063b193c00e7d3ff59b536e6bfe2dfd5 Mon Sep 17 00:00:00 2001 From: cretin45 Date: Mon, 23 Feb 2015 15:58:21 -0800 Subject: [PATCH] SetupWizard: Fix race conditions with async callbacks Change-Id: Ifeeec3ac74b4644bb26b9f90d0159a64b173785b --- .../setupwizard/setup/AbstractSetupData.java | 79 ++++++++++++++++--- .../setupwizard/setup/SetupDataCallbacks.java | 1 + .../setupwizard/setup/WifiSetupPage.java | 12 ++- .../setupwizard/ui/SetupWizardActivity.java | 9 +++ 4 files changed, 87 insertions(+), 14 deletions(-) diff --git a/src/com/cyanogenmod/setupwizard/setup/AbstractSetupData.java b/src/com/cyanogenmod/setupwizard/setup/AbstractSetupData.java index baab434..9c9d5fc 100644 --- a/src/com/cyanogenmod/setupwizard/setup/AbstractSetupData.java +++ b/src/com/cyanogenmod/setupwizard/setup/AbstractSetupData.java @@ -33,11 +33,17 @@ public abstract class AbstractSetupData extends BroadcastReceiver implements Set private int mCurrentPageIndex = 0; + private OnResumeRunnable mOnResumeRunnable; + public AbstractSetupData(SetupWizardActivity context) { mContext = context; mPageList = onNewPageList(); } + public void setContext(SetupWizardActivity context) { + mContext = context; + } + protected abstract PageList onNewPageList(); @Override @@ -75,6 +81,12 @@ public abstract class AbstractSetupData extends BroadcastReceiver implements Set return mPageList.getPage(mCurrentPageIndex); } + @Override + public boolean isCurrentPage(Page page) { + if (page == null) return false; + return page.getKey().equals(getCurrentPage().getKey()); + } + public boolean isFirstPage() { return mCurrentPageIndex == 0; } @@ -85,24 +97,36 @@ public abstract class AbstractSetupData extends BroadcastReceiver implements Set @Override public void onNextPage() { - if (getCurrentPage().doNextAction() == false) { - if (advanceToNextUnhidden()) { - for (int i = 0; i < mListeners.size(); i++) { - mListeners.get(i).onNextPage(); + Runnable runnable = new Runnable() { + @Override + public void run() { + if (getCurrentPage().doNextAction() == false) { + if (advanceToNextUnhidden()) { + for (int i = 0; i < mListeners.size(); i++) { + mListeners.get(i).onNextPage(); + } + } } } - } + }; + doPreviousNext(runnable); } @Override public void onPreviousPage() { - if (getCurrentPage().doPreviousAction() == false) { - if (advanceToPreviousUnhidden()) { - for (int i = 0; i < mListeners.size(); i++) { - mListeners.get(i).onPreviousPage(); + Runnable runnable = new Runnable() { + @Override + public void run() { + if (getCurrentPage().doPreviousAction() == false) { + if (advanceToPreviousUnhidden()) { + for (int i = 0; i < mListeners.size(); i++) { + mListeners.get(i).onPreviousPage(); + } + } } } - } + }; + doPreviousNext(runnable); } private boolean advanceToNextUnhidden() { @@ -134,6 +158,24 @@ public abstract class AbstractSetupData extends BroadcastReceiver implements Set } } + private void doPreviousNext(Runnable runnable) { + if (mContext.isResumed()) { + runnable.run(); + } else { + mOnResumeRunnable = new OnResumeRunnable(runnable, this); + } + } + + public void onDestroy() { + mOnResumeRunnable = null; + } + + public void onResume() { + if (mOnResumeRunnable != null) { + mOnResumeRunnable.run(); + } + } + public void finishPages() { for (Page page : mPageList.values()) { page.onFinishSetup(); @@ -155,4 +197,21 @@ public abstract class AbstractSetupData extends BroadcastReceiver implements Set public void unregisterListener(SetupDataCallbacks listener) { mListeners.remove(listener); } + + private static class OnResumeRunnable implements Runnable { + + private final AbstractSetupData mAbstractSetupData; + private final Runnable mRunnable; + + private OnResumeRunnable(Runnable runnable, AbstractSetupData abstractSetupData) { + mAbstractSetupData = abstractSetupData; + mRunnable = runnable; + } + + @Override + public void run() { + mRunnable.run(); + mAbstractSetupData.mOnResumeRunnable = null; + } + } } diff --git a/src/com/cyanogenmod/setupwizard/setup/SetupDataCallbacks.java b/src/com/cyanogenmod/setupwizard/setup/SetupDataCallbacks.java index d12da2c..4deee8d 100644 --- a/src/com/cyanogenmod/setupwizard/setup/SetupDataCallbacks.java +++ b/src/com/cyanogenmod/setupwizard/setup/SetupDataCallbacks.java @@ -22,6 +22,7 @@ public interface SetupDataCallbacks { void onPageLoaded(Page page); void onPageTreeChanged(); void onFinish(); + boolean isCurrentPage(Page page); Page getPage(String key); Page getPage(int key); } diff --git a/src/com/cyanogenmod/setupwizard/setup/WifiSetupPage.java b/src/com/cyanogenmod/setupwizard/setup/WifiSetupPage.java index 268d8a9..4a526b3 100644 --- a/src/com/cyanogenmod/setupwizard/setup/WifiSetupPage.java +++ b/src/com/cyanogenmod/setupwizard/setup/WifiSetupPage.java @@ -59,7 +59,7 @@ public class WifiSetupPage extends SetupPage { private Runnable mFinishCaptivePortalCheckRunnable = new Runnable() { @Override public void run() { - final Activity activity = mContext; + final SetupWizardActivity activity = mContext; if (mIsCaptivePortal) { try { int netId = ConnectivityManager.from(activity) @@ -82,10 +82,14 @@ public class WifiSetupPage extends SetupPage { } catch (Exception e) { //Oh well Log.e(TAG, "No captive portal activity found" + e); - getCallbacks().onNextPage(); + if (activity.isCurrentPage(WifiSetupPage.this)) { + getCallbacks().onNextPage(); + } } } else { - getCallbacks().onNextPage(); + if (activity.isCurrentPage(WifiSetupPage.this)) { + getCallbacks().onNextPage(); + } } } }; @@ -147,7 +151,7 @@ public class WifiSetupPage extends SetupPage { } } else if (requestCode == SetupWizardApp.REQUEST_CODE_SETUP_CAPTIVE_PORTAL) { if (resultCode == Activity.RESULT_CANCELED) { - SetupWizardUtils.launchWifiSetup((Activity)mContext); + SetupWizardUtils.launchWifiSetup(mContext); } else { getCallbacks().onNextPage(); } diff --git a/src/com/cyanogenmod/setupwizard/ui/SetupWizardActivity.java b/src/com/cyanogenmod/setupwizard/ui/SetupWizardActivity.java index 2fedee3..79ae2da 100644 --- a/src/com/cyanogenmod/setupwizard/ui/SetupWizardActivity.java +++ b/src/com/cyanogenmod/setupwizard/ui/SetupWizardActivity.java @@ -69,6 +69,8 @@ public class SetupWizardActivity extends Activity implements SetupDataCallbacks mSetupData = (CMSetupWizardData)getLastNonConfigurationInstance(); if (mSetupData == null) { mSetupData = new CMSetupWizardData(this); + } else { + mSetupData.setContext(this); } mNextButton = (Button) findViewById(R.id.next_button); mPrevButton = (Button) findViewById(R.id.prev_button); @@ -128,6 +130,7 @@ public class SetupWizardActivity extends Activity implements SetupDataCallbacks | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); super.onResume(); + mSetupData.onResume(); onPageTreeChanged(); enableButtonBar(true); } @@ -135,6 +138,7 @@ public class SetupWizardActivity extends Activity implements SetupDataCallbacks @Override protected void onDestroy() { super.onDestroy(); + mSetupData.onDestroy(); mSetupData.unregisterListener(this); unregisterReceiver(mSetupData); } @@ -236,6 +240,11 @@ public class SetupWizardActivity extends Activity implements SetupDataCallbacks return mSetupData.getPage(key); } + @Override + public boolean isCurrentPage(Page page) { + return mSetupData.isCurrentPage(page); + } + @Override public void onFinish() { animateOut();