Settings Drawer: Support multi-user changes

Change-Id: I3a6e481ca18794bf1ed3bc9dc0382deacfcf81f4
This commit is contained in:
Jason Monk
2015-11-04 13:16:18 -05:00
parent 4da79e088f
commit af00109242
9 changed files with 13 additions and 365 deletions

View File

@@ -1,47 +0,0 @@
<?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"
android:id="@android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="@dimen/user_spinner_item_height"
android:paddingStart="@dimen/user_spinner_padding_sides"
android:paddingEnd="@dimen/user_spinner_padding_sides"
android:orientation="horizontal" >
<ImageView
android:id="@+android:id/icon"
android:layout_width="@dimen/user_icon_view_height"
android:layout_height="@dimen/user_icon_view_height"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:paddingBottom="@dimen/user_spinner_padding"
android:paddingTop="@dimen/user_spinner_padding" />
<TextView
android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_gravity="center"
android:labelFor="@+android:id/icon"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:paddingStart="@dimen/user_spinner_padding"
android:paddingEnd="@dimen/user_spinner_padding"
style="@style/TextAppearance.Medium" />
</LinearLayout>

View File

@@ -193,11 +193,6 @@
<!-- Height of a user icon view -->
<dimen name="user_icon_view_height">56dp</dimen>
<!-- User spinner -->
<dimen name="user_spinner_height">72dp</dimen>
<dimen name="user_spinner_padding">4dp</dimen>
<dimen name="user_spinner_padding_sides">20dp</dimen>
<dimen name="user_spinner_item_height">56dp</dimen>
<!-- CheckBoxPreference -->
<dimen name="checkbox_widget_min_width">58dip</dimen>

View File

@@ -1959,10 +1959,6 @@
<!-- Account settings header. [CHAR LIMIT=30] -->
<string name="account_settings">Accounts</string>
<!-- Header for items under the personal user [CHAR LIMIT=30] -->
<string name="category_personal">Personal</string>
<!-- Header for items under the work user [CHAR LIMIT=30] -->
<string name="category_work">Work</string>
<!-- Content description for work profile accounts group [CHAR LIMIT=NONE] -->
<string name="accessibility_category_work">Work profile accounts - <xliff:g id="managed_by" example="Managed by Corporate application">%s</xliff:g></string>
<!-- Content description for personal profile accounts group [CHAR LIMIT=NONE] -->
@@ -6335,9 +6331,6 @@
<!-- [CHAR LIMIT=60] Unlock setting for screen pinning -->
<string name="screen_pinning_unlock_none">Lock device when unpinning</string>
<!-- TODO: Remove it once the same entry in SettingsLib is translated. -->
<!-- Title for a work profile. [CHAR LIMIT=25] -->
<string name="managed_user_title">Work profile</string>
<!-- Opening string on the dialog that prompts the user to confirm that they really want to delete their existing work profile. The administration app icon and name appear after the final colon. [CHAR LIMIT=NONE] -->
<string name="opening_paragraph_delete_profile_unknown_company">This work profile is managed by:</string>
<!-- Summary for work profile accounts group. [CHAR LIMIT=25] -->
@@ -6540,9 +6533,6 @@
<!-- Warning toast shown when data usage screen can't find specified app -->
<string name="unknown_app">Unknown app</string>
<!-- Title for profile selection dialog [CHAR LIMIT=30] -->
<string name="choose_profile">Choose Profile</string>
<!-- Label for list that shows all permissions -->
<string name="app_permissions">App permissions</string>
<!-- Summary of permissions currently granted to apps [CHAR LIMIT=45] -->

View File

@@ -1,68 +0,0 @@
/*
* Copyright (C) 2015 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.settings;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import com.android.settingslib.drawer.DashboardTile;
public class ProfileSelectDialog extends DialogFragment implements OnClickListener {
private static final String ARG_SELECTED_TILE = "selectedTile";
private DashboardTile mSelectedTile;
public static void show(FragmentManager manager, DashboardTile tile) {
ProfileSelectDialog dialog = new ProfileSelectDialog();
Bundle args = new Bundle();
args.putParcelable(ARG_SELECTED_TILE, tile);
dialog.setArguments(args);
dialog.show(manager, "select_profile");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSelectedTile = getArguments().getParcelable(ARG_SELECTED_TILE);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
UserAdapter adapter = Utils.createUserAdapter(UserManager.get(context), context,
mSelectedTile.userHandle);
builder.setTitle(R.string.choose_profile)
.setAdapter(adapter, this);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
UserHandle user = mSelectedTile.userHandle.get(which);
getActivity().startActivityAsUser(mSelectedTile.intent, user);
}
}

View File

@@ -1133,6 +1133,13 @@ public class SettingsActivity extends SettingsDrawerActivity
}
}
@Override
public void onProfileTileOpen() {
if (!mIsShowingDashboard) {
finish();
}
}
private void switchToSearchResultsFragmentIfNeeded() {
if (mSearchResultsFragment != null) {
return;

View File

@@ -1,176 +0,0 @@
/*
* 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.settings;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.UserInfo;
import android.database.DataSetObserver;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import com.android.internal.util.UserIcons;
import com.android.settingslib.drawable.CircleFramedDrawable;
import java.util.ArrayList;
/**
* Adapter for a spinner that shows a list of users.
*/
public class UserAdapter implements SpinnerAdapter, ListAdapter {
// TODO: Update UI. See: http://b/16518801
/** Holder for user details */
public static class UserDetails {
private final UserHandle mUserHandle;
private final String mName;
private final Drawable mIcon;
public UserDetails(UserHandle userHandle, UserManager um, Context context) {
mUserHandle = userHandle;
UserInfo userInfo = um.getUserInfo(mUserHandle.getIdentifier());
Drawable icon;
if (userInfo.isManagedProfile()) {
mName = context.getString(R.string.managed_user_title);
icon = context.getDrawable(
com.android.internal.R.drawable.ic_corp_icon);
} else {
mName = userInfo.name;
final int userId = userInfo.id;
if (um.getUserIcon(userId) != null) {
icon = new BitmapDrawable(context.getResources(), um.getUserIcon(userId));
} else {
icon = UserIcons.getDefaultUserIcon(userId, /* light= */ false);
}
}
this.mIcon = encircle(context, icon);
}
private static Drawable encircle(Context context, Drawable icon) {
return CircleFramedDrawable.getInstance(context, UserIcons.convertToBitmap(icon));
}
}
private ArrayList<UserDetails> data;
private final LayoutInflater mInflater;
public UserAdapter(Context context, ArrayList<UserDetails> users) {
if (users == null) {
throw new IllegalArgumentException("A list of user details must be provided");
}
this.data = users;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public UserHandle getUserHandle(int position) {
if (position < 0 || position >= data.size()) {
return null;
}
return data.get(position).mUserHandle;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
final View row = convertView != null ? convertView : createUser(parent);
UserDetails user = data.get(position);
((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(user.mIcon);
((TextView) row.findViewById(android.R.id.title)).setText(getTitle(user));
return row;
}
private int getTitle(UserDetails user) {
int userHandle = user.mUserHandle.getIdentifier();
if (userHandle == UserHandle.USER_CURRENT
|| userHandle == ActivityManager.getCurrentUser()) {
return R.string.category_personal;
} else {
return R.string.category_work;
}
}
private View createUser(ViewGroup parent) {
return mInflater.inflate(R.layout.user_preference, parent, false);
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
// We don't support observers
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// We don't support observers
}
@Override
public int getCount() {
return data.size();
}
@Override
public UserDetails getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return data.get(position).mUserHandle.getIdentifier();
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getDropDownView(position, convertView, parent);
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean isEmpty() {
return data.isEmpty();
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int position) {
return true;
}
}

View File

@@ -83,7 +83,8 @@ import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.TabWidget;
import com.android.internal.util.UserIcons;
import com.android.settings.UserAdapter.UserDetails;
import com.android.settingslib.drawer.UserAdapter;
import com.android.settingslib.drawer.UserAdapter.UserDetails;
import java.io.IOException;
import java.io.InputStream;
@@ -631,39 +632,6 @@ public final class Utils {
return currentUser.isManagedProfile();
}
/**
* Creates a {@link UserAdapter} if there is more than one profile on the device.
*
* <p> The adapter can be used to populate a spinner that switches between the Settings
* app on the different profiles.
*
* @return a {@link UserAdapter} or null if there is only one profile.
*/
public static UserAdapter createUserSpinnerAdapter(UserManager userManager,
Context context) {
List<UserHandle> userProfiles = userManager.getUserProfiles();
if (userProfiles.size() < 2) {
return null;
}
UserHandle myUserHandle = new UserHandle(UserHandle.myUserId());
// The first option should be the current profile
userProfiles.remove(myUserHandle);
userProfiles.add(0, myUserHandle);
return createUserAdapter(userManager, context, userProfiles);
}
public static UserAdapter createUserAdapter(UserManager userManager,
Context context, List<UserHandle> userProfiles) {
ArrayList<UserDetails> userDetails = new ArrayList<UserDetails>(userProfiles.size());
final int count = userProfiles.size();
for (int i = 0; i < count; i++) {
userDetails.add(new UserDetails(userProfiles.get(i), userManager, context));
}
return new UserAdapter(context, userDetails);
}
/**
* Returns the target user for a Settings activity.
*

View File

@@ -16,7 +16,6 @@
package com.android.settings.dashboard;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -24,10 +23,8 @@ import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.settings.ProfileSelectDialog;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.SettingsActivity;
import com.android.settingslib.drawer.DashboardTile;
public class DashboardTileView extends FrameLayout implements View.OnClickListener {
@@ -92,22 +89,6 @@ public class DashboardTileView extends FrameLayout implements View.OnClickListen
@Override
public void onClick(View v) {
clickTile(getContext(), mTile);
}
public static void clickTile(Context context, DashboardTile tile) {
if (tile.fragment != null) {
Utils.startWithFragment(context, tile.fragment, tile.fragmentArguments, null, 0,
0, tile.title);
} else if (tile.intent != null) {
int numUserHandles = tile.userHandle.size();
if (numUserHandles > 1) {
ProfileSelectDialog.show(((Activity) context).getFragmentManager(), tile);
} else if (numUserHandles == 1) {
context.startActivityAsUser(tile.intent, tile.userHandle.get(0));
} else {
context.startActivity(tile.intent);
}
}
((SettingsActivity) getContext()).openTile(mTile);
}
}

View File

@@ -56,17 +56,15 @@ import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import com.android.internal.content.PackageMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.UserAdapter;
import com.android.settings.Utils;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.drawer.UserAdapter;
import java.text.DateFormat;
import java.util.ArrayList;
@@ -191,7 +189,7 @@ public class PrintSettingsFragment extends SettingsPreferenceFragment
setEmptyView(emptyView);
final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
mProfileSpinnerAdapter = Utils.createUserSpinnerAdapter(um, getActivity());
mProfileSpinnerAdapter = UserAdapter.createUserSpinnerAdapter(um, getActivity());
if (mProfileSpinnerAdapter != null) {
mSpinner = (Spinner) setPinnedHeaderView(R.layout.spinner_view);
mSpinner.setAdapter(mProfileSpinnerAdapter);