Fix bug #17250939 Stability: ANRs in Settings: at com.android.settings.search.Index.updateInternal(Index.java:518)

- do not care about getting a result for updating the Index as
there is no way to make it useful (the result will come later
when this is no more relevant)
- make a copy of the data to process and pass it to the AsyncTask

Change-Id: I6b8a08ecbe3d32cffac1314c03f682ebacfd64bf
This commit is contained in:
Fabrice Di Meglio
2014-08-29 17:44:52 -07:00
parent 8dade422e5
commit 72e07cf21c

View File

@@ -181,6 +181,16 @@ public class Index {
nonIndexableKeys = new HashMap<String, List<String>>(); nonIndexableKeys = new HashMap<String, List<String>>();
} }
public UpdateData(UpdateData other) {
dataToUpdate = new ArrayList<SearchIndexableData>(other.dataToUpdate);
dataToDelete = new ArrayList<SearchIndexableData>(other.dataToDelete);
nonIndexableKeys = new HashMap<String, List<String>>(other.nonIndexableKeys);
}
public UpdateData copy() {
return new UpdateData(this);
}
public void clear() { public void clear() {
dataToUpdate.clear(); dataToUpdate.clear();
dataToDelete.clear(); dataToDelete.clear();
@@ -286,7 +296,7 @@ public class Index {
} }
} }
public boolean update() { public void update() {
final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE); final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE);
List<ResolveInfo> list = List<ResolveInfo> list =
mContext.getPackageManager().queryIntentContentProviders(intent, 0); mContext.getPackageManager().queryIntentContentProviders(intent, 0);
@@ -304,7 +314,7 @@ public class Index {
addNonIndexablesKeysFromRemoteProvider(packageName, authority); addNonIndexablesKeysFromRemoteProvider(packageName, authority);
} }
return updateInternal(); updateInternal();
} }
private boolean addIndexablesFromRemoteProvider(String packageName, String authority) { private boolean addIndexablesFromRemoteProvider(String packageName, String authority) {
@@ -443,11 +453,10 @@ public class Index {
} }
} }
private boolean updateFromRemoteProvider(String packageName, String authority) { private void updateFromRemoteProvider(String packageName, String authority) {
if (!addIndexablesFromRemoteProvider(packageName, authority)) { if (addIndexablesFromRemoteProvider(packageName, authority)) {
return false; updateInternal();
} }
return updateInternal();
} }
/** /**
@@ -457,9 +466,8 @@ public class Index {
* @param rebuild true means that you want to delete the data from the Index first. * @param rebuild true means that you want to delete the data from the Index first.
* @param includeInSearchResults true means that you want the bit "enabled" set so that the * @param includeInSearchResults true means that you want the bit "enabled" set so that the
* data will be seen included into the search results * data will be seen included into the search results
* @return true of the Index update has been successful.
*/ */
public boolean updateFromClassNameResource(String className, boolean rebuild, public void updateFromClassNameResource(String className, boolean rebuild,
boolean includeInSearchResults) { boolean includeInSearchResults) {
if (className == null) { if (className == null) {
throw new IllegalArgumentException("class name cannot be null!"); throw new IllegalArgumentException("class name cannot be null!");
@@ -467,7 +475,7 @@ public class Index {
final SearchIndexableResource res = SearchIndexableResources.getResourceByName(className); final SearchIndexableResource res = SearchIndexableResources.getResourceByName(className);
if (res == null ) { if (res == null ) {
Log.e(LOG_TAG, "Cannot find SearchIndexableResources for class name: " + className); Log.e(LOG_TAG, "Cannot find SearchIndexableResources for class name: " + className);
return false; return;
} }
res.context = mContext; res.context = mContext;
res.enabled = includeInSearchResults; res.enabled = includeInSearchResults;
@@ -476,15 +484,14 @@ public class Index {
} }
addIndexableData(res); addIndexableData(res);
mDataToProcess.forceUpdate = true; mDataToProcess.forceUpdate = true;
boolean result = updateInternal(); updateInternal();
res.enabled = false; res.enabled = false;
return result;
} }
public boolean updateFromSearchIndexableData(SearchIndexableData data) { public void updateFromSearchIndexableData(SearchIndexableData data) {
addIndexableData(data); addIndexableData(data);
mDataToProcess.forceUpdate = true; mDataToProcess.forceUpdate = true;
return updateInternal(); updateInternal();
} }
private SQLiteDatabase getReadableDatabase() { private SQLiteDatabase getReadableDatabase() {
@@ -510,21 +517,12 @@ public class Index {
SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH); SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH);
} }
private boolean updateInternal() { private void updateInternal() {
synchronized (mDataToProcess) { synchronized (mDataToProcess) {
final UpdateIndexTask task = new UpdateIndexTask(); final UpdateIndexTask task = new UpdateIndexTask();
task.execute(mDataToProcess); UpdateData copy = mDataToProcess.copy();
try { task.execute(copy);
final boolean result = task.get(); mDataToProcess.clear();
mDataToProcess.clear();
return result;
} catch (InterruptedException e) {
Log.e(LOG_TAG, "Cannot update index", e);
return false;
} catch (ExecutionException e) {
Log.e(LOG_TAG, "Cannot update index", e);
return false;
}
} }
} }
@@ -1143,7 +1141,7 @@ public class Index {
/** /**
* A private class for updating the Index database * A private class for updating the Index database
*/ */
private class UpdateIndexTask extends AsyncTask<UpdateData, Integer, Boolean> { private class UpdateIndexTask extends AsyncTask<UpdateData, Integer, Void> {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
@@ -1152,15 +1150,13 @@ public class Index {
} }
@Override @Override
protected void onPostExecute(Boolean aBoolean) { protected void onPostExecute(Void aVoid) {
super.onPostExecute(aBoolean); super.onPostExecute(aVoid);
mIsAvailable.set(true); mIsAvailable.set(true);
} }
@Override @Override
protected Boolean doInBackground(UpdateData... params) { protected Void doInBackground(UpdateData... params) {
boolean result = false;
final List<SearchIndexableData> dataToUpdate = params[0].dataToUpdate; final List<SearchIndexableData> dataToUpdate = params[0].dataToUpdate;
final List<SearchIndexableData> dataToDelete = params[0].dataToDelete; final List<SearchIndexableData> dataToDelete = params[0].dataToDelete;
final Map<String, List<String>> nonIndexableKeys = params[0].nonIndexableKeys; final Map<String, List<String>> nonIndexableKeys = params[0].nonIndexableKeys;
@@ -1180,11 +1176,11 @@ public class Index {
forceUpdate); forceUpdate);
} }
database.setTransactionSuccessful(); database.setTransactionSuccessful();
result = true;
} finally { } finally {
database.endTransaction(); database.endTransaction();
} }
return result;
return null;
} }
private boolean processDataToUpdate(SQLiteDatabase database, String localeStr, private boolean processDataToUpdate(SQLiteDatabase database, String localeStr,