Skip to content

Most visited

Recently visited

navigation
AppRestrictionEnforcer / src / com.example.android.apprestrictionenforcer /

AppRestrictionEnforcerFragment.java

1
/*
2
 * Copyright (C) 2014 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
package com.example.android.apprestrictionenforcer;
18
 
19
import android.app.Activity;
20
import android.app.admin.DevicePolicyManager;
21
import android.content.Context;
22
import android.content.RestrictionEntry;
23
import android.content.RestrictionsManager;
24
import android.content.SharedPreferences;
25
import android.os.Build;
26
import android.os.Bundle;
27
import android.os.Parcelable;
28
import android.support.annotation.NonNull;
29
import android.support.annotation.Nullable;
30
import android.support.v4.app.Fragment;
31
import android.text.Editable;
32
import android.text.TextUtils;
33
import android.text.TextWatcher;
34
import android.view.LayoutInflater;
35
import android.view.View;
36
import android.view.ViewGroup;
37
import android.widget.AdapterView;
38
import android.widget.ArrayAdapter;
39
import android.widget.Button;
40
import android.widget.CompoundButton;
41
import android.widget.EditText;
42
import android.widget.LinearLayout;
43
import android.widget.Spinner;
44
import android.widget.Switch;
45
import android.widget.TextView;
46
import android.widget.Toast;
47
 
48
import java.util.ArrayList;
49
import java.util.Arrays;
50
import java.util.HashMap;
51
import java.util.List;
52
import java.util.Map;
53
 
54
/**
55
 * This fragment provides UI and functionality to set restrictions on the AppRestrictionSchema
56
 * sample.
57
 */
58
public class AppRestrictionEnforcerFragment extends Fragment implements
59
        CompoundButton.OnCheckedChangeListener, AdapterView.OnItemSelectedListener,
60
        View.OnClickListener, ItemAddFragment.OnItemAddedListener {
61
 
62
    /**
63
     * Key for {@link SharedPreferences}
64
     */
65
    private static final String PREFS_KEY = "AppRestrictionEnforcerFragment";
66
 
67
    /**
68
     * Key for the boolean restriction in AppRestrictionSchema.
69
     */
70
    private static final String RESTRICTION_KEY_SAY_HELLO = "can_say_hello";
71
 
72
    /**
73
     * Key for the string restriction in AppRestrictionSchema.
74
     */
75
    private static final String RESTRICTION_KEY_MESSAGE = "message";
76
 
77
    /**
78
     * Key for the integer restriction in AppRestrictionSchema.
79
     */
80
    private static final String RESTRICTION_KEY_NUMBER = "number";
81
 
82
    /**
83
     * Key for the choice restriction in AppRestrictionSchema.
84
     */
85
    private static final String RESTRICTION_KEY_RANK = "rank";
86
 
87
    /**
88
     * Key for the multi-select restriction in AppRestrictionSchema.
89
     */
90
    private static final String RESTRICTION_KEY_APPROVALS = "approvals";
91
 
92
    /**
93
     * Key for the bundle array restriction in AppRestrictionSchema.
94
     */
95
    private static final String RESTRICTION_KEY_ITEMS = "items";
96
    private static final String RESTRICTION_KEY_ITEM_KEY = "key";
97
    private static final String RESTRICTION_KEY_ITEM_VALUE = "value";
98
 
99
    private static final String DELIMETER = ",";
100
    private static final String SEPARATOR = ":";
101
 
102
    private static final boolean BUNDLE_SUPPORTED = Build.VERSION.SDK_INT >= 23;
103
 
104
    /**
105
     * Current status of the restrictions.
106
     */
107
    private Bundle mCurrentRestrictions = new Bundle();
108
 
109
    // UI Components
110
    private Switch mSwitchSayHello;
111
    private EditText mEditMessage;
112
    private EditText mEditNumber;
113
    private Spinner mSpinnerRank;
114
    private LinearLayout mLayoutApprovals;
115
    private LinearLayout mLayoutItems;
116
 
117
    @Override
118
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
119
                             @Nullable Bundle savedInstanceState) {
120
        return inflater.inflate(R.layout.fragment_app_restriction_enforcer, container, false);
121
    }
122
 
123
    @Override
124
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
125
        // Retain references for the UI elements
126
        mSwitchSayHello = (Switch) view.findViewById(R.id.say_hello);
127
        mEditMessage = (EditText) view.findViewById(R.id.message);
128
        mEditNumber = (EditText) view.findViewById(R.id.number);
129
        mSpinnerRank = (Spinner) view.findViewById(R.id.rank);
130
        mLayoutApprovals = (LinearLayout) view.findViewById(R.id.approvals);
131
        mLayoutItems = (LinearLayout) view.findViewById(R.id.items);
132
        view.findViewById(R.id.item_add).setOnClickListener(this);
133
        View bundleArrayLayout = view.findViewById(R.id.bundle_array_layout);
134
        if (BUNDLE_SUPPORTED) {
135
            bundleArrayLayout.setVisibility(View.VISIBLE);
136
        } else {
137
            bundleArrayLayout.setVisibility(View.GONE);
138
        }
139
    }
140
 
141
    @Override
142
    public void onResume() {
143
        super.onResume();
144
        loadRestrictions(getActivity());
145
    }
146
 
147
    @Override
148
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
149
        switch (compoundButton.getId()) {
150
            case R.id.say_hello: {
151
                saveCanSayHello(getActivity(), checked);
152
                break;
153
            }
154
            case R.id.approval: {
155
                if (checked) {
156
                    addApproval(getActivity(), (String) compoundButton.getTag());
157
                } else {
158
                    removeApproval(getActivity(), (String) compoundButton.getTag());
159
                }
160
                break;
161
            }
162
        }
163
    }
164
 
165
    private TextWatcher mWatcherMessage = new EasyTextWatcher() {
166
        @Override
167
        public void afterTextChanged(Editable s) {
168
            saveMessage(getActivity(), s.toString());
169
        }
170
    };
171
 
172
    private TextWatcher mWatcherNumber = new EasyTextWatcher() {
173
        @Override
174
        public void afterTextChanged(Editable s) {
175
            try {
176
                String string = s.toString();
177
                if (!TextUtils.isEmpty(string)) {
178
                    saveNumber(getActivity(), Integer.parseInt(string));
179
                }
180
            } catch (NumberFormatException e) {
181
                Toast.makeText(getActivity(), "Not an integer!", Toast.LENGTH_SHORT).show();
182
            }
183
        }
184
    };
185
 
186
    @Override
187
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
188
        switch (parent.getId()) {
189
            case R.id.rank: {
190
                saveRank(getActivity(), (String) parent.getAdapter().getItem(position));
191
                break;
192
            }
193
        }
194
    }
195
 
196
    @Override
197
    public void onNothingSelected(AdapterView<?> parent) {
198
        // Nothing to do
199
    }
200
 
201
    @Override
202
    public void onClick(View v) {
203
        switch (v.getId()) {
204
            case R.id.item_add:
205
                new ItemAddFragment().show(getChildFragmentManager(), "dialog");
206
                break;
207
            case R.id.item_remove:
208
                String key = (String) v.getTag();
209
                removeItem(key);
210
                mLayoutItems.removeView((View) v.getParent());
211
                break;
212
        }
213
    }
214
 
215
    @Override
216
    public void onItemAdded(String key, String value) {
217
        key = TextUtils.replace(key,
218
                new String[]{DELIMETER, SEPARATOR}, new String[]{"", ""}).toString();
219
        value = TextUtils.replace(value,
220
                new String[]{DELIMETER, SEPARATOR}, new String[]{"", ""}).toString();
221
        Parcelable[] parcelables = mCurrentRestrictions.getParcelableArray(RESTRICTION_KEY_ITEMS);
222
        Map<String, String> items = new HashMap<>();
223
        if (parcelables != null) {
224
            for (Parcelable parcelable : parcelables) {
225
                Bundle bundle = (Bundle) parcelable;
226
                items.put(bundle.getString(RESTRICTION_KEY_ITEM_KEY),
227
                        bundle.getString(RESTRICTION_KEY_ITEM_VALUE));
228
            }
229
        }
230
        items.put(key, value);
231
        insertItemRow(LayoutInflater.from(getActivity()), key, value);
232
        saveItems(getActivity(), items);
233
    }
234
 
235
    /**
236
     * Loads the restrictions for the AppRestrictionSchema sample.
237
     *
238
     * @param activity The activity
239
     */
240
    private void loadRestrictions(Activity activity) {
241
        RestrictionsManager manager =
242
                (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
243
        List<RestrictionEntry> restrictions =
244
                manager.getManifestRestrictions(Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
245
        SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
246
        for (RestrictionEntry restriction : restrictions) {
247
            String key = restriction.getKey();
248
            if (RESTRICTION_KEY_SAY_HELLO.equals(key)) {
249
                updateCanSayHello(prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO,
250
                        restriction.getSelectedState()));
251
            } else if (RESTRICTION_KEY_MESSAGE.equals(key)) {
252
                updateMessage(prefs.getString(RESTRICTION_KEY_MESSAGE,
253
                        restriction.getSelectedString()));
254
            } else if (RESTRICTION_KEY_NUMBER.equals(key)) {
255
                updateNumber(prefs.getInt(RESTRICTION_KEY_NUMBER,
256
                        restriction.getIntValue()));
257
            } else if (RESTRICTION_KEY_RANK.equals(key)) {
258
                updateRank(activity, restriction.getChoiceValues(),
259
                        prefs.getString(RESTRICTION_KEY_RANK, restriction.getSelectedString()));
260
            } else if (RESTRICTION_KEY_APPROVALS.equals(key)) {
261
                updateApprovals(activity, restriction.getChoiceValues(),
262
                        TextUtils.split(prefs.getString(RESTRICTION_KEY_APPROVALS,
263
                                        TextUtils.join(DELIMETER,
264
                                                restriction.getAllSelectedStrings())),
265
                                DELIMETER));
266
            } else if (BUNDLE_SUPPORTED && RESTRICTION_KEY_ITEMS.equals(key)) {
267
                String itemsString = prefs.getString(RESTRICTION_KEY_ITEMS, "");
268
                HashMap<String, String> items = new HashMap<>();
269
                for (String itemString : TextUtils.split(itemsString, DELIMETER)) {
270
                    String[] strings = itemString.split(SEPARATOR, 2);
271
                    items.put(strings[0], strings[1]);
272
                }
273
                updateItems(activity, items);
274
            }
275
        }
276
    }
277
 
278
    private void updateCanSayHello(boolean canSayHello) {
279
        mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, canSayHello);
280
        mSwitchSayHello.setOnCheckedChangeListener(null);
281
        mSwitchSayHello.setChecked(canSayHello);
282
        mSwitchSayHello.setOnCheckedChangeListener(this);
283
    }
284
 
285
    private void updateMessage(String message) {
286
        mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
287
        mEditMessage.removeTextChangedListener(mWatcherMessage);
288
        mEditMessage.setText(message);
289
        mEditMessage.addTextChangedListener(mWatcherMessage);
290
    }
291
 
292
    private void updateNumber(int number) {
293
        mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
294
        mEditNumber.removeTextChangedListener(mWatcherNumber);
295
        mEditNumber.setText(String.valueOf(number));
296
        mEditNumber.addTextChangedListener(mWatcherNumber);
297
    }
298
 
299
    private void updateRank(Context context, String[] ranks, String selectedRank) {
300
        mCurrentRestrictions.putString(RESTRICTION