diff options
author | Adam Powell <adamp@google.com> | 2015-09-16 21:02:58 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-09-16 21:02:58 +0000 |
commit | 4873c549f7f4c45237a6f1185dd29216157965df (patch) | |
tree | ff6f5e2a381377bdbd94396f5167af393cab3d92 /core/java/com | |
parent | d20f21065036a50cf0ba8537746f68f713f20f8b (diff) | |
parent | 39e94ebe22d4959facea4c3621a0a5377242a570 (diff) | |
download | frameworks_base-4873c549f7f4c45237a6f1185dd29216157965df.zip frameworks_base-4873c549f7f4c45237a6f1185dd29216157965df.tar.gz frameworks_base-4873c549f7f4c45237a6f1185dd29216157965df.tar.bz2 |
am 39e94ebe: Handle single-choice ChooserActivities and bound ChooserTargetServices
* commit '39e94ebe22d4959facea4c3621a0a5377242a570':
Handle single-choice ChooserActivities and bound ChooserTargetServices
Diffstat (limited to 'core/java/com')
-rw-r--r-- | core/java/com/android/internal/app/ChooserActivity.java | 97 | ||||
-rw-r--r-- | core/java/com/android/internal/app/ResolverActivity.java | 20 |
2 files changed, 89 insertions, 28 deletions
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index d9faece..80f9b0f 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -104,6 +104,7 @@ public class ChooserActivity extends ResolverActivity { sri.resultTargets); } unbindService(sri.connection); + sri.connection.destroy(); mServiceConnections.remove(sri.connection); if (mServiceConnections.isEmpty()) { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); @@ -208,6 +209,8 @@ public class ChooserActivity extends ResolverActivity { mRefinementResultReceiver.destroy(); mRefinementResultReceiver = null; } + unbindRemainingServices(); + mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); } @Override @@ -265,6 +268,11 @@ public class ChooserActivity extends ResolverActivity { return true; } + @Override + boolean shouldAutoLaunchSingleChoice() { + return false; + } + private void modifyTargetIntent(Intent in) { final String action = in.getAction(); if (Intent.ACTION_SEND.equals(action) || @@ -371,7 +379,8 @@ public class ChooserActivity extends ResolverActivity { continue; } - final ChooserTargetServiceConnection conn = new ChooserTargetServiceConnection(dri); + final ChooserTargetServiceConnection conn = + new ChooserTargetServiceConnection(this, dri); if (bindServiceAsUser(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND, UserHandle.CURRENT)) { if (DEBUG) { @@ -425,6 +434,7 @@ public class ChooserActivity extends ResolverActivity { final ChooserTargetServiceConnection conn = mServiceConnections.get(i); if (DEBUG) Log.d(TAG, "unbinding " + conn); unbindService(conn); + conn.destroy(); } mServiceConnections.clear(); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); @@ -1024,54 +1034,93 @@ public class ChooserActivity extends ResolverActivity { } } - class ChooserTargetServiceConnection implements ServiceConnection { + static class ChooserTargetServiceConnection implements ServiceConnection { private final DisplayResolveInfo mOriginalTarget; + private ComponentName mConnectedComponent; + private ChooserActivity mChooserActivity; + private final Object mLock = new Object(); private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() { @Override public void sendResult(List<ChooserTarget> targets) throws RemoteException { - filterServiceTargets(mOriginalTarget.getResolveInfo().activityInfo.packageName, - targets); - final Message msg = Message.obtain(); - msg.what = CHOOSER_TARGET_SERVICE_RESULT; - msg.obj = new ServiceResultInfo(mOriginalTarget, targets, - ChooserTargetServiceConnection.this); - mChooserHandler.sendMessage(msg); + synchronized (mLock) { + if (mChooserActivity == null) { + Log.e(TAG, "destroyed ChooserTargetServiceConnection received result from " + + mConnectedComponent + "; ignoring..."); + return; + } + mChooserActivity.filterServiceTargets( + mOriginalTarget.getResolveInfo().activityInfo.packageName, targets); + final Message msg = Message.obtain(); + msg.what = CHOOSER_TARGET_SERVICE_RESULT; + msg.obj = new ServiceResultInfo(mOriginalTarget, targets, + ChooserTargetServiceConnection.this); + mChooserActivity.mChooserHandler.sendMessage(msg); + } } }; - public ChooserTargetServiceConnection(DisplayResolveInfo dri) { + public ChooserTargetServiceConnection(ChooserActivity chooserActivity, + DisplayResolveInfo dri) { + mChooserActivity = chooserActivity; mOriginalTarget = dri; } @Override public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG) Log.d(TAG, "onServiceConnected: " + name); - final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service); - try { - icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(), - mOriginalTarget.getResolveInfo().filter, mChooserTargetResult); - } catch (RemoteException e) { - Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e); - unbindService(this); - mServiceConnections.remove(this); + synchronized (mLock) { + if (mChooserActivity == null) { + Log.e(TAG, "destroyed ChooserTargetServiceConnection got onServiceConnected"); + return; + } + + final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service); + try { + icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(), + mOriginalTarget.getResolveInfo().filter, mChooserTargetResult); + } catch (RemoteException e) { + Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e); + mChooserActivity.unbindService(this); + destroy(); + mChooserActivity.mServiceConnections.remove(this); + } } } @Override public void onServiceDisconnected(ComponentName name) { if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name); - unbindService(this); - mServiceConnections.remove(this); - if (mServiceConnections.isEmpty()) { - mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); - sendVoiceChoicesIfNeeded(); + synchronized (mLock) { + if (mChooserActivity == null) { + Log.e(TAG, + "destroyed ChooserTargetServiceConnection got onServiceDisconnected"); + return; + } + + mChooserActivity.unbindService(this); + destroy(); + mChooserActivity.mServiceConnections.remove(this); + if (mChooserActivity.mServiceConnections.isEmpty()) { + mChooserActivity.mChooserHandler.removeMessages( + CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); + mChooserActivity.sendVoiceChoicesIfNeeded(); + } + mConnectedComponent = null; + } + } + + public void destroy() { + synchronized (mLock) { + mChooserActivity = null; } } @Override public String toString() { - return mOriginalTarget.getResolveInfo().activityInfo.toString(); + return "ChooserTargetServiceConnection{service=" + + mConnectedComponent + ", activity=" + + mOriginalTarget.getResolveInfo().activityInfo.toString() + "}"; } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 7dd3bed..9272193 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -234,7 +234,9 @@ public class ResolverActivity extends Activity { mResolverComparator = new ResolverComparator(this, getTargetIntent(), referrerPackage); - configureContentView(mIntents, initialIntents, rList, alwaysUseOption); + if (configureContentView(mIntents, initialIntents, rList, alwaysUseOption)) { + return; + } // Prevent the Resolver window from becoming the top fullscreen window and thus from taking // control of the system bars. @@ -794,6 +796,10 @@ public class ResolverActivity extends Activity { return false; } + boolean shouldAutoLaunchSingleChoice() { + return true; + } + void showAppDetails(ResolveInfo ri) { Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) .setData(Uri.fromParts("package", ri.activityInfo.packageName, null)) @@ -808,7 +814,10 @@ public class ResolverActivity extends Activity { launchedFromUid, filterLastUsed); } - void configureContentView(List<Intent> payloadIntents, Intent[] initialIntents, + /** + * Returns true if the activity is finishing and creation should halt + */ + boolean configureContentView(List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean alwaysUseOption) { // The last argument of createAdapter is whether to do special handling // of the last used choice to highlight it in the list. We need to always @@ -828,7 +837,9 @@ public class ResolverActivity extends Activity { mAlwaysUseOption = alwaysUseOption; int count = mAdapter.getUnfilteredCount(); - if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) { + if ((!shouldAutoLaunchSingleChoice() && count > 0) + || count > 1 + || (count == 1 && mAdapter.getOtherProfile() != null)) { setContentView(layoutId); mAdapterView = (AbsListView) findViewById(R.id.resolver_list); onPrepareAdapterView(mAdapterView, mAdapter, alwaysUseOption); @@ -837,7 +848,7 @@ public class ResolverActivity extends Activity { mPackageMonitor.unregister(); mRegistered = false; finish(); - return; + return true; } else { setContentView(R.layout.resolver_list); @@ -847,6 +858,7 @@ public class ResolverActivity extends Activity { mAdapterView = (AbsListView) findViewById(R.id.resolver_list); mAdapterView.setVisibility(View.GONE); } + return false; } void onPrepareAdapterView(AbsListView adapterView, ResolveListAdapter adapter, |