Merge "Remove AssistPreviewPanel when orb is not visible." into sc-dev
This commit is contained in:
@@ -14,14 +14,8 @@ import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
@@ -30,12 +24,6 @@ import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.voice.VoiceInteractionSession;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.internal.app.IVoiceInteractionSessionListener;
|
||||
@@ -43,7 +31,6 @@ import com.android.internal.app.IVoiceInteractionSessionShowCallback;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.settingslib.applications.InterestingConfigChanges;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.assist.ui.DefaultUiController;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
@@ -97,8 +84,6 @@ public class AssistManager {
|
||||
// Note that VERBOSE logging may leak PII (e.g. transcription contents).
|
||||
private static final boolean VERBOSE = false;
|
||||
|
||||
private static final String ASSIST_ICON_METADATA_NAME =
|
||||
"com.android.systemui.action_assist_icon";
|
||||
private static final String INVOCATION_TIME_MS_KEY = "invocation_time_ms";
|
||||
private static final String INVOCATION_PHONE_STATE_KEY = "invocation_phone_state";
|
||||
public static final String INVOCATION_TYPE_KEY = "invocation_type";
|
||||
@@ -123,69 +108,29 @@ public class AssistManager {
|
||||
private static final long TIMEOUT_ACTIVITY = 1000;
|
||||
|
||||
protected final Context mContext;
|
||||
private final WindowManager mWindowManager;
|
||||
private final AssistDisclosure mAssistDisclosure;
|
||||
private final InterestingConfigChanges mInterestingConfigChanges;
|
||||
private final PhoneStateMonitor mPhoneStateMonitor;
|
||||
private final AssistHandleBehaviorController mHandleController;
|
||||
private final UiController mUiController;
|
||||
protected final Lazy<SysUiState> mSysUiState;
|
||||
protected final AssistLogger mAssistLogger;
|
||||
|
||||
private AssistOrbContainer mView;
|
||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||
private final CommandQueue mCommandQueue;
|
||||
private final AssistOrbController mOrbController;
|
||||
protected final AssistUtils mAssistUtils;
|
||||
private final boolean mShouldEnableOrb;
|
||||
|
||||
private IVoiceInteractionSessionShowCallback mShowCallback =
|
||||
new IVoiceInteractionSessionShowCallback.Stub() {
|
||||
|
||||
@Override
|
||||
public void onFailed() throws RemoteException {
|
||||
mView.post(mHideRunnable);
|
||||
mOrbController.postHide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShown() throws RemoteException {
|
||||
mView.post(mHideRunnable);
|
||||
}
|
||||
};
|
||||
|
||||
private Runnable mHideRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mView.removeCallbacks(this);
|
||||
mView.show(false /* show */, true /* animate */);
|
||||
}
|
||||
};
|
||||
|
||||
private ConfigurationController.ConfigurationListener mConfigurationListener =
|
||||
new ConfigurationController.ConfigurationListener() {
|
||||
@Override
|
||||
public void onConfigChanged(Configuration newConfig) {
|
||||
if (!mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
|
||||
return;
|
||||
}
|
||||
boolean visible = false;
|
||||
if (mView != null) {
|
||||
visible = mView.isShowing();
|
||||
if (mView.isAttachedToWindow()) {
|
||||
mWindowManager.removeView(mView);
|
||||
}
|
||||
}
|
||||
|
||||
mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.assist_orb, null);
|
||||
mView.setVisibility(View.GONE);
|
||||
mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
WindowManager.LayoutParams lp = getLayoutParams();
|
||||
mWindowManager.addView(mView, lp);
|
||||
if (visible) {
|
||||
mView.show(true /* show */, false /* animate */);
|
||||
}
|
||||
mOrbController.postHide();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -205,21 +150,15 @@ public class AssistManager {
|
||||
mContext = context;
|
||||
mDeviceProvisionedController = controller;
|
||||
mCommandQueue = commandQueue;
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
mAssistUtils = assistUtils;
|
||||
mAssistDisclosure = new AssistDisclosure(context, new Handler());
|
||||
mPhoneStateMonitor = phoneStateMonitor;
|
||||
mHandleController = handleController;
|
||||
mAssistLogger = assistLogger;
|
||||
|
||||
configurationController.addCallback(mConfigurationListener);
|
||||
mOrbController = new AssistOrbController(configurationController, context);
|
||||
|
||||
registerVoiceInteractionSessionListener();
|
||||
mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION
|
||||
| ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE
|
||||
| ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
|
||||
mConfigurationListener.onConfigChanged(context.getResources().getConfiguration());
|
||||
mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic();
|
||||
|
||||
mUiController = defaultUiController;
|
||||
|
||||
@@ -282,7 +221,7 @@ public class AssistManager {
|
||||
}
|
||||
|
||||
protected boolean shouldShowOrb() {
|
||||
return false;
|
||||
return !ActivityManager.isLowRamDeviceStatic();
|
||||
}
|
||||
|
||||
public void startAssist(Bundle args) {
|
||||
@@ -293,10 +232,8 @@ public class AssistManager {
|
||||
|
||||
final boolean isService = assistComponent.equals(getVoiceInteractorComponentName());
|
||||
if (!isService || (!isVoiceSessionRunning() && shouldShowOrb())) {
|
||||
showOrb(assistComponent, isService);
|
||||
mView.postDelayed(mHideRunnable, isService
|
||||
? TIMEOUT_SERVICE
|
||||
: TIMEOUT_ACTIVITY);
|
||||
mOrbController.showOrb(assistComponent, isService);
|
||||
mOrbController.postHideDelayed(isService ? TIMEOUT_SERVICE : TIMEOUT_ACTIVITY);
|
||||
}
|
||||
|
||||
if (args == null) {
|
||||
@@ -340,30 +277,6 @@ public class AssistManager {
|
||||
mAssistUtils.hideCurrentSession();
|
||||
}
|
||||
|
||||
private WindowManager.LayoutParams getLayoutParams() {
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.assist_orb_scrim_height),
|
||||
WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING,
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
lp.token = new Binder();
|
||||
lp.gravity = Gravity.BOTTOM | Gravity.START;
|
||||
lp.setTitle("AssistPreviewPanel");
|
||||
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
|
||||
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
||||
return lp;
|
||||
}
|
||||
|
||||
private void showOrb(@NonNull ComponentName assistComponent, boolean isService) {
|
||||
maybeSwapSearchIcon(assistComponent, isService);
|
||||
if (mShouldEnableOrb) {
|
||||
mView.show(true /* show */, true /* animate */);
|
||||
}
|
||||
}
|
||||
|
||||
private void startAssistInternal(Bundle args, @NonNull ComponentName assistComponent,
|
||||
boolean isService) {
|
||||
if (isService) {
|
||||
@@ -440,44 +353,6 @@ public class AssistManager {
|
||||
return mAssistUtils.isSessionRunning();
|
||||
}
|
||||
|
||||
private void maybeSwapSearchIcon(@NonNull ComponentName assistComponent, boolean isService) {
|
||||
replaceDrawable(mView.getOrb().getLogo(), assistComponent, ASSIST_ICON_METADATA_NAME,
|
||||
isService);
|
||||
}
|
||||
|
||||
public void replaceDrawable(ImageView v, ComponentName component, String name,
|
||||
boolean isService) {
|
||||
if (component != null) {
|
||||
try {
|
||||
PackageManager packageManager = mContext.getPackageManager();
|
||||
// Look for the search icon specified in the activity meta-data
|
||||
Bundle metaData = isService
|
||||
? packageManager.getServiceInfo(
|
||||
component, PackageManager.GET_META_DATA).metaData
|
||||
: packageManager.getActivityInfo(
|
||||
component, PackageManager.GET_META_DATA).metaData;
|
||||
if (metaData != null) {
|
||||
int iconResId = metaData.getInt(name);
|
||||
if (iconResId != 0) {
|
||||
Resources res = packageManager.getResourcesForApplication(
|
||||
component.getPackageName());
|
||||
v.setImageDrawable(res.getDrawable(iconResId));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, "Assistant component "
|
||||
+ component.flattenToShortString() + " not found");
|
||||
}
|
||||
} catch (Resources.NotFoundException nfe) {
|
||||
Log.w(TAG, "Failed to swap drawable from "
|
||||
+ component.flattenToShortString(), nfe);
|
||||
}
|
||||
}
|
||||
v.setImageDrawable(null);
|
||||
}
|
||||
|
||||
protected AssistHandleBehaviorController getHandleBehaviorController() {
|
||||
return mHandleController;
|
||||
}
|
||||
|
||||
@@ -55,14 +55,17 @@ public class AssistOrbContainer extends FrameLayout {
|
||||
mOrb = (AssistOrbView) findViewById(R.id.assist_orb);
|
||||
}
|
||||
|
||||
public void show(final boolean show, boolean animate) {
|
||||
public void show(final boolean show, boolean animate, Runnable onDone) {
|
||||
if (show) {
|
||||
if (getVisibility() != View.VISIBLE) {
|
||||
setVisibility(View.VISIBLE);
|
||||
if (animate) {
|
||||
startEnterAnimation();
|
||||
startEnterAnimation(onDone);
|
||||
} else {
|
||||
reset();
|
||||
if (onDone != null) {
|
||||
onDone.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -72,10 +75,16 @@ public class AssistOrbContainer extends FrameLayout {
|
||||
public void run() {
|
||||
mAnimatingOut = false;
|
||||
setVisibility(View.GONE);
|
||||
if (onDone != null) {
|
||||
onDone.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setVisibility(View.GONE);
|
||||
if (onDone != null) {
|
||||
onDone.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +96,7 @@ public class AssistOrbContainer extends FrameLayout {
|
||||
mNavbarScrim.setAlpha(1f);
|
||||
}
|
||||
|
||||
private void startEnterAnimation() {
|
||||
private void startEnterAnimation(Runnable onDone) {
|
||||
if (mAnimatingOut) {
|
||||
return;
|
||||
}
|
||||
@@ -106,7 +115,8 @@ public class AssistOrbContainer extends FrameLayout {
|
||||
.alpha(1f)
|
||||
.setDuration(300)
|
||||
.setStartDelay(0)
|
||||
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
|
||||
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
|
||||
.withEndAction(onDone);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.assist;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.settingslib.applications.InterestingConfigChanges;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
|
||||
/**
|
||||
* AssistOrbController controls the showing and hiding of the assistant orb.
|
||||
*/
|
||||
public class AssistOrbController {
|
||||
private static final String ASSIST_ICON_METADATA_NAME =
|
||||
"com.android.systemui.action_assist_icon";
|
||||
private static final String TAG = "AssistOrbController";
|
||||
private static final boolean VERBOSE = false;
|
||||
|
||||
private final InterestingConfigChanges mInterestingConfigChanges;
|
||||
private AssistOrbContainer mView;
|
||||
private final Context mContext;
|
||||
private final WindowManager mWindowManager;
|
||||
|
||||
private Runnable mHideRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mView.removeCallbacks(this);
|
||||
mView.show(false /* show */, true /* animate */, () -> {
|
||||
mWindowManager.removeView(mView);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private ConfigurationController.ConfigurationListener mConfigurationListener =
|
||||
new ConfigurationController.ConfigurationListener() {
|
||||
@Override
|
||||
public void onConfigChanged(Configuration newConfig) {
|
||||
if (!mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
|
||||
return;
|
||||
}
|
||||
boolean visible = false;
|
||||
if (mView != null) {
|
||||
visible = mView.isShowing();
|
||||
if (mView.isAttachedToWindow()) {
|
||||
mWindowManager.removeView(mView);
|
||||
}
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
showOrb(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AssistOrbController(ConfigurationController configurationController, Context context) {
|
||||
mContext = context;
|
||||
mWindowManager = mContext.getSystemService(WindowManager.class);
|
||||
mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION
|
||||
| ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE
|
||||
| ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS);
|
||||
|
||||
configurationController.addCallback(mConfigurationListener);
|
||||
mConfigurationListener.onConfigChanged(context.getResources().getConfiguration());
|
||||
}
|
||||
|
||||
public void postHide() {
|
||||
mView.post(mHideRunnable);
|
||||
}
|
||||
|
||||
public void postHideDelayed(long delayMs) {
|
||||
mView.postDelayed(mHideRunnable, delayMs);
|
||||
}
|
||||
|
||||
private void showOrb(boolean animated) {
|
||||
if (mView == null) {
|
||||
mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.assist_orb, null);
|
||||
mView.setVisibility(View.GONE);
|
||||
mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
}
|
||||
if (!mView.isAttachedToWindow()) {
|
||||
WindowManager.LayoutParams params = getLayoutParams();
|
||||
mWindowManager.addView(mView, params);
|
||||
}
|
||||
mView.show(true, animated, null);
|
||||
}
|
||||
|
||||
private WindowManager.LayoutParams getLayoutParams() {
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.assist_orb_scrim_height),
|
||||
WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING,
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
lp.token = new Binder();
|
||||
lp.gravity = Gravity.BOTTOM | Gravity.START;
|
||||
lp.setTitle("AssistPreviewPanel");
|
||||
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
|
||||
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
||||
return lp;
|
||||
}
|
||||
|
||||
public void showOrb(@NonNull ComponentName assistComponent, boolean isService) {
|
||||
showOrb(true);
|
||||
maybeSwapSearchIcon(assistComponent, isService);
|
||||
}
|
||||
|
||||
private void maybeSwapSearchIcon(@NonNull ComponentName assistComponent, boolean isService) {
|
||||
replaceDrawable(mView.getOrb().getLogo(), assistComponent, ASSIST_ICON_METADATA_NAME,
|
||||
isService);
|
||||
}
|
||||
|
||||
public void replaceDrawable(ImageView v, ComponentName component, String name,
|
||||
boolean isService) {
|
||||
if (component != null) {
|
||||
try {
|
||||
PackageManager packageManager = mContext.getPackageManager();
|
||||
// Look for the search icon specified in the activity meta-data
|
||||
Bundle metaData = isService
|
||||
? packageManager.getServiceInfo(
|
||||
component, PackageManager.GET_META_DATA).metaData
|
||||
: packageManager.getActivityInfo(
|
||||
component, PackageManager.GET_META_DATA).metaData;
|
||||
if (metaData != null) {
|
||||
int iconResId = metaData.getInt(name);
|
||||
if (iconResId != 0) {
|
||||
Resources res = packageManager.getResourcesForApplication(
|
||||
component.getPackageName());
|
||||
v.setImageDrawable(res.getDrawable(iconResId));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
if (VERBOSE) {
|
||||
Log.v(TAG, "Assistant component "
|
||||
+ component.flattenToShortString() + " not found");
|
||||
}
|
||||
} catch (Resources.NotFoundException nfe) {
|
||||
Log.w(TAG, "Failed to swap drawable from "
|
||||
+ component.flattenToShortString(), nfe);
|
||||
}
|
||||
}
|
||||
v.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user