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.content.pm.ApplicationInfo;
26
import android.content.pm.PackageManager;
27
import android.os.Bundle;
28
import android.support.annotation.Nullable;
29
import android.support.v4.app.Fragment;
30
import android.view.LayoutInflater;
31
import android.view.View;
32
import android.view.ViewGroup;
33
import android.widget.Button;
34
import android.widget.CompoundButton;
35
import android.widget.Switch;
36
import android.widget.TextView;
37
import android.widget.Toast;
38
 
39
import java.util.List;
40
 
41
/**
42
 * This fragment provides UI and functionality to set restrictions on the AppRestrictionSchema
43
 * sample.
44
 */
45
public class AppRestrictionEnforcerFragment extends Fragment implements View.OnClickListener,
46
        CompoundButton.OnCheckedChangeListener {
47
 
48
    /**
49
     * Package name of the AppRestrictionSchema sample.
50
     */
51
    private static final String PACKAGE_NAME_APP_RESTRICTION_SCHEMA
52
            = "com.example.android.apprestrictionschema";
53
 
54
    /**
55
     * Key for {@link SharedPreferences}
56
     */
57
    private static final String PREFS_KEY = "AppRestrictionEnforcerFragment";
58
 
59
    /**
60
     * Key for the boolean restriction in AppRestrictionSchema.
61
     */
62
    private static final String RESTRICTION_KEY_SAY_HELLO = "can_say_hello";
63
 
64
    /**
65
     * Default boolean value for "can_say_hello" restriction. The actual value is loaded in
66
     * {@link #loadRestrictions(android.app.Activity)}.
67
     */
68
    private boolean mDefaultValueRestrictionSayHello;
69
 
70
    // UI Components
71
    private TextView mTextStatus;
72
    private Button mButtonUnhide;
73
    private Switch mSwitchSayHello;
74
 
75
    @Override
76
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
77
                             @Nullable Bundle savedInstanceState) {
78
        return inflater.inflate(R.layout.fragment_app_restriction_enforcer, container, false);
79
    }
80
 
81
    @Override
82
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
83
        mTextStatus = (TextView) view.findViewById(R.id.status);
84
        mButtonUnhide = (Button) view.findViewById(R.id.unhide);
85
        mSwitchSayHello = (Switch) view.findViewById(R.id.say_hello);
86
        mButtonUnhide.setOnClickListener(this);
87
        mSwitchSayHello.setOnCheckedChangeListener(this);
88
    }
89
 
90
    @Override
91
    public void onResume() {
92
        super.onResume();
93
        updateUi(getActivity());
94
    }
95
 
96
    @Override
97
    public void onClick(View view) {
98
        switch (view.getId()) {
99
            case R.id.unhide: {
100
                unhideApp(getActivity());
101
                break;
102
            }
103
        }
104
    }
105
 
106
    @Override
107
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
108
        switch (compoundButton.getId()) {
109
            case R.id.say_hello: {
110
                allowSayHello(getActivity(), checked);
111
                break;
112
            }
113
        }
114
    }
115
 
116
    /**
117
     * Updates the UI components according to the current status of AppRestrictionSchema and its
118
     * restriction.
119
     *
120
     * @param activity The activity
121
     */
122
    private void updateUi(Activity activity) {
123
        PackageManager packageManager = activity.getPackageManager();
124
        try {
125
            ApplicationInfo info = packageManager.getApplicationInfo(
126
                    PACKAGE_NAME_APP_RESTRICTION_SCHEMA, PackageManager.GET_UNINSTALLED_PACKAGES);
127
            DevicePolicyManager devicePolicyManager =
128
                    (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
129
            if (0 < (info.flags & ApplicationInfo.FLAG_INSTALLED)) {
130
                if (!devicePolicyManager.isApplicationHidden(
131
                        EnforcerDeviceAdminReceiver.getComponentName(activity),
132
                        PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
133
                    // The app is ready
134
                    loadRestrictions(activity);
135
                    mTextStatus.setVisibility(View.GONE);
136
                    mButtonUnhide.setVisibility(View.GONE);
137
                    mSwitchSayHello.setVisibility(View.VISIBLE);
138
                    mSwitchSayHello.setOnCheckedChangeListener(null);
139
                    mSwitchSayHello.setChecked(canSayHello(activity));
140
                    mSwitchSayHello.setOnCheckedChangeListener(this);
141
                } else {
142
                    // The app is installed but hidden in this profile
143
                    mTextStatus.setText(R.string.status_not_activated);
144
                    mTextStatus.setVisibility(View.VISIBLE);
145
                    mButtonUnhide.setVisibility(View.VISIBLE);
146
                    mSwitchSayHello.setVisibility(View.GONE);
147
                }
148
            } else {
149
                // Need to reinstall the sample app
150
                mTextStatus.setText(R.string.status_need_reinstall);
151
                mTextStatus.setVisibility(View.VISIBLE);
152
                mButtonUnhide.setVisibility(View.GONE);
153
                mSwitchSayHello.setVisibility(View.GONE);
154
            }
155
        } catch (PackageManager.NameNotFoundException e) {
156
            mTextStatus.setText(R.string.status_not_installed);
157
            mTextStatus.setVisibility(View.VISIBLE);
158
            mButtonUnhide.setVisibility(View.GONE);
159
            mSwitchSayHello.setVisibility(View.GONE);
160
        }
161
    }
162
 
163
    /**
164
     * Unhides the AppRestrictionSchema sample in case it is hidden in this profile.
165
     *
166
     * @param activity The activity
167
     */
168
    private void unhideApp(Activity activity) {
169
        DevicePolicyManager devicePolicyManager =
170
                (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
171
        devicePolicyManager.setApplicationHidden(
172
                EnforcerDeviceAdminReceiver.getComponentName(activity),
173
                PACKAGE_NAME_APP_RESTRICTION_SCHEMA, false);
174
        Toast.makeText(activity, "Enabled the app", Toast.LENGTH_SHORT).show();
175
        updateUi(activity);
176
    }
177
 
178
    /**
179
     * Loads the restrictions for the AppRestrictionSchema sample. In this implementation, we just
180
     * read the default value for the "can_say_hello" restriction.
181
     *
182
     * @param activity The activity
183
     */
184
    private void loadRestrictions(Activity activity) {
185
        RestrictionsManager restrictionsManager =
186
                (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
187
        List<RestrictionEntry> restrictions =
188
                restrictionsManager.getManifestRestrictions(PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
189
        for (RestrictionEntry restriction : restrictions) {
190
            if (RESTRICTION_KEY_SAY_HELLO.equals(restriction.getKey())) {
191
                mDefaultValueRestrictionSayHello = restriction.getSelectedState();
192
            }
193
        }
194
    }
195
 
196
    /**
197
     * Returns whether the AppRestrictionSchema is currently allowed to say hello to its user. Note
198
     * that a profile/device owner needs to remember each restriction value on its own.
199
     *
200
     * @param activity The activity
201
     * @return True if the AppRestrictionSchema is allowed to say hello
202
     */
203
    private boolean canSayHello(Activity activity) {
204
        SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
205
        return prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO, mDefaultValueRestrictionSayHello);
206
    }
207
 
208
    /**
209
     * Sets the value for the "cay_say_hello" restriction of AppRestrictionSchema.
210
     *
211
     * @param activity The activity
212
     * @param allow    The value to be set for the restriction.
213
     */
214
    private void allowSayHello(Activity activity, boolean allow) {
215
        DevicePolicyManager devicePolicyManager
216
                = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
217
        Bundle restrictions = new Bundle();
218
        restrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
219
        devicePolicyManager.setApplicationRestrictions(
220
                EnforcerDeviceAdminReceiver.getComponentName(activity),
221
                PACKAGE_NAME_APP_RESTRICTION_SCHEMA, restrictions);
222
        // The profile/device owner needs to remember the current state of restrictions on its own
223
        activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
224
                .edit()
225
                .putBoolean(RESTRICTION_KEY_SAY_HELLO, allow)
226
                .apply();
227
        Toast.makeText(activity, allow ? R.string.allowed : R.string.disallowed,
228
                Toast.LENGTH_SHORT).show();
229
    }
230
 
231
}