summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher3/LauncherAppState.java27
-rw-r--r--src/com/android/launcher3/SettingsActivity.java42
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java24
-rw-r--r--src/com/android/launcher3/allapps/AllAppsTransitionController.java4
-rw-r--r--src/com/android/launcher3/notification/NotificationListener.java40
-rw-r--r--src/com/android/launcher3/util/SettingsObserver.java100
-rw-r--r--src/com/android/launcher3/widget/WidgetsBottomSheet.java22
7 files changed, 207 insertions, 52 deletions
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index cf20febd5..1ffe41bc6 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
@@ -28,13 +29,17 @@ import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dynamicui.ExtractionUtils;
+import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.SettingsObserver;
import com.android.launcher3.util.TestingUtils;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
+import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
+
public class LauncherAppState {
public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD;
@@ -47,7 +52,7 @@ public class LauncherAppState {
private final IconCache mIconCache;
private final WidgetPreviewLoader mWidgetCache;
private final InvariantDeviceProfile mInvariantDeviceProfile;
-
+ private final SettingsObserver mNotificationBadgingObserver;
public static LauncherAppState getInstance(final Context context) {
if (INSTANCE == null) {
@@ -117,6 +122,23 @@ public class LauncherAppState {
new ConfigMonitor(mContext).register();
ExtractionUtils.startColorExtractionServiceIfNecessary(mContext);
+
+ if (!mContext.getResources().getBoolean(R.bool.notification_badging_enabled)) {
+ mNotificationBadgingObserver = null;
+ } else {
+ // Register an observer to rebind the notification listener when badging is re-enabled.
+ mNotificationBadgingObserver = new SettingsObserver.Secure(
+ mContext.getContentResolver()) {
+ @Override
+ public void onSettingChanged(boolean isNotificationBadgingEnabled) {
+ if (isNotificationBadgingEnabled) {
+ NotificationListener.requestRebind(new ComponentName(
+ mContext, NotificationListener.class));
+ }
+ }
+ };
+ mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+ }
}
/**
@@ -127,6 +149,9 @@ public class LauncherAppState {
final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
launcherApps.removeOnAppsChangedCallback(mModel);
PackageInstallerCompat.getInstance(mContext).onStop();
+ if (mNotificationBadgingObserver != null) {
+ mNotificationBadgingObserver.unregister();
+ }
}
LauncherModel setLauncher(Launcher launcher) {
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index fa7769e3f..90463725f 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -26,17 +26,15 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.database.ContentObserver;
import android.os.Bundle;
-import android.os.Handler;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.provider.Settings;
-import android.provider.Settings.System;
import com.android.launcher3.graphics.IconShapeOverride;
import com.android.launcher3.notification.NotificationListener;
+import com.android.launcher3.util.SettingsObserver;
import com.android.launcher3.views.ButtonPreference;
/**
@@ -45,8 +43,8 @@ import com.android.launcher3.views.ButtonPreference;
public class SettingsActivity extends Activity {
private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
- // TODO: use Settings.Secure.NOTIFICATION_BADGING
- private static final String NOTIFICATION_BADGING = "notification_badging";
+ /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
+ public static final String NOTIFICATION_BADGING = "notification_badging";
/** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
@@ -88,12 +86,9 @@ public class SettingsActivity extends Activity {
// Register a content observer to listen for system setting changes while
// this UI is active.
- resolver.registerContentObserver(
- Settings.System.getUriFor(System.ACCELEROMETER_ROTATION),
- false, mRotationLockObserver);
+ mRotationLockObserver.register(Settings.System.ACCELEROMETER_ROTATION);
// Initialize the UI once
- mRotationLockObserver.onChange(true);
rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
}
@@ -107,13 +102,7 @@ public class SettingsActivity extends Activity {
// Listen to system notification badge settings while this UI is active.
mIconBadgingObserver = new IconBadgingObserver(
iconBadgingPref, resolver, getFragmentManager());
- resolver.registerContentObserver(
- Settings.Secure.getUriFor(NOTIFICATION_BADGING),
- false, mIconBadgingObserver);
- resolver.registerContentObserver(
- Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS),
- false, mIconBadgingObserver);
- mIconBadgingObserver.onChange(true);
+ mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS);
}
Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE);
@@ -129,11 +118,11 @@ public class SettingsActivity extends Activity {
@Override
public void onDestroy() {
if (mRotationLockObserver != null) {
- getActivity().getContentResolver().unregisterContentObserver(mRotationLockObserver);
+ mRotationLockObserver.unregister();
mRotationLockObserver = null;
}
if (mIconBadgingObserver != null) {
- getActivity().getContentResolver().unregisterContentObserver(mIconBadgingObserver);
+ mIconBadgingObserver.unregister();
mIconBadgingObserver = null;
}
super.onDestroy();
@@ -144,22 +133,18 @@ public class SettingsActivity extends Activity {
* Content observer which listens for system auto-rotate setting changes, and enables/disables
* the launcher rotation setting accordingly.
*/
- private static class SystemDisplayRotationLockObserver extends ContentObserver {
+ private static class SystemDisplayRotationLockObserver extends SettingsObserver.System {
private final Preference mRotationPref;
- private final ContentResolver mResolver;
public SystemDisplayRotationLockObserver(
Preference rotationPref, ContentResolver resolver) {
- super(new Handler());
+ super(resolver);
mRotationPref = rotationPref;
- mResolver = resolver;
}
@Override
- public void onChange(boolean selfChange) {
- boolean enabled = Settings.System.getInt(mResolver,
- Settings.System.ACCELEROMETER_ROTATION, 1) == 1;
+ public void onSettingChanged(boolean enabled) {
mRotationPref.setEnabled(enabled);
mRotationPref.setSummary(enabled
? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc);
@@ -170,7 +155,7 @@ public class SettingsActivity extends Activity {
* Content observer which listens for system badging setting changes,
* and updates the launcher badging setting subtext accordingly.
*/
- private static class IconBadgingObserver extends ContentObserver
+ private static class IconBadgingObserver extends SettingsObserver.Secure
implements Preference.OnPreferenceClickListener {
private final ButtonPreference mBadgingPref;
@@ -179,15 +164,14 @@ public class SettingsActivity extends Activity {
public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
FragmentManager fragmentManager) {
- super(new Handler());
+ super(resolver);
mBadgingPref = badgingPref;
mResolver = resolver;
mFragmentManager = fragmentManager;
}
@Override
- public void onChange(boolean selfChange) {
- boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1;
+ public void onSettingChanged(boolean enabled) {
int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
boolean serviceEnabled = true;
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index d4a7b9377..494cd5ac5 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -111,12 +111,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
}
@Override
- public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent ev) {
- mPullDetector.onTouchEvent(ev);
- return super.onInterceptTouchEvent(rv, ev) || mOverScrollHelper.isInOverScroll();
- }
-
- @Override
public boolean onTouchEvent(MotionEvent e) {
mPullDetector.onTouchEvent(e);
if (FeatureFlags.LAUNCHER3_PHYSICS && mSpringAnimationHandler != null) {
@@ -287,7 +281,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
- boolean result = super.onInterceptTouchEvent(e);
+ mPullDetector.onTouchEvent(e);
+ boolean result = super.onInterceptTouchEvent(e) || mOverScrollHelper.isInOverScroll();
if (!result && e.getAction() == MotionEvent.ACTION_DOWN
&& mEmptySearchBackground != null && mEmptySearchBackground.getAlpha() > 0) {
mEmptySearchBackground.setHotspot(e.getX(), e.getY());
@@ -562,11 +557,16 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
// and if one of the following criteria are met:
// - User scrolls down when they're already at the bottom.
// - User starts scrolling up, hits the top, and continues scrolling up.
+ boolean wasInOverScroll = mIsInOverScroll;
mIsInOverScroll = !mScrollbar.isDraggingThumb() &&
((!canScrollVertically(1) && displacement < 0) ||
(!canScrollVertically(-1) && isScrollingUp && mFirstScrollYOnScrollUp != 0));
- if (mIsInOverScroll) {
+ if (wasInOverScroll && !mIsInOverScroll) {
+ // Exit overscroll. This can happen when the user is in overscroll and then
+ // scrolls the opposite way.
+ reset(false /* shouldSpring */);
+ } else if (mIsInOverScroll) {
if (Float.compare(mFirstDisplacement, 0) == 0) {
// Because users can scroll before entering overscroll, we need to
// subtract the amount where the user was not in overscroll.
@@ -581,11 +581,15 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
@Override
public void onDragEnd(float velocity, boolean fling) {
+ reset(mIsInOverScroll /* shouldSpring */);
+ }
+
+ private void reset(boolean shouldSpring) {
float y = getContentTranslationY();
if (Float.compare(y, 0) != 0) {
- if (FeatureFlags.LAUNCHER3_PHYSICS) {
+ if (FeatureFlags.LAUNCHER3_PHYSICS && shouldSpring) {
// We calculate our own velocity to give the springs the desired effect.
- velocity = y / getDampedOverScroll(getHeight()) * MAX_RELEASE_VELOCITY;
+ float velocity = y / getDampedOverScroll(getHeight()) * MAX_RELEASE_VELOCITY;
// We want to negate the velocity because we are moving to 0 from -1 due to the
// downward motion. (y-axis -1 is above 0).
mSpringAnimationHandler.animateToPositionWithVelocity(0, -1, -velocity);
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 6896b37d9..edfe0c15e 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -283,7 +283,9 @@ public class AllAppsTransitionController implements TouchController, SwipeDetect
}
// Use a light system UI (dark icons) if all apps is behind at least half of the status bar.
- boolean forceChange = shift <= mStatusBarHeight / 2;
+ boolean forceChange = FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS ?
+ shift <= mShiftRange / 4 :
+ shift <= mStatusBarHeight / 2;
if (forceChange) {
mLauncher.getSystemUiController().updateUiState(
SystemUiController.UI_STATE_ALL_APPS, !mIsDarkTheme);
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 73d89aa18..6a7098915 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -30,15 +30,20 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
+
import com.android.launcher3.LauncherModel;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.SettingsObserver;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
+
/**
* A {@link NotificationListenerService} that sends updates to its
* {@link NotificationsChangedListener} when notifications are posted or canceled,
@@ -57,12 +62,14 @@ public class NotificationListener extends NotificationListenerService {
private static NotificationListener sNotificationListenerInstance = null;
private static NotificationsChangedListener sNotificationsChangedListener;
private static boolean sIsConnected;
+ private static boolean sIsCreated;
private final Handler mWorkerHandler;
private final Handler mUiHandler;
-
private final Ranking mTempRanking = new Ranking();
+ private SettingsObserver mNotificationBadgingObserver;
+
private final Handler.Callback mWorkerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
@@ -77,7 +84,7 @@ public class NotificationListener extends NotificationListenerService {
List<StatusBarNotification> activeNotifications;
if (sIsConnected) {
try {
- activeNotifications = filterNotifications(getActiveNotifications());
+ activeNotifications = filterNotifications(getActiveNotifications());
} catch (SecurityException ex) {
Log.e(TAG, "SecurityException: failed to fetch notifications");
activeNotifications = new ArrayList<StatusBarNotification>();
@@ -130,6 +137,28 @@ public class NotificationListener extends NotificationListenerService {
sNotificationListenerInstance = this;
}
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ sIsCreated = true;
+ mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) {
+ @Override
+ public void onSettingChanged(boolean isNotificationBadgingEnabled) {
+ if (!isNotificationBadgingEnabled) {
+ requestUnbind();
+ }
+ }
+ };
+ mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ sIsCreated = false;
+ mNotificationBadgingObserver.unregister();
+ }
+
public static @Nullable NotificationListener getInstanceIfConnected() {
return sIsConnected ? sNotificationListenerInstance : null;
}
@@ -143,6 +172,11 @@ public class NotificationListener extends NotificationListenerService {
NotificationListener notificationListener = getInstanceIfConnected();
if (notificationListener != null) {
notificationListener.onNotificationFullRefresh();
+ } else if (!sIsCreated && sNotificationsChangedListener != null) {
+ // User turned off badging globally, so we unbound this service;
+ // tell the listener that there are no notifications to remove dots.
+ sNotificationsChangedListener.onNotificationFullRefresh(
+ Collections.<StatusBarNotification>emptyList());
}
}
@@ -205,7 +239,7 @@ public class NotificationListener extends NotificationListenerService {
.getActiveNotifications(NotificationKeyData.extractKeysOnly(keys)
.toArray(new String[keys.size()]));
return notifications == null
- ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications);
+ ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications);
}
/**
diff --git a/src/com/android/launcher3/util/SettingsObserver.java b/src/com/android/launcher3/util/SettingsObserver.java
new file mode 100644
index 000000000..6baa24293
--- /dev/null
+++ b/src/com/android/launcher3/util/SettingsObserver.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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 android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+
+public interface SettingsObserver {
+
+ /**
+ * Registers the content observer to call {@link #onSettingChanged(boolean)} when any of the
+ * passed settings change. The value passed to onSettingChanged() is based on the key setting.
+ */
+ void register(String keySetting, String ... dependentSettings);
+ void unregister();
+ void onSettingChanged(boolean keySettingEnabled);
+
+
+ abstract class Secure extends ContentObserver implements SettingsObserver {
+ private ContentResolver mResolver;
+ private String mKeySetting;
+
+ public Secure(ContentResolver resolver) {
+ super(new Handler());
+ mResolver = resolver;
+ }
+
+ @Override
+ public void register(String keySetting, String ... dependentSettings) {
+ mKeySetting = keySetting;
+ mResolver.registerContentObserver(
+ Settings.Secure.getUriFor(mKeySetting), false, this);
+ for (String setting : dependentSettings) {
+ mResolver.registerContentObserver(
+ Settings.Secure.getUriFor(setting), false, this);
+ }
+ onChange(true);
+ }
+
+ @Override
+ public void unregister() {
+ mResolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ onSettingChanged(Settings.Secure.getInt(mResolver, mKeySetting, 1) == 1);
+ }
+ }
+
+ abstract class System extends ContentObserver implements SettingsObserver {
+ private ContentResolver mResolver;
+ private String mKeySetting;
+
+ public System(ContentResolver resolver) {
+ super(new Handler());
+ mResolver = resolver;
+ }
+
+ @Override
+ public void register(String keySetting, String ... dependentSettings) {
+ mKeySetting = keySetting;
+ mResolver.registerContentObserver(
+ Settings.System.getUriFor(mKeySetting), false, this);
+ for (String setting : dependentSettings) {
+ mResolver.registerContentObserver(
+ Settings.System.getUriFor(setting), false, this);
+ }
+ onChange(true);
+ }
+
+ @Override
+ public void unregister() {
+ mResolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ onSettingChanged(Settings.System.getInt(mResolver, mKeySetting, 1) == 1);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 0b4bf628e..01101ac74 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -88,7 +88,8 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab
mScrollInterpolator = new SwipeDetector.ScrollInterpolator();
mInsets = new Rect();
mSwipeDetector = new SwipeDetector(context, this, SwipeDetector.VERTICAL);
- mGradientBackground = (GradientView) mLauncher.findViewById(R.id.gradient_bg);
+ mGradientBackground = (GradientView) mLauncher.getLayoutInflater().inflate(
+ R.layout.gradient_bg, mLauncher.getDragLayer(), false);
}
@Override
@@ -106,6 +107,8 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab
onWidgetsBound();
+ mLauncher.getDragLayer().addView(mGradientBackground);
+ mGradientBackground.setVisibility(VISIBLE);
mLauncher.getDragLayer().addView(this);
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
setTranslationY(mTranslationYClosed);
@@ -212,11 +215,8 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mIsOpen = false;
mSwipeDetector.finishedScrolling();
- ((ViewGroup) getParent()).removeView(WidgetsBottomSheet.this);
- mLauncher.getSystemUiController().updateUiState(
- SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0);
+ onCloseComplete();
}
});
mOpenCloseAnimator.setInterpolator(mSwipeDetector.isIdleState()
@@ -224,12 +224,18 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab
mOpenCloseAnimator.start();
} else {
setTranslationY(mTranslationYClosed);
- mLauncher.getSystemUiController().updateUiState(
- SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0);
- mIsOpen = false;
+ onCloseComplete();
}
}
+ private void onCloseComplete() {
+ mIsOpen = false;
+ mLauncher.getDragLayer().removeView(mGradientBackground);
+ mLauncher.getDragLayer().removeView(WidgetsBottomSheet.this);
+ mLauncher.getSystemUiController().updateUiState(
+ SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0);
+ }
+
@Override
protected boolean isOfType(@FloatingViewType int type) {
return (type & TYPE_WIDGETS_BOTTOM_SHEET) != 0;