aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuichi Araki <yaraki@google.com>2014-12-01 21:05:48 +0900
committerYuichi Araki <yaraki@google.com>2014-12-09 13:16:29 +0900
commit2b431b5552d50c696bd80e9bf84c45509f727cc2 (patch)
treefa776d6a6c908dc0bf55dd108a44039c27e121dd
parentbc036ecdf44cd03163c206096172299f3940b057 (diff)
downloadandroid-2b431b5552d50c696bd80e9bf84c45509f727cc2.tar.gz
AppRestrictionSchema, Enforcer: More restrictions
Bug: 18509464 Change-Id: I82e56aa4f79ea1d5c00d807489ddcfa5fd328061
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java351
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java27
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java38
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java47
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java136
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml124
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml39
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml22
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml21
-rw-r--r--admin/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml4
-rw-r--r--admin/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--admin/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java117
-rw-r--r--admin/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml70
-rw-r--r--admin/AppRestrictionSchema/Application/src/main/res/layout/separator.xml22
-rw-r--r--admin/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml77
-rw-r--r--admin/AppRestrictionSchema/Application/src/main/res/values/strings.xml11
-rw-r--r--admin/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml48
-rw-r--r--admin/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties2
18 files changed, 971 insertions, 187 deletions
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java
index 6db54f65..8b0620fb 100644
--- a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java
+++ b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java
@@ -22,34 +22,34 @@ import android.content.Context;
import android.content.RestrictionEntry;
import android.content.RestrictionsManager;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Button;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
import android.widget.Switch;
-import android.widget.TextView;
import android.widget.Toast;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
* This fragment provides UI and functionality to set restrictions on the AppRestrictionSchema
* sample.
*/
-public class AppRestrictionEnforcerFragment extends Fragment implements View.OnClickListener,
- CompoundButton.OnCheckedChangeListener {
-
- /**
- * Package name of the AppRestrictionSchema sample.
- */
- private static final String PACKAGE_NAME_APP_RESTRICTION_SCHEMA
- = "com.example.android.apprestrictionschema";
+public class AppRestrictionEnforcerFragment extends Fragment implements
+ CompoundButton.OnCheckedChangeListener, AdapterView.OnItemSelectedListener {
/**
* Key for {@link SharedPreferences}
@@ -62,15 +62,38 @@ public class AppRestrictionEnforcerFragment extends Fragment implements View.OnC
private static final String RESTRICTION_KEY_SAY_HELLO = "can_say_hello";
/**
- * Default boolean value for "can_say_hello" restriction. The actual value is loaded in
- * {@link #loadRestrictions(android.app.Activity)}.
+ * Key for the string restriction in AppRestrictionSchema.
+ */
+ private static final String RESTRICTION_KEY_MESSAGE = "message";
+
+ /**
+ * Key for the integer restriction in AppRestrictionSchema.
+ */
+ private static final String RESTRICTION_KEY_NUMBER = "number";
+
+ /**
+ * Key for the choice restriction in AppRestrictionSchema.
+ */
+ private static final String RESTRICTION_KEY_RANK = "rank";
+
+ /**
+ * Key for the multi-select restriction in AppRestrictionSchema.
*/
- private boolean mDefaultValueRestrictionSayHello;
+ private static final String RESTRICTION_KEY_APPROVALS = "approvals";
+
+ private static final String DELIMETER = ",";
+
+ /**
+ * Current status of the restrictions.
+ */
+ private Bundle mCurrentRestrictions = new Bundle();
// UI Components
- private TextView mTextStatus;
- private Button mButtonUnhide;
private Switch mSwitchSayHello;
+ private EditText mEditMessage;
+ private EditText mEditNumber;
+ private Spinner mSpinnerRank;
+ private LinearLayout mLayoutApprovals;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -80,152 +103,262 @@ public class AppRestrictionEnforcerFragment extends Fragment implements View.OnC
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- mTextStatus = (TextView) view.findViewById(R.id.status);
- mButtonUnhide = (Button) view.findViewById(R.id.unhide);
+ // Retain references for the UI elements
mSwitchSayHello = (Switch) view.findViewById(R.id.say_hello);
- mButtonUnhide.setOnClickListener(this);
- mSwitchSayHello.setOnCheckedChangeListener(this);
+ mEditMessage = (EditText) view.findViewById(R.id.message);
+ mEditNumber = (EditText) view.findViewById(R.id.number);
+ mSpinnerRank = (Spinner) view.findViewById(R.id.rank);
+ mLayoutApprovals = (LinearLayout) view.findViewById(R.id.approvals);
}
@Override
public void onResume() {
super.onResume();
- updateUi(getActivity());
+ loadRestrictions(getActivity());
}
@Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.unhide: {
- unhideApp(getActivity());
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ switch (compoundButton.getId()) {
+ case R.id.say_hello: {
+ saveCanSayHello(getActivity(), checked);
+ break;
+ }
+ case R.id.approval: {
+ if (checked) {
+ addApproval(getActivity(), (String) compoundButton.getTag());
+ } else {
+ removeApproval(getActivity(), (String) compoundButton.getTag());
+ }
break;
}
}
}
+ private TextWatcher mWatcherMessage = new EasyTextWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ saveMessage(getActivity(), s.toString());
+ }
+ };
+
+ private TextWatcher mWatcherNumber = new EasyTextWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ String string = s.toString();
+ if (!TextUtils.isEmpty(string)) {
+ saveNumber(getActivity(), Integer.parseInt(string));
+ }
+ } catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), "Not an integer!", Toast.LENGTH_SHORT).show();
+ }
+ }
+ };
+
@Override
- public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
- switch (compoundButton.getId()) {
- case R.id.say_hello: {
- allowSayHello(getActivity(), checked);
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ switch (parent.getId()) {
+ case R.id.rank: {
+ saveRank(getActivity(), (String) parent.getAdapter().getItem(position));
break;
}
}
}
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Nothing to do
+ }
+
/**
- * Updates the UI components according to the current status of AppRestrictionSchema and its
- * restriction.
+ * Loads the restrictions for the AppRestrictionSchema sample. In this implementation, we just
+ * read the default value for the "can_say_hello" restriction.
*
* @param activity The activity
*/
- private void updateUi(Activity activity) {
- PackageManager packageManager = activity.getPackageManager();
- try {
- ApplicationInfo info = packageManager.getApplicationInfo(
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA, PackageManager.GET_UNINSTALLED_PACKAGES);
- DevicePolicyManager devicePolicyManager =
- (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
- if (0 < (info.flags & ApplicationInfo.FLAG_INSTALLED)) {
- if (!devicePolicyManager.isApplicationHidden(
- EnforcerDeviceAdminReceiver.getComponentName(activity),
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
- // The app is ready
- loadRestrictions(activity);
- mTextStatus.setVisibility(View.GONE);
- mButtonUnhide.setVisibility(View.GONE);
- mSwitchSayHello.setVisibility(View.VISIBLE);
- mSwitchSayHello.setOnCheckedChangeListener(null);
- mSwitchSayHello.setChecked(canSayHello(activity));
- mSwitchSayHello.setOnCheckedChangeListener(this);
- } else {
- // The app is installed but hidden in this profile
- mTextStatus.setText(R.string.status_not_activated);
- mTextStatus.setVisibility(View.VISIBLE);
- mButtonUnhide.setVisibility(View.VISIBLE);
- mSwitchSayHello.setVisibility(View.GONE);
- }
- } else {
- // Need to reinstall the sample app
- mTextStatus.setText(R.string.status_need_reinstall);
- mTextStatus.setVisibility(View.VISIBLE);
- mButtonUnhide.setVisibility(View.GONE);
- mSwitchSayHello.setVisibility(View.GONE);
+ private void loadRestrictions(Activity activity) {
+ RestrictionsManager manager =
+ (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
+ List<RestrictionEntry> restrictions =
+ manager.getManifestRestrictions(Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
+ SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
+ for (RestrictionEntry restriction : restrictions) {
+ String key = restriction.getKey();
+ if (RESTRICTION_KEY_SAY_HELLO.equals(key)) {
+ updateCanSayHello(prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO,
+ restriction.getSelectedState()));
+ } else if (RESTRICTION_KEY_MESSAGE.equals(key)) {
+ updateMessage(prefs.getString(RESTRICTION_KEY_MESSAGE,
+ restriction.getSelectedString()));
+ } else if (RESTRICTION_KEY_NUMBER.equals(key)) {
+ updateNumber(prefs.getInt(RESTRICTION_KEY_NUMBER,
+ restriction.getIntValue()));
+ } else if (RESTRICTION_KEY_RANK.equals(key)) {
+ updateRank(activity, restriction.getChoiceValues(),
+ prefs.getString(RESTRICTION_KEY_RANK, restriction.getSelectedString()));
+ } else if (RESTRICTION_KEY_APPROVALS.equals(key)) {
+ updateApprovals(activity, restriction.getChoiceValues(),
+ TextUtils.split(prefs.getString(RESTRICTION_KEY_APPROVALS,
+ TextUtils.join(DELIMETER,
+ restriction.getAllSelectedStrings())),
+ DELIMETER));
}
- } catch (PackageManager.NameNotFoundException e) {
- mTextStatus.setText(R.string.status_not_installed);
- mTextStatus.setVisibility(View.VISIBLE);
- mButtonUnhide.setVisibility(View.GONE);
- mSwitchSayHello.setVisibility(View.GONE);
+ }
+ }
+
+ private void updateCanSayHello(boolean canSayHello) {
+ mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, canSayHello);
+ mSwitchSayHello.setOnCheckedChangeListener(null);
+ mSwitchSayHello.setChecked(canSayHello);
+ mSwitchSayHello.setOnCheckedChangeListener(this);
+ }
+
+ private void updateMessage(String message) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
+ mEditMessage.removeTextChangedListener(mWatcherMessage);
+ mEditMessage.setText(message);
+ mEditMessage.addTextChangedListener(mWatcherMessage);
+ }
+
+ private void updateNumber(int number) {
+ mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
+ mEditNumber.removeTextChangedListener(mWatcherNumber);
+ mEditNumber.setText(String.valueOf(number));
+ mEditNumber.addTextChangedListener(mWatcherNumber);
+ }
+
+ private void updateRank(Context context, String[] ranks, String selectedRank) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_RANK, selectedRank);
+ mSpinnerRank.setAdapter(new ArrayAdapter<>(context,
+ android.R.layout.simple_spinner_dropdown_item, ranks));
+ mSpinnerRank.setSelection(search(ranks, selectedRank));
+ mSpinnerRank.setOnItemSelectedListener(this);
+ }
+
+ private void updateApprovals(Context context, String[] approvals,
+ String[] selectedApprovals) {
+ mCurrentRestrictions.putStringArray(RESTRICTION_KEY_APPROVALS, selectedApprovals);
+ mLayoutApprovals.removeAllViews();
+ for (String approval : approvals) {
+ Switch sw = new Switch(context);
+ sw.setText(approval);
+ sw.setTag(approval);
+ sw.setChecked(Arrays.asList(selectedApprovals).contains(approval));
+ sw.setOnCheckedChangeListener(this);
+ sw.setId(R.id.approval);
+ mLayoutApprovals.addView(sw);
}
}
/**
- * Unhides the AppRestrictionSchema sample in case it is hidden in this profile.
+ * Saves the value for the "cay_say_hello" restriction of AppRestrictionSchema.
*
* @param activity The activity
+ * @param allow The value to be set for the restriction.
*/
- private void unhideApp(Activity activity) {
- DevicePolicyManager devicePolicyManager =
- (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
- devicePolicyManager.setApplicationHidden(
- EnforcerDeviceAdminReceiver.getComponentName(activity),
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA, false);
- Toast.makeText(activity, "Enabled the app", Toast.LENGTH_SHORT).show();
- updateUi(activity);
+ private void saveCanSayHello(Activity activity, boolean allow) {
+ mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
+ saveRestrictions(activity);
+ // Note that the owner app needs to remember the restrictions on its own.
+ editPreferences(activity).putBoolean(RESTRICTION_KEY_SAY_HELLO, allow).apply();
}
/**
- * Loads the restrictions for the AppRestrictionSchema sample. In this implementation, we just
- * read the default value for the "can_say_hello" restriction.
+ * Saves the value for the "message" restriction of AppRestrictionSchema.
*
* @param activity The activity
+ * @param message The value to be set for the restriction.
*/
- private void loadRestrictions(Activity activity) {
- RestrictionsManager restrictionsManager =
- (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
- List<RestrictionEntry> restrictions =
- restrictionsManager.getManifestRestrictions(PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
- for (RestrictionEntry restriction : restrictions) {
- if (RESTRICTION_KEY_SAY_HELLO.equals(restriction.getKey())) {
- mDefaultValueRestrictionSayHello = restriction.getSelectedState();
- }
- }
+ private void saveMessage(Activity activity, String message) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
+ saveRestrictions(activity);
+ editPreferences(activity).putString(RESTRICTION_KEY_MESSAGE, message).apply();
}
/**
- * Returns whether the AppRestrictionSchema is currently allowed to say hello to its user. Note
- * that a profile/device owner needs to remember each restriction value on its own.
+ * Saves the value for the "number" restriction of AppRestrictionSchema.
*
* @param activity The activity
- * @return True if the AppRestrictionSchema is allowed to say hello
+ * @param number The value to be set for the restriction.
*/
- private boolean canSayHello(Activity activity) {
- SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
- return prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO, mDefaultValueRestrictionSayHello);
+ private void saveNumber(Activity activity, int number) {
+ mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
+ saveRestrictions(activity);
+ editPreferences(activity).putInt(RESTRICTION_KEY_NUMBER, number).apply();
}
/**
- * Sets the value for the "cay_say_hello" restriction of AppRestrictionSchema.
+ * Saves the value for the "rank" restriction of AppRestrictionSchema.
*
* @param activity The activity
- * @param allow The value to be set for the restriction.
+ * @param rank The value to be set for the restriction.
*/
- private void allowSayHello(Activity activity, boolean allow) {
+ private void saveRank(Activity activity, String rank) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_RANK, rank);
+ saveRestrictions(activity);
+ editPreferences(activity).putString(RESTRICTION_KEY_RANK, rank).apply();
+ }
+
+ private void addApproval(Activity activity, String approval) {
+ List<String> approvals = new ArrayList<>(Arrays.asList(
+ mCurrentRestrictions.getStringArray(RESTRICTION_KEY_APPROVALS)));
+ if (approvals.contains(approval)) {
+ return;
+ }
+ approvals.add(approval);
+ saveApprovals(activity, approvals.toArray(new String[approvals.size()]));
+ }
+
+ private void removeApproval(Activity activity, String approval) {
+ List<String> approvals = new ArrayList<>(Arrays.asList(
+ mCurrentRestrictions.getStringArray(RESTRICTION_KEY_APPROVALS)));
+ if (!approval.contains(approval)) {
+ return;
+ }
+ approvals.remove(approval);
+ saveApprovals(activity, approvals.toArray(new String[approvals.size()]));
+ }
+
+ /**
+ * Saves the value for the "approvals" restriction of AppRestrictionSchema.
+ *
+ * @param activity The activity
+ * @param approvals The value to be set for the restriction.
+ */
+ private void saveApprovals(Activity activity, String[] approvals) {
+ mCurrentRestrictions.putStringArray(RESTRICTION_KEY_APPROVALS, approvals);
+ saveRestrictions(activity);
+ editPreferences(activity).putString(RESTRICTION_KEY_APPROVALS,
+ TextUtils.join(DELIMETER, approvals)).apply();
+ }
+
+ private void saveRestrictions(Activity activity) {
DevicePolicyManager devicePolicyManager
= (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
- Bundle restrictions = new Bundle();
- restrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
devicePolicyManager.setApplicationRestrictions(
EnforcerDeviceAdminReceiver.getComponentName(activity),
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA, restrictions);
- // The profile/device owner needs to remember the current state of restrictions on its own
- activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
- .edit()
- .putBoolean(RESTRICTION_KEY_SAY_HELLO, allow)
- .apply();
- Toast.makeText(activity, allow ? R.string.allowed : R.string.disallowed,
- Toast.LENGTH_SHORT).show();
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA, mCurrentRestrictions);
+ }
+
+ private SharedPreferences.Editor editPreferences(Activity activity) {
+ return activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE).edit();
+ }
+
+ /**
+ * Sequential search
+ *
+ * @param array The string array
+ * @param s The string to search for
+ * @return Index if found. -1 if not found.
+ */
+ private int search(String[] array, String s) {
+ for (int i = 0; i < array.length; ++i) {
+ if (s.equals(array[i])) {
+ return i;
+ }
+ }
+ return -1;
}
}
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java
new file mode 100644
index 00000000..bb4e958c
--- /dev/null
+++ b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java
@@ -0,0 +1,27 @@
+/*
+ * 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.example.android.apprestrictionenforcer;
+
+public interface Constants {
+
+ /**
+ * Package name of the AppRestrictionSchema sample.
+ */
+ public static final String PACKAGE_NAME_APP_RESTRICTION_SCHEMA
+ = "com.example.android.apprestrictionschema";
+
+}
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java
new file mode 100644
index 00000000..8e0abb44
--- /dev/null
+++ b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java
@@ -0,0 +1,38 @@
+/*
+ * 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.example.android.apprestrictionenforcer;
+
+import android.text.TextWatcher;
+
+/**
+ * This is a wrapper around {@link TextWatcher} that overrides
+ * {@link TextWatcher#beforeTextChanged(CharSequence, int, int, int)} and
+ * {@link TextWatcher#onTextChanged(CharSequence, int, int, int)} with empty bodies.
+ */
+public abstract class EasyTextWatcher implements TextWatcher {
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Do nothing
+ }
+
+}
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java
index 72224e17..c6b012be 100644
--- a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java
+++ b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java
@@ -18,24 +18,44 @@ package com.example.android.apprestrictionenforcer;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
-public class MainActivity extends FragmentActivity {
+public class MainActivity extends FragmentActivity implements StatusFragment.StatusUpdatedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_real);
if (null == savedInstanceState) {
- DevicePolicyManager manager = (DevicePolicyManager)
- getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (manager.isProfileOwnerApp(getApplicationContext().getPackageName())) {
- // If the managed profile is already set up, we show the main screen.
- showMainFragment();
- } else {
- // If not, we show the set up screen.
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+ PackageManager packageManager = getPackageManager();
+ if (!devicePolicyManager.isProfileOwnerApp(getApplicationContext().getPackageName())) {
+ // If the managed profile is not yet set up, we show the setup screen.
showSetupProfile();
+ } else {
+ try {
+ ApplicationInfo info = packageManager.getApplicationInfo(
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA,
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ if (0 == (info.flags & ApplicationInfo.FLAG_INSTALLED)) {
+ // Need to reinstall the sample app
+ showStatusProfile();
+ } else if (devicePolicyManager.isApplicationHidden(
+ EnforcerDeviceAdminReceiver.getComponentName(this),
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
+ // The app is installed but hidden in this profile
+ showStatusProfile();
+ } else {
+ // Everything is clear; show the main screen
+ showMainFragment();
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ showStatusProfile();
+ }
}
}
}
@@ -46,10 +66,21 @@ public class MainActivity extends FragmentActivity {
.commit();
}
+ private void showStatusProfile() {
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.container, new StatusFragment())
+ .commit();
+ }
+
private void showMainFragment() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new AppRestrictionEnforcerFragment())
.commit();
}
+ @Override
+ public void onStatusUpdated() {
+ showMainFragment();
+ }
+
}
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java
new file mode 100644
index 00000000..f4a4eb79
--- /dev/null
+++ b/admin/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java
@@ -0,0 +1,136 @@
+/*
+ * 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.example.android.apprestrictionenforcer;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Provides UI for enabling the target app in this profile. The status of the app can be
+ * uninstalled, hidden, or enabled depending on the situations. This fragment shows suitable
+ * controls for each status.
+ */
+public class StatusFragment extends Fragment implements View.OnClickListener {
+
+ private TextView mTextStatus;
+ private Button mButtonUnhide;
+ private StatusUpdatedListener mListener;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_status, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ mTextStatus = (TextView) view.findViewById(R.id.status);
+ mButtonUnhide = (Button) view.findViewById(R.id.unhide);
+ mButtonUnhide.setOnClickListener(this);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ mListener = (StatusUpdatedListener) activity;
+ }
+
+ @Override
+ public void onDetach() {
+ mListener = null;
+ super.onDetach();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateUi(getActivity());
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.unhide: {
+ unhideApp(getActivity());
+ break;
+ }
+ }
+ }
+
+ private void updateUi(Activity activity) {
+ PackageManager packageManager = activity.getPackageManager();
+ try {
+ ApplicationInfo info = packageManager.getApplicationInfo(
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA,
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
+ if ((info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
+ if (!devicePolicyManager.isApplicationHidden(
+ EnforcerDeviceAdminReceiver.getComponentName(activity),
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
+ // The app is ready to enforce restrictions
+ // This is unlikely to happen in this sample as unhideApp() handles it.
+ mListener.onStatusUpdated();
+ } else {
+ // The app is installed but hidden in this profile
+ mTextStatus.setText(R.string.status_not_activated);
+ mButtonUnhide.setVisibility(View.VISIBLE);
+ }
+ } else {
+ // Need to reinstall the sample app
+ mTextStatus.setText(R.string.status_need_reinstall);
+ mButtonUnhide.setVisibility(View.GONE);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Need to reinstall the sample app
+ mTextStatus.setText(R.string.status_need_reinstall);
+ mButtonUnhide.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Unhides the AppRestrictionSchema sample in case it is hidden in this profile.
+ *
+ * @param activity The activity
+ */
+ private void unhideApp(Activity activity) {
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
+ devicePolicyManager.setApplicationHidden(
+ EnforcerDeviceAdminReceiver.getComponentName(activity),
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA, false);
+ Toast.makeText(activity, "Enabled the app", Toast.LENGTH_SHORT).show();
+ mListener.onStatusUpdated();
+ }
+
+ public interface StatusUpdatedListener {
+ public void onStatusUpdated();
+ }
+
+}
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml b/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml
index e6c50a24..01181916 100644
--- a/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml
+++ b/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml
@@ -14,31 +14,111 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingBottom="@dimen/vertical_page_margin"
- android:paddingLeft="@dimen/horizontal_page_margin"
- android:paddingRight="@dimen/horizontal_page_margin"
- android:paddingTop="@dimen/vertical_page_margin">
-
- <TextView
- android:id="@+id/status"
+ android:layout_height="match_parent">
+
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/status_not_installed" />
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin">
- <Button
- android:id="@+id/unhide"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/unhide" />
- <Switch
- android:id="@+id/say_hello"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/allow_saying_hello" />
+ <Switch
+ android:id="@+id/say_hello"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/allow_saying_hello"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:labelFor="@id/message"
+ android:text="@string/message"/>
+
+ <EditText
+ android:id="@id/message"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:inputType="text"
+ android:maxLines="1"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:labelFor="@id/number"
+ android:text="@string/number"/>
+
+ <EditText
+ android:id="@id/number"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:inputType="number"
+ android:maxLines="1"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/rank"/>
+
+ <Spinner
+ android:id="@+id/rank"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/margin_small"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/approvals"/>
+
+ <LinearLayout
+ android:id="@+id/approvals"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/margin_small"
+ android:orientation="vertical"/>
+
+ </LinearLayout>
+
+ </LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml b/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml
new file mode 100644
index 00000000..a2d60eb7
--- /dev/null
+++ b/admin/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 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:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin">
+
+ <TextView
+ android:id="@+id/status"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_not_installed"/>
+
+ <Button
+ android:id="@+id/unhide"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/unhide"/>
+
+</LinearLayout>
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml b/admin/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml
new file mode 100644
index 00000000..6927d801
--- /dev/null
+++ b/admin/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 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.
+-->
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="@dimen/margin_medium"
+ android:layout_marginTop="@dimen/margin_medium"
+ android:background="#9000"/>
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml b/admin/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml
new file mode 100644
index 00000000..04ba4ec2
--- /dev/null
+++ b/admin/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 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.
+-->
+<resources>
+ <item name="message" type="id"/>
+ <item name="number" type="id"/>
+ <item name="approval" type="id"/>
+</resources>
diff --git a/admin/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml b/admin/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml
index 3029e046..e35daee3 100644
--- a/admin/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml
+++ b/admin/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml
@@ -25,4 +25,8 @@
<string name="allowed">Allowed</string>
<string name="disallowed">Disallowed</string>
<string name="profile_name">AppRestrictionEnforcer </string>
+ <string name="message">Message: </string>
+ <string name="number">Number: </string>
+ <string name="rank">Rank: </string>
+ <string name="approvals">Approvals: </string>
</resources>
diff --git a/admin/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties b/admin/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties
index 0c71e760..f2e517b2 100644
--- a/admin/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties
+++ b/admin/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Mon Dec 01 16:00:44 JST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/admin/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java b/admin/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java
index 76f024f3..7b8dba83 100644
--- a/admin/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java
+++ b/admin/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java
@@ -17,10 +17,12 @@
package com.example.android.apprestrictionschema;
import android.content.Context;
+import android.content.RestrictionEntry;
import android.content.RestrictionsManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,6 +32,8 @@ import android.widget.Toast;
import com.example.android.common.logger.Log;
+import java.util.List;
+
/**
* Pressing the button on this fragment pops up a simple Toast message. The button is enabled or
* disabled according to the restrictions set by device/profile owner. You can use the
@@ -40,9 +44,21 @@ public class AppRestrictionSchemaFragment extends Fragment implements View.OnCli
// Tag for the logger
private static final String TAG = "AppRestrictionSchemaFragment";
+ private static final String KEY_CAN_SAY_HELLO = "can_say_hello";
+ private static final String KEY_MESSAGE = "message";
+ private static final String KEY_NUMBER = "number";
+ private static final String KEY_RANK = "rank";
+ private static final String KEY_APPROVALS = "approvals";
+
+ // Message to show when the button is clicked (String restriction)
+ private String mMessage;
+
// UI Components
private TextView mTextSayHello;
private Button mButtonSayHello;
+ private TextView mTextNumber;
+ private TextView mTextRank;
+ private TextView mTextApprovals;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -54,48 +70,103 @@ public class AppRestrictionSchemaFragment extends Fragment implements View.OnCli
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
mTextSayHello = (TextView) view.findViewById(R.id.say_hello_explanation);
mButtonSayHello = (Button) view.findViewById(R.id.say_hello);
+ mTextNumber = (TextView) view.findViewById(R.id.your_number);
+ mTextRank = (TextView) view.findViewById(R.id.your_rank);
+ mTextApprovals = (TextView) view.findViewById(R.id.approvals_you_have);
mButtonSayHello.setOnClickListener(this);
}
@Override
public void onResume() {
super.onResume();
- // Update the UI according to the configured restrictions
- RestrictionsManager restrictionsManager =
+ resolveRestrictions();
+ }
+
+ private void resolveRestrictions() {
+ RestrictionsManager manager =
(RestrictionsManager) getActivity().getSystemService(Context.RESTRICTIONS_SERVICE);
- Bundle restrictions = restrictionsManager.getApplicationRestrictions();
- updateUI(restrictions);
+ Bundle restrictions = manager.getApplicationRestrictions();
+ List<RestrictionEntry> entries = manager.getManifestRestrictions(getActivity().getApplicationContext().getPackageName());
+ for (RestrictionEntry entry : entries) {
+ String key = entry.getKey();
+ Log.d(TAG, "key: " + key);
+ if (key.equals(KEY_CAN_SAY_HELLO)) {
+ updateCanSayHello(entry, restrictions);
+ } else if (key.equals(KEY_MESSAGE)) {
+ updateMessage(entry, restrictions);
+ } else if (key.equals(KEY_NUMBER)) {
+ updateNumber(entry, restrictions);
+ } else if (key.equals(KEY_RANK)) {
+ updateRank(entry, restrictions);
+ } else if (key.equals(KEY_APPROVALS)) {
+ updateApprovals(entry, restrictions);
+ }
+ }
+ }
+
+ private void updateCanSayHello(RestrictionEntry entry, Bundle restrictions) {
+ boolean canSayHello;
+ if (restrictions == null || !restrictions.containsKey(KEY_CAN_SAY_HELLO)) {
+ canSayHello = entry.getSelectedState();
+ } else {
+ canSayHello = restrictions.getBoolean(KEY_CAN_SAY_HELLO);
+ }
+ mTextSayHello.setText(canSayHello ?
+ R.string.explanation_can_say_hello_true :
+ R.string.explanation_can_say_hello_false);
+ mButtonSayHello.setEnabled(canSayHello);
}
- private void updateUI(Bundle restrictions) {
- if (canSayHello(restrictions)) {
- mTextSayHello.setText(R.string.explanation_can_say_hello_true);
- mButtonSayHello.setEnabled(true);
+ private void updateMessage(RestrictionEntry entry, Bundle restrictions) {
+ if (restrictions == null || !restrictions.containsKey(KEY_MESSAGE)) {
+ mMessage = entry.getSelectedString();
} else {
- mTextSayHello.setText(R.string.explanation_can_say_hello_false);
- mButtonSayHello.setEnabled(false);
+ mMessage = restrictions.getString(KEY_MESSAGE);
}
}
- /**
- * Returns the current status of the restriction.
- *
- * @param restrictions The application restrictions
- * @return True if the app is allowed to say hello
- */
- private boolean canSayHello(Bundle restrictions) {
- final boolean defaultValue = false;
- boolean canSayHello = restrictions == null ? defaultValue :
- restrictions.getBoolean("can_say_hello", defaultValue);
- Log.d(TAG, "canSayHello: " + canSayHello);
- return canSayHello;
+ private void updateNumber(RestrictionEntry entry, Bundle restrictions) {
+ int number;
+ if (restrictions == null || !restrictions.containsKey(KEY_NUMBER)) {
+ number = entry.getIntValue();
+ } else {
+ number = restrictions.getInt(KEY_NUMBER);
+ }
+ mTextNumber.setText(getString(R.string.your_number, number));
+ }
+
+ private void updateRank(RestrictionEntry entry, Bundle restrictions) {
+ String rank;
+ if (restrictions == null || !restrictions.containsKey(KEY_RANK)) {
+ rank = entry.getSelectedString();
+ } else {
+ rank = restrictions.getString(KEY_RANK);
+ }
+ mTextRank.setText(getString(R.string.your_rank, rank));
+ }
+
+ private void updateApprovals(RestrictionEntry entry, Bundle restrictions) {
+ String[] approvals;
+ if (restrictions == null || !restrictions.containsKey(KEY_APPROVALS)) {
+ approvals = entry.getAllSelectedStrings();
+ } else {
+ approvals = restrictions.getStringArray(KEY_APPROVALS);
+ }
+ String text;
+ if (approvals == null || approvals.length == 0) {
+ text = getString(R.string.none);
+ } else {
+ text = TextUtils.join(", ", approvals);
+ }
+ mTextApprovals.setText(getString(R.string.approvals_you_have, text));
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.say_hello: {
- Toast.makeText(getActivity(), R.string.message_hello, Toast.LENGTH_SHORT).show();
+ Toast.makeText(getActivity(), getString(R.string.message, mMessage),
+ Toast.LENGTH_SHORT).show();
break;
}
}
diff --git a/admin/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml b/admin/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml
index fc5e23dc..18ca0a4d 100644
--- a/admin/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml
+++ b/admin/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml
@@ -14,24 +14,60 @@ 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:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="@dimen/margin_medium">
-
- <TextView
- android:id="@+id/say_hello_explanation"
+
+
+<ScrollView 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">
+
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/explanation_can_say_hello_true"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:orientation="vertical"
+ android:padding="@dimen/margin_medium">
- <Button
- android:id="@+id/say_hello"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/margin_medium"
- android:text="@string/action_can_say_hello" />
+ <TextView
+ android:id="@+id/say_hello_explanation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/explanation_can_say_hello_true"/>
+
+ <Button
+ android:id="@+id/say_hello"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/margin_medium"
+ android:text="@string/action_can_say_hello"/>
+
+ <include layout="@layout/separator"/>
+
+ <TextView
+ android:id="@+id/your_number"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/your_number"/>
+
+ <include layout="@layout/separator"/>
+
+ <TextView
+ android:id="@+id/your_rank"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/your_rank"/>
+
+ <include layout="@layout/separator"/>
+
+ <TextView
+ android:id="@+id/approvals_you_have"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/approvals_you_have"/>
+
+ </LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/admin/AppRestrictionSchema/Application/src/main/res/layout/separator.xml b/admin/AppRestrictionSchema/Application/src/main/res/layout/separator.xml
new file mode 100644
index 00000000..6927d801
--- /dev/null
+++ b/admin/AppRestrictionSchema/Application/src/main/res/layout/separator.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 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.
+-->
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="@dimen/margin_medium"
+ android:layout_marginTop="@dimen/margin_medium"
+ android:background="#9000"/>
diff --git a/admin/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml b/admin/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml
new file mode 100644
index 00000000..558d097f
--- /dev/null
+++ b/admin/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 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.
+-->
+<resources>
+
+ <!-- Bool restriction -->
+ <string name="title_can_say_hello">Can say hello</string>
+ <string name="description_can_say_hello">Whether the app can say hello to the user</string>
+ <bool name="default_can_say_hello">false</bool>
+
+ <!-- String restriction -->
+ <string name="title_message">Message</string>
+ <string name="description_message">A message string to show</string>
+ <string name="default_message">Hello!</string>
+
+ <!-- Integer restriction -->
+ <string name="title_number">Number</string>
+ <string name="description_number">Sample integer value</string>
+ <integer name="default_number">32582657</integer>
+
+ <!-- Choice restriction -->
+ <string name="title_rank">Rank</string>
+ <string name="description_rank">Rank of the user</string>
+ <string-array name="entries_rank">
+ <item>Apprentice</item>
+ <item>Intermediate</item>
+ <item>Master</item>
+ </string-array>
+ <string name="entry_value_rank_apprentice">apprentice</string>
+ <string name="entry_value_rank_intermediate">intermediate</string>
+ <string name="entry_value_rank_master">master</string>
+ <string-array name="entry_values_rank">
+ <item>@string/entry_value_rank_apprentice</item>
+ <item>@string/entry_value_rank_intermediate</item>
+ <item>@string/entry_value_rank_master</item>
+ </string-array>
+ <string name="default_rank">@string/entry_value_rank_apprentice</string>
+
+ <!-- Multi-select restriction -->
+ <string name="title_approvals">Approvals</string>
+ <string name="description_approvals">Approvals</string>
+ <string-array name="entries_approvals">
+ <item>Read</item>
+ <item>Write</item>
+ <item>Execute</item>
+ </string-array>
+ <string name="entry_value_approvals_read">read</string>
+ <string name="entry_value_approvals_write">write</string>
+ <string name="entry_value_approvals_execute">execute</string>
+ <string-array name="entry_values_approvals">
+ <item>@string/entry_value_approvals_read</item>
+ <item>@string/entry_value_approvals_write</item>
+ <item>@string/entry_value_approvals_execute</item>
+ </string-array>
+ <string-array name="default_approvals">
+ <!-- Empty -->
+ </string-array>
+
+ <!-- Hidden restriction -->
+ <string name="title_secret_code">Secret code</string>
+ <string name="description_secret_code">This restriction is hidden and will not be shown to the administrator.</string>
+ <string name="default_secret_code">(Hidden restriction must have some default value)</string>
+
+</resources>
diff --git a/admin/AppRestrictionSchema/Application/src/main/res/values/strings.xml b/admin/AppRestrictionSchema/Application/src/main/res/values/strings.xml
index b8ef110b..6dce123f 100644
--- a/admin/AppRestrictionSchema/Application/src/main/res/values/strings.xml
+++ b/admin/AppRestrictionSchema/Application/src/main/res/values/strings.xml
@@ -16,11 +16,14 @@ limitations under the License.
-->
<resources>
- <string name="title_can_say_hello">Can say hello</string>
- <string name="description_can_say_hello">Whether the app can say hello to the user</string>
<string name="explanation_can_say_hello_true">I can say hello to you.</string>
<string name="explanation_can_say_hello_false">I am restricted from saying hello to you.</string>
<string name="action_can_say_hello">Say hello</string>
- <string name="message_hello">Hello!</string>
+ <string name="message">All I can say is \"%s\".</string>
-</resources> \ No newline at end of file
+ <string name="your_number">Your number: %d</string>
+ <string name="your_rank">Your rank: %s</string>
+ <string name="approvals_you_have">Approvals you have: %s</string>
+ <string name="none">none</string>
+
+</resources>
diff --git a/admin/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml b/admin/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml
index 409527fc..9e47f458 100644
--- a/admin/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml
+++ b/admin/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml
@@ -16,11 +16,55 @@ limitations under the License.
-->
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
+ <!--
+ Refer to the javadoc of RestrictionsManager for detail of this file.
+ https://developer.android.com/reference/android/content/RestrictionsManager.html
+ -->
+
<restriction
- android:defaultValue="false"
+ android:defaultValue="@bool/default_can_say_hello"
android:description="@string/description_can_say_hello"
android:key="can_say_hello"
android:restrictionType="bool"
- android:title="@string/title_can_say_hello" />
+ android:title="@string/title_can_say_hello"/>
+
+ <restriction
+ android:defaultValue="@string/default_message"
+ android:description="@string/description_message"
+ android:key="message"
+ android:restrictionType="string"
+ android:title="@string/title_message"/>
+
+ <restriction
+ android:defaultValue="@integer/default_number"
+ android:description="@string/description_number"
+ android:key="number"
+ android:restrictionType="integer"
+ android:title="@string/title_number"/>
+
+ <restriction
+ android:defaultValue="@string/default_rank"
+ android:description="@string/description_rank"
+ android:entries="@array/entries_rank"
+ android:entryValues="@array/entry_values_rank"
+ android:key="rank"
+ android:restrictionType="choice"
+ android:title="@string/title_rank"/>
+
+ <restriction
+ android:defaultValue="@array/default_approvals"
+ android:description="@string/description_approvals"
+ android:entries="@array/entries_approvals"
+ android:entryValues="@array/entry_values_approvals"
+ android:key="approvals"
+ android:restrictionType="multi-select"
+ android:title="@string/title_approvals"/>
+
+ <restriction
+ android:defaultValue="@string/default_secret_code"
+ android:description="@string/description_secret_code"
+ android:key="secret_code"
+ android:restrictionType="hidden"
+ android:title="@string/title_secret_code"/>
</restrictions>
diff --git a/admin/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties b/admin/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties
index 0c71e760..fb79885e 100644
--- a/admin/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties
+++ b/admin/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Mon Dec 01 11:44:58 JST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME