Snap for 9516552 from 98a2510a48 to udc-release

Change-Id: Ibcb7c009fd5402efa3f8bbe90624214b8d3489c6
This commit is contained in:
Android Build Coastguard Worker
2023-01-23 00:27:17 +00:00
22 changed files with 271 additions and 142 deletions
@@ -37,7 +37,7 @@
app:layout_constraintTop_toBottomOf="@id/title"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/taskbar_edu_splitscreen_transient" />
app:lottie_rawRes="@raw/taskbar_edu_splitscreen" />
<TextView
android:id="@+id/splitscreen_text"
@@ -61,7 +61,7 @@
app:layout_constraintTop_toBottomOf="@id/title"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/taskbar_edu_suggestions_transient" />
app:lottie_rawRes="@raw/taskbar_edu_suggestions" />
<TextView
android:id="@+id/suggestions_text"
+4 -4
View File
@@ -22,12 +22,12 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/taskbar_edu_stashing"
app:layout_constraintEnd_toEndOf="@id/animation"
app:layout_constraintStart_toStartOf="@id/animation"
app:layout_constraintEnd_toEndOf="@id/swipe_animation"
app:layout_constraintStart_toStartOf="@id/swipe_animation"
app:layout_constraintTop_toTopOf="parent" />
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animation"
android:id="@+id/swipe_animation"
android:layout_width="@dimen/taskbar_edu_swipe_lottie_width"
android:layout_height="@dimen/taskbar_edu_swipe_lottie_height"
android:layout_marginTop="@dimen/taskbar_edu_tooltip_vertical_margin"
@@ -38,6 +38,6 @@
app:layout_constraintTop_toBottomOf="@id/title"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/taskbar_edu_stashing_transient" />
app:lottie_rawRes="@raw/taskbar_edu_stashing" />
</merge>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+12
View File
@@ -79,4 +79,16 @@
<!-- Recents overview -->
<color name="recents_filter_icon">#333333</color>
<!-- Lottie light theme colors. -->
<color name="lottie_blue400">#669df6</color>
<color name="lottie_blue600">#1a73e8</color>
<color name="lottie_green400">#5bb974</color>
<color name="lottie_green600">#1e8e3e</color>
<color name="lottie_grey200">#e8eaed</color>
<color name="lottie_grey600">#80868b</color>
<color name="lottie_grey700">#5f6368</color>
<color name="lottie_red600">#d93025</color>
<color name="lottie_yellow400">#fcc934</color>
<color name="lottie_yellow600">#f9ab00</color>
</resources>
@@ -18,6 +18,8 @@ package com.android.launcher3.model;
import static android.content.ContentResolver.SCHEME_CONTENT;
import static com.android.launcher3.util.SimpleBroadcastReceiver.getPackageFilter;
import android.annotation.TargetApi;
import android.app.RemoteAction;
import android.content.ContentProviderClient;
@@ -55,7 +57,6 @@ import com.android.launcher3.popup.RemoteActionShortcut;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.util.BgObjectWithLooper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -117,7 +118,7 @@ public final class WellbeingModel extends BgObjectWithLooper {
if (!TextUtils.isEmpty(mWellbeingProviderPkg)) {
mContext.registerReceiver(
new SimpleBroadcastReceiver(t -> restartObserver()),
PackageManagerHelper.getPackageFilter(mWellbeingProviderPkg,
getPackageFilter(mWellbeingProviderPkg,
Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_CHANGED,
Intent.ACTION_PACKAGE_REMOVED, Intent.ACTION_PACKAGE_DATA_CLEARED,
Intent.ACTION_PACKAGE_RESTARTED),
@@ -15,11 +15,17 @@
*/
package com.android.launcher3.taskbar
import android.graphics.PorterDuff.Mode.SRC_ATOP
import android.graphics.PorterDuffColorFilter
import android.view.View
import android.view.ViewGroup
import androidx.annotation.IntDef
import androidx.annotation.LayoutRes
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieProperty.COLOR_FILTER
import com.airbnb.lottie.model.KeyPath
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_EDU_TOOLTIP
import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN
@@ -82,7 +88,10 @@ class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) :
tooltipStep = TOOLTIP_STEP_FEATURES
inflateTooltip(R.layout.taskbar_edu_swipe)
tooltip?.show()
tooltip?.apply {
findViewById<LottieAnimationView>(R.id.swipe_animation).supportLightTheme()
show()
}
}
/**
@@ -99,6 +108,9 @@ class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) :
tooltipStep = TOOLTIP_STEP_NONE
inflateTooltip(R.layout.taskbar_edu_features)
tooltip?.apply {
findViewById<LottieAnimationView>(R.id.splitscreen_animation).supportLightTheme()
findViewById<LottieAnimationView>(R.id.suggestions_animation).supportLightTheme()
findViewById<View>(R.id.done_button)?.setOnClickListener { hide() }
if (DisplayController.isTransientTaskbar(activityContext)) {
(layoutParams as ViewGroup.MarginLayoutParams).bottomMargin +=
@@ -145,3 +157,37 @@ class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) :
pw?.println("$prefix\ttooltipStep=$tooltipStep")
}
}
/**
* Maps colors in the dark-themed Lottie assets to their light-themed equivalents.
*
* For instance, `".blue100" to R.color.lottie_blue400` means objects that are material blue100 in
* dark theme should be changed to material blue400 in light theme.
*/
private val DARK_TO_LIGHT_COLORS =
mapOf(
".blue100" to R.color.lottie_blue400,
".blue400" to R.color.lottie_blue600,
".green100" to R.color.lottie_green400,
".green400" to R.color.lottie_green600,
".grey300" to R.color.lottie_grey600,
".grey400" to R.color.lottie_grey700,
".grey800" to R.color.lottie_grey200,
".red400" to R.color.lottie_red600,
".yellow100" to R.color.lottie_yellow400,
".yellow400" to R.color.lottie_yellow600,
)
private fun LottieAnimationView.supportLightTheme() {
if (Utilities.isDarkTheme(context)) {
return
}
addLottieOnCompositionLoadedListener {
DARK_TO_LIGHT_COLORS.forEach { (key, color) ->
addValueCallback(KeyPath("**", key, "**"), COLOR_FILTER) {
PorterDuffColorFilter(context.getColor(color), SRC_ATOP)
}
}
}
}
@@ -10,12 +10,10 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_S
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.systemui.shared.system.QuickStepContract;
import java.io.PrintWriter;
@@ -30,6 +28,7 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas
SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED |
SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
private final ScreenOnListener mScreenOnListener;
private final TaskbarActivityContext mContext;
private int mKeyguardSysuiFlags;
private boolean mBouncerShowing;
@@ -37,22 +36,20 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas
private final KeyguardManager mKeyguardManager;
private boolean mIsScreenOff;
private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mIsScreenOff = true;
AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL);
}
};
public TaskbarKeyguardController(TaskbarActivityContext context) {
mContext = context;
mScreenOnListener = isOn -> {
if (!isOn) {
mIsScreenOff = true;
AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL);
}
};
mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
}
public void init(NavbarButtonsViewController navbarButtonUIController) {
mNavbarButtonsViewController = navbarButtonUIController;
mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
ScreenOnTracker.INSTANCE.get(mContext).addListener(mScreenOnListener);
}
public void updateStateForSysuiFlags(int systemUiStateFlags) {
@@ -104,7 +101,7 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas
}
public void onDestroy() {
mContext.unregisterReceiver(mScreenOffReceiver);
ScreenOnTracker.INSTANCE.get(mContext).removeListener(mScreenOnListener);
}
@Override
@@ -609,10 +609,12 @@ public class QuickstepLauncher extends Launcher {
}
@Override
protected void onScreenOff() {
super.onScreenOff();
RecentsView recentsView = getOverviewPanel();
recentsView.finishRecentsAnimation(true /* toRecents */, null);
protected void onScreenOnChanged(boolean isOn) {
super.onScreenOnChanged(isOn);
if (!isOn) {
RecentsView recentsView = getOverviewPanel();
recentsView.finishRecentsAnimation(true /* toRecents */, null);
}
}
@Override
@@ -21,15 +21,12 @@ import static android.content.Intent.ACTION_PACKAGE_CHANGED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -57,9 +54,9 @@ import java.util.function.Consumer;
public final class OverviewComponentObserver {
private static final String TAG = "OverviewComponentObserver";
private final BroadcastReceiver mUserPreferenceChangeReceiver =
private final SimpleBroadcastReceiver mUserPreferenceChangeReceiver =
new SimpleBroadcastReceiver(this::updateOverviewTargets);
private final BroadcastReceiver mOtherHomeAppUpdateReceiver =
private final SimpleBroadcastReceiver mOtherHomeAppUpdateReceiver =
new SimpleBroadcastReceiver(this::updateOverviewTargets);
private final Context mContext;
@@ -102,9 +99,7 @@ public final class OverviewComponentObserver {
mConfigChangesMap.append(fallbackComponent.hashCode(), fallbackInfo.configChanges);
} catch (PackageManager.NameNotFoundException ignored) { /* Impossible */ }
mContext.registerReceiver(mUserPreferenceChangeReceiver,
new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED),
Context.RECEIVER_EXPORTED/*UNAUDITED*/);
mUserPreferenceChangeReceiver.register(mContext, ACTION_PREFERRED_ACTIVITY_CHANGED);
updateOverviewTargets();
}
@@ -182,9 +177,8 @@ public final class OverviewComponentObserver {
unregisterOtherHomeAppUpdateReceiver();
mUpdateRegisteredPackage = defaultHome.getPackageName();
mContext.registerReceiver(mOtherHomeAppUpdateReceiver, getPackageFilter(
mUpdateRegisteredPackage, ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED,
ACTION_PACKAGE_REMOVED), Context.RECEIVER_EXPORTED/*UNAUDITED*/);
mOtherHomeAppUpdateReceiver.registerPkgActions(mContext, mUpdateRegisteredPackage,
ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REMOVED);
}
}
mOverviewChangeListener.accept(mIsHomeAndOverviewSame);
@@ -63,11 +63,13 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
TYPE_TASK_MENU,
TYPE_OPTIONS_POPUP,
TYPE_ICON_SURFACE,
TYPE_OPTIONS_POPUP_DIALOG,
TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP,
TYPE_WIDGETS_EDUCATION_DIALOG,
TYPE_TASKBAR_EDUCATION_DIALOG,
TYPE_TASKBAR_ALL_APPS,
TYPE_OPTIONS_POPUP_DIALOG
TYPE_ADD_TO_HOME_CONFIRMATION,
TYPE_TASKBAR_OVERLAY_PROXY
})
@Retention(RetentionPolicy.SOURCE)
public @interface FloatingViewType {}
@@ -87,14 +89,14 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
public static final int TYPE_TASK_MENU = 1 << 11;
public static final int TYPE_OPTIONS_POPUP = 1 << 12;
public static final int TYPE_ICON_SURFACE = 1 << 13;
public static final int TYPE_OPTIONS_POPUP_DIALOG = 1 << 18;
public static final int TYPE_OPTIONS_POPUP_DIALOG = 1 << 14;
public static final int TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP = 1 << 14;
public static final int TYPE_WIDGETS_EDUCATION_DIALOG = 1 << 15;
public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 16;
public static final int TYPE_TASKBAR_ALL_APPS = 1 << 17;
public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 18;
public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 19;
public static final int TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP = 1 << 15;
public static final int TYPE_WIDGETS_EDUCATION_DIALOG = 1 << 16;
public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 17;
public static final int TYPE_TASKBAR_ALL_APPS = 1 << 18;
public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 19;
public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 20;
public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
+8 -14
View File
@@ -76,11 +76,9 @@ import android.app.PendingIntent;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -198,6 +196,8 @@ import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
@@ -536,9 +536,8 @@ public class Launcher extends StatefulActivity<LauncherState>
}
getRootView().dispatchInsets();
// Listen for broadcasts
registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
// Listen for screen turning off
ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
@@ -1476,12 +1475,7 @@ public class Launcher extends StatefulActivity<LauncherState>
hostView.setOnFocusChangeListener(mFocusHandler);
}
private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
onScreenOff();
}
};
private final ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
mWorkspace.updateNotificationDots(updatedDots);
@@ -1715,7 +1709,7 @@ public class Launcher extends StatefulActivity<LauncherState>
super.onDestroy();
ACTIVITY_TRACKER.onActivityDestroyed(this);
unregisterReceiver(mScreenOffReceiver);
ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
mWorkspace.removeFolderListeners();
PluginManagerWrapper.INSTANCE.get(this).removePluginListener(this);
@@ -2083,10 +2077,10 @@ public class Launcher extends StatefulActivity<LauncherState>
mStateManager.getState().onBackCancelled(this);
}
protected void onScreenOff() {
protected void onScreenOnChanged(boolean isOn) {
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
if (mPendingRequestArgs == null) {
if (!isOn && mPendingRequestArgs == null) {
if (!isInState(NORMAL)) {
onUiChangedWhileSleeping();
}
@@ -102,7 +102,7 @@ public class LauncherAppState implements SafeCloseable {
Intent.ACTION_MANAGED_PROFILE_UNLOCKED,
ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
if (FeatureFlags.IS_STUDIO_BUILD) {
modelChangeReceiver.register(mContext, Context.RECEIVER_EXPORTED, ACTION_FORCE_ROLOAD);
modelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
}
mOnTerminateCallback.add(() -> mContext.unregisterReceiver(modelChangeReceiver));
@@ -16,17 +16,10 @@
package com.android.launcher3.graphics;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_USER_PRESENT;
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.ObjectAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -43,10 +36,12 @@ import android.view.WindowInsets;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.launcher3.util.Themes;
import com.android.systemui.plugins.ResourceProvider;
@@ -85,18 +80,20 @@ public class SysUiScrim implements View.OnAttachStateChangeListener {
/**
* Receiver used to get a signal that the user unlocked their device.
*/
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
private final ScreenOnListener mScreenOnListener = new ScreenOnListener() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (ACTION_SCREEN_OFF.equals(action)) {
public void onScreenOnChanged(boolean isOn) {
if (!isOn) {
mAnimateScrimOnNextDraw = true;
} else if (ACTION_USER_PRESENT.equals(action)) {
// ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
// the user unlocked and the Launcher is not in the foreground.
mAnimateScrimOnNextDraw = false;
}
}
@Override
public void onUserPresent() {
// ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
// the user unlocked and the Launcher is not in the foreground.
mAnimateScrimOnNextDraw = false;
}
};
private static final int MAX_HOTSEAT_SCRIM_ALPHA = 100;
@@ -208,16 +205,14 @@ public class SysUiScrim implements View.OnAttachStateChangeListener {
@Override
public void onViewAttachedToWindow(View view) {
if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF);
filter.addAction(ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone
mRoot.getContext().registerReceiver(mReceiver, filter);
ScreenOnTracker.INSTANCE.get(mActivity).addListener(mScreenOnListener);
}
}
@Override
public void onViewDetachedFromWindow(View view) {
if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
mRoot.getContext().unregisterReceiver(mReceiver);
ScreenOnTracker.INSTANCE.get(mActivity).removeListener(mScreenOnListener);
}
}
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.settings;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_CHANGED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.view.View.GONE;
@@ -25,11 +28,9 @@ import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLU
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -66,6 +67,7 @@ import com.android.launcher3.config.FlagTogglerPrefUi;
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import java.util.ArrayList;
import java.util.List;
@@ -83,12 +85,8 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
private static final String ACTION_PLUGIN_SETTINGS = "com.android.systemui.action.PLUGIN_SETTINGS";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
private final BroadcastReceiver mPluginReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
loadPluginPrefs();
}
};
private final SimpleBroadcastReceiver mPluginReceiver =
new SimpleBroadcastReceiver(i -> loadPluginPrefs());
private PreferenceScreen mPreferenceScreen;
@@ -97,13 +95,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
getContext().registerReceiver(mPluginReceiver, filter);
getContext().registerReceiver(mPluginReceiver,
new IntentFilter(Intent.ACTION_USER_UNLOCKED));
mPluginReceiver.registerPkgActions(getContext(), null,
ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REMOVED);
mPluginReceiver.register(getContext(), Intent.ACTION_USER_UNLOCKED);
mPreferenceScreen = getPreferenceManager().createPreferenceScreen(getContext());
setPreferenceScreen(mPreferenceScreen);
@@ -185,7 +179,7 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
@Override
public void onDestroy() {
super.onDestroy();
getContext().unregisterReceiver(mPluginReceiver);
mPluginReceiver.unregisterReceiverSafely(getContext());
}
private PreferenceCategory newCategory(String title) {
@@ -23,7 +23,6 @@ import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRANSIENT_TASKBAR;
import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
@@ -111,8 +110,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
}
// Initialize navigation mode change listener
mContext.registerReceiver(mReceiver,
getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
mReceiver.registerPkgActions(mContext, TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED);
WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(context);
Context displayInfoContext = getDisplayInfoContext(display);
@@ -21,7 +21,6 @@ import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
@@ -33,7 +32,6 @@ import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PatternMatcher;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
@@ -249,19 +247,6 @@ public class PackageManagerHelper {
}
}
/**
* Creates an intent filter to listen for actions with a specific package in the data field.
*/
public static IntentFilter getPackageFilter(String pkg, String... actions) {
IntentFilter packageFilter = new IntentFilter();
for (String action : actions) {
packageFilter.addAction(action);
}
packageFilter.addDataScheme("package");
packageFilter.addDataSchemeSpecificPart(pkg, PatternMatcher.PATTERN_LITERAL);
return packageFilter;
}
public static boolean isSystemApp(@NonNull final Context context,
@NonNull final Intent intent) {
PackageManager pm = context.getPackageManager();
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2023 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.launcher3.util;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_SCREEN_ON;
import static android.content.Intent.ACTION_USER_PRESENT;
import android.content.Context;
import android.content.Intent;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Utility class for tracking if the screen is currently on or off
*/
public class ScreenOnTracker {
public static final MainThreadInitializedObject<ScreenOnTracker> INSTANCE =
new MainThreadInitializedObject<>(ScreenOnTracker::new);
private final SimpleBroadcastReceiver mReceiver = new SimpleBroadcastReceiver(this::onReceive);
private final CopyOnWriteArrayList<ScreenOnListener> mListeners = new CopyOnWriteArrayList<>();
private boolean mIsScreenOn;
private ScreenOnTracker(Context context) {
// Assume that the screen is on to begin with
mIsScreenOn = true;
mReceiver.register(context, ACTION_SCREEN_ON, ACTION_SCREEN_OFF, ACTION_USER_PRESENT);
}
private void onReceive(Intent intent) {
String action = intent.getAction();
if (ACTION_SCREEN_ON.equals(action)) {
mIsScreenOn = true;
dispatchScreenOnChanged();
} else if (ACTION_SCREEN_OFF.equals(action)) {
mIsScreenOn = false;
dispatchScreenOnChanged();
} else if (ACTION_USER_PRESENT.equals(action)) {
mListeners.forEach(ScreenOnListener::onUserPresent);
}
}
private void dispatchScreenOnChanged() {
mListeners.forEach(l -> l.onScreenOnChanged(mIsScreenOn));
}
/** Returns if the screen is on or not */
public boolean isScreenOn() {
return mIsScreenOn;
}
/** Adds a listener for screen on changes */
public void addListener(ScreenOnListener listener) {
mListeners.add(listener);
}
/** Removes a previously added listener */
public void removeListener(ScreenOnListener listener) {
mListeners.remove(listener);
}
/**
* Interface to listen for screen on changes
*/
public interface ScreenOnListener {
/**
* Called when the screen turns on/off
*/
void onScreenOnChanged(boolean isOn);
/**
* Called when the keyguard goes away
*/
default void onUserPresent() { }
}
}
@@ -19,6 +19,10 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PatternMatcher;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import java.util.function.Consumer;
@@ -39,18 +43,34 @@ public class SimpleBroadcastReceiver extends BroadcastReceiver {
* Helper method to register multiple actions
*/
public void register(Context context, String... actions) {
register(context, 0, actions);
context.registerReceiver(this, getFilter(actions));
}
/**
* Helper method to register multiple actions with one or more {@code flags}.
* Helper method to register multiple actions associated with a paction
*/
public void register(Context context, int flags, String... actions) {
public void registerPkgActions(Context context, @Nullable String pkg, String... actions) {
context.registerReceiver(this, getPackageFilter(pkg, actions));
}
/**
* Creates an intent filter to listen for actions with a specific package in the data field.
*/
public static IntentFilter getPackageFilter(String pkg, String... actions) {
IntentFilter filter = getFilter(actions);
filter.addDataScheme("package");
if (!TextUtils.isEmpty(pkg)) {
filter.addDataSchemeSpecificPart(pkg, PatternMatcher.PATTERN_LITERAL);
}
return filter;
}
private static IntentFilter getFilter(String... actions) {
IntentFilter filter = new IntentFilter();
for (String action : actions) {
filter.addAction(action);
}
context.registerReceiver(this, filter, flags);
return filter;
}
/**
@@ -1,12 +1,11 @@
package com.android.launcher3.util;
import static android.content.Intent.ACTION_WALLPAPER_CHANGED;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -23,7 +22,7 @@ import com.android.launcher3.anim.Interpolators;
/**
* Utility class to handle wallpaper scrolling along with workspace.
*/
public class WallpaperOffsetInterpolator extends BroadcastReceiver {
public class WallpaperOffsetInterpolator {
private static final int[] sTempInt = new int[2];
private static final String TAG = "WPOffsetInterpolator";
@@ -32,6 +31,8 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
// Don't use all the wallpaper for parallax until you have at least this many pages
private static final int MIN_PARALLAX_PAGE_SPAN = 4;
private final SimpleBroadcastReceiver mWallpaperChangeReceiver =
new SimpleBroadcastReceiver(i -> onWallpaperChanged());
private final Workspace<?> mWorkspace;
private final boolean mIsRtl;
private final Handler mHandler;
@@ -197,22 +198,20 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
public void setWindowToken(IBinder token) {
mWindowToken = token;
if (mWindowToken == null && mRegistered) {
mWorkspace.getContext().unregisterReceiver(this);
mWallpaperChangeReceiver.unregisterReceiverSafely(mWorkspace.getContext());
mRegistered = false;
} else if (mWindowToken != null && !mRegistered) {
mWorkspace.getContext()
.registerReceiver(this, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
onReceive(mWorkspace.getContext(), null);
mWallpaperChangeReceiver.register(mWorkspace.getContext(), ACTION_WALLPAPER_CHANGED);
onWallpaperChanged();
mRegistered = true;
}
}
@Override
public void onReceive(Context context, Intent intent) {
private void onWallpaperChanged() {
UI_HELPER_EXECUTOR.execute(() -> {
// Updating the boolean on a background thread is fine as the assignments are atomic
mWallpaperIsLiveWallpaper =
WallpaperManager.getInstance(context).getWallpaperInfo() != null;
mWallpaperIsLiveWallpaper = WallpaperManager.getInstance(mWorkspace.getContext())
.getWallpaperInfo() != null;
updateOffset();
});
}
@@ -63,7 +63,7 @@ import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.TestCommandReceiver;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.util.rule.FailureWatcher;
@@ -196,16 +196,10 @@ public abstract class AbstractLauncherUiTest {
protected void clearPackageData(String pkg) throws IOException, InterruptedException {
final CountDownLatch count = new CountDownLatch(2);
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
count.countDown();
}
};
mTargetContext.registerReceiver(broadcastReceiver,
PackageManagerHelper.getPackageFilter(pkg,
Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED),
Context.RECEIVER_EXPORTED/*UNAUDITED*/);
final SimpleBroadcastReceiver broadcastReceiver =
new SimpleBroadcastReceiver(i -> count.countDown());
broadcastReceiver.registerPkgActions(mTargetContext, pkg,
Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED);
mDevice.executeShellCommand("pm clear " + pkg);
assertTrue(pkg + " didn't restart", count.await(10, TimeUnit.SECONDS));