Commit Graph

2184 Commits

Author SHA1 Message Date
Erik Kline
35bf06c968 Add ConnectivityManager.networkCapabilitiesForType()
This static method returns a NetworkCapabilities instance with
transports and capabilities set according to the given legacy type.

Also:
    - add NetworkRequest.Builder.setCapabilities(), to be able to use
      the NetworkCapabilities instances returned from the above
    - update UpstreamNetworkMonitor to make immediate use of this

Test: as follows
    - build (bullhead)
    - flashed
    - booted
    - runtest frameworks-net passes
    - WiFi to DUN upstream tethering works
Bug: 32163131

Change-Id: Idfe1ddd2815c355cbf27cf29eb0e3de177de84e9
2017-02-02 11:07:59 +09:00
Jeremy Joslin
c695a17421 Post runnables instead of sending messages.
Gaining access to a Handler's Looper can be problematic in custom
Handler implementations. Instead of creating a new internal Handler
to dispatch the method calls on we simply post Runnables to the
given Handler.

Test: adb shell am instrument -e class android.net.NetworkRecommendationProviderTest -w com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
Bug: 34845471
Change-Id: I6fe380a92aebd630781abe5853f94737bcfeaa5f
2017-01-31 11:51:25 -08:00
John Reck
ed065024a5 Fix a bunch of repeated reads of a ro.* property
SystemProperties.get() is not particularly fast,
especially if a string is returned. Since ro.* values
are unable to be changed, there's no need to
continously re-query them. Cache the value at
static init time to trivially fix this.

Test: refactoring CL.
Change-Id: Iccb021d3cb2ba3a4a1d0048ddec6811bb7409eec
(cherry picked from commit aa67f684ff)
2017-01-27 11:04:39 -08:00
Jeremy Joslin
84fae83f8c Mark the INetworkScoreCache as oneway.
Test: built & run
Bug: 34522097
Change-Id: I7d2075febe6c3cdc24b56df255f8ba59e13322bf
2017-01-23 10:51:41 -08:00
Amin Shaikh
b50ade8bb0 Add additional fields to RecommendationRequest.
- Add networkId and timestamp for the last user selected network

Bug: 34467596
Test: runtest --path core/tests/coretests/src/android/net/RecommendationRequestTest.java
Change-Id: Ic81c1beede1a643cd428b6e5c57ed430a6b1ccc0
Merged-In: Ic81c1beede1a643cd428b6e5c57ed430a6b1ccc0
2017-01-20 09:37:59 -08:00
Jeremy Joslin
122957b0b0 Pass more data through the recommendation request.
Expanding the API so it can accept the WiFi config of the currently
connected network (if any) and the set of connectable WiFi
configurations. Also renamed currentRecommendedWifiConfig to
defaultWifiConfig so the name was more representative of the
parameter's purpose and added more documentation throughout.

Test: adb shell am instrument -e class android.net.RecommendationRequestTest -w com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
Test: adb shell am instrument -w com.android.networkrecommendation.tests/android.support.test.runner.AndroidJUnitRunner
Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
Bug: 34387385
Change-Id: Ib8c3cab8f92b5c9da806070d32412f688690f82f
Merged-In: I1089b70303b0396def7e6bf3737fdc67e40c9dcd
2017-01-19 16:14:21 -08:00
Jeremy Joslin
88f50a5a08 Have requestRecommendation return a CompletableFuture.
Reworked the new requestRecommendation call to return a
CompletableFuture instead of using a custom callback.

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
Bug: 33784158
Change-Id: Ib12f0674d45ad6e2e21449bc3665467b3c20f49d
Merged-In: If24a94eb6289cb1952052b2cc3bc7856ce2192a5
2017-01-19 13:31:16 -08:00
Jeremy Joslin
cb925074d3 Async network recommendation requests.
Exposing a new hidden API method that allows network recommendations
to be requested asynchronously.

Test: Built & run.
BUG:33784158
Change-Id: I8d210b686138cb42bf69185f0b2f2d25dfcb9dd1
Merged-In: I8f84b09f43a6c5fae5d8f03ec01e75c25b4b62d6
2017-01-19 13:18:21 -08:00
Etan Cohen
dfe8f5dc13 Merge "[AWARE] Unhide Wi-Fi Aware API (baseline)" 2017-01-11 22:59:25 +00:00
Treehugger Robot
b5488ec3b3 Merge "Move getActiveScorerPackage() to the score service." 2017-01-11 19:40:45 +00:00
Etan Cohen
6a4b323f08 [AWARE] Unhide Wi-Fi Aware API (baseline)
Baseline Wi-Fi Aware API providing discovery and connectivity (data-path).

Bug: 30983968
Test: unit tests + integration (sl4a) tests passing.
Change-Id: Idd7c6a625f168717b083d5f13e291ce916571933
2017-01-11 11:13:26 -08:00
Neil Fuller
649a89e524 Merge "Refactor RFCOMM / BluetoothSocket usage of LocalSocket" 2017-01-11 13:27:10 +00:00
Treehugger Robot
663b444196 Merge "Moved isCallerActiveScorer() to the score service." 2017-01-11 01:30:03 +00:00
Treehugger Robot
60d10ea0f4 Merge changes I559eb049,I52425b84
* changes:
  DO NOT MERGE Captive portals: login activity probes like NetworkMonitor
  DO NOT MERGE Logging improvements in CaptivePortalLoginActivity
2017-01-11 01:06:57 +00:00
Jeremy Joslin
d7670f6d7c Move getActiveScorerPackage() to the score service.
Implemented getActiveScorerPackage() in the NetworkScoreService to
make it more efficient (no need to query PM).

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
Bug: 33781558
Change-Id: Iee7610e4982b44aefa1ef8b6c208292b8f9adcf8
Merged-In: I2144351c2c09cad30f80399069364f3572e38445
2017-01-10 16:41:42 -08:00
Jeremy Joslin
9b442faa91 Moved isCallerActiveScorer() to the score service.
Implemented isCallerActiveScorer() in the NetworkScoreService to make
it more efficient (no need to query PM). Exposed the call as a new
internal API on NetworkScoreManager and deprecated the call on
NetworkScorerAppManager.

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
Bug: 33781558
Change-Id: I8ad232f8ef34b6e2f155ebb232e64300303300f0
Merged-In: I0e2142af95b068d322343f7c9362ac53d46b545e
2017-01-10 16:11:33 -08:00
Treehugger Robot
e34e47d645 Merge "Cherrypick: Create ScoredNetwork Badging API changes." 2017-01-09 23:39:48 +00:00
Sundeep Ghuman
8bc096c09d Cherrypick: Create ScoredNetwork Badging API changes.
Defines an attribute bundles key to hold the badging curve, the
enums for badge values, and an API to retrieve a badge for a
specific RSSI.

OCL: ag/1727147
Bug: 33457699
Test: Unit tests
Change-Id: If9e8a60c4670b51c395fb501f55ddece8a72981e
Merged-In: If9e8a60c4670b51c395fb501f55ddece8a72981e
2017-01-09 12:57:02 -08:00
Jeremy Joslin
186f3339ab Check for REQUEST_NETWORK_SCORES instead of BROADCAST_NETWORK_PRIVILEGED.
Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
BUG: 33752149
Change-Id: I3dd352c98bbc34b128ab9c2a28f81e1261ae2669
Merged-In: I7d91fa9a4f6ef4f9170c6af98567ce443c805e74
2017-01-09 11:03:21 -08:00
Neil Fuller
7fd724611b Refactor RFCOMM / BluetoothSocket usage of LocalSocket
LocalSocket is used by BluetoothSocket. BluetoothSocket
passes a pre-created file descriptor to LocalSocket that
is then given to the LocalSocketImpl.

Commit b08c7bc0bd broke the
behavior. Commit 7a8c36aa4e
put in a minimal fix.

This change tidies up LocalSocket and associated classes
and replaces a specialist constructor with a factory method
to highlight the special case. While there an unnecessary
exception has been removed.

Bug: 34111534
Test: Boot device
Test: vogar --mode app_process tests/tests/net/src/android/net/cts/LocalSocketTest.java
Change-Id: I4ba2f2d9ea361a950ff8bc8d64fc800d998c3210
2017-01-06 14:18:07 +00:00
Treehugger Robot
616910fd53 Merge "Prevent LocalSocket from creating an fd if fd is already there" 2017-01-06 01:29:47 +00:00
Ajay Panicker
7a8c36aa4e Prevent LocalSocket from creating an fd if fd is already there
Any LocalSocket created with a FileDescriptor will throw IOExceptions
when performing most opperations due to the fact that the LocalSocket
tries to create an implementation but fails since there is a FileDescriptor
already set.

Bug: 34095140
Test: Setup using tap&go
Change-Id: Ie8f50def6156c16617697d939d6c0ab570281642
2017-01-05 23:52:30 +00:00
Amin Shaikh
2cd918a63e Fix NetworkScorerAppManager#isCallerActiveScorer.
The current implementation checks whether the caller's uid has the
SCORE_NETWORKS permission instead of checking the passed in callingUid. I
removed this check entirely because the getActiveScorer method already checks
whether the scorer's package has the SCORE_NETWORKS permission. There is no way
callingUid can equal the active scoring package's uid without also having the
SCORE_NETWORKS permission.

Bug: 34107721
Test: runtest --path core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
Change-Id: Ifd427792169837c84a10a76b208c76137db06ae9
2017-01-05 14:28:47 -08:00
Hugo Benichi
2c02197bdd DO NOT MERGE Captive portals: login activity probes like NetworkMonitor
This patch changes CaptivePortalLoginActivity captive portal test to be
consistent with NetworkMonitor by:
 - using Network.java to open the http connection.
 - adding a UserAgent property to the request header.

Test: manually tested.
Bug: 32369183

(cherry picked from commit cdf3ba48cc)

Change-Id: I559eb0497475daad758ba3b3395225dcd0a27a57
2017-01-05 12:12:50 +09:00
Treehugger Robot
944b017031 Merge "Expose RecommendationRequest.Builder as SystemApi." 2017-01-04 19:42:17 +00:00
Joe LaPenna
010e8b0dc8 Expose RecommendationRequest.Builder as SystemApi.
In order to test our recommender, we need to be able to create
network recommendation requests.

Test: make update-api
Change-Id: I68df0d3e684bcdb90709a34478d2aa669ee23547
Merged-In: I68df0d3e684bcdb90709a34478d2aa669ee23547
2017-01-04 10:15:52 -08:00
Treehugger Robot
75ba827a4e Merge "Set isConnected, isBound, implCreated on server-side LocalSockets" 2017-01-04 12:26:49 +00:00
Neil Fuller
b08c7bc0bd Set isConnected, isBound, implCreated on server-side LocalSockets
Previously LocalServerSocket.accept() would return a LocalSocket
instance with isConnected, isBound and implCreated set to false.
[implCreated determines whether impl.create() needs to called].

A socket created via accept() in this way is implicitly bound
and connected. impl.create() does not need to be called because
impl.accept(LocalSocketImpl s) is called instead and has the same
effect (s.fd and s.mFdCreatedInternally set correctly).

This change modifies the behavior so that the flags are now all
set to true in this case and isBound() and isConnected() will
now return the correct answer.

Attempts to call bind() and connect() will still throw
IOException as before, but with a different exception message.

Correctly setting implCreated in LocalSocket means that
LocalSocketImpl.create() will no longer be called for accept()
created sockets and no longer needs to treat the "fd != null"
case as a no-op: we can now assert that there must be no fd set
when create() is called as we will no longer call it with sockets
created using accept().

Bug: https://code.google.com/p/android/issues/detail?id=35942
Test: Device boot
Test: vogar --mode app_process cts/tests/tests/net/src/android/net/cts/LocalServerSocketTest.java
Test: vogar --mode app_process cts/tests/tests/net/src/android/net/cts/LocalSocketTest.java
Change-Id: I3ac55439412e84501ae7c5ae6c9976e03b2d6fc5
2017-01-04 10:33:18 +00:00
Treehugger Robot
425af45d02 Merge "Cherrypick: Define the calculateRankingScore method and Key." 2016-12-22 00:03:57 +00:00
Sundeep Ghuman
0d79bdef27 Cherrypick: Define the calculateRankingScore method and Key.
Define the key to be used to store the rankingScoreOffset inside the
ScoredNetwork bundle. Implement a platform API method to calculate the
ranking score for a given rssi.

OCL: ag/1688711

Bug: 33049302
Test: Unit tests
Change-Id: Ia3fea2197d7c211a2313fced8713d79d8d5f4f6e
Merged-In: Ia3fea2197d7c211a2313fced8713d79d8d5f4f6e
Topic: ScoredNetworkRankingScore
2016-12-21 13:57:24 -08:00
Jeff Sharkey
febd982cdd Merge "Avoid Calendar's unexpect change in snapToCycleDay()" 2016-12-21 21:11:20 +00:00
Amin Shaikh
3d18c621cb Expose ScanResult#untrusted as a @SystemApi.
- Expose ScanResult#untrusted to inform NetworkRecommendationProviders
  that a ScanResult does not correspond to a saved network.
- Add static construction methods and assertions to RecommendationResult

Test: runtest frameworks-services

Bug: 33490132
Change-Id: If7006040f63843c1c468c9d95c5c017383c5c5dd
Merged-In: If7006040f63843c1c468c9d95c5c017383c5c5dd
2016-12-21 11:46:22 -08:00
Shunta Sato
d18ffd8223 Avoid Calendar's unexpect change in snapToCycleDay()
Symptom:
Calendar object's certain field is unexpectedly changed after
using Calendar.add() method.

Detail and sample:
Following patch causes this issue.
- Switch network cycle calculation to use Calendar.
  https://android.googlesource.com/platform/frameworks/base/+/f2bead5

Call of Calendar.add() method might make a smaller field value
invariant. The smaller field means such a field of
Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND and so on
if Calendar.MONTH field is focused.
According to above, sometimes correct Calendar value won't be
acquired by original code.
To avoid unexpected change, it requires initialization toward
each smaller field after Calendar.add() call.

Solutions:
Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE,
and Calendar.SECOND fields is set to 0 after added value to
Calendar.MONTH field.

Bug: 32724903
Author: Shigeki Yokomichi <shigeki.x.yokomichi@sonymobile.com>
Change-Id: I7af6391653be21786b662b2f8eaad10c413733c1
2016-12-21 12:44:30 -07:00
Jeremy Joslin
36d4c48496 Implement the request and recommend calls.
Implemented requestRecommendation() and requestScores() to call
through to the bound network recommendation provider if available.

BUG: 33593157
BUG: 33668692
Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
Change-Id: I055251fa94d93d4ea4e5001c4ec6c1dfb626d1b2
Merged-In: I8e2ed73dc6876deb1a8bd47bcaeaca8db68f3a44
2016-12-19 17:53:47 -08:00
Jeremy Joslin
b8418ac89a Implement the discovery of a network recommendation provider.
Updated the NetworkScorerAppManager to examine the list of configured
network recommendation providers and to select the first valid
provider.

As part of this update the old logic of looking for a valid network
scorer has been removed. Scorers/recommendation providers are only
selected from the configured list now. The setActiveScorer() method
has been deprecated as a result.

The NetworkScoreService has been updated to monitor the list of
potential recommendation providers and to reevaluate the binding
whenever they change. It also monitors the new setting for
NETWORK_RECOMMENDATIONS_ENABLED to connect or disconnect from the
provider as needed.

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
BUG: 33158362
Change-Id: I450981261aa5355c1c91ec2e3a0a3b58cc65316b
Merged-In: I42aeb5223da794f71f7e58cb1bdf18817200cbf2
2016-12-19 17:53:47 -08:00
Treehugger Robot
5fdc86fb27 Merge "Fix ScanResult array parceling." 2016-12-19 21:57:05 +00:00
Joe LaPenna
68685240f5 Remove "final" from ResultCallback.
Removing final makes providers easier to test using mocks.

Test: Build system image.

Change-Id: Iaaa30f73226e1d0cb0e9e68faa349e86986be72d
Merged-In: Iaaa30f73226e1d0cb0e9e68faa349e86986be72d
2016-12-19 11:25:45 -08:00
Jeremy Joslin
ab60cb6a6d Fix ScanResult array parceling.
readParcelableArray() wasn't working as expected so I just parceled
the array myself.

Test: adb shell am instrument -e class android.net.RecommendationRequestTest  -w com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I83939d17769930b707b8bc579542c74a05e31d19
Merged-In: I47bc31adbedea817feaa5953cb6ee48506f9c6d6
2016-12-19 09:43:34 -08:00
Erik Kline
ade3a8ccb0 Have IpManager track L2-L4 signaling traffic required for IP connectivity.
Test: as follows
    - built and flashed
    - observed logcat
    - observed "dumpsys wifi ipmanager"
    - runtest BlockingSocketReaderTest passes
    - runtest ConnectivityPacketSummaryTest passes
Bug: 21859053
Bug: 26101306
Bug: 31742572
Bug: 31707128
Bug: 33531488

Change-Id: Ibecaf809dcc1813924b25749e8ba8eb2d4bdf114
2016-12-15 19:09:49 +09:00
Jeremy Joslin
e7f273d508 Add an IPC for requesting network scores.
Migrating the NetworkScoreManager.requestScores() method to use an
IPC rather than a broadcast.

Defined the new IPC in the AIDL files for NetworkScoreService and
NetworkRecommendationProvider. Added a no-op implementation in
NetworkScoreService and a full implementation in
NetworkRecommendationProvider (plus tests).

Test: adb shell am instrument -e class android.net.NetworkRecommendationProviderTest -w com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
BUG: 33593157
Change-Id: Iacf7b6d424ec3c57e8b89e5abc6bc3e8414097b9
Merged-In: I951f6186aa11ddbe5a94e374173a1fd40b2a4cce
2016-12-14 09:11:29 -08:00
Jeremy Joslin
280f82c312 Make the onRequestRecommendation() method async.
Converted the NetworkRecommendationProvider.onRequestRecommendation()
method into an async call to give implementors more flexibility.

Added unit tests for NetworkRecommendationProvider.

Test: Added NetworkRecommendationProviderTest.
BUG: 32909424
Change-Id: I8c1d2e11baa539744d77a012e85351f750523e3b
Merged-In: Iebe72f260133e9ad1946b0b75e2f69635e154ef3
2016-12-12 17:48:41 -08:00
Sundeep Ghuman
23f98ebe33 Fix erroneous constructor in ScoredNetwork.java
Test: Unit tests in ag/310934.
Change-Id: I0075b15f59796872ea9779c04373563607d2f883
2016-12-12 14:36:03 -08:00
Jeremy Joslin
823db059e4 Update registerNetworkScoreCache() to accept a filter type.
Defined a new IntDef in NetworkScoreManager named CacheUpdateFilter
with 3 values. Caches must be registered with a filter value and will
only receive updates based on their registered filter. Actual
filtering implementation will follow.

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
BUG: 32912120
Change-Id: I3ce0bee171e6405176358479fa8a532fd5193824
Merged-In: I8940e0ed1a7bbcb5a81fb3b6a7fafe4fbbc33875
2016-12-09 13:15:15 -08:00
Stephen Chen
963e8ddf6d DO NOT MERGE: Implement metered tracking for NetworkStats summary queries.
Dependent on ag/1550196 where API is defined.

Bug: 31015360
Bug: 26545374
Test: runtest --path
frameworks/base/core/tests/coretests/src/android/net/NetworkStatsTest.java,
other test classes.

(cherry picked from commit 2514787897)

Change-Id: I46da93ba4afa968facf98f7c3d844fd0c469095a
2016-12-09 13:59:33 +09:00
Hugo Benichi
21680fd25d DO NOT MERGE: NetworkMonitor metrics: add first validation information
This patch adds first validation information to:
  - ValidationProbeEvent, by extending the probe_type int field of to
    also include a bit indicating if the probe was part of a first
    validation attempt or not.
  - NetworkMonitorEvent, by defining new contants for the event_type
    field.

Test: $ runtest frameworks-net
      + manually generating events and inspecting the
        output of $ adb shell dumpsys connmetrics list
Bug: b/32198726

(cherry picked from commit 147aa6d53b)

Change-Id: Ie7a62c4f62a13ce52806d3adaa9e627cb246073c
2016-12-09 13:59:20 +09:00
Jeff Sharkey
dda938a698 DO NOT MERGE: Switch over to new "time.android.com" NTP pool.
Also add logging to measure success/failure details.

Test: builds, boots, and NTP fix obtained
Bug: 32969463

(cherry picked from commit d3f689bf14)

Change-Id: I7da416099ae903fd92beb516251ef4e51673eecf
2016-12-09 13:59:18 +09:00
Jeremy Joslin
ffe5a46b3e DO NOT MERGE: VPN network stat accounting changes.
Properly account for VPN apps that make heavy use of the tun
interface. Prior to this change a VPN app could be incorrectly charged
for more data than it actually used if it sent more traffic through
the tun interface than the underlying interface.

This change excludes VPN app traffic on the tun interface from the
adjustment pool and doesn't redistribute traffic to the VPN app.
Instead all of the redistributed traffic is deducted from the VPN app
which effectively represents any overhead incurred by the VPN app.

BUG: 30557871

(cherry picked from commit 8b436d865c)

Change-Id: I06f01aa8fe5fdc06b2d36cfb9c68feb244c2e5de
2016-12-09 13:42:29 +09:00
Hugo Benichi
ce765b7a51 DO NOT MERGE: ConnectivityThread: use lazy holder idiom
This patch changes the way that the ConnectivityThread is lazily
instantiated by using the "lazy initialization holder class idiom".

The first code point that tries to obtain a reference to the unique
ConnectivityThread instance will trigger the creation of the Singleton
class, which will guarantee a thread-safe initialization of the static
INSTANCE field inside Singleton according to the language specs.

This is the Item #71 of Effective Java.

The unique static instance of ConnectivityThread is not stored directly
inside ConnectivityThread class but is stored in a static nested class.
This is to avoid triggering the creation of that unique instance when
Zygote does class preloading at phone startup. Otherwise this would lead
to Zygote creating a new OS thread during preloading, which is a fatal
error.

Test: frameworks-wifi tests pass
Bug: 26749700
Bug: 28537383
Bug: 32130437

(cherry picked from commit c4fe5d373c)

Change-Id: If13b363889a8e9396273a90c3d9f9421a48aecbc
2016-12-09 13:42:26 +09:00
Hugo Benichi
1853f78d76 DO NOT MERGE: ConnectivityManager: use ConnectivityThread looper
This patch removes the static singleton looper used by
ConnectivityManager and instead uses the common ConnectivityThread.

This allows to removes the static atomic counter used to track
the number of registered NetworkCallback in ConnectivityManager, because
the looper is not turned off anymore when no callbacks are registered.

Also an overloaded version of sendRequestForNetwork is added taking as a
new parameter a Handler. This will allow to overload various callback
and request related API calls with user provided Handlers.

Test: ConnectivityServiceTest passes
Bug: 26749700
Bug: 28537383
Bug: 32130437

(cherry picked from commit 7724cdd8b9)

Change-Id: If956addbf8e7b11b36a4b966de7fca00e8f362c1
2016-12-09 13:42:24 +09:00
Hugo Benichi
4983e55853 DO NOT MERGE: ConnectivityManager: a simpler CallbackHandler
This patch simplifies CallbackHandler in the following way:
  - CallbackHandler directly uses the static references to
    sNetworkCallback and sCallbackRefCount. This allows to remove
    instance fields in CallbackHandler.
  - CallbackHandler does not have a reference to ConnectivityManager
    anymore
  - CallbackHandler.getObject() is now generic in a type-safe way.

Test: ConnectivityServiceTest passes
Bug: 28537383
Bug: 32130437

(cherry picked from commit d42650faaa)

Change-Id: I1b5fe2a361b5f623a8310ae698497c83d72f3034
2016-12-09 13:42:20 +09:00