diff options
| author | 2018-01-11 12:10:32 -0800 | |
|---|---|---|
| committer | 2018-01-11 12:10:32 -0800 | |
| commit | 7d09277f99ca919db70d45425bd366ff1b1b7e0e (patch) | |
| tree | 80ad944a52c7cd03de16353d119b5690427c3134 | |
| parent | f0720bc5a165c835d291b36b368dd46e895e3871 (diff) | |
Add rotate suggestion button by default to left side of navbar
Icons, animations are preliminary
Test: manual
Change-Id: If8a6942c1e78f6cfb5aae6d78e6acfa2b0bb6566
8 files changed, 392 insertions, 2 deletions
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml new file mode 100644 index 000000000000..255e377cf9dd --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt"> + <aapt:attr name="android:drawable"> + <vector android:height="24dp" + android:width="24dp" + android:viewportHeight="102" + android:viewportWidth="102" + android:tint="?attr/singleToneColor"> + <group android:name="_R_G"> + <group android:name="_R_G_L_0_G" android:translateX="53.086" android:translateY="48.907000000000004" android:pivotX="-2.083" android:pivotY="2.083" android:rotation="90"> + <group android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0" android:rotation="100.1" android:scaleX="0.7979999999999999" android:scaleY="0.7979999999999999"> + <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17.15 -37.84 C30.19,-31.91 39.52,-19.62 41.9,-4.86 C42.15,-3.39 43.45,-2.31 44.95,-2.31 C46.88,-2.31 48.34,-4.06 48.05,-5.94 C44.37,-27.64 27.64,-45.91 0.84,-48.09 C-1.08,-48.25 -2.17,-45.91 -0.83,-44.53 C-0.83,-44.53 9.87,-33.83 9.87,-33.83 C10.67,-33.04 11.92,-33.04 12.76,-33.79 C12.76,-33.79 17.15,-37.84 17.15,-37.84c "/> + </group> + <group android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0" android:rotation="87.2" android:scaleX="0.77" android:scaleY="0.77"> + <path android:name="_R_G_L_0_G_D_1_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-21.32 42.01 C-34.36,36.07 -43.68,23.78 -46.07,9.02 C-46.33,7.55 -47.62,6.47 -49.12,6.47 C-51.04,6.47 -52.51,8.23 -52.21,10.11 C-48.53,31.81 -31.81,50.08 -5.01,52.25 C-3.09,52.42 -2,50.08 -3.34,48.7 C-3.34,48.7 -14.04,38 -14.04,38 C-14.84,37.21 -16.11,37.19 -16.93,37.96 C-16.93,37.96 -21.32,42.01 -21.32,42.01c "/> + </group> + <path android:name="_R_G_L_0_G_D_2_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40.77 9.4 C40.77,9.4 -9.4,-40.77 -9.4,-40.77 C-11.91,-43.28 -15.67,-43.28 -18.18,-40.77 C-18.18,-40.77 -44.94,-14.01 -44.94,-14.01 C-47.45,-11.5 -47.45,-7.74 -44.94,-5.23 C-44.94,-5.23 5.23,44.94 5.23,44.94 C7.74,47.45 11.51,47.45 14.01,44.94 C14.01,44.94 40.77,18.18 40.77,18.18 C43.28,15.67 43.28,11.91 40.77,9.4c M3.85 34.82 C3.85,34.82 -34.4,-3.44 -34.4,-3.44 C-34.4,-3.44 -7.64,-30.19 -7.64,-30.19 C-7.64,-30.19 30.61,8.06 30.61,8.06 C30.61,8.06 3.85,34.82 3.85,34.82c "/> + </group> + </group> + <group android:name="time_group"/> + </vector> + </aapt:attr> + + <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="rotation" android:duration="333" android:startOffset="0" android:valueFrom="100.1" android:valueTo="0" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + + <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="scaleX" android:duration="333" android:startOffset="0" android:valueFrom="0.798" android:valueTo="1" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="scaleY" android:duration="333" android:startOffset="0" android:valueFrom="0.798" android:valueTo="1" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + + <target android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="rotation" android:duration="333" android:startOffset="0" android:valueFrom="87.2" android:valueTo="0" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + + <target android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="scaleX" android:duration="333" android:startOffset="0" android:valueFrom="0.77" android:valueTo="1" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="scaleY" android:duration="333" android:startOffset="0" android:valueFrom="0.77" android:valueTo="1" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + + <target android:name="_R_G_L_0_G"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="rotation" android:duration="333" android:startOffset="0" android:valueFrom="90" android:valueTo="0" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateX" android:duration="517" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/> + </set> + </aapt:attr> + </target> +</animated-vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/rotate_suggestion.xml b/packages/SystemUI/res/layout/rotate_suggestion.xml new file mode 100644 index 000000000000..7762950b5a23 --- /dev/null +++ b/packages/SystemUI/res/layout/rotate_suggestion.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res-auto" + android:layout_width="@dimen/navigation_side_padding" + android:layout_height="match_parent" + android:layout_weight="0" + > + <com.android.systemui.statusbar.policy.KeyButtonView + android:id="@+id/rotate_suggestion" + android:layout_width="@dimen/navigation_extra_key_width" + android:layout_height="match_parent" + android:layout_marginEnd="2dp" + android:visibility="invisible" + android:scaleType="centerInside" + /> + <!-- TODO android:contentDescription --> +</FrameLayout> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index a83e6591c48b..78ee04048644 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -89,6 +89,10 @@ public class ButtonDispatcher { return mAlpha != null ? mAlpha : 1; } + public KeyButtonDrawable getImageDrawable() { + return mImageDrawable; + } + public void setImageDrawable(KeyButtonDrawable drawable) { mImageDrawable = drawable; final int N = mViews.size(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 695168e3dbc2..70ec45e4cdb4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -24,6 +24,10 @@ import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE; import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions; import android.accessibilityservice.AccessibilityServiceInfo; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerNative; @@ -39,6 +43,7 @@ import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.graphics.drawable.AnimatedVectorDrawable; import android.inputmethodservice.InputMethodService; import android.os.Binder; import android.os.Bundle; @@ -70,17 +75,22 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; import com.android.systemui.Dependency; import com.android.systemui.OverviewProxyService; +import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.AssistManager; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.recents.Recents; +import com.android.systemui.recents.misc.SysUiTaskStackChangeListener; +import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; +import com.android.systemui.statusbar.policy.KeyButtonDrawable; import com.android.systemui.statusbar.policy.KeyButtonView; +import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.stack.StackStateAnimator; import java.io.FileDescriptor; @@ -101,6 +111,8 @@ public class NavigationBarFragment extends Fragment implements Callbacks { /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; + private static final int ROTATE_SUGGESTION_TIMEOUT_MS = 4000; + protected NavigationBarView mNavigationBarView = null; protected AssistManager mAssistManager; @@ -130,6 +142,15 @@ public class NavigationBarFragment extends Fragment implements Callbacks { public boolean mHomeBlockedThisTouch; + private int mLastRotationSuggestion; + private RotationLockController mRotationLockController; + private TaskStackListenerImpl mTaskStackListener; + + private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false); + private Animator mRotateShowAnimator; + private Animator mRotateHideAnimator; + + // ----- Fragment Lifecycle Callbacks ----- @Override @@ -163,6 +184,12 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + + mRotationLockController = Dependency.get(RotationLockController.class); + + // Register the task stack listener + mTaskStackListener = new TaskStackListenerImpl(); + ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); } @Override @@ -178,6 +205,9 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + + // Unregister the task stack listener + ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener); } @Override @@ -304,6 +334,92 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } } + @Override + public void onRotationProposal(final int rotation) { + // This method will only be called if rotation is valid but will include proposals for the + // current system rotation + Handler h = getView().getHandler(); + if (rotation == mWindowManager.getDefaultDisplay().getRotation()) { + // Use this as a signal to remove any current suggestions + h.removeCallbacks(mRemoveRotationProposal); + setRotateSuggestionButtonState(false); + } else { + mLastRotationSuggestion = rotation; // Remember rotation for click + setRotateSuggestionButtonState(true); + h.removeCallbacks(mRemoveRotationProposal); // Stop any pending removal + h.postDelayed(mRemoveRotationProposal, + ROTATE_SUGGESTION_TIMEOUT_MS); // Schedule timeout + } + } + + public void setRotateSuggestionButtonState(final boolean visible) { + setRotateSuggestionButtonState(visible, false); + } + + public void setRotateSuggestionButtonState(final boolean visible, final boolean skipAnim) { + ButtonDispatcher rotBtn = mNavigationBarView.getRotateSuggestionButton(); + boolean currentlyVisible = rotBtn.getVisibility() == View.VISIBLE; + + // Rerun a show animation to indicate change but don't rerun a hide animation + if (!visible && !currentlyVisible) return; + + View currentView = mNavigationBarView.getRotateSuggestionButton().getCurrentView(); + if (currentView == null) return; + + KeyButtonDrawable kbd = mNavigationBarView.getRotateSuggestionButton().getImageDrawable(); + if (kbd == null) return; + + AnimatedVectorDrawable animIcon = (AnimatedVectorDrawable) kbd.getDrawable(0); + if (visible) { // Appear and change + rotBtn.setVisibility(View.VISIBLE); + + if (skipAnim) { + currentView.setAlpha(1f); + return; + } + + // Start a new animation if running + if (mRotateShowAnimator != null) mRotateShowAnimator.pause(); + if (mRotateHideAnimator != null) mRotateHideAnimator.pause(); + + ObjectAnimator appearFade = ObjectAnimator.ofFloat(currentView, "alpha", + 0f, 1f); + appearFade.setDuration(100); + appearFade.setInterpolator(Interpolators.LINEAR); + mRotateShowAnimator = appearFade; + appearFade.start(); + + // Run the rotate icon's animation + animIcon.reset(); + animIcon.start(); + } else { // Hide + + if (skipAnim) { + rotBtn.setVisibility(View.INVISIBLE); + return; + } + + // Don't start any new hide animations if one is running + if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return; + // Pause any active show animations but don't reset the AVD to avoid jumps + if (mRotateShowAnimator != null) mRotateShowAnimator.pause(); + + ObjectAnimator fadeOut = ObjectAnimator.ofFloat(currentView, "alpha", + 0f); + fadeOut.setDuration(100); + fadeOut.setInterpolator(Interpolators.LINEAR); + fadeOut.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + rotBtn.setVisibility(View.INVISIBLE); + } + }); + + mRotateHideAnimator = fadeOut; + fadeOut.start(); + } + } + // Injected from StatusBar at creation. public void setCurrentSysuiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; @@ -406,6 +522,9 @@ public class NavigationBarFragment extends Fragment implements Callbacks { accessibilityButton.setOnClickListener(this::onAccessibilityClick); accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick); updateAccessibilityServicesState(mAccessibilityManager); + + ButtonDispatcher rotateSuggestionButton = mNavigationBarView.getRotateSuggestionButton(); + rotateSuggestionButton.setOnClickListener(this::onRotateSuggestionClick); } private boolean onHomeTouch(View v, MotionEvent event) { @@ -598,6 +717,10 @@ public class NavigationBarFragment extends Fragment implements Callbacks { mNavigationBarView.setAccessibilityButtonState(showAccessibilityButton, targetSelection); } + private void onRotateSuggestionClick(View v) { + mRotationLockController.setRotationLockedAtAngle(true, mLastRotationSuggestion); + } + // ----- Methods that StatusBar talks to (should be minimized) ----- public void setLightBarController(LightBarController lightBarController) { @@ -646,6 +769,13 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private final Stub mRotationWatcher = new Stub() { @Override public void onRotationChanged(int rotation) throws RemoteException { + // If the screen rotation changes while locked, update lock rotation to flow with + // new screen rotation and hide any showing suggestions. + if (mRotationLockController.isRotationLocked()) { + mRotationLockController.setRotationLockedAtAngle(true, rotation); + setRotateSuggestionButtonState(false, true); + } + // We need this to be scheduled as early as possible to beat the redrawing of // window in response to the orientation change. Handler h = getView().getHandler(); @@ -671,6 +801,31 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } }; + class TaskStackListenerImpl extends SysUiTaskStackChangeListener { + // Invalidate any rotation suggestion on task change or activity orientation change + // Note: all callbacks happen on main thread + + @Override + public void onTaskStackChanged() { + setRotateSuggestionButtonState(false); + } + + @Override + public void onTaskRemoved(int taskId) { + setRotateSuggestionButtonState(false); + } + + @Override + public void onTaskMovedToFront(int taskId) { + setRotateSuggestionButtonState(false); + } + + @Override + public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { + setRotateSuggestionButtonState(false); + } + } + public static View create(Context context, FragmentListener listener) { WindowManager.LayoutParams lp = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 4e79314bb818..b8b309b38b27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -63,6 +63,7 @@ public class NavigationBarInflaterView extends FrameLayout public static final String RECENT = "recent"; public static final String NAVSPACE = "space"; public static final String CLIPBOARD = "clipboard"; + public static final String ROTATE = "rotate"; public static final String KEY = "key"; public static final String LEFT = "left"; public static final String RIGHT = "right"; @@ -311,7 +312,7 @@ public class NavigationBarInflaterView extends FrameLayout View v = null; String button = extractButton(buttonSpec); if (LEFT.equals(button)) { - String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE); + String s = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, ROTATE); button = extractButton(s); } else if (RIGHT.equals(button)) { String s = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME); @@ -334,6 +335,8 @@ public class NavigationBarInflaterView extends FrameLayout v = inflater.inflate(R.layout.nav_key_space, parent, false); } else if (CLIPBOARD.equals(button)) { v = inflater.inflate(R.layout.clipboard, parent, false); + } else if (ROTATE.equals(button)) { + v = inflater.inflate(R.layout.rotate_suggestion, parent, false); } else if (button.startsWith(KEY)) { String uri = extractImage(button); int code = extractKeycode(button); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 392581de8607..006a85b7ef8c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -31,6 +31,7 @@ import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.os.RemoteException; +import android.support.annotation.ColorInt; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; @@ -56,6 +57,7 @@ import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.statusbar.phone.NavGesture; import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; import com.android.systemui.stackdivider.Divider; +import com.android.systemui.statusbar.policy.TintedKeyButtonDrawable; import com.android.systemui.statusbar.policy.DeadZone; import com.android.systemui.statusbar.policy.KeyButtonDrawable; @@ -94,6 +96,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private KeyButtonDrawable mImeIcon; private KeyButtonDrawable mMenuIcon; private KeyButtonDrawable mAccessibilityIcon; + private KeyButtonDrawable mRotateSuggestionIcon; private GestureHelper mGestureHelper; private DeadZone mDeadZone; @@ -229,6 +232,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mButtonDispatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher)); mButtonDispatchers.put(R.id.accessibility_button, new ButtonDispatcher(R.id.accessibility_button)); + mButtonDispatchers.put(R.id.rotate_suggestion, + new ButtonDispatcher(R.id.rotate_suggestion)); + mOverviewProxyService = Dependency.get(OverviewProxyService.class); } @@ -305,6 +311,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mButtonDispatchers.get(R.id.accessibility_button); } + public ButtonDispatcher getRotateSuggestionButton() { + return mButtonDispatchers.get(R.id.rotate_suggestion); + } + public SparseArray<ButtonDispatcher> getButtonDispatchers() { return mButtonDispatchers; } @@ -349,6 +359,11 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mImeIcon = getDrawable(darkContext, lightContext, R.drawable.ic_ime_switcher_default, R.drawable.ic_ime_switcher_default); + int lightColor = Utils.getColorAttr(lightContext, R.attr.singleToneColor); + int darkColor = Utils.getColorAttr(darkContext, R.attr.singleToneColor); + mRotateSuggestionIcon = getDrawable(ctx, R.drawable.ic_sysbar_rotate_button, + lightColor, darkColor); + if (ALTERNATE_CAR_MODE_UI) { updateCarModeIcons(ctx); } @@ -366,6 +381,11 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav darkContext.getDrawable(darkIcon)); } + private KeyButtonDrawable getDrawable(Context ctx, @DrawableRes int icon, + @ColorInt int lightColor, @ColorInt int darkColor) { + return TintedKeyButtonDrawable.create(ctx.getDrawable(icon), lightColor, darkColor); + } + @Override public void setLayoutDirection(int layoutDirection) { // Reload all the icons @@ -439,6 +459,8 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav setAccessibilityButtonState(mShowAccessibilityButton, mLongClickableAccessibilityButton); getAccessibilityButton().setImageDrawable(mAccessibilityIcon); + getRotateSuggestionButton().setImageDrawable(mRotateSuggestionIcon); + setDisabledFlags(mDisabledFlags, true); mBarTransitions.reapplyDarkIntensity(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java index 21a96e2ea06a..cce9d1cd6d95 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java @@ -39,7 +39,7 @@ public class KeyButtonDrawable extends LayerDrawable { } } - private KeyButtonDrawable(Drawable[] drawables) { + protected KeyButtonDrawable(Drawable[] drawables) { super(drawables); for (int i = 0; i < drawables.length; i++) { setLayerGravity(i, Gravity.CENTER); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java new file mode 100644 index 000000000000..acf9c00a111c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018 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.statusbar.policy; + +import android.annotation.ColorInt; +import android.graphics.drawable.Drawable; + +import com.android.internal.graphics.ColorUtils; + +/** + * Drawable for {@link KeyButtonView}s which contains a single asset and colors for light and dark + * navigation bar mode. + */ +public class TintedKeyButtonDrawable extends KeyButtonDrawable { + + private final int mLightColor; + private final int mDarkColor; + + public static TintedKeyButtonDrawable create(Drawable drawable, @ColorInt int lightColor, + @ColorInt int darkColor) { + return new TintedKeyButtonDrawable(new Drawable[] { drawable }, lightColor, darkColor); + } + + private TintedKeyButtonDrawable(Drawable[] drawables, int lightColor, int darkColor){ + super(drawables); + mLightColor = lightColor; + mDarkColor = darkColor; + } + + @Override + public void setDarkIntensity(float intensity) { + // Duplicate intensity scaling from KeyButtonDrawable + int intermediateColor = ColorUtils.compositeColors( + setAlphaFloat(mDarkColor, intensity), + setAlphaFloat(mLightColor,1f - intensity)); + getDrawable(0).setTint(intermediateColor); + invalidateSelf(); + } + + private int setAlphaFloat(int color, float alpha) { + return ColorUtils.setAlphaComponent(color, (int) (alpha * 255f)); + } +} |