summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI
diff options
context:
space:
mode:
authorDanesh M <daneshm90@gmail.com>2015-01-18 00:33:00 -0800
committerGerrit Code Review <gerrit@cyanogenmod.org>2015-11-05 17:30:47 -0800
commit197ae04ffdfea8e476336a450cc413f845ca10fc (patch)
tree53ffe2945c89303622f14bcac0a07cbac3dc2f02 /packages/SystemUI
parent4ba410a36b3db5d1b4dc45145371a14b45eb8edd (diff)
downloadframeworks_base-197ae04ffdfea8e476336a450cc413f845ca10fc.zip
frameworks_base-197ae04ffdfea8e476336a450cc413f845ca10fc.tar.gz
frameworks_base-197ae04ffdfea8e476336a450cc413f845ca10fc.tar.bz2
SystemUI: Lockscreen shortcut customization
Change-Id: I4abf1deed0a342e111453516fa7820191a55ffc4
Diffstat (limited to 'packages/SystemUI')
-rw-r--r--packages/SystemUI/Android.mk5
-rw-r--r--packages/SystemUI/AndroidManifest.xml5
-rw-r--r--packages/SystemUI/AndroidManifest_cm.xml39
-rw-r--r--packages/SystemUI/res/drawable/ic_lockscreen_shortcuts_blank.xml30
-rw-r--r--packages/SystemUI/res/drawable/lockscreen_shortcuts_phone_background.xml21
-rw-r--r--packages/SystemUI/res/drawable/lockscreen_target_background.xml20
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml2
-rw-r--r--packages/SystemUI/res/layout/lockscreen_shortcuts.xml65
-rw-r--r--packages/SystemUI/res/values-land/cm_dimens.xml21
-rw-r--r--packages/SystemUI/res/values/cm_dimens.xml6
-rw-r--r--packages/SystemUI/res/values/cm_strings.xml10
-rw-r--r--packages/SystemUI/src/com/android/systemui/cm/GlowBackground.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsActivity.java239
-rw-r--r--packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsHelper.java196
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java187
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java12
18 files changed, 954 insertions, 55 deletions
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 51b8af5..49fe595 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -7,9 +7,12 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) \
src/com/android/systemui/EventLogTags.logtags
LOCAL_STATIC_JAVA_LIBRARIES := Keyguard \
- org.cyanogenmod.platform.sdk
+ org.cyanogenmod.platform.sdk \
+ android-support-v7-palette \
+ android-support-v4
LOCAL_JAVA_LIBRARIES := telephony-common
+LOCAL_FULL_LIBS_MANIFEST_FILES := $(LOCAL_PATH)/AndroidManifest_cm.xml
LOCAL_PACKAGE_NAME := SystemUI
LOCAL_CERTIFICATE := platform
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 210e998..d7e222e 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -430,10 +430,5 @@
</intent-filter>
</receiver>
- <provider android:name=".cm.SpamMessageProvider"
- android:permission="android.permission.INTERACT_ACROSS_USERS_FULL"
- android:exported="true"
- android:authorities="com.cyanogenmod.spam" />
-
</application>
</manifest>
diff --git a/packages/SystemUI/AndroidManifest_cm.xml b/packages/SystemUI/AndroidManifest_cm.xml
new file mode 100644
index 0000000..a788da2
--- /dev/null
+++ b/packages/SystemUI/AndroidManifest_cm.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2015 The CyanogenMod 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.systemui">
+
+ <uses-permission android:name="cyanogenmod.permission.WRITE_SECURE_SETTINGS" />
+
+ <application>
+ <provider android:name=".cm.SpamMessageProvider"
+ android:permission="android.permission.INTERACT_ACROSS_USERS_FULL"
+ android:exported="true"
+ android:authorities="com.cyanogenmod.spam" />
+
+ <activity
+ android:name=".cm.LockscreenShortcutsActivity"
+ android:icon="@drawable/tuner"
+ android:label="@string/lockscreen_targets_message"
+ android:theme="@android:style/Theme.Material.Settings"
+ android:process=":cmsettings"
+ android:exported="true">
+ </activity>
+ </application>
+</manifest>
diff --git a/packages/SystemUI/res/drawable/ic_lockscreen_shortcuts_blank.xml b/packages/SystemUI/res/drawable/ic_lockscreen_shortcuts_blank.xml
new file mode 100644
index 0000000..1debdda
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_lockscreen_shortcuts_blank.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 The CyanogenMod 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="@dimen/keyguard_affordance_icon_width"
+ android:height="@dimen/keyguard_affordance_icon_height"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+
+ <path
+ android:fillColor="#666666"
+ android:pathData="M14 10h4V6h-4v4zm0 16h4v-4h-4v4zm0 16h4v-4h-4v4zm8-8h4v-4h-4v4zm0 8h4v-4h-4v4zM6
+42h4v-4H6v4zm0-8h4v-4H6v4zm0-8h4v-4H6v4zm0-8h4v-4H6v4zm0-8h4V6H6v4zm16
+16h4v-4h-4v4zm16 8h4v-4h-4v4zm0-8h4v-4h-4v4zm0 16h4v-4h-4v4zm0-24h4v-4h-4v4zm-16
+0h4v-4h-4v4zM38 6v4h4V6h-4zm-16 4h4V6h-4v4zm8
+32h4v-4h-4v4zm0-16h4v-4h-4v4zm0-16h4V6h-4v4z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_shortcuts_phone_background.xml b/packages/SystemUI/res/drawable/lockscreen_shortcuts_phone_background.xml
new file mode 100644
index 0000000..e3cae61
--- /dev/null
+++ b/packages/SystemUI/res/drawable/lockscreen_shortcuts_phone_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item>
+ <shape
+ android:shape="rectangle">
+ <solid
+ android:color="#333333" />
+ <size android:height="@dimen/phone_height" android:width="@dimen/phone_width" />
+ <corners android:bottomLeftRadius="15dp" android:bottomRightRadius="15dp" />
+ </shape>
+ </item>
+ <item android:bottom="@dimen/phone_bottom_padding" android:right="@dimen/phone_side_padding" android:left="@dimen/phone_side_padding">
+ <shape
+ android:shape="rectangle">
+ <solid
+ android:color="@android:color/black" />
+ </shape>
+ </item>
+</layer-list>
+
diff --git a/packages/SystemUI/res/drawable/lockscreen_target_background.xml b/packages/SystemUI/res/drawable/lockscreen_target_background.xml
new file mode 100644
index 0000000..d26da7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/lockscreen_target_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <!--
+ Copyright (C) 2014 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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#DDDDDD">
+</ripple>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 444f0f0..6c85a8f 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -47,7 +47,6 @@
android:layout_height="@dimen/keyguard_affordance_height"
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_gravity="bottom|end"
- android:tint="#ffffffff"
android:src="@drawable/ic_camera_alt_24dp"
android:scaleType="center"
android:contentDescription="@string/accessibility_camera_button" />
@@ -57,7 +56,6 @@
android:layout_height="@dimen/keyguard_affordance_height"
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_gravity="bottom|start"
- android:tint="#ffffffff"
android:src="@drawable/ic_phone_24dp"
android:scaleType="center"
android:contentDescription="@string/accessibility_phone_button" />
diff --git a/packages/SystemUI/res/layout/lockscreen_shortcuts.xml b/packages/SystemUI/res/layout/lockscreen_shortcuts.xml
new file mode 100644
index 0000000..1c99d96
--- /dev/null
+++ b/packages/SystemUI/res/layout/lockscreen_shortcuts.xml
@@ -0,0 +1,65 @@
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <ImageView
+ android:id="@+id/phone_button"
+ android:gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_centerHorizontal="true"
+ android:src="@drawable/lockscreen_shortcuts_phone_background" />
+
+ <TextView
+ android:textSize="15sp"
+ android:textColor="#424242"
+ android:gravity="center"
+ android:layout_below="@id/phone_button"
+ android:layout_alignStart="@id/phone_button"
+ android:layout_alignEnd="@id/phone_button"
+ android:text="@string/lockscreen_message"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent" />
+
+ <RelativeLayout
+ android:layout_alignEnd="@id/phone_button"
+ android:layout_alignStart="@id/phone_button"
+ android:layout_alignBottom="@id/phone_button"
+ android:layout_marginStart="@dimen/phone_side_padding"
+ android:layout_marginEnd="@dimen/phone_side_padding"
+ android:paddingBottom="@dimen/phone_bottom_padding"
+ android:clipChildren="false"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/phone_height">
+ <ImageView
+ android:layout_marginStart="@dimen/lockscreen_icon_side_padding"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentStart="true"
+ android:clickable="true"
+ android:scaleType="center"
+ android:id="@+id/left_button"
+ android:layout_width="@dimen/keyguard_affordance_width"
+ android:layout_height="@dimen/keyguard_affordance_height" />
+ <ImageView
+ android:id="@+id/middle_button"
+ android:tint="#666666"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentBottom="true"
+ android:scaleType="center"
+ android:src="@drawable/ic_lock_24dp"
+ android:layout_width="@dimen/keyguard_affordance_width"
+ android:layout_height="@dimen/keyguard_affordance_height" />
+ <ImageView
+ android:layout_marginEnd="@dimen/lockscreen_icon_side_padding"
+ android:id="@+id/right_button"
+ android:clickable="true"
+ android:scaleType="center"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_width="@dimen/keyguard_affordance_width"
+ android:layout_height="@dimen/keyguard_affordance_height" />
+ </RelativeLayout>
+</RelativeLayout>
diff --git a/packages/SystemUI/res/values-land/cm_dimens.xml b/packages/SystemUI/res/values-land/cm_dimens.xml
new file mode 100644
index 0000000..e996f02
--- /dev/null
+++ b/packages/SystemUI/res/values-land/cm_dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2015, The CyanogenMod 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.
+*/
+-->
+<resources>
+ <dimen name="phone_height">210dp</dimen>
+ <dimen name="phone_width">420dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values/cm_dimens.xml b/packages/SystemUI/res/values/cm_dimens.xml
index 8c3f91b..dfcdcb4 100644
--- a/packages/SystemUI/res/values/cm_dimens.xml
+++ b/packages/SystemUI/res/values/cm_dimens.xml
@@ -39,4 +39,10 @@
<!-- Padding end for weather text -->
<dimen name="status_bar_weather_padding_end">16dp</dimen>
+ <dimen name="lockscreen_icon_side_padding">10dp</dimen>
+ <dimen name="lockscreen_icon_size">35dp</dimen>
+ <dimen name="phone_side_padding">10dp</dimen>
+ <dimen name="phone_bottom_padding">40dp</dimen>
+ <dimen name="phone_width">320dp</dimen>
+ <dimen name="phone_height">420dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/cm_strings.xml b/packages/SystemUI/res/values/cm_strings.xml
index 4bebac3..3024ec9 100644
--- a/packages/SystemUI/res/values/cm_strings.xml
+++ b/packages/SystemUI/res/values/cm_strings.xml
@@ -30,4 +30,14 @@
<!-- Content description of the superuser tile -->
<string name="accessibility_su_active">Superuser session active</string>
+
+ <!-- Strings for lockscreen shortcut hints -->
+ <string name="left_shortcut_hint">Swipe right for %1$s</string>
+ <string name="right_shortcut_hint">Swipe left for %1$s</string>
+
+ <string name="lockscreen_message">Tap an icon on the left or right to reassign a lock screen shortcut.</string>
+ <string name="lockscreen_default_target">Default</string>
+ <string name="select_application">Select application</string>
+ <string name="lockscreen_choose_action_title">Choose action</string>
+ <string name="lockscreen_none_target">None</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/cm/GlowBackground.java b/packages/SystemUI/src/com/android/systemui/cm/GlowBackground.java
new file mode 100644
index 0000000..8b4bf06
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/cm/GlowBackground.java
@@ -0,0 +1,83 @@
+package com.android.systemui.cm;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.view.animation.AnticipateOvershootInterpolator;
+
+public class GlowBackground extends Drawable implements ValueAnimator.AnimatorUpdateListener {
+
+ private static final int MAX_CIRCLE_SIZE = 150;
+
+ private final Paint mPaint;
+ private Animator mAnimator;
+ private float mCircleSize;
+
+ public GlowBackground(int color) {
+ mPaint = new Paint();
+ mPaint.setColor(color);
+ }
+
+ private void startAnimation(boolean hide) {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ if (hide && mCircleSize == 0f) {
+ return;
+ } else if (!hide && mCircleSize == MAX_CIRCLE_SIZE) {
+ return;
+ }
+ mAnimator = getAnimator(hide);
+ mAnimator.start();
+ }
+
+ private Animator getAnimator(boolean hide) {
+ float start = mCircleSize;
+ float end = MAX_CIRCLE_SIZE;
+ if (hide) {
+ end = 0f;
+ }
+ ValueAnimator animator = ObjectAnimator.ofFloat(start, end);
+ animator.setInterpolator(new AnticipateOvershootInterpolator());
+ animator.setDuration(300);
+ animator.addUpdateListener(this);
+ return animator;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawCircle(getBounds().width() / 2, getBounds().height() / 2, mCircleSize, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int i) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return 0;
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ mCircleSize = (Float) valueAnimator.getAnimatedValue();
+ invalidateSelf();
+ }
+
+ public void hideGlow() {
+ startAnimation(true);
+ }
+
+ public void showGlow() {
+ startAnimation(false);
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsActivity.java b/packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsActivity.java
new file mode 100644
index 0000000..d8cfa5e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsActivity.java
@@ -0,0 +1,239 @@
+package com.android.systemui.cm;
+
+import com.android.settingslib.cm.ShortcutPickHelper;
+import com.android.systemui.R;
+import com.android.systemui.cm.LockscreenShortcutsHelper.Shortcuts;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+
+import java.util.ArrayList;
+
+public class LockscreenShortcutsActivity extends Activity implements View.OnClickListener,
+ ShortcutPickHelper.OnPickListener, View.OnTouchListener, LockscreenShortcutsHelper.OnChangeListener {
+
+ private static final int[] sIconIds = new int[]{R.id.left_button, R.id.right_button};
+ private static final String ACTION_APP = "action_app";
+
+ private ActionHolder mActions;
+ private ShortcutPickHelper mPicker;
+ private LockscreenShortcutsHelper mShortcutHelper;
+ private View mSelectedView;
+ private ColorMatrixColorFilter mFilter;
+ private ColorStateList mDefaultTintList;
+
+ @Override
+ public void shortcutPicked(String uri, String friendlyName, boolean isApplication) {
+ onTargetChange(uri);
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ GlowBackground background = (GlowBackground) v.getBackground();
+ background.showGlow();
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ background = (GlowBackground) v.getBackground();
+ background.hideGlow();
+ break;
+ }
+ return false;
+ }
+
+ @Override
+ public void onChange() {
+ updateDrawables();
+ }
+
+ private class ActionHolder {
+ private ArrayList<CharSequence> mAvailableEntries = new ArrayList<CharSequence>();
+ private ArrayList<String> mAvailableValues = new ArrayList<String>();
+
+ public void addAction(String action, int entryResId) {
+ mAvailableEntries.add(getString(entryResId));
+ mAvailableValues.add(action);
+ }
+
+ public int getActionIndex(String action) {
+ int count = mAvailableValues.size();
+ for (int i = 0; i < count; i++) {
+ if (TextUtils.equals(mAvailableValues.get(i), action)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public String getAction(int index) {
+ if (index > mAvailableValues.size()) {
+ return null;
+ }
+
+ return mAvailableValues.get(index);
+ }
+
+ public CharSequence[] getEntries() {
+ return mAvailableEntries.toArray(new CharSequence[mAvailableEntries.size()]);
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.lockscreen_shortcuts);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ mPicker = new ShortcutPickHelper(this, this);
+ mShortcutHelper = new LockscreenShortcutsHelper(this, this);
+ ColorMatrix cm = new ColorMatrix();
+ cm.setSaturation(0);
+ mFilter = new ColorMatrixColorFilter(cm);
+ ImageView unlockButton = (ImageView) findViewById(R.id.middle_button);
+ mDefaultTintList = unlockButton.getImageTintList();
+ createActionList();
+ initiateViews();
+ updateDrawables();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void initiateViews() {
+ int size = getResources().getDimensionPixelSize(R.dimen.lockscreen_icon_size);
+ for (int id : sIconIds) {
+ View v = findViewById(id);
+ v.setOnClickListener(this);
+ v.setOnTouchListener(this);
+ GlowBackground background = new GlowBackground(Color.WHITE);
+ background.setBounds(0, 0, size, size);
+ v.setBackground(background);
+ }
+ }
+
+ private void updateDrawables() {
+ for (int i = 0; i < sIconIds.length; i++) {
+ int id = sIconIds[i];
+ ImageView v = (ImageView) findViewById(id);
+ v.setImageTintList(null);
+ v.setColorFilter(null);
+ Shortcuts shortcut = Shortcuts.values()[i];
+ v.setTag(mShortcutHelper.getUriForTarget(shortcut));
+ Drawable drawable;
+ if (mShortcutHelper.isTargetEmpty(shortcut)) {
+ drawable = getResources().getDrawable(R.drawable.ic_lockscreen_shortcuts_blank);
+ } else {
+ drawable = mShortcutHelper.getDrawableForTarget(shortcut);
+ if (drawable == null) {
+ drawable = getResources().getDrawable(shortcut == Shortcuts.LEFT_SHORTCUT
+ ? R.drawable.ic_phone_24dp : R.drawable.ic_camera_alt_24dp);
+ v.setImageTintList(mDefaultTintList);
+ } else {
+ v.setColorFilter(mFilter);
+ }
+ }
+ v.setImageDrawable(drawable);
+ }
+ }
+
+ private void createActionList() {
+ mActions = new ActionHolder();
+ mActions.addAction(LockscreenShortcutsHelper.NONE, R.string.lockscreen_none_target);
+ mActions.addAction(LockscreenShortcutsHelper.DEFAULT, R.string.lockscreen_default_target);
+ mActions.addAction(ACTION_APP, R.string.select_application);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mPicker.onActivityResult(requestCode, resultCode, data);
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public void onClick(View v) {
+ mSelectedView = v;
+
+ final GlowBackground background = (GlowBackground) mSelectedView.getBackground();
+
+ mSelectedView.postOnAnimation(new Runnable() {
+ @Override
+ public void run() {
+ background.showGlow();
+ }
+ });
+
+ final DialogInterface.OnClickListener l = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int item) {
+ onTargetChange(mActions.getAction(item));
+ dialog.dismiss();
+ }
+ };
+
+ final DialogInterface.OnCancelListener cancel = new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ onTargetChange(null);
+ }
+ };
+
+ final AlertDialog dialog = new AlertDialog.Builder(this)
+ .setTitle(R.string.lockscreen_choose_action_title)
+ .setItems(mActions.getEntries(), l)
+ .setOnCancelListener(cancel)
+ .create();
+
+ dialog.show();
+ }
+
+ private void onTargetChange(String uri) {
+ if (uri == null) {
+ final GlowBackground background = (GlowBackground) mSelectedView.getBackground();
+ background.hideGlow();
+ return;
+ }
+
+ if (uri.equals(ACTION_APP)) {
+ mPicker.pickShortcut(null, null, 0);
+ } else {
+ mSelectedView.setTag(uri);
+ saveCustomActions();
+ GlowBackground background = (GlowBackground) mSelectedView.getBackground();
+ background.hideGlow();
+ }
+ }
+
+ private void saveCustomActions() {
+ ArrayList<String> targets = new ArrayList<String>();
+ for (int id : sIconIds) {
+ View v = findViewById(id);
+ String uri = (String) v.getTag();
+ targets.add(uri);
+ }
+ mShortcutHelper.saveTargets(targets);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsHelper.java b/packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsHelper.java
new file mode 100644
index 0000000..12b9810
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/cm/LockscreenShortcutsHelper.java
@@ -0,0 +1,196 @@
+package com.android.systemui.cm;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.ColorFilter;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.android.systemui.R;
+import cyanogenmod.providers.CMSettings;
+
+public class LockscreenShortcutsHelper {
+
+ private Handler mHandler;
+
+ public enum Shortcuts {
+ LEFT_SHORTCUT(0),
+ RIGHT_SHORTCUT(1);
+
+ private final int index;
+
+ Shortcuts(int index) {
+ this.index = index;
+ }
+ }
+
+ public static final String DEFAULT = "default";
+ public static final String NONE = "none";
+ private static final String DELIMITER = "|";
+
+ private final Context mContext;
+ private OnChangeListener mListener;
+ private List<String> mTargetActivities;
+
+ public interface OnChangeListener {
+ void onChange();
+ }
+
+ public LockscreenShortcutsHelper(Context context, OnChangeListener listener) {
+ mContext = context;
+ if (listener != null) {
+ mListener = listener;
+ mHandler = new Handler(Looper.getMainLooper());
+ mContext.getContentResolver().registerContentObserver(
+ CMSettings.Secure.getUriFor(CMSettings.Secure.LOCKSCREEN_TARGETS), false, mObserver);
+ }
+ fetchTargets();
+ }
+
+ private ContentObserver mObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ fetchTargets();
+ if (mListener != null && mHandler != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onChange();
+ }
+ });
+ }
+ }
+ };
+
+ public void cleanup() {
+ mContext.getContentResolver().unregisterContentObserver(mObserver);
+ mListener = null;
+ }
+
+ public static class TargetInfo {
+ public Drawable icon;
+ public ColorFilter colorFilter;
+ public String uri;
+ public TargetInfo(Drawable icon, ColorFilter colorFilter, String uri) {
+ this.icon = icon;
+ this.colorFilter = colorFilter;
+ this.uri = uri;
+ }
+ }
+
+ private void fetchTargets() {
+ mTargetActivities = CMSettings.Secure.getDelimitedStringAsList(mContext.getContentResolver(),
+ CMSettings.Secure.LOCKSCREEN_TARGETS, DELIMITER);
+ int itemsToPad = Shortcuts.values().length - mTargetActivities.size();
+ if (itemsToPad > 0) {
+ for (int i = 0; i < itemsToPad; i++) {
+ mTargetActivities.add(DEFAULT);
+ }
+ }
+ }
+
+ public Drawable getDrawableForTarget(Shortcuts shortcut) {
+ Intent intent = getIntent(shortcut);
+ if (intent != null) {
+ PackageManager pm = mContext.getPackageManager();
+ ActivityInfo info = intent.resolveActivityInfo(pm, PackageManager.GET_ACTIVITIES);
+ if (info != null) {
+ return getScaledDrawable(info.loadIcon(pm));
+ }
+ }
+ return null;
+ }
+
+ public String getUriForTarget(Shortcuts shortcuts) {
+ return mTargetActivities.get(shortcuts.index);
+ }
+
+ private Drawable getScaledDrawable(Drawable drawable) {
+ if (drawable instanceof BitmapDrawable) {
+ Resources res = mContext.getResources();
+ int width = res.getDimensionPixelSize(R.dimen.keyguard_affordance_icon_width);
+ int height = res.getDimensionPixelSize(R.dimen.keyguard_affordance_icon_height);
+ return new BitmapDrawable(mContext.getResources(),
+ Bitmap.createScaledBitmap(((BitmapDrawable) drawable).getBitmap(),
+ width, height, true));
+ } else {
+ return drawable;
+ }
+ }
+
+ private String getFriendlyActivityName(Intent intent, boolean labelOnly) {
+ PackageManager pm = mContext.getPackageManager();
+ ActivityInfo ai = intent.resolveActivityInfo(pm, PackageManager.GET_ACTIVITIES);
+ String friendlyName = null;
+ if (ai != null) {
+ friendlyName = ai.loadLabel(pm).toString();
+ if (friendlyName == null && !labelOnly) {
+ friendlyName = ai.name;
+ }
+ }
+ return friendlyName != null || labelOnly ? friendlyName : intent.toUri(0);
+ }
+
+ private String getFriendlyShortcutName(Intent intent) {
+ String activityName = getFriendlyActivityName(intent, true);
+ String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+
+ if (activityName != null && name != null) {
+ return activityName + ": " + name;
+ }
+ return name != null ? name : intent.toUri(0);
+ }
+
+ public String getFriendlyNameForUri(Shortcuts shortcut) {
+ Intent intent = getIntent(shortcut);
+ if (Intent.ACTION_MAIN.equals(intent.getAction())) {
+ return getFriendlyActivityName(intent, false);
+ }
+ return getFriendlyShortcutName(intent);
+ }
+
+ public boolean isTargetCustom(Shortcuts shortcut) {
+ if (mTargetActivities == null || mTargetActivities.isEmpty()) {
+ return false;
+ }
+ String action = mTargetActivities.get(shortcut.index);
+ if (DEFAULT.equals(action)) {
+ return false;
+ }
+
+ return NONE.equals(action) || getIntent(shortcut) != null;
+ }
+
+ public boolean isTargetEmpty(Shortcuts shortcut) {
+ return mTargetActivities != null &&
+ !mTargetActivities.isEmpty() &&
+ mTargetActivities.get(shortcut.index).equals(NONE);
+ }
+
+ public Intent getIntent(Shortcuts shortcut) {
+ Intent intent = null;
+ try {
+ intent = Intent.parseUri(mTargetActivities.get(shortcut.index), 0);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ return intent;
+ }
+
+ public void saveTargets(ArrayList<String> targets) {
+ CMSettings.Secure.putListAsDelimitedString(mContext.getContentResolver(),
+ CMSettings.Secure.LOCKSCREEN_TARGETS, DELIMITER, targets);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 8058933..26b9c8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -25,9 +25,13 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Color;
+import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.support.v7.graphics.Palette;
import android.util.AttributeSet;
import android.view.DisplayListCanvas;
import android.view.RenderNodeAnimator;
@@ -45,7 +49,7 @@ import com.android.systemui.statusbar.phone.PhoneStatusBar;
* An ImageView which does not have overlapping renderings commands and therefore does not need a
* layer when alpha is changed.
*/
-public class KeyguardAffordanceView extends ImageView {
+public class KeyguardAffordanceView extends ImageView implements Palette.PaletteAsyncListener {
private static final long CIRCLE_APPEAR_DURATION = 80;
private static final long CIRCLE_DISAPPEAR_MAX_DURATION = 200;
@@ -81,6 +85,7 @@ public class KeyguardAffordanceView extends ImageView {
private boolean mSupportHardware;
private boolean mFinishing;
private boolean mLaunchingAffordance;
+ private ColorFilter mDefaultFilter;
private CanvasProperty<Float> mHwCircleRadius;
private CanvasProperty<Float> mHwCenterX;
@@ -162,21 +167,66 @@ public class KeyguardAffordanceView extends ImageView {
canvas.restore();
}
+
+ @Override
+ public void setImageDrawable(Drawable drawable) {
+ super.setImageDrawable(drawable);
+ doPaletteIfNecessary();
+ }
+
+ private void doPaletteIfNecessary() {
+ if (mDefaultFilter != null && getDrawable() instanceof BitmapDrawable) {
+ Palette.generateAsync(((BitmapDrawable) getDrawable()).getBitmap(), this);
+ }
+ }
+
+
public void setPreviewView(View v) {
View oldPreviewView = mPreviewView;
mPreviewView = v;
if (mPreviewView != null) {
mPreviewView.setVisibility(mLaunchingAffordance
? oldPreviewView.getVisibility() : INVISIBLE);
+ mPreviewView.setVisibility(INVISIBLE);
+ addOverlay();
}
}
+ private void addOverlay() {
+ if (mPreviewView != null) {
+ mPreviewView.getOverlay().clear();
+ if (mDefaultFilter != null) {
+ ColorDrawable d = new ColorDrawable(mCircleColor);
+ d.setBounds(0, 0, mPreviewView.getWidth(), mPreviewView.getHeight());
+ mPreviewView.getOverlay().add(d);
+ }
+ }
+ }
+
+ public void setDefaultFilter(ColorFilter filter) {
+ mDefaultFilter = filter;
+ mCircleColor = Color.WHITE;
+ addOverlay();
+ updateIconColor();
+ }
+
private void updateIconColor() {
+ if (getDrawable() == null) {
+ return;
+ }
Drawable drawable = getDrawable().mutate();
float alpha = mCircleRadius / mMinBackgroundRadius;
alpha = Math.min(1.0f, alpha);
int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mInverseColor);
- drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+ if (mDefaultFilter != null) {
+ if (alpha == 0) {
+ drawable.setColorFilter(mDefaultFilter);
+ } else {
+ drawable.setColorFilter(color, PorterDuff.Mode.DST_IN);
+ }
+ } else {
+ drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+ }
}
private void drawBackgroundCircle(Canvas canvas) {
@@ -551,4 +601,10 @@ public class KeyguardAffordanceView extends ImageView {
public void setLaunchingAffordance(boolean launchingAffordance) {
mLaunchingAffordance = launchingAffordance;
}
+
+ @Override
+ public void onGenerated(Palette palette) {
+ mCircleColor = palette.getDarkVibrantColor(Color.WHITE);
+ addOverlay();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 63660a5..cde3733 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -29,6 +29,14 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.hardware.fingerprint.FingerprintManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
@@ -50,7 +58,6 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.TextView;
-
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.EmergencyButton;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -59,6 +66,8 @@ import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.cm.LockscreenShortcutsHelper;
+import com.android.systemui.cm.LockscreenShortcutsHelper.Shortcuts;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -74,7 +83,7 @@ import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityActi
* text.
*/
public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
- UnlockMethodCache.OnUnlockMethodChangedListener,
+ UnlockMethodCache.OnUnlockMethodChangedListener, LockscreenShortcutsHelper.OnChangeListener,
AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener {
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
@@ -113,6 +122,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardIndicationController mIndicationController;
private AccessibilityController mAccessibilityController;
private PhoneStatusBar mPhoneStatusBar;
+ private LockscreenShortcutsHelper mShortcutHelper;
+ private final ColorMatrixColorFilter mGrayScaleFilter;
private final Interpolator mLinearOutSlowInInterpolator;
private boolean mUserSetupComplete;
@@ -131,7 +142,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
};
- private boolean mLeftIsVoiceAssist;
private AssistManager mAssistManager;
public KeyguardBottomAreaView(Context context) {
@@ -151,6 +161,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
super(context, attrs, defStyleAttr, defStyleRes);
mLinearOutSlowInInterpolator =
AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
+ ColorMatrix cm = new ColorMatrix();
+ cm.setSaturation(0);
+ mGrayScaleFilter = new ColorMatrixColorFilter(cm);
}
private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
@@ -161,12 +174,20 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
if (host == mLockIcon) {
label = getResources().getString(R.string.unlock_label);
} else if (host == mCameraImageView) {
- label = getResources().getString(R.string.camera_label);
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ label = mShortcutHelper.getFriendlyNameForUri(Shortcuts.RIGHT_SHORTCUT);
+ } else {
+ label = getResources().getString(R.string.camera_label);
+ }
} else if (host == mLeftAffordanceView) {
- if (mLeftIsVoiceAssist) {
- label = getResources().getString(R.string.voice_assist_label);
+ if (isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ label = mShortcutHelper.getFriendlyNameForUri(Shortcuts.LEFT_SHORTCUT);
} else {
- label = getResources().getString(R.string.phone_label);
+ if (isLeftVoiceAssist()) {
+ label = getResources().getString(R.string.voice_assist_label);
+ } else {
+ label = getResources().getString(R.string.phone_label);
+ }
}
}
info.addAction(new AccessibilityAction(ACTION_CLICK, label));
@@ -201,6 +222,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
+ mShortcutHelper = new LockscreenShortcutsHelper(mContext, this);
watchForCameraPolicyChanges();
updateCameraVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
@@ -210,12 +232,36 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
setClipChildren(false);
setClipToPadding(false);
mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
- inflateCameraPreview();
mLockIcon.setOnClickListener(this);
mLockIcon.setOnLongClickListener(this);
mCameraImageView.setOnClickListener(this);
mLeftAffordanceView.setOnClickListener(this);
initAccessibility();
+ updateCustomShortcuts();
+ }
+
+ private void updateCustomShortcuts() {
+ updateLeftAffordanceIcon();
+ updateRightAffordanceIcon();
+ inflateCameraPreview();
+ }
+
+ private void updateRightAffordanceIcon() {
+ Drawable drawable;
+ String contentDescription;
+ boolean shouldGrayScale = false;
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ drawable = mShortcutHelper.getDrawableForTarget(Shortcuts.RIGHT_SHORTCUT);
+ shouldGrayScale = true;
+ contentDescription = mShortcutHelper.getFriendlyNameForUri(Shortcuts.RIGHT_SHORTCUT);
+ } else {
+ drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
+ contentDescription = mContext.getString(R.string.accessibility_camera_button);
+ }
+ mCameraImageView.setImageDrawable(drawable);
+ mCameraImageView.setContentDescription(contentDescription);
+ mCameraImageView.setDefaultFilter(shouldGrayScale ? mGrayScaleFilter : null);
+ updateCameraVisibility();
}
private void initAccessibility() {
@@ -289,33 +335,45 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
// Things are not set up yet; reply hazy, ask again later
return;
}
- ResolveInfo resolved = resolveCameraIntent();
- boolean visible = !isCameraDisabledByDpm() && resolved != null
- && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
- && mUserSetupComplete;
+ boolean visible = mUserSetupComplete;
+ if (visible) {
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ visible = !mShortcutHelper.isTargetEmpty(Shortcuts.RIGHT_SHORTCUT);
+ } else {
+ ResolveInfo resolved = resolveCameraIntent();
+ visible = !isCameraDisabledByDpm() && resolved != null
+ && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance);
+ }
+ }
mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private void updateLeftAffordanceIcon() {
- mLeftIsVoiceAssist = canLaunchVoiceAssist();
- int drawableId;
- int contentDescription;
+ Drawable drawable;
+ String contentDescription;
+ boolean shouldGrayScale = false;
boolean visible = mUserSetupComplete;
- if (mLeftIsVoiceAssist) {
- drawableId = R.drawable.ic_mic_26dp;
- contentDescription = R.string.accessibility_voice_assist_button;
+ if (mShortcutHelper.isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ drawable = mShortcutHelper.getDrawableForTarget(Shortcuts.LEFT_SHORTCUT);
+ shouldGrayScale = true;
+ contentDescription = mShortcutHelper.getFriendlyNameForUri(Shortcuts.LEFT_SHORTCUT);
+ visible |= !mShortcutHelper.isTargetEmpty(Shortcuts.LEFT_SHORTCUT);
+ } else if (canLaunchVoiceAssist()) {
+ drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
+ contentDescription = mContext.getString(R.string.accessibility_voice_assist_button);
} else {
visible &= isPhoneVisible();
- drawableId = R.drawable.ic_phone_24dp;
- contentDescription = R.string.accessibility_phone_button;
+ drawable = mContext.getDrawable(R.drawable.ic_phone_24dp);
+ contentDescription = mContext.getString(R.string.accessibility_phone_button);
}
mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE);
- mLeftAffordanceView.setImageDrawable(mContext.getDrawable(drawableId));
- mLeftAffordanceView.setContentDescription(mContext.getString(contentDescription));
+ mLeftAffordanceView.setImageDrawable(drawable);
+ mLeftAffordanceView.setContentDescription(contentDescription);
+ mLeftAffordanceView.setDefaultFilter(shouldGrayScale ? mGrayScaleFilter : null);
}
public boolean isLeftVoiceAssist() {
- return mLeftIsVoiceAssist;
+ return !isTargetCustom(Shortcuts.LEFT_SHORTCUT) && canLaunchVoiceAssist();
}
private boolean isPhoneVisible() {
@@ -431,8 +489,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
public void launchCamera(String source) {
- final Intent intent = getCameraIntent();
- intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
+ final Intent intent;
+ if (!mShortcutHelper.isTargetCustom(LockscreenShortcutsHelper.Shortcuts.RIGHT_SHORTCUT)) {
+ intent = getCameraIntent();
+ } else {
+ intent = mShortcutHelper.getIntent(LockscreenShortcutsHelper.Shortcuts.RIGHT_SHORTCUT);
+ intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
+ }
boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
@@ -481,7 +544,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
public void launchLeftAffordance() {
- if (mLeftIsVoiceAssist) {
+ if (mShortcutHelper.isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ Intent intent = mShortcutHelper.getIntent(Shortcuts.LEFT_SHORTCUT);
+ mActivityStarter.startActivity(intent, false /* dismissShade */);
+ } else if (isLeftVoiceAssist()) {
launchVoiceAssist();
} else {
launchPhone();
@@ -505,6 +571,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private boolean canLaunchVoiceAssist() {
+ if (mAssistManager == null) {
+ return false;
+ }
return mAssistManager.canVoiceAssistBeLaunchedFromKeyguard();
}
@@ -568,10 +637,14 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private void inflateCameraPreview() {
- mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
- if (mCameraPreview != null) {
- mPreviewContainer.addView(mCameraPreview);
- mCameraPreview.setVisibility(View.INVISIBLE);
+ if (isTargetCustom(Shortcuts.RIGHT_SHORTCUT)) {
+ mPreviewContainer.removeView(mCameraPreview);
+ } else {
+ mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent());
+ if (mCameraPreview != null) {
+ mPreviewContainer.addView(mCameraPreview);
+ mCameraPreview.setVisibility(View.INVISIBLE);
+ }
}
}
@@ -580,7 +653,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
if (previewBefore != null) {
mPreviewContainer.removeView(previewBefore);
}
- if (mLeftIsVoiceAssist) {
+ if (isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ // Custom shortcuts don't support previews
+ return;
+ }
+ if (isLeftVoiceAssist()) {
mLeftPreview = mPreviewInflater.inflatePreviewFromService(
mAssistManager.getVoiceInteractorComponentName());
} else {
@@ -698,4 +775,52 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
}
}
+
+ private String getIndexHint(LockscreenShortcutsHelper.Shortcuts shortcut) {
+ if (mShortcutHelper.isTargetCustom(shortcut)) {
+ boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+ String label = mShortcutHelper.getFriendlyNameForUri(shortcut);
+ int resId = 0;
+ switch (shortcut) {
+ case LEFT_SHORTCUT:
+ resId = isRtl ? R.string.right_shortcut_hint : R.string.left_shortcut_hint;
+ break;
+ case RIGHT_SHORTCUT:
+ resId = isRtl ? R.string.left_shortcut_hint : R.string.right_shortcut_hint;
+ break;
+ }
+ return mContext.getString(resId, label);
+ } else {
+ return null;
+ }
+ }
+
+ public String getLeftHint() {
+ String label = getIndexHint(LockscreenShortcutsHelper.Shortcuts.LEFT_SHORTCUT);
+ if (label == null) {
+ if (isLeftVoiceAssist()) {
+ label = mContext.getString(R.string.voice_hint);
+ } else {
+ label = mContext.getString(R.string.phone_hint);
+ }
+ }
+ return label;
+ }
+
+ public String getRightHint() {
+ String label = getIndexHint(LockscreenShortcutsHelper.Shortcuts.RIGHT_SHORTCUT);
+ if (label == null) {
+ label = mContext.getString(R.string.camera_hint);
+ }
+ return label;
+ }
+
+ public boolean isTargetCustom(LockscreenShortcutsHelper.Shortcuts shortcut) {
+ return mShortcutHelper.isTargetCustom(shortcut);
+ }
+
+ @Override
+ public void onChange() {
+ updateCustomShortcuts();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 9c817fd..94677bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2075,13 +2075,9 @@ public class NotificationPanelView extends PanelView implements
});
rightIcon = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? !rightIcon : rightIcon;
if (rightIcon) {
- mStatusBar.onCameraHintStarted();
+ mStatusBar.onCameraHintStarted(mKeyguardBottomArea.getRightHint());
} else {
- if (mKeyguardBottomArea.isLeftVoiceAssist()) {
- mStatusBar.onVoiceAssistHintStarted();
- } else {
- mStatusBar.onPhoneHintStarted();
- }
+ mStatusBar.onLeftHintStarted(mKeyguardBottomArea.getLeftHint());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7bddfd0..e3a8925 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -4362,16 +4362,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
}
- public void onCameraHintStarted() {
- mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
+ public void onCameraHintStarted(String hint) {
+ mKeyguardIndicationController.showTransientIndication(hint);
}
- public void onVoiceAssistHintStarted() {
- mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
- }
-
- public void onPhoneHintStarted() {
- mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
+ public void onLeftHintStarted(String hint) {
+ mKeyguardIndicationController.showTransientIndication(hint);
}
public void onTrackingStopped(boolean expand) {