/*
* Copyright (C) 2012 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.
*/
package com.android.settings.profiles;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.NotificationGroup;
import android.app.Profile;
import android.app.ProfileManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import java.util.HashMap;
public class ProfilesSettings extends SettingsPreferenceFragment {
private static final String TAG = "ProfilesSettings";
private static final String TAB_PROFILES = "profiles";
private static final String TAB_APPGROUPS = "appgroups";
private static final String PROFILE_SERVICE = "profile";
private static final int MENU_RESET = Menu.FIRST;
private static final int MENU_ADD_PROFILE = Menu.FIRST + 1;
private static final int MENU_ADD_APPGROUP = Menu.FIRST + 2;
private final IntentFilter mFilter;
private final BroadcastReceiver mReceiver;
private static Menu mOptionsMenu;
private ProfileManager mProfileManager;
private ProfileEnabler mProfileEnabler;
private Switch mActionBarSwitch;
private static TabHost mTabHost;
ViewGroup mContainer;
TabManager mTabManager;
static Bundle mSavedState;
private static Activity mActivity;
public ProfilesSettings() {
mFilter = new IntentFilter();
mFilter.addAction(ProfileManager.PROFILES_STATE_CHANGED_ACTION);
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handleEvent(context, intent);
}
};
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mContainer = container;
mTabHost = (TabHost) inflater.inflate(R.layout.profile_tabs, container, false);
if (mTabHost != null) {
mProfileManager = (ProfileManager) getActivity().getSystemService(PROFILE_SERVICE);
mActivity = getActivity();
setupTabs();
// If we are resuming from a paused state, restore the last active tab
if (mSavedState != null) {
mTabHost.setCurrentTabByTag(mSavedState.getString("tab"));
}
setHasOptionsMenu(true);
}
return mTabHost;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// We don't call super.onActivityCreated() here, since it assumes we already set up
// Preference (probably in onCreate()), while ProfilesSettings exceptionally set it up in
// this method.
// On/off switch
Activity activity = getActivity();
//Switch
mActionBarSwitch = new Switch(activity);
if (activity instanceof PreferenceActivity) {
PreferenceActivity preferenceActivity = (PreferenceActivity) activity;
if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {
final int padding = activity.getResources().getDimensionPixelSize(
R.dimen.action_bar_switch_padding);
mActionBarSwitch.setPaddingRelative(0, 0, padding, 0);
activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM);
activity.getActionBar().setCustomView(mActionBarSwitch, new ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_VERTICAL | Gravity.END));
}
}
mProfileEnabler = new ProfileEnabler(activity, mActionBarSwitch);
// After confirming PreferenceScreen is available, we call super.
super.onActivityCreated(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
if (mProfileEnabler != null) {
mProfileEnabler.resume();
}
getActivity().registerReceiver(mReceiver, mFilter);
// If running on a phone, remove padding around tabs
if (!Utils.isTablet(getActivity())) {
mContainer.setPadding(0, 0, 0, 0);
}
}
@Override
public void onPause() {
super.onPause();
if (mProfileEnabler != null) {
mProfileEnabler.pause();
}
getActivity().unregisterReceiver(mReceiver);
// store the current tab so we can get back to it later
if (mSavedState == null) {
mSavedState = new Bundle();
}
mSavedState.putString("tab", mTabHost.getCurrentTabTag());
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
mOptionsMenu = menu;
menu.add(0, MENU_RESET, 0, R.string.profile_reset_title)
.setIcon(R.drawable.ic_settings_backup) // use the backup icon
.setAlphabeticShortcut('r')
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
menu.add(0, MENU_ADD_PROFILE, 0, R.string.profiles_add)
.setIcon(R.drawable.ic_menu_add)
.setAlphabeticShortcut('a')
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
menu.add(0, MENU_ADD_APPGROUP, 0, R.string.profiles_add)
.setIcon(R.drawable.ic_menu_add)
.setAlphabeticShortcut('a')
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
updateOptionsMenu();
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
updateOptionsMenu();
}
@Override
public void onDestroyOptionsMenu() {
mOptionsMenu = null;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_RESET:
resetAll();
return true;
case MENU_ADD_PROFILE:
addProfile();
return true;
case MENU_ADD_APPGROUP:
addAppGroup();
return true;
default:
return false;
}
}
static void updateOptionsMenu() {
if (mOptionsMenu == null) {
return;
}
boolean enabled = Settings.System.getInt(mActivity.getContentResolver(),
Settings.System.SYSTEM_PROFILES_ENABLED, 1) == 1;
String tabId = mTabHost.getCurrentTabTag();
if (TAB_PROFILES.equals(tabId) && enabled) {
mOptionsMenu.findItem(MENU_ADD_PROFILE).setVisible(true);
mOptionsMenu.findItem(MENU_ADD_APPGROUP).setVisible(false);
mOptionsMenu.findItem(MENU_RESET).setVisible(true);
} else if (TAB_APPGROUPS.equals(tabId) && enabled) {
mOptionsMenu.findItem(MENU_ADD_PROFILE).setVisible(false);
mOptionsMenu.findItem(MENU_ADD_APPGROUP).setVisible(true);
mOptionsMenu.findItem(MENU_RESET).setVisible(true);
} else {
// System Profiles are disabled, hide options menu items
mOptionsMenu.findItem(MENU_ADD_PROFILE).setVisible(false);
mOptionsMenu.findItem(MENU_ADD_APPGROUP).setVisible(false);
mOptionsMenu.findItem(MENU_RESET).setVisible(false);
}
}
public void setupTabs() {
mTabHost.setup();
mTabHost.clearAllTabs();
mTabManager = new TabManager(getActivity(), mTabHost, android.R.id.tabcontent);
mTabManager.addTab(mTabHost.newTabSpec(TAB_PROFILES).setIndicator(getString(R.string.profile_profiles_manage)),
ProfilesList.class, null);
mTabManager.addTab(mTabHost.newTabSpec(TAB_APPGROUPS).setIndicator(getString(R.string.profile_appgroups_manage)),
AppGroupList.class, null);
// Set the profiles tab as the default
mTabHost.setCurrentTabByTag(TAB_PROFILES);
updateOptionsMenu();
}
public void refreshActiveTab() {
if (mTabManager != null) {
mTabManager.refreshTab(mTabHost.getCurrentTabTag());
}
updateOptionsMenu();
}
private void addProfile() {
Context context = getActivity();
if (context != null) {
final EditText entry = new EditText(context);
entry.setSingleLine();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.menu_new_profile);
builder.setMessage(R.string.profile_profile_name_prompt);
builder.setView(entry, 34, 16, 34, 16);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = entry.getText().toString();
if (!mProfileManager.profileExists(name)) {
Profile profile = new Profile(name);
mProfileManager.addProfile(profile);
mTabManager.refreshTab(TAB_PROFILES);
} else {
Toast.makeText(getActivity(), R.string.duplicate_profile_name, Toast.LENGTH_LONG).show();
}
}
});
builder.setNegativeButton(android.R.string.cancel, null);
AlertDialog dialog = builder.create();
dialog.show();
((TextView)dialog.findViewById(android.R.id.message)).setTextAppearance(getActivity(),
android.R.style.TextAppearance_DeviceDefault_Small);
}
}
private void resetAll() {
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle(R.string.profile_reset_title);
alert.setIconAttribute(android.R.attr.alertDialogIcon);
alert.setMessage(R.string.profile_reset_message);
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mProfileManager.resetAll();
mTabManager.refreshTab(mTabHost.getCurrentTabTag());
}
});
alert.setNegativeButton(R.string.cancel, null);
alert.create().show();
}
private void addAppGroup() {
Context context = getActivity();
if (context != null) {
final EditText entry = new EditText(context);
entry.setSingleLine();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.profile_new_appgroup);
builder.setMessage(R.string.profile_appgroup_name_prompt);
builder.setView(entry, 34, 16, 34, 16);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = entry.getText().toString();
if (!mProfileManager.notificationGroupExists(name)) {
NotificationGroup newGroup = new NotificationGroup(entry.getText().toString());
mProfileManager.addNotificationGroup(newGroup);
mTabManager.refreshTab(TAB_APPGROUPS);
} else {
Toast.makeText(getActivity(), R.string.duplicate_appgroup_name, Toast.LENGTH_LONG).show();
}
}
});
builder.setNegativeButton(android.R.string.cancel, null);
AlertDialog dialog = builder.create();
dialog.show();
((TextView)dialog.findViewById(android.R.id.message)).setTextAppearance(getActivity(),
android.R.style.TextAppearance_DeviceDefault_Small);
}
}
private void handleEvent(Context context, Intent intent) {
String action = intent.getAction();
if (ProfileManager.PROFILES_STATE_CHANGED_ACTION.equals(action)) {
// we don't need to check the new state, refresh will do it
refreshActiveTab();
}
}
/**
* This is a helper class that implements a generic mechanism for
* associating fragments with the tabs in a tab host.
*/
public static class TabManager implements TabHost.OnTabChangeListener {
private final Activity mActivity;
private final TabHost mTabHost;
private final int mContainerId;
private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
TabInfo mLastTab;
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
private Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabManager(Activity activity, TabHost tabHost, int containerId) {
mActivity = activity;
mTabHost = tabHost;
mContainerId = containerId;
mTabHost.setOnTabChangedListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mActivity));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
info.fragment = mActivity.getFragmentManager().findFragmentByTag(tag);
if (info.fragment != null && !info.fragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.detach(info.fragment);
ft.commit();
}
mTabs.put(tag, info);
mTabHost.addTab(tabSpec);
}
@Override
public void onTabChanged(String tabId) {
TabInfo newTab = mTabs.get(tabId);
if (mLastTab != newTab) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mActivity,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
ft.commit();
// Toggle the appropriate menu options
updateOptionsMenu();
}
}
public void refreshTab(String tabId) {
TabInfo currentTab = mTabs.get(tabId);
if (currentTab != null) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
if (currentTab.fragment != null) {
ft.detach(currentTab.fragment);
}
if (currentTab.fragment == null) {
currentTab.fragment = Fragment.instantiate(mActivity,
currentTab.clss.getName(), currentTab.args);
ft.add(mContainerId, currentTab.fragment, currentTab.tag);
} else {
ft.attach(currentTab.fragment);
}
ft.commit();
// Toggle the appropriate menu options
updateOptionsMenu();
}
}
}
}