Loading packages/SystemUI/res/layout/user_switcher_host.xml 0 → 100644 +36 −0 Original line number Diff line number Diff line <?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 --> <!-- FrameLayout --> <com.android.systemui.settings.UserSwitcherHostView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#dd000000"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@*android:dimen/volume_panel_top" android:background="@*android:drawable/dialog_full_holo_dark"> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" tools:listitem="@layout/user_switcher_item"/> </FrameLayout> </com.android.systemui.settings.UserSwitcherHostView> No newline at end of file packages/SystemUI/res/layout/user_switcher_item.xml 0 → 100644 +40 −0 Original line number Diff line number Diff line <?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 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="64dp" android:orientation="horizontal" tools:context=".settings.UserSwitcherDialog"> <ImageView android:layout_width="64dp" android:layout_height="match_parent" android:id="@+id/user_picture" tools:src="@drawable/dessert_zombiegingerbread"/> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/user_name" android:textAppearance="?android:attr/textAppearanceLarge" android:padding="8dp" android:gravity="center_vertical" tools:text="Hiroshi Lockheimer" /> </LinearLayout> packages/SystemUI/src/com/android/systemui/settings/UserSwitcherHostView.java 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * 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 */ package com.android.systemui.settings; import com.android.systemui.R; 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.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManagerGlobal; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; /** * A quick and dirty view to show a user switcher. */ public class UserSwitcherHostView extends FrameLayout implements ListView.OnItemClickListener { private static final String TAG = "UserSwitcherDialog"; private ArrayList<UserInfo> mUserInfo = new ArrayList<UserInfo>(); private Adapter mAdapter = new Adapter(); private UserManager mUserManager; private Runnable mFinishRunnable; private ListView mListView; public UserSwitcherHostView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); if (isInEditMode()) { return; } mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); } public UserSwitcherHostView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.listViewStyle); } public UserSwitcherHostView(Context context) { this(context, null); } @Override protected void onFinishInflate() { super.onFinishInflate(); mListView = (ListView) findViewById(android.R.id.list); mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> l, View v, int position, long id) { int userId = mAdapter.getItem(position).id; try { WindowManagerGlobal.getWindowManagerService().lockNow(null); ActivityManagerNative.getDefault().switchUser(userId); finish(); } catch (RemoteException e) { Log.e(TAG, "Couldn't switch user.", e); } } private void finish() { if (mFinishRunnable != null) { mFinishRunnable.run(); } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { finish(); } return true; } @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); // A gross hack to get rid of the switcher when the shade is collapsed. if (visibility != VISIBLE) { finish(); } } public void setFinishRunnable(Runnable finishRunnable) { mFinishRunnable = finishRunnable; } public void refreshUsers() { mUserInfo.clear(); mUserInfo.addAll(mUserManager.getUsers(true)); mAdapter.notifyDataSetChanged(); } private class Adapter extends BaseAdapter { @Override public int getCount() { return mUserInfo.size(); } @Override public UserInfo getItem(int position) { return mUserInfo.get(position); } @Override public long getItemId(int position) { return getItem(position).serialNumber; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null || (!(convertView.getTag() instanceof ViewHolder))) { convertView = createView(parent); } ViewHolder h = (ViewHolder) convertView.getTag(); bindView(h, getItem(position)); return convertView; } private View createView(ViewGroup parent) { View v = LayoutInflater.from(getContext()).inflate( R.layout.user_switcher_item, parent, false); ViewHolder h = new ViewHolder(); h.name = (TextView) v.findViewById(R.id.user_name); h.picture = (ImageView) v.findViewById(R.id.user_picture); v.setTag(h); return v; } private void bindView(ViewHolder h, UserInfo item) { h.name.setText(item.name); h.picture.setImageBitmap(mUserManager.getUserIcon(item.id)); } class ViewHolder { TextView name; ImageView picture; } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +15 −0 Original line number Diff line number Diff line Loading @@ -2825,4 +2825,19 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { mExpandedVisible = true; mNotificationPanel.setExpandedFraction(1); } /** * @return a ViewGroup that spans the entire panel which contains the quick settings */ public ViewGroup getQuickSettingsOverlayParent() { if (mHasSettingsPanel) { if (mHasFlipSettings) { return mNotificationPanel; } else { return mSettingsPanel; } } else { return null; } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java +12 −13 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import android.widget.TextView; import com.android.internal.app.MediaRouteDialogPresenter; import com.android.systemui.R; import com.android.systemui.settings.UserSwitcherHostView; import com.android.systemui.statusbar.phone.QuickSettingsModel.ActivityState; import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState; import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState; Loading Loading @@ -310,30 +311,28 @@ class QuickSettings { collapsePanels(); } private void addUserTiles(ViewGroup parent, LayoutInflater inflater) { private void addUserTiles(final ViewGroup parent, final LayoutInflater inflater) { QuickSettingsTileView userTile = (QuickSettingsTileView) inflater.inflate(R.layout.quick_settings_tile, parent, false); userTile.setContent(R.layout.quick_settings_tile_user, inflater); userTile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { collapsePanels(); final UserManager um = UserManager.get(mContext); if (um.isUserSwitcherEnabled()) { // Since keyguard and systemui were merged into the same process to save // memory, they share the same Looper and graphics context. As a result, // there's no way to allow concurrent animation while keyguard inflates. // The workaround is to add a slight delay to allow the animation to finish. mHandler.postDelayed(new Runnable() { final ViewGroup switcherParent = getService().getQuickSettingsOverlayParent(); final UserSwitcherHostView switcher = (UserSwitcherHostView) inflater.inflate( R.layout.user_switcher_host, switcherParent, false); switcher.setFinishRunnable(new Runnable() { @Override public void run() { try { WindowManagerGlobal.getWindowManagerService().lockNow(null); } catch (RemoteException e) { Log.e(TAG, "Couldn't show user switcher", e); } switcherParent.removeView(switcher); } }, 400); // TODO: ideally this would be tied to the collapse of the panel }); switcher.refreshUsers(); switcherParent.addView(switcher); } else { collapsePanels(); Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent( mContext, v, ContactsContract.Profile.CONTENT_URI, ContactsContract.QuickContact.MODE_LARGE, null); Loading Loading
packages/SystemUI/res/layout/user_switcher_host.xml 0 → 100644 +36 −0 Original line number Diff line number Diff line <?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 --> <!-- FrameLayout --> <com.android.systemui.settings.UserSwitcherHostView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#dd000000"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@*android:dimen/volume_panel_top" android:background="@*android:drawable/dialog_full_holo_dark"> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" tools:listitem="@layout/user_switcher_item"/> </FrameLayout> </com.android.systemui.settings.UserSwitcherHostView> No newline at end of file
packages/SystemUI/res/layout/user_switcher_item.xml 0 → 100644 +40 −0 Original line number Diff line number Diff line <?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 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="64dp" android:orientation="horizontal" tools:context=".settings.UserSwitcherDialog"> <ImageView android:layout_width="64dp" android:layout_height="match_parent" android:id="@+id/user_picture" tools:src="@drawable/dessert_zombiegingerbread"/> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/user_name" android:textAppearance="?android:attr/textAppearanceLarge" android:padding="8dp" android:gravity="center_vertical" tools:text="Hiroshi Lockheimer" /> </LinearLayout>
packages/SystemUI/src/com/android/systemui/settings/UserSwitcherHostView.java 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * 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 */ package com.android.systemui.settings; import com.android.systemui.R; 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.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManagerGlobal; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import java.util.ArrayList; /** * A quick and dirty view to show a user switcher. */ public class UserSwitcherHostView extends FrameLayout implements ListView.OnItemClickListener { private static final String TAG = "UserSwitcherDialog"; private ArrayList<UserInfo> mUserInfo = new ArrayList<UserInfo>(); private Adapter mAdapter = new Adapter(); private UserManager mUserManager; private Runnable mFinishRunnable; private ListView mListView; public UserSwitcherHostView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); if (isInEditMode()) { return; } mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); } public UserSwitcherHostView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.listViewStyle); } public UserSwitcherHostView(Context context) { this(context, null); } @Override protected void onFinishInflate() { super.onFinishInflate(); mListView = (ListView) findViewById(android.R.id.list); mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> l, View v, int position, long id) { int userId = mAdapter.getItem(position).id; try { WindowManagerGlobal.getWindowManagerService().lockNow(null); ActivityManagerNative.getDefault().switchUser(userId); finish(); } catch (RemoteException e) { Log.e(TAG, "Couldn't switch user.", e); } } private void finish() { if (mFinishRunnable != null) { mFinishRunnable.run(); } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { finish(); } return true; } @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); // A gross hack to get rid of the switcher when the shade is collapsed. if (visibility != VISIBLE) { finish(); } } public void setFinishRunnable(Runnable finishRunnable) { mFinishRunnable = finishRunnable; } public void refreshUsers() { mUserInfo.clear(); mUserInfo.addAll(mUserManager.getUsers(true)); mAdapter.notifyDataSetChanged(); } private class Adapter extends BaseAdapter { @Override public int getCount() { return mUserInfo.size(); } @Override public UserInfo getItem(int position) { return mUserInfo.get(position); } @Override public long getItemId(int position) { return getItem(position).serialNumber; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null || (!(convertView.getTag() instanceof ViewHolder))) { convertView = createView(parent); } ViewHolder h = (ViewHolder) convertView.getTag(); bindView(h, getItem(position)); return convertView; } private View createView(ViewGroup parent) { View v = LayoutInflater.from(getContext()).inflate( R.layout.user_switcher_item, parent, false); ViewHolder h = new ViewHolder(); h.name = (TextView) v.findViewById(R.id.user_name); h.picture = (ImageView) v.findViewById(R.id.user_picture); v.setTag(h); return v; } private void bindView(ViewHolder h, UserInfo item) { h.name.setText(item.name); h.picture.setImageBitmap(mUserManager.getUserIcon(item.id)); } class ViewHolder { TextView name; ImageView picture; } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +15 −0 Original line number Diff line number Diff line Loading @@ -2825,4 +2825,19 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { mExpandedVisible = true; mNotificationPanel.setExpandedFraction(1); } /** * @return a ViewGroup that spans the entire panel which contains the quick settings */ public ViewGroup getQuickSettingsOverlayParent() { if (mHasSettingsPanel) { if (mHasFlipSettings) { return mNotificationPanel; } else { return mSettingsPanel; } } else { return null; } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java +12 −13 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import android.widget.TextView; import com.android.internal.app.MediaRouteDialogPresenter; import com.android.systemui.R; import com.android.systemui.settings.UserSwitcherHostView; import com.android.systemui.statusbar.phone.QuickSettingsModel.ActivityState; import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState; import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState; Loading Loading @@ -310,30 +311,28 @@ class QuickSettings { collapsePanels(); } private void addUserTiles(ViewGroup parent, LayoutInflater inflater) { private void addUserTiles(final ViewGroup parent, final LayoutInflater inflater) { QuickSettingsTileView userTile = (QuickSettingsTileView) inflater.inflate(R.layout.quick_settings_tile, parent, false); userTile.setContent(R.layout.quick_settings_tile_user, inflater); userTile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { collapsePanels(); final UserManager um = UserManager.get(mContext); if (um.isUserSwitcherEnabled()) { // Since keyguard and systemui were merged into the same process to save // memory, they share the same Looper and graphics context. As a result, // there's no way to allow concurrent animation while keyguard inflates. // The workaround is to add a slight delay to allow the animation to finish. mHandler.postDelayed(new Runnable() { final ViewGroup switcherParent = getService().getQuickSettingsOverlayParent(); final UserSwitcherHostView switcher = (UserSwitcherHostView) inflater.inflate( R.layout.user_switcher_host, switcherParent, false); switcher.setFinishRunnable(new Runnable() { @Override public void run() { try { WindowManagerGlobal.getWindowManagerService().lockNow(null); } catch (RemoteException e) { Log.e(TAG, "Couldn't show user switcher", e); } switcherParent.removeView(switcher); } }, 400); // TODO: ideally this would be tied to the collapse of the panel }); switcher.refreshUsers(); switcherParent.addView(switcher); } else { collapsePanels(); Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent( mContext, v, ContactsContract.Profile.CONTENT_URI, ContactsContract.QuickContact.MODE_LARGE, null); Loading