Loading res/layout/admin_support_details_content.xml 0 → 100644 +42 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2016 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. --> <!-- Layout used for displaying admin support details in empty preference fragments. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/admin_support_details" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@*android:dimen/preference_fragment_padding_side" android:gravity="center_vertical" android:orientation="vertical" android:visibility="gone"> <TextView android:id="@+id/admin_support_msg" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@android:style/TextAppearance.Material.Subhead" android:text="@string/default_admin_support_msg" android:maxLength="200" android:autoLink="email|phone" android:textColor="?android:attr/textColorSecondary" /> <TextView android:id="@+id/admins_policies_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/admin_details_dialog_link_padding_top" android:text="@string/admin_support_more_info" android:textAppearance="@android:style/TextAppearance.Material.Subhead" android:textColor="?android:attr/colorAccent" android:clickable="true" android:background="?android:attr/selectableItemBackground" /> </LinearLayout> No newline at end of file res/layout/preference_list_fragment.xml +2 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,8 @@ android:gravity="center" android:visibility="gone" /> <include layout="@layout/admin_support_details_content" /> <RelativeLayout android:id="@+id/button_bar" android:layout_height="wrap_content" android:layout_width="match_parent" Loading src/com/android/settings/RestrictedSettingsFragment.java +84 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -24,10 +25,18 @@ import android.content.IntentFilter; import android.content.RestrictionsManager; import android.os.Bundle; import android.os.PersistableBundle; import android.os.UserHandle; import android.os.UserManager; import android.view.View; import android.widget.TextView; import com.android.settingslib.RestrictedLockUtils; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; /** * Base class for settings screens that should be pin protected when in restricted mode. * Base class for settings screens that should be pin protected when in restricted mode or * that will display an admin support message in case an admin has disabled the options. * The constructor for this class will take the restriction key that this screen should be * locked by. If {@link RestrictionsManager.hasRestrictionsProvider()} and * {@link UserManager.hasUserRestriction()}, then the user will have to enter the restrictions Loading @@ -37,7 +46,8 @@ import android.os.UserManager; * {@link RestrictionsManager.hasRestrictionsProvider()} returns true, pass in * {@link RESTRICT_IF_OVERRIDABLE} to the constructor instead of a restrictions key. */ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment { public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment implements View.OnClickListener { protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable"; Loading @@ -55,6 +65,9 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm private RestrictionsManager mRestrictionsManager; private final String mRestrictionKey; private View mAdminSupportDetails; private EnforcedAdmin mEnforcedAdmin; private TextView mEmptyTextView; // Receiver to clear pin status when the screen is turned off. private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { Loading Loading @@ -94,6 +107,13 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm getActivity().registerReceiver(mScreenOffReceiver, offFilter); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mAdminSupportDetails = initAdminSupportDetailsView(); mEmptyTextView = initEmptyTextView(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Loading Loading @@ -178,6 +198,68 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm return restricted && mRestrictionsManager.hasRestrictionsProvider(); } protected View initAdminSupportDetailsView() { return null; } protected TextView initEmptyTextView() { return null; } private void updateAdminSupportDetailsView() { mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(), mRestrictionKey, UserHandle.myUserId()); if (mEnforcedAdmin != null) { final Activity activity = getActivity(); DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( Context.DEVICE_POLICY_SERVICE); if (mEnforcedAdmin.userId == UserHandle.USER_NULL) { mEnforcedAdmin.userId = UserHandle.myUserId(); } CharSequence supportMessage = dpm.getShortSupportMessageForUser( mEnforcedAdmin.component, mEnforcedAdmin.userId); if (supportMessage != null) { TextView textView = (TextView) activity.findViewById(R.id.admin_support_msg); textView.setText(supportMessage); } activity.findViewById(R.id.admins_policies_list).setOnClickListener(this); } } @Override public void onClick(View view) { Intent intent = new Intent(); if (view.getId() == R.id.admins_policies_list && mEnforcedAdmin != null) { if (mEnforcedAdmin.component != null) { intent.setClass(getActivity(), DeviceAdminAdd.class); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mEnforcedAdmin.component); // DeviceAdminAdd class may need to run as managed profile. getActivity().startActivityAsUser(intent, UserHandle.of(mEnforcedAdmin.userId)); } else { intent.setClass(getActivity(), Settings.DeviceAdminSettingsActivity.class); // Activity merges both managed profile and parent users // admins so show as same user as this activity. getActivity().startActivity(intent); } } } public TextView getEmptyTextView() { return mEmptyTextView; } @Override protected void onDataSetChanged() { highlightPreferenceIfNeeded(); if (mAdminSupportDetails != null && isUiRestricted()) { updateAdminSupportDetailsView(); setEmptyView(mAdminSupportDetails); } else if (mEmptyTextView != null) { setEmptyView(mEmptyTextView); } super.onDataSetChanged(); } /** * Returns whether restricted or actionable UI elements should be removed or disabled. */ Loading src/com/android/settings/SettingsPreferenceFragment.java +4 −8 Original line number Diff line number Diff line Loading @@ -176,13 +176,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF unregisterObserverIfNeeded(); } @Override public void onStop() { super.onStop(); unregisterObserverIfNeeded(); } public void showLoadingWhenEmpty() { View loading = getView().findViewById(R.id.loading_container); setEmptyView(loading); Loading Loading @@ -220,7 +213,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF } } private void onDataSetChanged() { protected void onDataSetChanged() { highlightPreferenceIfNeeded(); updateEmptyView(); } Loading Loading @@ -290,6 +283,9 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF } public void setEmptyView(View v) { if (mEmptyView != null) { mEmptyView.setVisibility(View.GONE); } mEmptyView = v; updateEmptyView(); } Loading src/com/android/settings/bluetooth/BluetoothSettings.java +19 −13 Original line number Diff line number Diff line Loading @@ -87,7 +87,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem private boolean mInitialScanStarted; private boolean mInitiateDiscoverable; private TextView mEmptyView; private SwitchBar mSwitchBar; private final IntentFilter mIntentFilter; Loading Loading @@ -136,10 +135,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem mInitialScanStarted = false; mInitiateDiscoverable = true; mEmptyView = (TextView) getView().findViewById(android.R.id.empty); setEmptyView(mEmptyView); mEmptyView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); final SettingsActivity activity = (SettingsActivity) getActivity(); mSwitchBar = activity.getSwitchBar(); Loading Loading @@ -175,7 +170,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem if (isUiRestricted()) { setDeviceListGroup(getPreferenceScreen()); removeAllDevices(); mEmptyView.setText(R.string.bluetooth_empty_list_user_restricted); return; } Loading Loading @@ -298,7 +292,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem mDevicePreferenceMap.clear(); if (isUiRestricted()) { messageId = R.string.bluetooth_empty_list_user_restricted; break; } Loading Loading @@ -360,7 +353,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem case BluetoothAdapter.STATE_OFF: setOffMessage(); if (isUiRestricted()) { messageId = R.string.bluetooth_empty_list_user_restricted; messageId = 0; } break; Loading @@ -373,15 +366,28 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem setDeviceListGroup(preferenceScreen); removeAllDevices(); if (messageId != 0) { mEmptyView.setText(messageId); getEmptyTextView().setText(messageId); } if (!isUiRestricted()) { getActivity().invalidateOptionsMenu(); } } @Override protected TextView initEmptyTextView() { TextView textView = (TextView) getView().findViewById(android.R.id.empty); textView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); return textView; } @Override protected View initAdminSupportDetailsView() { return getActivity().findViewById(R.id.admin_support_details); } private void setOffMessage() { if (mEmptyView == null) { final TextView emptyView = getEmptyTextView(); if (emptyView == null) { return; } final CharSequence briefText = getText(R.string.bluetooth_empty_list_bluetooth_off); Loading @@ -392,13 +398,13 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem if (!bleScanningMode) { // Show only the brief text if the scanning mode has been turned off. mEmptyView.setText(briefText, TextView.BufferType.SPANNABLE); emptyView.setText(briefText, TextView.BufferType.SPANNABLE); } else { final StringBuilder contentBuilder = new StringBuilder(); contentBuilder.append(briefText); contentBuilder.append("\n\n"); contentBuilder.append(getText(R.string.ble_scan_notify_text)); LinkifyUtils.linkify(mEmptyView, contentBuilder, new LinkifyUtils.OnClickListener() { LinkifyUtils.linkify(emptyView, contentBuilder, new LinkifyUtils.OnClickListener() { @Override public void onClick() { final SettingsActivity activity = Loading @@ -409,7 +415,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem }); } getPreferenceScreen().removeAll(); Spannable boldSpan = (Spannable) mEmptyView.getText(); Spannable boldSpan = (Spannable) emptyView.getText(); boldSpan.setSpan( new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0, briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Loading Loading
res/layout/admin_support_details_content.xml 0 → 100644 +42 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2016 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. --> <!-- Layout used for displaying admin support details in empty preference fragments. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/admin_support_details" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@*android:dimen/preference_fragment_padding_side" android:gravity="center_vertical" android:orientation="vertical" android:visibility="gone"> <TextView android:id="@+id/admin_support_msg" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@android:style/TextAppearance.Material.Subhead" android:text="@string/default_admin_support_msg" android:maxLength="200" android:autoLink="email|phone" android:textColor="?android:attr/textColorSecondary" /> <TextView android:id="@+id/admins_policies_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/admin_details_dialog_link_padding_top" android:text="@string/admin_support_more_info" android:textAppearance="@android:style/TextAppearance.Material.Subhead" android:textColor="?android:attr/colorAccent" android:clickable="true" android:background="?android:attr/selectableItemBackground" /> </LinearLayout> No newline at end of file
res/layout/preference_list_fragment.xml +2 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,8 @@ android:gravity="center" android:visibility="gone" /> <include layout="@layout/admin_support_details_content" /> <RelativeLayout android:id="@+id/button_bar" android:layout_height="wrap_content" android:layout_width="match_parent" Loading
src/com/android/settings/RestrictedSettingsFragment.java +84 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -24,10 +25,18 @@ import android.content.IntentFilter; import android.content.RestrictionsManager; import android.os.Bundle; import android.os.PersistableBundle; import android.os.UserHandle; import android.os.UserManager; import android.view.View; import android.widget.TextView; import com.android.settingslib.RestrictedLockUtils; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; /** * Base class for settings screens that should be pin protected when in restricted mode. * Base class for settings screens that should be pin protected when in restricted mode or * that will display an admin support message in case an admin has disabled the options. * The constructor for this class will take the restriction key that this screen should be * locked by. If {@link RestrictionsManager.hasRestrictionsProvider()} and * {@link UserManager.hasUserRestriction()}, then the user will have to enter the restrictions Loading @@ -37,7 +46,8 @@ import android.os.UserManager; * {@link RestrictionsManager.hasRestrictionsProvider()} returns true, pass in * {@link RESTRICT_IF_OVERRIDABLE} to the constructor instead of a restrictions key. */ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment { public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment implements View.OnClickListener { protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable"; Loading @@ -55,6 +65,9 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm private RestrictionsManager mRestrictionsManager; private final String mRestrictionKey; private View mAdminSupportDetails; private EnforcedAdmin mEnforcedAdmin; private TextView mEmptyTextView; // Receiver to clear pin status when the screen is turned off. private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { Loading Loading @@ -94,6 +107,13 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm getActivity().registerReceiver(mScreenOffReceiver, offFilter); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mAdminSupportDetails = initAdminSupportDetailsView(); mEmptyTextView = initEmptyTextView(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Loading Loading @@ -178,6 +198,68 @@ public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragm return restricted && mRestrictionsManager.hasRestrictionsProvider(); } protected View initAdminSupportDetailsView() { return null; } protected TextView initEmptyTextView() { return null; } private void updateAdminSupportDetailsView() { mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(), mRestrictionKey, UserHandle.myUserId()); if (mEnforcedAdmin != null) { final Activity activity = getActivity(); DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( Context.DEVICE_POLICY_SERVICE); if (mEnforcedAdmin.userId == UserHandle.USER_NULL) { mEnforcedAdmin.userId = UserHandle.myUserId(); } CharSequence supportMessage = dpm.getShortSupportMessageForUser( mEnforcedAdmin.component, mEnforcedAdmin.userId); if (supportMessage != null) { TextView textView = (TextView) activity.findViewById(R.id.admin_support_msg); textView.setText(supportMessage); } activity.findViewById(R.id.admins_policies_list).setOnClickListener(this); } } @Override public void onClick(View view) { Intent intent = new Intent(); if (view.getId() == R.id.admins_policies_list && mEnforcedAdmin != null) { if (mEnforcedAdmin.component != null) { intent.setClass(getActivity(), DeviceAdminAdd.class); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mEnforcedAdmin.component); // DeviceAdminAdd class may need to run as managed profile. getActivity().startActivityAsUser(intent, UserHandle.of(mEnforcedAdmin.userId)); } else { intent.setClass(getActivity(), Settings.DeviceAdminSettingsActivity.class); // Activity merges both managed profile and parent users // admins so show as same user as this activity. getActivity().startActivity(intent); } } } public TextView getEmptyTextView() { return mEmptyTextView; } @Override protected void onDataSetChanged() { highlightPreferenceIfNeeded(); if (mAdminSupportDetails != null && isUiRestricted()) { updateAdminSupportDetailsView(); setEmptyView(mAdminSupportDetails); } else if (mEmptyTextView != null) { setEmptyView(mEmptyTextView); } super.onDataSetChanged(); } /** * Returns whether restricted or actionable UI elements should be removed or disabled. */ Loading
src/com/android/settings/SettingsPreferenceFragment.java +4 −8 Original line number Diff line number Diff line Loading @@ -176,13 +176,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF unregisterObserverIfNeeded(); } @Override public void onStop() { super.onStop(); unregisterObserverIfNeeded(); } public void showLoadingWhenEmpty() { View loading = getView().findViewById(R.id.loading_container); setEmptyView(loading); Loading Loading @@ -220,7 +213,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF } } private void onDataSetChanged() { protected void onDataSetChanged() { highlightPreferenceIfNeeded(); updateEmptyView(); } Loading Loading @@ -290,6 +283,9 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF } public void setEmptyView(View v) { if (mEmptyView != null) { mEmptyView.setVisibility(View.GONE); } mEmptyView = v; updateEmptyView(); } Loading
src/com/android/settings/bluetooth/BluetoothSettings.java +19 −13 Original line number Diff line number Diff line Loading @@ -87,7 +87,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem private boolean mInitialScanStarted; private boolean mInitiateDiscoverable; private TextView mEmptyView; private SwitchBar mSwitchBar; private final IntentFilter mIntentFilter; Loading Loading @@ -136,10 +135,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem mInitialScanStarted = false; mInitiateDiscoverable = true; mEmptyView = (TextView) getView().findViewById(android.R.id.empty); setEmptyView(mEmptyView); mEmptyView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); final SettingsActivity activity = (SettingsActivity) getActivity(); mSwitchBar = activity.getSwitchBar(); Loading Loading @@ -175,7 +170,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem if (isUiRestricted()) { setDeviceListGroup(getPreferenceScreen()); removeAllDevices(); mEmptyView.setText(R.string.bluetooth_empty_list_user_restricted); return; } Loading Loading @@ -298,7 +292,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem mDevicePreferenceMap.clear(); if (isUiRestricted()) { messageId = R.string.bluetooth_empty_list_user_restricted; break; } Loading Loading @@ -360,7 +353,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem case BluetoothAdapter.STATE_OFF: setOffMessage(); if (isUiRestricted()) { messageId = R.string.bluetooth_empty_list_user_restricted; messageId = 0; } break; Loading @@ -373,15 +366,28 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem setDeviceListGroup(preferenceScreen); removeAllDevices(); if (messageId != 0) { mEmptyView.setText(messageId); getEmptyTextView().setText(messageId); } if (!isUiRestricted()) { getActivity().invalidateOptionsMenu(); } } @Override protected TextView initEmptyTextView() { TextView textView = (TextView) getView().findViewById(android.R.id.empty); textView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); return textView; } @Override protected View initAdminSupportDetailsView() { return getActivity().findViewById(R.id.admin_support_details); } private void setOffMessage() { if (mEmptyView == null) { final TextView emptyView = getEmptyTextView(); if (emptyView == null) { return; } final CharSequence briefText = getText(R.string.bluetooth_empty_list_bluetooth_off); Loading @@ -392,13 +398,13 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem if (!bleScanningMode) { // Show only the brief text if the scanning mode has been turned off. mEmptyView.setText(briefText, TextView.BufferType.SPANNABLE); emptyView.setText(briefText, TextView.BufferType.SPANNABLE); } else { final StringBuilder contentBuilder = new StringBuilder(); contentBuilder.append(briefText); contentBuilder.append("\n\n"); contentBuilder.append(getText(R.string.ble_scan_notify_text)); LinkifyUtils.linkify(mEmptyView, contentBuilder, new LinkifyUtils.OnClickListener() { LinkifyUtils.linkify(emptyView, contentBuilder, new LinkifyUtils.OnClickListener() { @Override public void onClick() { final SettingsActivity activity = Loading @@ -409,7 +415,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem }); } getPreferenceScreen().removeAll(); Spannable boldSpan = (Spannable) mEmptyView.getText(); Spannable boldSpan = (Spannable) emptyView.getText(); boldSpan.setSpan( new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0, briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); Loading