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
17package com.android.tv.settings.device.apps;
18
19import com.android.tv.settings.ActionBehavior;
20import com.android.tv.settings.ActionKey;
21import com.android.tv.settings.R;
22import com.android.tv.settings.SettingsConstant;
23import com.android.tv.settings.device.apps.ApplicationsState.AppEntry;
24import com.android.tv.settings.dialog.old.Action;
25import com.android.tv.settings.dialog.old.ActionAdapter;
26import com.android.tv.settings.dialog.old.ActionFragment;
27import com.android.tv.settings.dialog.old.ContentFragment;
28import com.android.tv.settings.dialog.old.DialogActivity;
29
30import android.content.ComponentName;
31import android.content.Context;
32import android.content.Intent;
33import android.net.Uri;
34import android.os.Bundle;
35import android.util.Log;
36
37import java.util.ArrayList;
38
39/**
40 * Activity that manages an apps.
41 */
42public class AppManagementActivity extends DialogActivity implements ActionAdapter.Listener,
43        ApplicationsState.Callbacks, DataClearer.Listener, CacheClearer.Listener,
44        DefaultClearer.Listener {
45
46    private static final String TAG = "AppManagementActivity";
47
48    private static final String EXTRA_PACKAGE_NAME_KEY = SettingsConstant.PACKAGE
49            + ".device.apps.PACKAGE_NAME";
50
51    // Result code identifiers
52    private static final int REQUEST_UNINSTALL = 1;
53    private static final int REQUEST_MANAGE_SPACE = 2;
54
55    private String mPackageName;
56    private ApplicationsState mApplicationsState;
57    private ApplicationsState.Session mSession;
58    private AppInfo mAppInfo;
59    private OpenManager mOpenManager;
60    private ForceStopManager mForceStopManager;
61    private UninstallManager mUninstallManager;
62    private NotificationSetter mNotificationSetter;
63    private DataClearer mDataClearer;
64    private DefaultClearer mDefaultClearer;
65    private CacheClearer mCacheClearer;
66    private ActionFragment mActionFragment;
67
68    @Override
69    protected void onCreate(Bundle savedInstanceState) {
70        super.onCreate(savedInstanceState);
71        mPackageName = getIntent().getStringExtra(EXTRA_PACKAGE_NAME_KEY);
72        mApplicationsState = ApplicationsState.getInstance(getApplication());
73        mAppInfo = new AppInfo(this, mApplicationsState.getEntry(mPackageName));
74        mOpenManager = new OpenManager(this, mAppInfo);
75        mForceStopManager = new ForceStopManager(this, mAppInfo);
76        mUninstallManager = new UninstallManager(this, mAppInfo);
77        mNotificationSetter = new NotificationSetter(mAppInfo);
78        mDataClearer = new DataClearer(this, mAppInfo);
79        mDefaultClearer = new DefaultClearer(this, mAppInfo);
80        mCacheClearer = new CacheClearer(this, mAppInfo);
81        mActionFragment = ActionFragment.newInstance(getActions());
82        mSession = mApplicationsState.newSession(this);
83        mSession.resume();
84
85        setContentAndActionFragments(ContentFragment.newInstance(mAppInfo.getName(),
86                getString(R.string.device_apps),
87                getString(R.string.device_apps_app_management_version, mAppInfo.getVersion()),
88                Uri.parse(AppsBrowseInfo.getAppIconUri(this, mAppInfo)),
89                getResources().getColor(R.color.icon_background)), mActionFragment);
90    }
91
92    public static Intent getLaunchIntent(String packageName) {
93        Intent i = new Intent();
94        i.setComponent(new ComponentName(SettingsConstant.PACKAGE,
95                SettingsConstant.PACKAGE + ".device.apps.AppManagementActivity"));
96        i.putExtra(AppManagementActivity.EXTRA_PACKAGE_NAME_KEY, packageName);
97        return i;
98    }
99
100    @Override
101    public void onActionClicked(Action action) {
102        ActionKey<ActionType, ActionBehavior> actionKey = new ActionKey<ActionType, ActionBehavior>(
103                ActionType.class, ActionBehavior.class, action.getKey());
104        ActionType actionType = actionKey.getType();
105
106        switch (actionKey.getBehavior()) {
107            case INIT:
108                onInit(actionType, action);
109                break;
110            case OK:
111                onOk(actionType);
112                break;
113            case CANCEL:
114                onCancel(actionType);
115                break;
116            case ON:
117                onOn(actionType);
118                break;
119            case OFF:
120                onOff(actionType);
121                break;
122            default:
123                break;
124        }
125    }
126
127    @Override
128    public void onActivityResult(int requestCode, int resultCode, Intent data) {
129        super.onActivityResult(requestCode, resultCode, data);
130        switch (requestCode) {
131            case REQUEST_UNINSTALL:
132                if (resultCode == RESULT_OK) {
133                    mApplicationsState.removePackage(mPackageName);
134                    goToAppSelectScreen();
135                }
136                break;
137            case REQUEST_MANAGE_SPACE:
138                mDataClearer.onActivityResult(resultCode);
139                break;
140        }
141    }
142
143    @Override
144    public void onRunningStateChanged(boolean running) {
145    }
146
147    @Override
148    public void onPackageListChanged() {
149    }
150
151    @Override
152    public void onRebuildComplete() {
153    }
154
155    @Override
156    public void onPackageIconChanged() {
157    }
158
159    @Override
160    public void onPackageSizeChanged(String packageName) {
161    }
162
163    @Override
164    public void onAllSizesComputed() {
165        updateActions();
166    }
167
168    @Override
169    public void dataCleared(boolean succeeded) {
170        if (succeeded) {
171            mApplicationsState.requestSize(mPackageName);
172        } else {
173            Log.w(TAG, "Failed to clear data!");
174            updateActions();
175        }
176    }
177
178    @Override
179    public void defaultCleared() {
180        updateActions();
181    }
182
183    @Override
184    public void cacheCleared(boolean succeeded) {
185        if (succeeded) {
186            mApplicationsState.requestSize(mPackageName);
187        } else {
188            Log.w(TAG, "Failed to clear cache!");
189            updateActions();
190        }
191    }
192
193    private void onInit(ActionType actionType, Action action) {
194        switch (actionType) {
195            case OPEN:
196                onOpen();
197                break;
198            case PERMISSIONS:
199                setContentAndActionFragments(createContentFragment(actionType, action),
200                        PermissionsFragment.newInstance(mPackageName));
201                break;
202            case NOTIFICATIONS:
203                setContentAndActionFragments(createContentFragment(actionType,
204                        action), ActionFragment.newInstance(actionType.toSelectableActions(
205                        getResources(),
206                        (mNotificationSetter.areNotificationsOn()) ? ActionBehavior.ON
207                                : ActionBehavior.OFF)));
208                break;
209            default:
210                setContentAndActionFragments(createContentFragment(actionType, action),
211                        ActionFragment.newInstance(actionType.toActions(getResources())));
212                break;
213        }
214    }
215
216    private ContentFragment createContentFragment(ActionType actionType, Action action) {
217        String description = actionType.getDesc(getResources());
218        String description2 = actionType.getDesc2(getResources());
219        String descriptionToUse = null;
220        if (description != null) {
221            if (description2 != null) {
222                descriptionToUse = description + "\n" + description2;
223            } else {
224                descriptionToUse = description;
225            }
226        } else if (description2 != null) {
227            descriptionToUse = description2;
228        }
229        return ContentFragment.newInstance(action.getTitle(), mAppInfo.getName(), descriptionToUse,
230                Uri.parse(AppsBrowseInfo.getAppIconUri(this, mAppInfo)),
231                getResources().getColor(R.color.icon_background));
232    }
233
234    private void onOk(ActionType actionType) {
235        switch (actionType) {
236            case CLEAR_CACHE:
237                onClearCacheOk();
238                break;
239            case CLEAR_DATA:
240                onClearDataOk();
241                break;
242            case CLEAR_DEFAULTS:
243                onClearDefaultOk();
244                break;
245            case FORCE_STOP:
246                onForceStopOk();
247                break;
248            case UNINSTALL:
249                onUninstallOk();
250                break;
251            default:
252                break;
253        }
254    }
255
256    private void onCancel(ActionType actionType) {
257        goToActionSelectScreen();
258    }
259
260    private void onOn(ActionType actionType) {
261        switch (actionType) {
262            case NOTIFICATIONS:
263                onNotificationsOn();
264                break;
265            default:
266                break;
267        }
268    }
269
270    private void onOff(ActionType actionType) {
271        switch (actionType) {
272            case NOTIFICATIONS:
273                onNotificationsOff();
274                break;
275            default:
276                break;
277        }
278    }
279
280    private void onUninstallOk() {
281        mUninstallManager.uninstall(REQUEST_UNINSTALL);
282    }
283
284    private void onNotificationsOn() {
285        if (!mNotificationSetter.enableNotifications()) {
286            Log.w(TAG, "Failed to enable notifications!");
287        }
288        goToActionSelectScreen();
289    }
290
291    private void onNotificationsOff() {
292        if (!mNotificationSetter.disableNotifications()) {
293            Log.w(TAG, "Failed to disable notifications!");
294        }
295        goToActionSelectScreen();
296    }
297
298    private void onOpen() {
299        mOpenManager.open(mApplicationsState);
300        // TODO: figure out what to do here
301    }
302
303    private void onForceStopOk() {
304        mForceStopManager.forceStop(mApplicationsState);
305        goToActionSelectScreen();
306    }
307
308    private void onClearDataOk() {
309        mDataClearer.clearData(this, REQUEST_MANAGE_SPACE);
310        goToActionSelectScreen();
311    }
312
313    private void onClearDefaultOk() {
314        mDefaultClearer.clearDefault(this);
315        goToActionSelectScreen();
316    }
317
318    private void onClearCacheOk() {
319        mCacheClearer.clearCache(this);
320        goToActionSelectScreen();
321    }
322
323    private void goToActionSelectScreen() {
324        updateActions();
325        getFragmentManager().popBackStack(null, 0);
326    }
327
328    private void goToAppSelectScreen() {
329        finish();
330    }
331
332    private ArrayList<Action> getActions() {
333        ArrayList<Action> actions = new ArrayList<Action>();
334
335        if (mOpenManager.canOpen()) {
336            actions.add(ActionType.OPEN.toInitAction(getResources()));
337        }
338        if (mForceStopManager.canForceStop()) {
339            actions.add(ActionType.FORCE_STOP.toInitAction(getResources()));
340        }
341        if (mUninstallManager.canUninstall()) {
342            actions.add(ActionType.UNINSTALL.toInitAction(getResources()));
343        }
344        actions.add(
345                ActionType.CLEAR_DATA.toInitAction(getResources(), mDataClearer.getDataSize(this)));
346        actions.add(ActionType.CLEAR_CACHE.toInitAction(
347                getResources(), mCacheClearer.getCacheSize(this)));
348        actions.add(ActionType.CLEAR_DEFAULTS.toInitAction(
349                getResources(), mDefaultClearer.getDescription(this)));
350        actions.add(ActionType.NOTIFICATIONS.toInitAction(getResources(),
351                getString((mNotificationSetter.areNotificationsOn()) ? R.string.settings_on
352                        : R.string.settings_off)));
353        actions.add(ActionType.PERMISSIONS.toInitAction(getResources()));
354
355        return actions;
356    }
357
358    private void updateActions() {
359        ((ActionAdapter) mActionFragment.getAdapter()).setActions(getActions());
360    }
361}
362