Loading core/java/com/android/internal/app/ChooserActivity.java +15 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,10 @@ public class ChooserActivity extends ResolverActivity { mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets); unbindService(sri.connection); mServiceConnections.remove(sri.connection); if (mServiceConnections.isEmpty()) { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); sendVoiceChoicesIfNeeded(); } break; case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT: Loading @@ -107,6 +111,7 @@ public class ChooserActivity extends ResolverActivity { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } unbindRemainingServices(); sendVoiceChoicesIfNeeded(); break; default: Loading Loading @@ -384,6 +389,8 @@ public class ChooserActivity extends ResolverActivity { + WATCHDOG_TIMEOUT_MILLIS + "ms"); mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT, WATCHDOG_TIMEOUT_MILLIS); } else { sendVoiceChoicesIfNeeded(); } } Loading Loading @@ -418,6 +425,10 @@ public class ChooserActivity extends ResolverActivity { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); } void onSetupVoiceInteraction() { // Do nothing. We'll send the voice stuff ourselves. } void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) { if (mRefinementResultReceiver != null) { mRefinementResultReceiver.destroy(); Loading Loading @@ -956,6 +967,10 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name); unbindService(this); mServiceConnections.remove(this); if (mServiceConnections.isEmpty()) { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); sendVoiceChoicesIfNeeded(); } } @Override Loading core/java/com/android/internal/app/ResolverActivity.java +88 −5 Original line number Diff line number Diff line Loading @@ -16,10 +16,17 @@ package com.android.internal.app; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityThread; import android.app.VoiceInteractor; import android.app.VoiceInteractor.PickOptionRequest; import android.app.VoiceInteractor.PickOptionRequest.Option; import android.app.VoiceInteractor.Prompt; import android.app.VoiceInteractor.Request; import android.os.AsyncTask; import android.provider.Settings; import android.service.chooser.ChooserTarget; import android.text.TextUtils; import android.util.Slog; import android.widget.AbsListView; Loading Loading @@ -96,6 +103,7 @@ public class ResolverActivity extends Activity { private int mProfileSwitchMessageId = -1; private final ArrayList<Intent> mIntents = new ArrayList<>(); private ResolverComparator mResolverComparator; private PickTargetOptionRequest mPickOptionRequest; private boolean mRegistered; private final PackageMonitor mPackageMonitor = new PackageMonitor() { Loading Loading @@ -242,6 +250,9 @@ public class ResolverActivity extends Activity { finish(); } }); if (isVoiceInteraction()) { rdl.setCollapsed(false); } } if (title == null) { Loading Loading @@ -313,6 +324,39 @@ public class ResolverActivity extends Activity { }); bindProfileView(); } if (isVoiceInteraction()) { onSetupVoiceInteraction(); } } /** * Perform any initialization needed for voice interaction. */ void onSetupVoiceInteraction() { // Do it right now. Subclasses may delay this and send it later. sendVoiceChoicesIfNeeded(); } void sendVoiceChoicesIfNeeded() { if (!isVoiceInteraction()) { // Clearly not needed. return; } final Option[] options = new Option[mAdapter.getCount()]; for (int i = 0, N = options.length; i < N; i++) { options[i] = optionForChooserTarget(mAdapter.getItem(i), i); } mPickOptionRequest = new PickTargetOptionRequest( new Prompt(getTitle()), options, null); getVoiceInteractor().submitRequest(mPickOptionRequest); } Option optionForChooserTarget(TargetInfo target, int index) { return new Option(target.getDisplayLabel(), index); } protected final void setAdditionalTargets(Intent[] intents) { Loading Loading @@ -472,6 +516,14 @@ public class ResolverActivity extends Activity { } } @Override protected void onDestroy() { super.onDestroy(); if (!isChangingConfigurations() && mPickOptionRequest != null) { mPickOptionRequest.cancel(); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); Loading Loading @@ -510,16 +562,12 @@ public class ResolverActivity extends Activity { try { ApplicationInfo appInfo = getPackageManager().getApplicationInfo( resolveInfo.activityInfo.packageName, 0 /* default flags */); return versionNumberAtLeastL(appInfo.targetSdkVersion); return appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP; } catch (NameNotFoundException e) { return false; } } private boolean versionNumberAtLeastL(int versionNumber) { return versionNumber >= Build.VERSION_CODES.LOLLIPOP; } private void setAlwaysButtonEnabled(boolean hasValidSelection, int checkedPos, boolean filtered) { boolean enabled = false; Loading Loading @@ -1644,4 +1692,39 @@ public class ResolverActivity extends Activity { && match <= IntentFilter.MATCH_CATEGORY_PATH; } static class PickTargetOptionRequest extends PickOptionRequest { public PickTargetOptionRequest(@Nullable Prompt prompt, Option[] options, @Nullable Bundle extras) { super(prompt, options, extras); } @Override public void onCancel() { super.onCancel(); final ResolverActivity ra = (ResolverActivity) getActivity(); if (ra != null) { ra.mPickOptionRequest = null; ra.finish(); } } @Override public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { super.onPickOptionResult(finished, selections, result); if (selections.length != 1) { // TODO In a better world we would filter the UI presented here and let the // user refine. Maybe later. return; } final ResolverActivity ra = (ResolverActivity) getActivity(); if (ra != null) { final TargetInfo ti = ra.mAdapter.getItem(selections[0].getIndex()); if (ra.onTargetSelected(ti, false)) { ra.mPickOptionRequest = null; ra.finish(); } } } } } core/java/com/android/internal/widget/ResolverDrawerLayout.java +15 −1 Original line number Diff line number Diff line Loading @@ -144,6 +144,14 @@ public class ResolverDrawerLayout extends ViewGroup { return mCollapseOffset > 0; } public void setCollapsed(boolean collapsed) { if (!isLaidOut()) { mOpenOnLayout = collapsed; } else { smoothScrollTo(collapsed ? mCollapsibleHeight : 0, 0); } } private boolean isMoving() { return mIsDragging || !mScroller.isFinished(); } Loading Loading @@ -575,7 +583,13 @@ public class ResolverDrawerLayout extends ViewGroup { @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) { if (mOnDismissedListener != null && velocityY < 0 && mCollapseOffset > mCollapsibleHeight) { smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, velocityY); mDismissOnScrollerFinished = true; } else { smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY); } return true; } return false; Loading core/res/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2457,6 +2457,7 @@ <intent-filter> <action android:name="android.intent.action.CHOOSER" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.VOICE" /> </intent-filter> </activity> <activity android:name="com.android.internal.app.IntentForwarderActivity" Loading Loading
core/java/com/android/internal/app/ChooserActivity.java +15 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,10 @@ public class ChooserActivity extends ResolverActivity { mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets); unbindService(sri.connection); mServiceConnections.remove(sri.connection); if (mServiceConnections.isEmpty()) { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); sendVoiceChoicesIfNeeded(); } break; case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT: Loading @@ -107,6 +111,7 @@ public class ChooserActivity extends ResolverActivity { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } unbindRemainingServices(); sendVoiceChoicesIfNeeded(); break; default: Loading Loading @@ -384,6 +389,8 @@ public class ChooserActivity extends ResolverActivity { + WATCHDOG_TIMEOUT_MILLIS + "ms"); mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT, WATCHDOG_TIMEOUT_MILLIS); } else { sendVoiceChoicesIfNeeded(); } } Loading Loading @@ -418,6 +425,10 @@ public class ChooserActivity extends ResolverActivity { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); } void onSetupVoiceInteraction() { // Do nothing. We'll send the voice stuff ourselves. } void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) { if (mRefinementResultReceiver != null) { mRefinementResultReceiver.destroy(); Loading Loading @@ -956,6 +967,10 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name); unbindService(this); mServiceConnections.remove(this); if (mServiceConnections.isEmpty()) { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); sendVoiceChoicesIfNeeded(); } } @Override Loading
core/java/com/android/internal/app/ResolverActivity.java +88 −5 Original line number Diff line number Diff line Loading @@ -16,10 +16,17 @@ package com.android.internal.app; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityThread; import android.app.VoiceInteractor; import android.app.VoiceInteractor.PickOptionRequest; import android.app.VoiceInteractor.PickOptionRequest.Option; import android.app.VoiceInteractor.Prompt; import android.app.VoiceInteractor.Request; import android.os.AsyncTask; import android.provider.Settings; import android.service.chooser.ChooserTarget; import android.text.TextUtils; import android.util.Slog; import android.widget.AbsListView; Loading Loading @@ -96,6 +103,7 @@ public class ResolverActivity extends Activity { private int mProfileSwitchMessageId = -1; private final ArrayList<Intent> mIntents = new ArrayList<>(); private ResolverComparator mResolverComparator; private PickTargetOptionRequest mPickOptionRequest; private boolean mRegistered; private final PackageMonitor mPackageMonitor = new PackageMonitor() { Loading Loading @@ -242,6 +250,9 @@ public class ResolverActivity extends Activity { finish(); } }); if (isVoiceInteraction()) { rdl.setCollapsed(false); } } if (title == null) { Loading Loading @@ -313,6 +324,39 @@ public class ResolverActivity extends Activity { }); bindProfileView(); } if (isVoiceInteraction()) { onSetupVoiceInteraction(); } } /** * Perform any initialization needed for voice interaction. */ void onSetupVoiceInteraction() { // Do it right now. Subclasses may delay this and send it later. sendVoiceChoicesIfNeeded(); } void sendVoiceChoicesIfNeeded() { if (!isVoiceInteraction()) { // Clearly not needed. return; } final Option[] options = new Option[mAdapter.getCount()]; for (int i = 0, N = options.length; i < N; i++) { options[i] = optionForChooserTarget(mAdapter.getItem(i), i); } mPickOptionRequest = new PickTargetOptionRequest( new Prompt(getTitle()), options, null); getVoiceInteractor().submitRequest(mPickOptionRequest); } Option optionForChooserTarget(TargetInfo target, int index) { return new Option(target.getDisplayLabel(), index); } protected final void setAdditionalTargets(Intent[] intents) { Loading Loading @@ -472,6 +516,14 @@ public class ResolverActivity extends Activity { } } @Override protected void onDestroy() { super.onDestroy(); if (!isChangingConfigurations() && mPickOptionRequest != null) { mPickOptionRequest.cancel(); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); Loading Loading @@ -510,16 +562,12 @@ public class ResolverActivity extends Activity { try { ApplicationInfo appInfo = getPackageManager().getApplicationInfo( resolveInfo.activityInfo.packageName, 0 /* default flags */); return versionNumberAtLeastL(appInfo.targetSdkVersion); return appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP; } catch (NameNotFoundException e) { return false; } } private boolean versionNumberAtLeastL(int versionNumber) { return versionNumber >= Build.VERSION_CODES.LOLLIPOP; } private void setAlwaysButtonEnabled(boolean hasValidSelection, int checkedPos, boolean filtered) { boolean enabled = false; Loading Loading @@ -1644,4 +1692,39 @@ public class ResolverActivity extends Activity { && match <= IntentFilter.MATCH_CATEGORY_PATH; } static class PickTargetOptionRequest extends PickOptionRequest { public PickTargetOptionRequest(@Nullable Prompt prompt, Option[] options, @Nullable Bundle extras) { super(prompt, options, extras); } @Override public void onCancel() { super.onCancel(); final ResolverActivity ra = (ResolverActivity) getActivity(); if (ra != null) { ra.mPickOptionRequest = null; ra.finish(); } } @Override public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { super.onPickOptionResult(finished, selections, result); if (selections.length != 1) { // TODO In a better world we would filter the UI presented here and let the // user refine. Maybe later. return; } final ResolverActivity ra = (ResolverActivity) getActivity(); if (ra != null) { final TargetInfo ti = ra.mAdapter.getItem(selections[0].getIndex()); if (ra.onTargetSelected(ti, false)) { ra.mPickOptionRequest = null; ra.finish(); } } } } }
core/java/com/android/internal/widget/ResolverDrawerLayout.java +15 −1 Original line number Diff line number Diff line Loading @@ -144,6 +144,14 @@ public class ResolverDrawerLayout extends ViewGroup { return mCollapseOffset > 0; } public void setCollapsed(boolean collapsed) { if (!isLaidOut()) { mOpenOnLayout = collapsed; } else { smoothScrollTo(collapsed ? mCollapsibleHeight : 0, 0); } } private boolean isMoving() { return mIsDragging || !mScroller.isFinished(); } Loading Loading @@ -575,7 +583,13 @@ public class ResolverDrawerLayout extends ViewGroup { @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) { if (mOnDismissedListener != null && velocityY < 0 && mCollapseOffset > mCollapsibleHeight) { smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, velocityY); mDismissOnScrollerFinished = true; } else { smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY); } return true; } return false; Loading
core/res/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2457,6 +2457,7 @@ <intent-filter> <action android:name="android.intent.action.CHOOSER" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.VOICE" /> </intent-filter> </activity> <activity android:name="com.android.internal.app.IntentForwarderActivity" Loading