From http://www.jwz.org/xscreensaver/xscreensaver-5.40.tar.gz
[xscreensaver] / android / xscreensaver / src / org / jwz / xscreensaver / Activity.java
1 /* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
4  * and Dennis Sheil <dennis@panaceasupplies.com>
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation.  No representations are made about the suitability of this
11  * software for any purpose.  It is provided "as is" without express or 
12  * implied warranty.
13  *
14  * This is the XScreenSaver "application" that just brings up the
15  * Live Wallpaper preferences.
16  */
17
18 package org.jwz.xscreensaver;
19
20 import android.app.WallpaperManager;
21 import android.content.ComponentName;
22 import android.content.Intent;
23 import android.os.Build;
24 import android.os.Bundle;
25 import android.view.View;
26 import android.provider.Settings;
27 import android.Manifest;
28 import android.support.v4.app.ActivityCompat;
29 import android.support.v4.content.ContextCompat;
30 import android.os.Build;
31 import android.content.pm.PackageManager;
32
33 public class Activity extends android.app.Activity
34   implements View.OnClickListener {
35
36   private boolean wallpaperButtonClicked, daydreamButtonClicked;
37   private final static int MY_REQ_READ_EXTERNAL_STORAGE = 271828;
38
39   @Override
40   protected void onCreate(Bundle savedInstanceState) {
41     super.onCreate(savedInstanceState);
42     // openList();
43     setContentView(R.layout.activity_xscreensaver);
44     wallpaperButtonClicked = false;
45     daydreamButtonClicked = false;
46
47     findViewById(R.id.apply_wallpaper).setOnClickListener(this);
48     findViewById(R.id.apply_daydream).setOnClickListener(this);
49   }
50
51   @Override
52   public void onClick(View v) {
53     switch (v.getId()) {
54     case R.id.apply_wallpaper:
55       wallpaperButtonClicked();
56       break;
57     case R.id.apply_daydream:
58       daydreamButtonClicked();
59       break;
60     }
61   }
62
63   // synchronized when dealing with wallpaper state - perhaps can
64   // narrow down more
65   private synchronized void withProceed() {
66     if (daydreamButtonClicked) {
67       String action;
68       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
69         action = Settings.ACTION_DREAM_SETTINGS;
70       } else {
71         action = Settings.ACTION_DISPLAY_SETTINGS;
72       }
73       startActivity(new Intent(action));
74     } else if (wallpaperButtonClicked) {
75       startActivity(new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER));
76     }
77   }
78
79   private void wallpaperButtonClicked() {
80       wallpaperButtonClicked = true;
81       checkPermission();
82   }
83
84   private void daydreamButtonClicked() {
85       daydreamButtonClicked = true;
86       checkPermission();
87   }
88
89   void checkPermission() {
90       // RES introduced in API 16
91       String permission = Manifest.permission.READ_EXTERNAL_STORAGE;
92       if (havePermission(permission)) {
93           withProceed();
94       } else {
95           noPermission(permission);
96       }
97   }
98
99   private void noPermission(String permission) {
100       int myRequestCode;
101       myRequestCode = MY_REQ_READ_EXTERNAL_STORAGE;
102
103       if (permissionsDeniedRationale(permission)) {
104           showDeniedRationale();
105       } else {
106           requestPermission(permission, myRequestCode);
107       }
108   }
109
110   private boolean permissionsDeniedRationale(String permission) {
111       boolean rationale = ActivityCompat.shouldShowRequestPermissionRationale(this,
112                 permission);
113       return rationale;
114   }
115
116   private void requestPermission(String permission, int myRequestCode) {
117       ActivityCompat.requestPermissions(this,
118               new String[]{permission},
119               myRequestCode);
120
121       // myRequestCode is an app-defined int constant.
122       // The callback method gets the result of the request.
123   }
124
125   // TODO: This method should be asynchronous, and not block the thread
126   private void showDeniedRationale() {
127     withProceed();
128   }
129
130   boolean havePermission(String permission) {
131
132       if (Build.VERSION.SDK_INT < 16) {
133           return true;
134       }
135
136       if (permissionGranted(permission)) {
137           return true;
138       }
139
140       return false;
141   }
142
143   private boolean permissionGranted(String permission) {
144         boolean check = ContextCompat.checkSelfPermission(this, permission) ==
145                 PackageManager.PERMISSION_GRANTED;
146       return check;
147   }
148
149   public void proceedIfPermissionGranted(int[] grantResults) {
150
151       // If request is cancelled, the result arrays are empty.
152       if (grantResults.length > 0
153               && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
154           withProceed();
155       } else if (grantResults.length > 0) {
156           withProceed();
157       }
158   }
159
160   @Override
161   public void onRequestPermissionsResult(int requestCode,
162         String permissions[], int[] grantResults) {
163     switch (requestCode) {
164       case MY_REQ_READ_EXTERNAL_STORAGE:
165           proceedIfPermissionGranted(grantResults);
166     }
167   }
168
169 }