From 66b9fb1662b304d24984af1ac4cc02f2ae8f4cc3 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Wed, 5 Sep 2012 16:23:58 -0700 Subject: [PATCH] Iintial stab at multi-user switcher on Keyguard Change-Id: I604a769ef43c354a8eeadb415e413c19ca02571d --- .../res/layout/keyguard_multi_user_avatar.xml | 40 +++++++++ .../layout/keyguard_multi_user_selector.xml | 41 +++++++++ .../keyguard_multi_user_selector_widget.xml | 28 ++++++ .../res/res/layout/keyguard_selector_view.xml | 2 +- core/res/res/values/public.xml | 6 ++ .../impl/keyguard/KeyguardHostView.java | 24 ++++- .../keyguard/KeyguardMultiUserAvatar.java | 89 +++++++++++++++++++ .../KeyguardMultiUserSelectorView.java | 84 +++++++++++++++++ .../impl/keyguard/KeyguardWidgetFrame.java | 20 +++-- .../impl/keyguard/KeyguardWidgetPager.java | 3 + 10 files changed, 326 insertions(+), 11 deletions(-) create mode 100644 core/res/res/layout/keyguard_multi_user_avatar.xml create mode 100644 core/res/res/layout/keyguard_multi_user_selector.xml create mode 100644 core/res/res/layout/keyguard_multi_user_selector_widget.xml create mode 100644 policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java create mode 100644 policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java diff --git a/core/res/res/layout/keyguard_multi_user_avatar.xml b/core/res/res/layout/keyguard_multi_user_avatar.xml new file mode 100644 index 0000000000000..9999177094013 --- /dev/null +++ b/core/res/res/layout/keyguard_multi_user_avatar.xml @@ -0,0 +1,40 @@ + + + + + + + + \ No newline at end of file diff --git a/core/res/res/layout/keyguard_multi_user_selector.xml b/core/res/res/layout/keyguard_multi_user_selector.xml new file mode 100644 index 0000000000000..3ed91038f833e --- /dev/null +++ b/core/res/res/layout/keyguard_multi_user_selector.xml @@ -0,0 +1,41 @@ + + + + + + + + + + \ No newline at end of file diff --git a/core/res/res/layout/keyguard_multi_user_selector_widget.xml b/core/res/res/layout/keyguard_multi_user_selector_widget.xml new file mode 100644 index 0000000000000..c00089cf1478d --- /dev/null +++ b/core/res/res/layout/keyguard_multi_user_selector_widget.xml @@ -0,0 +1,28 @@ + + + + + + + + + \ No newline at end of file diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml index d5163696686fa..d7f98f97b9fb3 100644 --- a/core/res/res/layout/keyguard_selector_view.xml +++ b/core/res/res/layout/keyguard_selector_view.xml @@ -32,7 +32,7 @@ android:layout_height="0dip" android:layout_weight="1" android:visibility="gone"> - + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 307fc81693111..2e639a1f6ecda 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1139,6 +1139,8 @@ + + @@ -1338,6 +1340,10 @@ + + + + diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index 058bf922e3ef7..7e148b3f92d65 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -29,26 +29,30 @@ import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.SharedPreferences; +import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Canvas; +import android.os.UserManager; import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.view.animation.AnimationUtils; import android.widget.Button; -import android.widget.ViewFlipper; import android.widget.RemoteViews.OnClickHandler; +import android.widget.ViewFlipper; +import com.android.internal.R; import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.internal.widget.LockPatternUtils; -import com.android.internal.R; import java.io.File; import java.util.ArrayList; +import java.util.List; public class KeyguardHostView extends KeyguardViewBase { // Use this to debug all of keyguard @@ -614,6 +618,7 @@ public class KeyguardHostView extends KeyguardViewBase { Log.v(TAG, "Keyguard widgets disabled because of device policy admin"); return; } + inflateAndAddUserSelectorWidgetIfNecessary(); SharedPreferences prefs = mContext.getSharedPreferences( KEYGUARD_WIDGET_PREFS, Context.MODE_PRIVATE); for (String key : prefs.getAll().keySet()) { @@ -627,6 +632,21 @@ public class KeyguardHostView extends KeyguardViewBase { } } + private void inflateAndAddUserSelectorWidgetIfNecessary() { + // if there are multiple users, we need to add the multi-user switcher widget to the + // keyguard. + UserManager mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + List users = mUm.getUsers(); + + if (users.size() > 1) { + KeyguardWidgetFrame userswitcher = (KeyguardWidgetFrame) + LayoutInflater.from(mContext).inflate(R.layout.keyguard_multi_user_selector_widget, + mAppWidgetContainer, false); + // add the switcher in the first position + mAppWidgetContainer.addView(userswitcher, 0); + } + } + @Override public void cleanUp() { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java new file mode 100644 index 0000000000000..8aef68f1e26c4 --- /dev/null +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 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.internal.policy.impl.keyguard; + +import android.app.ActivityManagerNative; +import android.content.Context; +import android.content.pm.UserInfo; +import android.graphics.drawable.Drawable; +import android.os.RemoteException; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManagerGlobal; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.internal.R; + +class KeyguardMultiUserAvatar extends FrameLayout { + private static final String TAG = "KeyguardViewHost"; + + private ImageView mUserImage; + private TextView mUserName; + private UserInfo mUserInfo; + private KeyguardMultiUserSelectorView mUserSelector; + + public static KeyguardMultiUserAvatar fromXml(int resId, Context context, + KeyguardMultiUserSelectorView userSelector, UserInfo info) { + KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar) + LayoutInflater.from(context).inflate(resId, userSelector, false); + + icon.setup(info, userSelector); + return icon; + } + + public KeyguardMultiUserAvatar(Context context) { + super(context, null, 0); + } + + public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) { + super(context, attrs, 0); + } + + public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setup(UserInfo user, KeyguardMultiUserSelectorView userSelector) { + mUserInfo = user; + mUserSelector = userSelector; + init(); + } + + private void init() { + mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar); + mUserName = (TextView) findViewById(R.id.keyguard_user_name); + + mUserImage.setImageDrawable(Drawable.createFromPath(mUserInfo.iconPath)); + mUserName.setText(mUserInfo.name); + setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + try { + ActivityManagerNative.getDefault().switchUser(mUserInfo.id); + WindowManagerGlobal.getWindowManagerService().lockNow(); + mUserSelector.init(); + } catch (RemoteException re) { + Log.e(TAG, "Couldn't switch user " + re); + } + } + }); + } +} diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java new file mode 100644 index 0000000000000..ba99a559b7c3f --- /dev/null +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 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.internal.policy.impl.keyguard; + +import android.app.ActivityManagerNative; +import android.content.Context; +import android.content.pm.UserInfo; +import android.os.RemoteException; +import android.os.UserManager; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import com.android.internal.R; + +import java.util.ArrayList; + +public class KeyguardMultiUserSelectorView extends LinearLayout{ + private KeyguardMultiUserAvatar mActiveUser; + private LinearLayout mInactiveUsers; + + public KeyguardMultiUserSelectorView(Context context) { + this(context, null, 0); + } + + public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + protected void onFinishInflate () { + init(); + } + + public void init() { + mActiveUser = (KeyguardMultiUserAvatar) findViewById(R.id.keyguard_active_user); + mInactiveUsers = (LinearLayout) findViewById(R.id.keyguard_inactive_users); + + mInactiveUsers.removeAllViews(); + + UserInfo currentUser; + try { + currentUser = ActivityManagerNative.getDefault().getCurrentUser(); + } catch (RemoteException re) { + currentUser = null; + } + + UserManager mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + ArrayList users = new ArrayList(mUm.getUsers()); + for (UserInfo user: users) { + if (user.id == currentUser.id) { + setActiveUser(user); + } else { + createAndAddInactiveUser(user); + } + } + } + + private void setActiveUser(UserInfo user) { + mActiveUser.setup(user, this); + } + + private void createAndAddInactiveUser(UserInfo user) { + KeyguardMultiUserAvatar uv = KeyguardMultiUserAvatar.fromXml( + R.layout.keyguard_multi_user_avatar, mContext, this, user); + mInactiveUsers.addView(uv); + } +} diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index e8078fd8906cd..f9577530fc3d0 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -38,6 +38,7 @@ public class KeyguardWidgetFrame extends FrameLayout { private static Drawable sRightOverscrollDrawable; private Drawable mForegroundDrawable; + private float mOverScrollAmount = 0f; private final Rect mForegroundRect = new Rect(); private int mForegroundAlpha = 0; @@ -80,14 +81,17 @@ public class KeyguardWidgetFrame extends FrameLayout { } void setOverScrollAmount(float r, boolean left) { - if (left && mForegroundDrawable != sLeftOverscrollDrawable) { - mForegroundDrawable = sLeftOverscrollDrawable; - } else if (!left && mForegroundDrawable != sRightOverscrollDrawable) { - mForegroundDrawable = sRightOverscrollDrawable; - } + if (Float.compare(mOverScrollAmount, r) != 0) { + mOverScrollAmount = r; + if (left && mForegroundDrawable != sLeftOverscrollDrawable) { + mForegroundDrawable = sLeftOverscrollDrawable; + } else if (!left && mForegroundDrawable != sRightOverscrollDrawable) { + mForegroundDrawable = sRightOverscrollDrawable; + } - mForegroundAlpha = (int) Math.round((r * 255)); - mForegroundDrawable.setAlpha(mForegroundAlpha); - invalidate(); + mForegroundAlpha = (int) Math.round((r * 255)); + mForegroundDrawable.setAlpha(mForegroundAlpha); + invalidate(); + } } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index 7d077e24888b4..fd9362af29154 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -146,6 +146,9 @@ public class KeyguardWidgetPager extends PagedView { v.setPivotY(pageHeight / 2.0f); v.setPivotX(pageWidth / 2.0f); v.setRotationY(0f); + if (v instanceof KeyguardWidgetFrame) { + ((KeyguardWidgetFrame) v).setOverScrollAmount(0, false); + } } }