am 9f49dcda: Merge "Add voice interaction support to ResolverActivity/ChooserActivity" into mnc-dev

* commit '9f49dcda24ea63efc8b16d0c7d69cc697cdf20d7':
  Add voice interaction support to ResolverActivity/ChooserActivity
This commit is contained in:
Adam Powell
2015-06-23 01:27:47 +00:00
committed by Android Git Automerger
4 changed files with 119 additions and 6 deletions

View File

@@ -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:
@@ -107,6 +111,7 @@ public class ChooserActivity extends ResolverActivity {
Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
}
unbindRemainingServices();
sendVoiceChoicesIfNeeded();
break;
default:
@@ -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();
}
}
@@ -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();
@@ -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

View File

@@ -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;
@@ -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() {
@@ -242,6 +250,9 @@ public class ResolverActivity extends Activity {
finish();
}
});
if (isVoiceInteraction()) {
rdl.setCollapsed(false);
}
}
if (title == null) {
@@ -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) {
@@ -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);
@@ -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;
@@ -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();
}
}
}
}
}

View File

@@ -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();
}
@@ -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) {
smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY);
if (mOnDismissedListener != null
&& velocityY < 0 && mCollapseOffset > mCollapsibleHeight) {
smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, velocityY);
mDismissOnScrollerFinished = true;
} else {
smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY);
}
return true;
}
return false;

View File

@@ -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"